Get closer to passing S4 RAW-ACLs.
authorJeremy Allison <jra@samba.org>
Sat, 1 Nov 2008 01:04:53 +0000 (18:04 -0700)
committerJeremy Allison <jra@samba.org>
Sat, 1 Nov 2008 01:04:53 +0000 (18:04 -0700)
Jeremy.

source3/include/smb.h
source3/lib/secdesc.c
source3/lib/util_seaccess.c
source3/modules/vfs_acl_xattr.c
source3/smbd/open.c
source3/smbd/trans2.c

index 8b64877d860111714565f9d49648b3d7b4706eb3..fdbad2a22a2a58cdc075facfc42ef2c17217ab1a 100644 (file)
@@ -1228,7 +1228,7 @@ struct bitmap {
 #define FILE_GENERIC_WRITE (STD_RIGHT_READ_CONTROL_ACCESS|FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|\
                                                        FILE_WRITE_EA|FILE_APPEND_DATA|SYNCHRONIZE_ACCESS)
 
-#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE_ACCESS|\
+#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE_ACCESS|FILE_READ_ATTRIBUTES|\
                                                                FILE_EXECUTE|SYNCHRONIZE_ACCESS)
 
 /* Share specific rights. */
index 1da2b3ec93546559faa1ce2c4b48c1ca403f2832..298730606668b767134fd1fba72e40858b0b9812 100644 (file)
@@ -529,7 +529,7 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
 
                        /* First add the regular ACE entry. */
                        init_sec_ace(new_ace, ptrustee, ace->type,
-                               ace->access_mask, SEC_ACE_FLAG_INHERITED_ACE);
+                               ace->access_mask, 0);
 
                        DEBUG(5,("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x"
                                " inherited as %s:%d/0x%02x/0x%08x\n",
@@ -549,7 +549,7 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
                }
 
                init_sec_ace(new_ace, ptrustee, ace->type,
-                            ace->access_mask, new_flags | SEC_ACE_FLAG_INHERITED_ACE);
+                            ace->access_mask, new_flags);
 
                DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
                          " inherited as %s:%d/0x%02x/0x%08x\n",
@@ -565,7 +565,7 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
        /* Create child security descriptor to return */
 
        new_dacl = make_sec_acl(ctx,
-                               ACL_REVISION,
+                               NT4_ACL_REVISION,
                                new_ace_list_ndx,
                                new_ace_list);
 
index 17d4b782027fecca82071bde86de264bd22e1ea7..d7fdc9a8b9eed82a1a43e442f8a67407edd9075a 100644 (file)
@@ -110,7 +110,7 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
 {
        uint32_t denied = 0, granted = 0;
        unsigned i;
-       
+
        if (is_sid_in_token(token, sd->owner_sid)) {
                granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL | SEC_STD_DELETE;
        } else if (user_has_privileges(token, &se_restore)) {
@@ -120,7 +120,7 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd,
        if (sd->dacl == NULL) {
                return granted & ~denied;
        }
-       
+
        for (i = 0;i<sd->dacl->num_aces; i++) {
                struct security_ace *ace = &sd->dacl->aces[i];
 
index ca34e97155200ddd3595d79a1afe77dcda2b405f..e465e8f3808edb358799aa13b516c014f1a2d673 100644 (file)
@@ -144,7 +144,7 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
        return NT_STATUS_OK;
 }
 
-static NTSTATUS create_acl_blob(const SEC_DESC *psd, DATA_BLOB *pblob)
+static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob)
 {
        struct xattr_NTACL xacl;
        struct security_descriptor_timestamp sd_ts;
@@ -163,7 +163,7 @@ static NTSTATUS create_acl_blob(const SEC_DESC *psd, DATA_BLOB *pblob)
 
        xacl.version = 2;
        xacl.info.sd_ts = &sd_ts;
-       xacl.info.sd_ts->sd = CONST_DISCARD(SEC_DESC *, psd);
+       xacl.info.sd_ts->sd = CONST_DISCARD(struct security_descriptor *, psd);
        unix_timespec_to_nt_time(&xacl.info.sd_ts->last_changed, curr);
 
        DEBUG(10, ("create_acl_blob: timestamp stored as %s\n",
@@ -250,7 +250,7 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
                                        files_struct *fsp,
                                        const char *name,
                                        uint32 security_info,
-                                       SEC_DESC **ppdesc)
+                                       struct security_descriptor **ppdesc)
 {
        TALLOC_CTX *ctx = talloc_tos();
        DATA_BLOB blob;
@@ -292,8 +292,50 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle,
 }
 
 /*********************************************************************
- * Currently this only works for existing files. Need to work on
- * inheritance for new files.
+ Create a default security descriptor for a file in case no inheritance
+ exists. All permissions to the owner and SYSTEM.
+*********************************************************************/
+
+static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
+                                               SMB_STRUCT_STAT *psbuf)
+{
+       struct dom_sid owner_sid, group_sid;
+       size_t sd_size;
+       struct security_ace *pace = NULL;
+       struct security_acl *pacl = NULL;
+
+       uid_to_sid(&owner_sid, psbuf->st_uid);
+       gid_to_sid(&group_sid, psbuf->st_gid);
+
+       pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2);
+       if (!pace) {
+               return NULL;
+       }
+
+       init_sec_ace(&pace[0], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+                       SEC_RIGHTS_FILE_ALL, 0);
+       init_sec_ace(&pace[1], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED,
+                       SEC_RIGHTS_FILE_ALL, 0);
+
+       pacl = make_sec_acl(mem_ctx,
+                               NT4_ACL_REVISION,
+                               2,
+                               pace);
+       if (!pacl) {
+               return NULL;
+       }
+       return make_sec_desc(mem_ctx,
+                       SECURITY_DESCRIPTOR_REVISION_1,
+                       SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT|
+                               SEC_DESC_DACL_DEFAULTED,
+                       &owner_sid,
+                       &group_sid,
+                       NULL,
+                        pacl,
+                       &sd_size);
+}
+
+/*********************************************************************
 *********************************************************************/
 
 static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
