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