aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2007-11-30 16:55:23 -0500
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-02-01 16:42:07 -0500
commit5c002b3bb294a637312cab7ad92a0deafa05a758 (patch)
tree0183f792fe61fe1bb6a117baf385020feb5b085c /fs
parent29dbf546159f5701e11de26fa2da5c4a962e0f83 (diff)
nfsd: allow root to set uid and gid on create
The server silently ignores attempts to set the uid and gid on create. Based on the comment, this appears to have been done to prevent some overly-clever IRIX client from causing itself problems. Perhaps we should remove that hack completely. For now, at least, it makes sense to allow root (when no_root_squash is set) to set uid and gid. While we're there, since nfsd_create and nfsd_create_v3 share the same logic, pull that out into a separate function. And spell out the individual modifications of ia_valid instead of doing them both at once inside a conditional. Thanks to Roger Willcocks <roger@filmlight.ltd.uk> for the bug report and original patch on which this is based. Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/vfs.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 755ba43c13e1..cc75e4fcd02b 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1151,6 +1151,26 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
1151} 1151}
1152#endif /* CONFIG_NFSD_V3 */ 1152#endif /* CONFIG_NFSD_V3 */
1153 1153
1154__be32
1155nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp,
1156 struct iattr *iap)
1157{
1158 /*
1159 * Mode has already been set earlier in create:
1160 */
1161 iap->ia_valid &= ~ATTR_MODE;
1162 /*
1163 * Setting uid/gid works only for root. Irix appears to
1164 * send along the gid on create when it tries to implement
1165 * setgid directories via NFS:
1166 */
1167 if (current->fsuid != 0)
1168 iap->ia_valid &= ~(ATTR_UID|ATTR_GID);
1169 if (iap->ia_valid)
1170 return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
1171 return 0;
1172}
1173
1154/* 1174/*
1155 * Create a file (regular, directory, device, fifo); UNIX sockets 1175 * Create a file (regular, directory, device, fifo); UNIX sockets
1156 * not yet implemented. 1176 * not yet implemented.
@@ -1167,6 +1187,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1167 struct dentry *dentry, *dchild = NULL; 1187 struct dentry *dentry, *dchild = NULL;
1168 struct inode *dirp; 1188 struct inode *dirp;
1169 __be32 err; 1189 __be32 err;
1190 __be32 err2;
1170 int host_err; 1191 int host_err;
1171 1192
1172 err = nfserr_perm; 1193 err = nfserr_perm;
@@ -1257,16 +1278,9 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
1257 } 1278 }
1258 1279
1259 1280
1260 /* Set file attributes. Mode has already been set and 1281 err2 = nfsd_create_setattr(rqstp, resfhp, iap);
1261 * setting uid/gid works only for root. Irix appears to 1282 if (err2)
1262 * send along the gid when it tries to implement setgid 1283 err = err2;
1263 * directories via NFS.
1264 */
1265 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) {
1266 __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
1267 if (err2)
1268 err = err2;
1269 }
1270 /* 1284 /*
1271 * Update the file handle to get the new inode info. 1285 * Update the file handle to get the new inode info.
1272 */ 1286 */
@@ -1295,6 +1309,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1295 struct dentry *dentry, *dchild = NULL; 1309 struct dentry *dentry, *dchild = NULL;
1296 struct inode *dirp; 1310 struct inode *dirp;
1297 __be32 err; 1311 __be32 err;
1312 __be32 err2;
1298 int host_err; 1313 int host_err;
1299 __u32 v_mtime=0, v_atime=0; 1314 __u32 v_mtime=0, v_atime=0;
1300 1315
@@ -1399,16 +1414,10 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp,
1399 iap->ia_atime.tv_nsec = 0; 1414 iap->ia_atime.tv_nsec = 0;
1400 } 1415 }
1401 1416
1402 /* Set file attributes.
1403 * Irix appears to send along the gid when it tries to
1404 * implement setgid directories via NFS. Clear out all that cruft.
1405 */
1406 set_attr: 1417 set_attr:
1407 if ((iap->ia_valid &= ~(ATTR_UID|ATTR_GID|ATTR_MODE)) != 0) { 1418 err2 = nfsd_create_setattr(rqstp, resfhp, iap);
1408 __be32 err2 = nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); 1419 if (err2)
1409 if (err2) 1420 err = err2;
1410 err = err2;
1411 }
1412 1421
1413 /* 1422 /*
1414 * Update the filehandle to get the new inode info. 1423 * Update the filehandle to get the new inode info.