@@ -303,8 +345,8 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
 {
        TALLOC_CTX *ctx = talloc_tos();
        NTSTATUS status;
-       SEC_DESC *parent_desc = NULL;
-       SEC_DESC *psd = NULL;
+       struct security_descriptor *parent_desc = NULL;
+       struct security_descriptor *psd = NULL;
        DATA_BLOB blob;
        size_t size;
        char *parent_name;
@@ -343,6 +385,25 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle,
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
+       if (psd->dacl == NULL) {
+               SMB_STRUCT_STAT sbuf;
+               int ret;
+
+               TALLOC_FREE(psd);
+               if (fsp && !fsp->is_directory && fsp->fh->fd != -1) {
+                       ret = SMB_VFS_FSTAT(fsp, &sbuf);
+               } else {
+                       ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf);
+               }
+               if (ret == -1) {
+                       return map_nt_error_from_unix(errno);
+               }
+               psd = default_file_sd(ctx, &sbuf);
+               if (!psd) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
        status = create_acl_blob(psd, &blob);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -365,7 +426,7 @@ static int open_acl_xattr(vfs_handle_struct *handle,
                                        mode_t mode)
 {
        uint32_t access_granted = 0;
-       SEC_DESC *pdesc = NULL;
+       struct security_descriptor *pdesc = NULL;
        bool file_existed = true;
        NTSTATUS status = get_nt_acl_xattr_internal(handle,
                                        NULL,
@@ -417,7 +478,7 @@ static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t m
 }
 
 static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
-        uint32 security_info, SEC_DESC **ppdesc)
+        uint32 security_info, struct security_descriptor **ppdesc)
 {
        NTSTATUS status = get_nt_acl_xattr_internal(handle, fsp,
                                NULL, security_info, ppdesc);
@@ -434,7 +495,7 @@ static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle,
-        const char *name, uint32 security_info, SEC_DESC **ppdesc)
+        const char *name, uint32 security_info, struct security_descriptor **ppdesc)
 {
        NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL,
                                name, security_info, ppdesc);
@@ -451,7 +512,7 @@ static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle,
 }
 
 static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
-        uint32 security_info_sent, const SEC_DESC *psd)
+        uint32 security_info_sent, const struct security_descriptor *psd)
 {
        NTSTATUS status;
        DATA_BLOB blob;
@@ -460,7 +521,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
                DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n",
                        fsp->fsp_name));
                NDR_PRINT_DEBUG(security_descriptor,
-                       CONST_DISCARD(SEC_DESC *,psd));
+                       CONST_DISCARD(struct security_descriptor *,psd));
        }
 
        status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
