[CIFS] Fix missing permission check on setattr when noperm mount option is
authorSteve French <sfrench@us.ibm.com>
Wed, 30 Nov 2005 04:20:10 +0000 (20:20 -0800)
committerSteve French <sfrench@us.ibm.com>
Wed, 30 Nov 2005 04:20:10 +0000 (20:20 -0800)
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>
fs/cifs/CHANGES
fs/cifs/README
fs/cifs/TODO
fs/cifs/dir.c
fs/cifs/inode.c

index c40bd0df80ad5dd7b4c2440086908b4373fb1a2b..943ef9b82244ef9b71a3211e24bb1a1899f51409 100644 (file)
@@ -6,7 +6,7 @@ stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2
 Fix SFU style symlinks and mknod needed for servers which do not support the
 CIFS Unix Extensions.  Fix setfacl/getfacl on bigendian. Timeout negative
 dentries so files that the client sees as deleted but that later get created
-on the server will be recognized.
+on the server will be recognized.  Add client side permission check on setattr.
 
 Version 1.38
 ------------
index bb90941826adb4e60d662d930aa293055c42cd2b..e5d09a2fc7a5eccf7a7b8f15b56de07173a5d535 100644 (file)
@@ -278,7 +278,9 @@ A partial list of the supported mount options follows:
                (such as Windows), permissions can also be checked at the
                client, and a crude form of client side permission checking 
                can be enabled by specifying file_mode and dir_mode on 
-               the client
+               the client.  Note that the mount.cifs helper must be
+               at version 1.10 or higher to support specifying the uid
+               (or gid) in non-numberic form.
   gid          If CIFS Unix extensions are not supported by the server
                this overrides the default gid for inodes.
   file_mode     If CIFS Unix extensions are not supported by the server
@@ -345,7 +347,10 @@ A partial list of the supported mount options follows:
                client system. It is typically only needed when the server
                supports the CIFS Unix Extensions but the UIDs/GIDs on the
                client and server system do not match closely enough to allow
-               access by the user doing the mount.
+               access by the user doing the mount, but it may be useful with
+               non CIFS Unix Extension mounts for cases in which the default
+               mode is specified on the mount but is not to be enforced on the
+               client (e.g. perhaps when MultiUserMount is enabled)
                Note that this does not affect the normal ACL check on the
                target machine done by the server software (of the server
                ACL against the user name provided at mount time).
@@ -368,15 +373,21 @@ A partial list of the supported mount options follows:
   setuids       If the CIFS Unix extensions are negotiated with the server
                the client will attempt to set the effective uid and gid of
                the local process on newly created files, directories, and
-               devices (create, mkdir, mknod).
+               devices (create, mkdir, mknod).  If the CIFS Unix Extensions
+               are not negotiated, for newly created files and directories
+               instead of using the default uid and gid specified on the
+               the mount, cache the new file's uid and gid locally which means
+               that the uid for the file can change when the inode is
+               reloaded (or the user remounts the share).
   nosetuids     The client will not attempt to set the uid and gid on
                on newly created files, directories, and devices (create, 
                mkdir, mknod) which will result in the server setting the
                uid and gid to the default (usually the server uid of the
                user who mounted the share).  Letting the server (rather than
-               the client) set the uid and gid is the default. This
-               parameter has no effect if the CIFS Unix Extensions are not
-               negotiated.
+               the client) set the uid and gid is the default. If the CIFS
+               Unix Extensions are not negotiated then the uid and gid for
+               new files will appear to be the uid (gid) of the mounter or the
+               uid (gid) parameter specified on the mount.
   netbiosname   When mounting to servers via port 139, specifies the RFC1001
                source name to use to represent the client netbios machine 
                name when doing the RFC1001 netbios session initialize.
@@ -418,6 +429,13 @@ A partial list of the supported mount options follows:
                byte range locks).
  remount        remount the share (often used to change from ro to rw mounts
                or vice versa)
