Patch from Jim McDonough for bug #802. Retrieve the correct ACL group bits
authorJeremy Allison <jra@samba.org>
Tue, 25 Nov 2003 23:25:15 +0000 (23:25 +0000)
committerJeremy Allison <jra@samba.org>
Tue, 25 Nov 2003 23:25:15 +0000 (23:25 +0000)
if the file has an ACL.
Jeremy.
(This used to be commit a51d9e947ef012fabf5a13250df6232d23722f68)

source3/smbd/dosmode.c
source3/smbd/posix_acls.c

index f88964123e1cf4b1b0c3f94a14b69f28aac76e8d..fb72a2eafc893ed4eb95388a299b8e98b0e5459b 100644 (file)
@@ -183,6 +183,7 @@ uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
 /*******************************************************************
 chmod a file - but preserve some bits
 ********************************************************************/
+
 int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_STAT *st)
 {
        SMB_STRUCT_STAT st1;
@@ -197,6 +198,8 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST
                        return(-1);
        }
 
+       get_acl_group_bits(conn, fname, &st->st_mode);
+
        if (S_ISDIR(st->st_mode))
                dosmode |= aDIR;
        else
index aa1d25c483afb581bae6c13ea68fdc25b3af6d54..8033c694f5db8ab7bba72b7edc528a5b3e795ae5 100644 (file)
@@ -3177,6 +3177,48 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
        return True;
 }
 
+/****************************************************************************
+ Get the actual group bits stored on a file with an ACL. Has no effect if
+ the file has no ACL. Needed in dosmode code where the stat() will return
+ the mask bits, not the real group bits, for a file with an ACL.
+****************************************************************************/
+
+int get_acl_group_bits( connection_struct *conn, char *fname, mode_t *mode )
+{
+       int entry_id = SMB_ACL_FIRST_ENTRY;
+       SMB_ACL_ENTRY_T entry;
+       SMB_ACL_T posix_acl;
+
+       posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
+       if (posix_acl == (SMB_ACL_T)NULL)
+               return -1;
+
+       while (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1) {
+               SMB_ACL_TAG_T tagtype;
+               SMB_ACL_PERMSET_T permset;
+
+               /* get_next... */
+               if (entry_id == SMB_ACL_FIRST_ENTRY)
+                       entry_id = SMB_ACL_NEXT_ENTRY;
+
+               if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) ==-1)
+                       return -1;
+
+               if (tagtype == SMB_ACL_GROUP_OBJ) {
+                       if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
+                               return -1;
+                       } else {
+                               *mode &= ~(S_IRGRP|S_IWGRP|S_IXGRP);
+                               *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? S_IRGRP : 0);
+                               *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? S_IWGRP : 0);
+                               *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? S_IXGRP : 0);
+                               return 0;;
+                       }
+               }
+       }
+       return -1;
+}
+
 /****************************************************************************
  Do a chmod by setting the ACL USER_OBJ, GROUP_OBJ and OTHER bits in an ACL
  and set the mask to rwx. Needed to preserve complex ACLs set by NT.