@@ -473,7 +534,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
                int ret;
                SMB_STRUCT_STAT sbuf;
                DOM_SID owner_sid, group_sid;
-               SEC_DESC *nc_psd = dup_sec_desc(talloc_tos(), psd);
+               struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd);
 
                if (!nc_psd) {
                        return NT_STATUS_OK;
@@ -502,7 +563,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
                                SE_DESC_DACL_AUTO_INHERIT_REQ))==
                                (SE_DESC_DACL_AUTO_INHERITED|
                                SE_DESC_DACL_AUTO_INHERIT_REQ) ) {
-               SEC_DESC *new_psd = NULL;
+               struct security_descriptor *new_psd = NULL;
                status = append_parent_acl(fsp, psd, &new_psd);
                if (!NT_STATUS_IS_OK(status)) {
                        /* Lower level acl set succeeded,
@@ -516,7 +577,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp,
                DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n",
                        fsp->fsp_name));
                NDR_PRINT_DEBUG(security_descriptor,
-                       CONST_DISCARD(SEC_DESC *,psd));
+                       CONST_DISCARD(struct security_descriptor *,psd));
        }
        create_acl_blob(psd, &blob);
        store_acl_blob_fsp(fsp, &blob);
index 15645250054d927e9e5b9a5004351d46ff941fbd..5836c43afc479a159f21b88df071e6f6880c5067 100644 (file)
@@ -1370,16 +1370,53 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
                }
        }
 
-       /* This is a nasty hack - must fix... JRA. */
-       if (access_mask == MAXIMUM_ALLOWED_ACCESS) {
-               open_access_mask = access_mask = FILE_GENERIC_ALL;
-       }
-
        /*
         * Convert GENERIC bits to specific bits.
         */
 
        se_map_generic(&access_mask, &file_generic_mapping);
+
+       /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
+       if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
+               if (file_existed) {
+                       struct security_descriptor *sd;
+                       uint32_t access_granted = 0;
+
+                       status = SMB_VFS_GET_NT_ACL(conn, fname,
+                                       (OWNER_SECURITY_INFORMATION |
+                                       GROUP_SECURITY_INFORMATION |
+                                       DACL_SECURITY_INFORMATION),&sd);
+
+                       if (!NT_STATUS_IS_OK(status)) {
+                               DEBUG(10, ("open_file_ntcreate: Could not get acl "
+                                       "on file %s: %s\n",
+                                       fname,
+                                       nt_errstr(status)));
+                               return NT_STATUS_ACCESS_DENIED;
+                       }
+
+                       status = se_access_check(sd, conn->server_info->ptok,
+                                       access_mask, &access_granted);
+
+                       TALLOC_FREE(sd);
+
+                       if (!NT_STATUS_IS_OK(status)) {
+                               DEBUG(10, ("open_file_ntcreate: Access denied on "
+                                       "file %s: when calculating maximum access\n",
+                                       fname));
+                               return NT_STATUS_ACCESS_DENIED;
+                       }
+
+                       access_mask = access_granted;
+                       /*
+                        * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
+                        */
+                       access_mask |= FILE_READ_ATTRIBUTES;
+               } else {
+                       access_mask = FILE_GENERIC_ALL;
+               }
+       }
+
        open_access_mask = access_mask;
 
        if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
index 1da45a8b58c8ca645a69e48727647737e7025820..a450a56e72a61cdae74a04d4fa8641e529c30280 100644 (file)
@@ -3846,7 +3846,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
        files_struct *fsp = NULL;
        struct file_id fileid;
        struct ea_list *ea_list = NULL;
-       uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
        char *lock_data = NULL;
        bool ms_dfs_link = false;
        TALLOC_CTX *ctx = talloc_tos();
@@ -3939,7 +3938,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
                        pos = fsp->fh->position_information;
                        fileid = vfs_file_id_from_sbuf(conn, &sbuf);
                        get_file_infos(fileid, &delete_pending, &write_time_ts);
-                       access_mask = fsp->access_mask;
                }
 
        } else {
@@ -4403,7 +4401,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
 
                case SMB_FILE_ACCESS_INFORMATION:
                        DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
-                       SIVAL(pdata,0,access_mask);
+                       if (fsp) {
+                               SIVAL(pdata,0,fsp->access_mask);
+                       } else {
+                               /* GENERIC_EXECUTE mapping from Windows */
+                               SIVAL(pdata,0,0x12019F);
+                       }
                        data_size = 4;
                        break;