[CIFS] Fix missing permission check on setattr when noperm mount option is disabled. Also set mode, uid, gid better on mkdir and create for the case when Unix Extensions is not enabled and setuids is enabled. This is necessary to fix the hole in which chown could be allowed for non-root users in some cases if root mounted, and also to display the mode and uid properly in some cases.

Signed-off-by: Steve French <sfrench@us.ibm.com>

+60 -13
+1 -1
fs/cifs/CHANGES
··· 6 6 Fix SFU style symlinks and mknod needed for servers which do not support the 7 7 CIFS Unix Extensions. Fix setfacl/getfacl on bigendian. Timeout negative 8 8 dentries so files that the client sees as deleted but that later get created 9 - on the server will be recognized. 9 + on the server will be recognized. Add client side permission check on setattr. 10 10 11 11 Version 1.38 12 12 ------------
+24 -6
fs/cifs/README
··· 278 278 (such as Windows), permissions can also be checked at the 279 279 client, and a crude form of client side permission checking 280 280 can be enabled by specifying file_mode and dir_mode on 281 - the client 281 + the client. Note that the mount.cifs helper must be 282 + at version 1.10 or higher to support specifying the uid 283 + (or gid) in non-numberic form. 282 284 gid If CIFS Unix extensions are not supported by the server 283 285 this overrides the default gid for inodes. 284 286 file_mode If CIFS Unix extensions are not supported by the server ··· 347 345 client system. It is typically only needed when the server 348 346 supports the CIFS Unix Extensions but the UIDs/GIDs on the 349 347 client and server system do not match closely enough to allow 350 - access by the user doing the mount. 348 + access by the user doing the mount, but it may be useful with 349 + non CIFS Unix Extension mounts for cases in which the default 350 + mode is specified on the mount but is not to be enforced on the 351 + client (e.g. perhaps when MultiUserMount is enabled) 351 352 Note that this does not affect the normal ACL check on the 352 353 target machine done by the server software (of the server 353 354 ACL against the user name provided at mount time). ··· 373 368 setuids If the CIFS Unix extensions are negotiated with the server 374 369 the client will attempt to set the effective uid and gid of 375 370 the local process on newly created files, directories, and 376 - devices (create, mkdir, mknod). 371 + devices (create, mkdir, mknod). If the CIFS Unix Extensions 372 + are not negotiated, for newly created files and directories 373 + instead of using the default uid and gid specified on the 374 + the mount, cache the new file's uid and gid locally which means 375 + that the uid for the file can change when the inode is 376 + reloaded (or the user remounts the share). 377 377 nosetuids The client will not attempt to set the uid and gid on 378 378 on newly created files, directories, and devices (create, 379 379 mkdir, mknod) which will result in the server setting the 380 380 uid and gid to the default (usually the server uid of the 381 381 user who mounted the share). Letting the server (rather than 382 - the client) set the uid and gid is the default. This 383 - parameter has no effect if the CIFS Unix Extensions are not 384 - negotiated. 382 + the client) set the uid and gid is the default. If the CIFS 383 + Unix Extensions are not negotiated then the uid and gid for 384 + new files will appear to be the uid (gid) of the mounter or the 385 + uid (gid) parameter specified on the mount. 385 386 netbiosname When mounting to servers via port 139, specifies the RFC1001 386 387 source name to use to represent the client netbios machine 387 388 name when doing the RFC1001 netbios session initialize. ··· 429 418 byte range locks). 430 419 remount remount the share (often used to change from ro to rw mounts 431 420 or vice versa) 421 + sfu When the CIFS Unix Extensions are not negotiated, attempt to 422 + create device files and fifos in a format compatible with 423 + Services for Unix (SFU). In addition retrieve bits 10-12 424 + of the mode via the SETFILEBITS extended attribute (as 425 + SFU does). In the future the bottom 9 bits of the mode 426 + mode also will be emulated using queries of the security 427 + descriptor (ACL). 432 428 433 429 The mount.cifs mount helper also accepts a few mount options before -o 434 430 including:
+2 -2
fs/cifs/TODO
··· 1 - version 1.37 October 9, 2005 1 + Version 1.39 November 30, 2005 2 2 3 3 A Partial List of Missing Features 4 4 ================================== ··· 58 58 at a time when 8 pages or more are requested. In conjuntion 59 59 add support for async_cifs_readpages. 60 60 61 - p) Add support for storing symlink and fifo info to Windows servers 61 + p) Add support for storing symlink info to Windows servers 62 62 in the Extended Attribute format their SFU clients would recognize. 63 63 64 64 q) Finish fcntl D_NOTIFY support so kde and gnome file list windows
+8 -1
fs/cifs/dir.c
··· 228 228 else { 229 229 rc = cifs_get_inode_info(&newinode, full_path, 230 230 buf, inode->i_sb,xid); 231 - if(newinode) 231 + if(newinode) { 232 232 newinode->i_mode = mode; 233 + if((oplock & CIFS_CREATE_ACTION) && 234 + (cifs_sb->mnt_cifs_flags & 235 + CIFS_MOUNT_SET_UID)) { 236 + newinode->i_uid = current->fsuid; 237 + newinode->i_gid = current->fsgid; 238 + } 239 + } 233 240 } 234 241 235 242 if (rc != 0) {
+25 -3
fs/cifs/inode.c
··· 710 710 char *full_path = NULL; 711 711 struct inode *newinode = NULL; 712 712 713 - cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p ", mode, inode)); 713 + cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode)); 714 714 715 715 xid = GetXid(); 716 716 ··· 768 768 /* BB to be implemented via Windows secrty descriptors 769 769 eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, 770 770 -1, -1, local_nls); */ 771 - } 771 + if(direntry->d_inode) { 772 + direntry->d_inode->i_mode = mode; 773 + if(cifs_sb->mnt_cifs_flags & 774 + CIFS_MOUNT_SET_UID) { 775 + direntry->d_inode->i_uid = 776 + current->fsuid; 777 + direntry->d_inode->i_gid = 778 + current->fsgid; 779 + } 780 + } 772 781 } 773 782 kfree(full_path); 774 783 FreeXid(xid); ··· 1120 1111 1121 1112 cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ", 1122 1113 direntry->d_name.name, attrs->ia_valid)); 1114 + 1123 1115 cifs_sb = CIFS_SB(direntry->d_inode->i_sb); 1124 1116 pTcon = cifs_sb->tcon; 1125 1117 1118 + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM == 0) { 1119 + /* check if we have permission to change attrs */ 1120 + rc = inode_change_ok(direntry->d_inode, attrs); 1121 + if(rc < 0) { 1122 + FreeXid(xid); 1123 + return rc; 1124 + } else 1125 + rc = 0; 1126 + } 1127 + 1126 1128 down(&direntry->d_sb->s_vfs_rename_sem); 1127 1129 full_path = build_path_from_dentry(direntry); 1128 1130 up(&direntry->d_sb->s_vfs_rename_sem); ··· 1173 1153 1 /* 45 seconds */); 1174 1154 cFYI(1,("Wrt seteof rc %d", rc)); 1175 1155 } 1176 - } 1156 + } else 1157 + rc = -EINVAL; 1158 + 1177 1159 if (rc != 0) { 1178 1160 /* Set file size by pathname rather than by handle 1179 1161 either because no valid, writeable file handle for