|
@@ -33,6 +33,7 @@
|
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
*/
|
|
|
|
|
|
+#include <linux/fs_struct.h>
|
|
|
#include <linux/file.h>
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/namei.h>
|
|
@@ -299,7 +300,7 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval)
|
|
|
static __be32
|
|
|
nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
|
|
|
struct iattr *iattr, struct nfs4_acl **acl,
|
|
|
- struct xdr_netobj *label)
|
|
|
+ struct xdr_netobj *label, int *umask)
|
|
|
{
|
|
|
int expected_len, len = 0;
|
|
|
u32 dummy32;
|
|
@@ -457,6 +458,17 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
|
|
|
return nfserr_jukebox;
|
|
|
}
|
|
|
#endif
|
|
|
+ if (bmval[2] & FATTR4_WORD2_MODE_UMASK) {
|
|
|
+ if (!umask)
|
|
|
+ goto xdr_error;
|
|
|
+ READ_BUF(8);
|
|
|
+ len += 8;
|
|
|
+ dummy32 = be32_to_cpup(p++);
|
|
|
+ iattr->ia_mode = dummy32 & (S_IFMT | S_IALLUGO);
|
|
|
+ dummy32 = be32_to_cpup(p++);
|
|
|
+ *umask = dummy32 & S_IRWXUGO;
|
|
|
+ iattr->ia_valid |= ATTR_MODE;
|
|
|
+ }
|
|
|
if (len != expected_len)
|
|
|
goto xdr_error;
|
|
|
|
|
@@ -651,7 +663,8 @@ nfsd4_decode_create(struct nfsd4_compoundargs *argp, struct nfsd4_create *create
|
|
|
return status;
|
|
|
|
|
|
status = nfsd4_decode_fattr(argp, create->cr_bmval, &create->cr_iattr,
|
|
|
- &create->cr_acl, &create->cr_label);
|
|
|
+ &create->cr_acl, &create->cr_label,
|
|
|
+ ¤t->fs->umask);
|
|
|
if (status)
|
|
|
goto out;
|
|
|
|
|
@@ -896,13 +909,15 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
|
|
|
case NFS4_OPEN_NOCREATE:
|
|
|
break;
|
|
|
case NFS4_OPEN_CREATE:
|
|
|
+ current->fs->umask = 0;
|
|
|
READ_BUF(4);
|
|
|
open->op_createmode = be32_to_cpup(p++);
|
|
|
switch (open->op_createmode) {
|
|
|
case NFS4_CREATE_UNCHECKED:
|
|
|
case NFS4_CREATE_GUARDED:
|
|
|
status = nfsd4_decode_fattr(argp, open->op_bmval,
|
|
|
- &open->op_iattr, &open->op_acl, &open->op_label);
|
|
|
+ &open->op_iattr, &open->op_acl, &open->op_label,
|
|
|
+ ¤t->fs->umask);
|
|
|
if (status)
|
|
|
goto out;
|
|
|
break;
|
|
@@ -916,7 +931,8 @@ nfsd4_decode_open(struct nfsd4_compoundargs *argp, struct nfsd4_open *open)
|
|
|
READ_BUF(NFS4_VERIFIER_SIZE);
|
|
|
COPYMEM(open->op_verf.data, NFS4_VERIFIER_SIZE);
|
|
|
status = nfsd4_decode_fattr(argp, open->op_bmval,
|
|
|
- &open->op_iattr, &open->op_acl, &open->op_label);
|
|
|
+ &open->op_iattr, &open->op_acl, &open->op_label,
|
|
|
+ ¤t->fs->umask);
|
|
|
if (status)
|
|
|
goto out;
|
|
|
break;
|
|
@@ -1153,7 +1169,7 @@ nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *seta
|
|
|
if (status)
|
|
|
return status;
|
|
|
return nfsd4_decode_fattr(argp, setattr->sa_bmval, &setattr->sa_iattr,
|
|
|
- &setattr->sa_acl, &setattr->sa_label);
|
|
|
+ &setattr->sa_acl, &setattr->sa_label, NULL);
|
|
|
}
|
|
|
|
|
|
static __be32
|