[CIFS] enable get mode from ACL when cifsacl mount option specified
authorShirish Pargaonkar <shirishp@us.ibm.com>
Tue, 30 Oct 2007 04:45:14 +0000 (04:45 +0000)
committerSteve French <sfrench@us.ibm.com>
Tue, 30 Oct 2007 04:45:14 +0000 (04:45 +0000)
Part 9 of ACL patch series.  getting mode from ACL now works in
some cases (and requires CIFS_EXPERIMENTAL config option).

Signed-off-by: Shirish Pargaonkar <shirishp@us.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/CHANGES
fs/cifs/cifsacl.c

index 3d419163c3d3a345f0a3bd06b230f0186038d60b..c65c9da863f3179d5ae273cbcc66629086a8b30f 100644 (file)
@@ -12,7 +12,9 @@ leak that causes cifsd not to stop and rmmod to fail to cleanup
 cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on
 bigendian architectures. Fix possible memory corruption when
 EAGAIN returned on kern_recvmsg. Return better error if server
-requires packet signing but client has disabled it.
+requires packet signing but client has disabled it. When mounted
+with cifsacl mount option - mode bits are approximated based
+on the contents of the files ACL.
 
 Version 1.50
 ------------
index cad2da3a447dd29bc7e32812fbcec5eceaca99c9..629b96c2163995ce04c08b7891ef3f0426f632a7 100644 (file)
@@ -43,8 +43,8 @@ static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
 
 
 /* security id for everyone */
-static const struct cifs_sid sid_everyone =
-               {1, 1, {0, 0, 0, 0, 0, 0}, {} };
+static const struct cifs_sid sid_everyone = {
+       1, 1, {0, 0, 0, 0, 0, 1}, {0} };
 /* group users */
 static const struct cifs_sid sid_user =
                {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
@@ -138,8 +138,6 @@ static void access_flags_to_mode(__u32 ace_flags, umode_t *pmode,
                                 umode_t bits_to_set)
 {
 
-       *pmode &= ~bits_to_set;
-
        if (ace_flags & GENERIC_ALL) {
                *pmode |= (S_IRWXUGO & bits_to_set);
 #ifdef CONFIG_CIFS_DEBUG2
@@ -147,11 +145,14 @@ static void access_flags_to_mode(__u32 ace_flags, umode_t *pmode,
 #endif
                return;
        }
-       if ((ace_flags & GENERIC_WRITE) || (ace_flags & FILE_WRITE_RIGHTS))
+       if ((ace_flags & GENERIC_WRITE) ||
+                       ((ace_flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
                *pmode |= (S_IWUGO & bits_to_set);
-       if ((ace_flags & GENERIC_READ) || (ace_flags & FILE_READ_RIGHTS))
+       if ((ace_flags & GENERIC_READ) ||
+                       ((ace_flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
                *pmode |= (S_IRUGO & bits_to_set);
-       if ((ace_flags & GENERIC_EXECUTE) || (ace_flags & FILE_EXEC_RIGHTS))
+       if ((ace_flags & GENERIC_EXECUTE) ||
+                       ((ace_flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
                *pmode |= (S_IXUGO & bits_to_set);
 
 #ifdef CONFIG_CIFS_DEBUG2
@@ -234,11 +235,24 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
                cifscred->aces = kmalloc(num_aces *
                        sizeof(struct cifs_ace *), GFP_KERNEL);*/
 
+               /* reset rwx permissions for user/group/other */
+               inode->i_mode &= ~(S_IRWXUGO);
+
                for (i = 0; i < num_aces; ++i) {
                        ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
 
                        parse_ace(ppace[i], end_of_acl);
 
+                       if (compare_sids(&(ppace[i]->sid), pownersid))
+                               access_flags_to_mode(ppace[i]->access_req,
+                                               &(inode->i_mode), S_IRWXU);
+                       if (compare_sids(&(ppace[i]->sid), pgrpsid))
+                               access_flags_to_mode(ppace[i]->access_req,
+                                               &(inode->i_mode), S_IRWXG);
+                       if (compare_sids(&(ppace[i]->sid), &sid_everyone))
+                               access_flags_to_mode(ppace[i]->access_req,
+                                               &(inode->i_mode), S_IRWXO);
+
 /*                     memcpy((void *)(&(cifscred->aces[i])),
                                (void *)ppace[i],
                                sizeof(struct cifs_ace)); */