+ sfu            When the CIFS Unix Extensions are not negotiated, attempt to
+               create device files and fifos in a format compatible with
+               Services for Unix (SFU).  In addition retrieve bits 10-12
+               of the mode via the SETFILEBITS extended attribute (as
+               SFU does).  In the future the bottom 9 bits of the mode
+               mode also will be emulated using queries of the security
+               descriptor (ACL).
                
 The mount.cifs mount helper also accepts a few mount options before -o
 including:
index c909298d11ed60deba5809a8e3346130019e63bf..fc34c74ec4bef91ed0c686ebe451b8787db26375 100644 (file)
@@ -1,4 +1,4 @@
-version 1.37 October 9, 2005
+Version 1.39 November 30, 2005
 
 A Partial List of Missing Features
 ==================================
@@ -58,7 +58,7 @@ o) Improve performance of readpages by sending more than one read
 at a time when 8 pages or more are requested. In conjuntion
 add support for async_cifs_readpages.
 
-p) Add support for storing symlink and fifo info to Windows servers 
+p) Add support for storing symlink info to Windows servers 
 in the Extended Attribute format their SFU clients would recognize.
 
 q) Finish fcntl D_NOTIFY support so kde and gnome file list windows
index aa4ea965b329a8d27763917ea0868bb4a220680b..32cc96cafa3eb050d19871f85cf4e089c68b7562 100644 (file)
@@ -228,8 +228,15 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
                else {
                        rc = cifs_get_inode_info(&newinode, full_path,
                                                 buf, inode->i_sb,xid);
-                       if(newinode)
+                       if(newinode) {
                                newinode->i_mode = mode;
+                               if((oplock & CIFS_CREATE_ACTION) &&
+                                 (cifs_sb->mnt_cifs_flags & 
+                                    CIFS_MOUNT_SET_UID)) {
+                                       newinode->i_uid = current->fsuid;
+                                       newinode->i_gid = current->fsgid;
+                               }
+                       }
                }
 
                if (rc != 0) {
index d34325c887c4977bc2a6a0197372986423c0fd86..053c1cadf7031b805e752a26488c04166bcd6074 100644 (file)
@@ -710,7 +710,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
        char *full_path = NULL;
        struct inode *newinode = NULL;
 
-       cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p ", mode, inode));
+       cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
 
        xid = GetXid();
 
@@ -768,7 +768,16 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
                        /* BB to be implemented via Windows secrty descriptors
                           eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
                                                 -1, -1, local_nls); */
-               }
+                       if(direntry->d_inode) {
+                               direntry->d_inode->i_mode = mode;
+                               if(cifs_sb->mnt_cifs_flags & 
+                                    CIFS_MOUNT_SET_UID) {
+                                       direntry->d_inode->i_uid = 
+                                               current->fsuid;
+                                       direntry->d_inode->i_gid = 
+                                               current->fsgid;
+                               }
+                       }
        }
        kfree(full_path);
        FreeXid(xid);
@@ -1111,9 +1120,20 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
 
        cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ",
                 direntry->d_name.name, attrs->ia_valid));
+
        cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
        pTcon = cifs_sb->tcon;
 
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM == 0) {
+               /* check if we have permission to change attrs */
+               rc = inode_change_ok(direntry->d_inode, attrs);
+               if(rc < 0) {
+                       FreeXid(xid);
+                       return rc;
+               } else
+                       rc = 0;
+       }
+               
        down(&direntry->d_sb->s_vfs_rename_sem);
        full_path = build_path_from_dentry(direntry);
        up(&direntry->d_sb->s_vfs_rename_sem);
@@ -1153,7 +1173,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                                                  1 /* 45 seconds */);
                                cFYI(1,("Wrt seteof rc %d", rc));
                        }
-               }
+               } else 
+                       rc = -EINVAL;
+
                if (rc != 0) {
                        /* Set file size by pathname rather than by handle
                           either because no valid, writeable file handle for