]> err.no Git - linux-2.6/commitdiff
[CIFS] Don't request too much permission when reading an ACL
authorSteve French <sfrench@us.ibm.com>
Wed, 31 Oct 2007 04:54:42 +0000 (04:54 +0000)
committerSteve French <sfrench@us.ibm.com>
Wed, 31 Oct 2007 04:54:42 +0000 (04:54 +0000)
We were requesting GENERIC_READ but that fails when  we do not have
read permission on the file (even if we could read the ACL).

Also move the dump access control entry code into debug ifdef.

Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/cifsacl.c
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/inode.c

index 629b96c2163995ce04c08b7891ef3f0426f632a7..f1215df7fbee8f76449acb9d42cab3e8128885b1 100644 (file)
@@ -162,7 +162,8 @@ static void access_flags_to_mode(__u32 ace_flags, umode_t *pmode,
 }
 
 
-static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
+#ifdef CONFIG_CIFS_DEBUG2
+static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
 {
        int num_subauth;
 
@@ -180,7 +181,6 @@ static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
 
        num_subauth = pace->sid.num_subauth;
        if (num_subauth) {
-#ifdef CONFIG_CIFS_DEBUG2
                int i;
                cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d",
                        pace->sid.revision, pace->sid.num_subauth, pace->type,
@@ -192,11 +192,11 @@ static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
 
                /* BB add length check to make sure that we do not have huge
                        num auths and therefore go off the end */
-#endif
        }
 
        return;
 }
+#endif
 
 
 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
@@ -240,9 +240,9 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
 
                for (i = 0; i < num_aces; ++i) {
                        ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
-
-                       parse_ace(ppace[i], end_of_acl);
-
+#ifdef CONFIG_CIFS_DEBUG2
+                       dump_ace(ppace[i], end_of_acl);
+#endif
                        if (compare_sids(&(ppace[i]->sid), pownersid))
                                access_flags_to_mode(ppace[i]->access_req,
                                                &(inode->i_mode), S_IRWXU);
@@ -385,7 +385,7 @@ void acl_to_uid_mode(struct inode *inode, const char *path)
                int oplock = FALSE;
                /* open file */
                rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
-                               GENERIC_READ, 0, &fid, &oplock, NULL,
+                               READ_CONTROL, 0, &fid, &oplock, NULL,
                                cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
                if (rc != 0) {
@@ -409,4 +409,22 @@ void acl_to_uid_mode(struct inode *inode, const char *path)
        FreeXid(xid);
        return;
 }
+
+int mode_to_acl(struct inode *inode, const char *path)
+{
+       int rc = 0;
+       __u32 acllen = 0;
+       struct cifs_ntsd *pntsd = NULL;
+
+       cFYI(1, ("set ACL from mode for %s", path));
+
+       /* Get the security descriptor */
+
+       /* Add/Modify the three ACEs for owner, group, everyone */
+
+       /* Set the security descriptor */
+       kfree(pntsd);
+
+       return rc;
+}
 #endif /* CONFIG_CIFS_EXPERIMENTAL */
index c41ff74e9128b91af914930334b241fd3c0d313f..07464b6ac1294b286ac40975f333418abc0ff6be 100644 (file)
                                | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
 #define FILE_EXEC_RIGHTS (FILE_EXECUTE)
 
+#define SET_FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_WRITE_EA \
+                               | FILE_READ_ATTRIBUTES \
+                               | FILE_WRITE_ATTRIBUTES \
+                               | DELETE | READ_CONTROL | WRITE_DAC \
+                               | WRITE_OWNER | SYNCHRONIZE)
+#define SET_FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
+                               | FILE_READ_EA | FILE_WRITE_EA \
+                               | FILE_DELETE_CHILD | FILE_READ_ATTRIBUTES \
+                               | FILE_WRITE_ATTRIBUTES \
+                               | DELETE | READ_CONTROL | WRITE_DAC \
+                               | WRITE_OWNER | SYNCHRONIZE)
+#define SET_FILE_EXEC_RIGHTS (FILE_READ_EA | FILE_WRITE_EA | FILE_EXECUTE \
+                               | FILE_READ_ATTRIBUTES \
+                               | FILE_WRITE_ATTRIBUTES \
+                               | DELETE | READ_CONTROL | WRITE_DAC \
+                               | WRITE_OWNER | SYNCHRONIZE)
+
 
 /*
  * Invalid readdir handle
index 88c02ac97c3f65c340bef6cbd03054e0dd219e77..1ffe25592b25639520d0109c43416916dd941674 100644 (file)
@@ -96,6 +96,8 @@ extern int cifs_get_inode_info_unix(struct inode **pinode,
                        const unsigned char *search_path,
                        struct super_block *sb, int xid);
 extern void acl_to_uid_mode(struct inode *inode, const char *search_path);
+extern int mode_to_acl(struct inode *inode, const char *path);
+
 extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
                        const char *);
 extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
index 9be0bbd20dfd25ca03639c94b1dac9ebf6583dba..7d907e84e0327d01d531ef9fa142670de04b1ccb 100644 (file)
@@ -289,7 +289,7 @@ static int decode_sfu_inode(struct inode *inode, __u64 size,
 
 #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID)  /* SETFILEBITS valid bits */
 
-static int get_sfu_uid_mode(struct inode *inode,
+static int get_sfu_mode(struct inode *inode,
                        const unsigned char *path,
                        struct cifs_sb_info *cifs_sb, int xid)
 {
@@ -528,16 +528,15 @@ int cifs_get_inode_info(struct inode **pinode,
                /* BB fill in uid and gid here? with help from winbind?
                   or retrieve from NTFS stream extended attribute */
 #ifdef CONFIG_CIFS_EXPERIMENTAL
+               /* fill in 0777 bits from ACL */
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
                        cFYI(1, ("Getting mode bits from ACL"));
                        acl_to_uid_mode(inode, search_path);
                }
 #endif
                if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
-                       /* fill in uid, gid, mode from server ACL */
-                       /* BB FIXME this should also take into account the
-                        * default uid specified on mount if present */
-                       get_sfu_uid_mode(inode, search_path, cifs_sb, xid);
+                       /* fill in remaining high mode bits e.g. SUID, VTX */
+                       get_sfu_mode(inode, search_path, cifs_sb, xid);
                } else if (atomic_read(&cifsInfo->inUse) == 0) {
                        inode->i_uid = cifs_sb->mnt_uid;
                        inode->i_gid = cifs_sb->mnt_gid;