The branch, master has been updated via 06fc79f Add acl_xattr:ignore system acls boolean (normally false) to allow Samba ACL module to ignore mapping to lower POSIX layer. With this fix Samba 3.6.x now passes RAW-ACLs (with certain smb.conf parameters set). via cf45581 Add make_default_filesystem_acl() function to be used in following change to acl_xattr and acl_tdb module. via 1904c44 Fix handling of "NULL" DACL. Map to u/g/w - rwx. via e031f8a Fix "force unknown ACL user" to strip out foreign SIDs from POSIX ACLs if they can't be mapped. via f4a9d25 Add debug message to get_nt_acl_internal() to see what we got. via 625126d Fix valgrind "uninitialized read" error on "info" when returning !NT_STATUS_OK. via 8cad5e2 Fix bug #7734 - When creating files with "inherit ACLs" set to true, we neglect to apply appropriate create masks. via 92adb68 Fix bug #7733 - Invalid client DOS attributes on create can cause incorrect unix mode_t to be generated. from 68d1b3b heimdal Add missing dependencies on wind.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 06fc79f1fde5963ef89027e2cd297e866aa8c204 Author: Jeremy Allison <j...@samba.org> Date: Fri Oct 15 15:56:09 2010 -0700 Add acl_xattr:ignore system acls boolean (normally false) to allow Samba ACL module to ignore mapping to lower POSIX layer. With this fix Samba 3.6.x now passes RAW-ACLs (with certain smb.conf parameters set). Jeremy. Autobuild-User: Jeremy Allison <j...@samba.org> Autobuild-Date: Sat Oct 16 01:26:31 UTC 2010 on sn-devel-104 commit cf45581cdfbe60815c5b278f2c4cbceeb7ca1407 Author: Jeremy Allison <j...@samba.org> Date: Fri Oct 15 15:53:51 2010 -0700 Add make_default_filesystem_acl() function to be used in following change to acl_xattr and acl_tdb module. commit 1904c44ec84fe5d706a4e07f73bad17d0948535a Author: Jeremy Allison <j...@samba.org> Date: Fri Oct 15 15:42:44 2010 -0700 Fix handling of "NULL" DACL. Map to u/g/w - rwx. Jeremy. commit e031f8ae6aee266c0ebf0b53465906e215ac9561 Author: Jeremy Allison <j...@samba.org> Date: Fri Oct 15 15:28:23 2010 -0700 Fix "force unknown ACL user" to strip out foreign SIDs from POSIX ACLs if they can't be mapped. commit f4a9d25cfc70e79f476d01ae3234f2155bbcf39e Author: Jeremy Allison <j...@samba.org> Date: Fri Oct 15 14:18:22 2010 -0700 Add debug message to get_nt_acl_internal() to see what we got. commit 625126dc8dec1198b94bda0643222f0b046587d8 Author: Jeremy Allison <j...@samba.org> Date: Fri Oct 15 14:16:30 2010 -0700 Fix valgrind "uninitialized read" error on "info" when returning !NT_STATUS_OK. Jeremy. commit 8cad5e23b6e2440a566def6fb138d484e3b47643 Author: Jeremy Allison <j...@samba.org> Date: Fri Oct 15 14:12:04 2010 -0700 Fix bug #7734 - When creating files with "inherit ACLs" set to true, we neglect to apply appropriate create masks. Jeremy. commit 92adb686372a9b67e47efb5b051bc351212f1780 Author: Jeremy Allison <j...@samba.org> Date: Fri Oct 15 13:30:07 2010 -0700 Fix bug #7733 - Invalid client DOS attributes on create can cause incorrect unix mode_t to be generated. It turns out a client can send an NTCreateX call for a new file, but specify FILE_ATTRIBUTE_DIRECTORY in the attribute list. Windows silently strips this, but we don't - causing the unix_mode() function to go through the "mode bits for new directory" codepath, instead of the "mode bits for new file" codepath. Jeremy. ----------------------------------------------------------------------- Summary of changes: source3/include/proto.h | 4 + source3/modules/vfs_acl_common.c | 59 ++++++++++--- source3/modules/vfs_acl_tdb.c | 1 + source3/modules/vfs_acl_xattr.c | 2 + source3/modules/vfs_default.c | 2 +- source3/smbd/open.c | 11 ++- source3/smbd/posix_acls.c | 174 +++++++++++++++++++++++++++++++++----- 7 files changed, 216 insertions(+), 37 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/proto.h b/source3/include/proto.h index 650d431..9a8cf67 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5123,6 +5123,10 @@ bool set_unix_posix_default_acl(connection_struct *conn, const char *fname, uint16 num_def_acls, const char *pdata); bool set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char *fname, uint16 num_acls, const char *pdata); struct security_descriptor *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname); +NTSTATUS make_default_filesystem_acl(TALLOC_CTX *ctx, + const char *name, + SMB_STRUCT_STAT *psbuf, + struct security_descriptor **ppdesc); /* The following definitions come from smbd/process.c */ diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c index 2ddcd0e..5fbf686 100644 --- a/source3/modules/vfs_acl_common.c +++ b/source3/modules/vfs_acl_common.c @@ -257,6 +257,10 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, uint8_t hash_tmp[XATTR_SD_HASH_SIZE]; struct security_descriptor *psd = NULL; struct security_descriptor *pdesc_next = NULL; + bool ignore_file_system_acl = lp_parm_bool(SNUM(handle->conn), + ACL_MODULE_NAME, + "ignore system acls", + false); if (fsp && name == NULL) { name = fsp->fsp_name->base_name; @@ -320,6 +324,9 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, goto out; } + if (ignore_file_system_acl) { + goto out; + } status = hash_sd_sha256(pdesc_next, hash_tmp); if (!NT_STATUS_IS_OK(status)) { @@ -356,28 +363,45 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, * inheritable ACE entries we have to fake them. */ if (fsp) { - is_directory = fsp->is_directory; + status = vfs_stat_fsp(fsp); + if (!NT_STATUS_IS_OK(status)) { + return status; + } psbuf = &fsp->fsp_name->st; } else { - if (vfs_stat_smb_fname(handle->conn, + int ret = vfs_stat_smb_fname(handle->conn, name, - &sbuf) == 0) { - is_directory = S_ISDIR(sbuf.st_ex_mode); + &sbuf); + if (ret == -1) { + return map_nt_error_from_unix(errno); } } - if (is_directory && + is_directory = S_ISDIR(sbuf.st_ex_mode); + + if (ignore_file_system_acl) { + TALLOC_FREE(pdesc_next); + status = make_default_filesystem_acl(talloc_tos(), + name, + psbuf, + &psd); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } else { + if (is_directory && !sd_has_inheritable_components(psd, true)) { - add_directory_inheritable_components(handle, + add_directory_inheritable_components(handle, name, psbuf, psd); + } + /* The underlying POSIX module always sets + the ~SEC_DESC_DACL_PROTECTED bit, as ACLs + can't be inherited in this way under POSIX. + Remove it for Windows-style ACLs. */ + psd->type &= ~SEC_DESC_DACL_PROTECTED; } - /* The underlying POSIX module always sets - the ~SEC_DESC_DACL_PROTECTED bit, as ACLs - can't be inherited in this way under POSIX. - Remove it for Windows-style ACLs. */ - psd->type &= ~SEC_DESC_DACL_PROTECTED; } if (!(security_info & SECINFO_OWNER)) { @@ -395,6 +419,13 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, TALLOC_FREE(blob.data); *ppdesc = psd; + + if (DEBUGLEVEL >= 10) { + DEBUG(10,("get_nt_acl_internal: returning acl for %s is:\n", + name )); + NDR_PRINT_DEBUG(security_descriptor, psd); + } + return NT_STATUS_OK; } @@ -895,6 +926,10 @@ static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle, result, &info); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + if (info != FILE_WAS_CREATED) { /* File/directory was opened, not created. */ goto out; @@ -902,7 +937,7 @@ static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle, fsp = *result; - if (!NT_STATUS_IS_OK(status) || fsp == NULL) { + if (fsp == NULL) { /* Only handle success. */ goto out; } diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index f31e093..6364b7b 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -29,6 +29,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS +#define ACL_MODULE_NAME "acl_tdb" #include "modules/vfs_acl_common.c" static unsigned int ref_count; diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index 18f2d42..e486e20 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -29,6 +29,8 @@ #define DBGC_CLASS DBGC_VFS /* Pull in the common functions. */ +#define ACL_MODULE_NAME "acl_xattr" + #include "modules/vfs_acl_common.c" /******************************************************************* diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index c290782..2cbb84c 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -217,7 +217,7 @@ static int vfswrap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mo if (lp_inherit_acls(SNUM(handle->conn)) && parent_dirname(talloc_tos(), path, &parent, NULL) && (has_dacl = directory_has_default_acl(handle->conn, parent))) - mode = 0777; + mode = (0777 & lp_dir_mask(SNUM(handle->conn))); TALLOC_FREE(parent); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 77f33b1..01f0cd6 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1512,6 +1512,12 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, ZERO_STRUCT(id); + /* Windows allows a new file to be created and + silently removes a FILE_ATTRIBUTE_DIRECTORY + sent by the client. Do the same. */ + + new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY; + if (conn->printer) { /* * Printers are handled completely differently. @@ -1991,7 +1997,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) && (def_acl = directory_has_default_acl(conn, parent_dir))) { - unx_mode = 0777; + unx_mode = (0777 & lp_create_mask(SNUM(conn))); } DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, " @@ -2469,6 +2475,9 @@ static NTSTATUS open_directory(connection_struct *conn, SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname)); + /* Ensure we have a directory attribute. */ + file_attributes |= FILE_ATTRIBUTE_DIRECTORY; + DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, " "share_access = 0x%x create_options = 0x%x, " "create_disposition = 0x%x, file_attributes = 0x%x\n", diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index fa715fb..54fa5bf 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -1753,6 +1753,14 @@ static bool create_canon_ace_lists(files_struct *fsp, continue; } + if (lp_force_unknown_acl_user(SNUM(fsp->conn))) { + DEBUG(10, ("create_canon_ace_lists: ignoring " + "unknown or foreign SID %s\n", + sid_string_dbg(&psa->trustee))); + SAFE_FREE(current_ace); + continue; + } + free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); DEBUG(0, ("create_canon_ace_lists: unable to map SID " @@ -3862,29 +3870,6 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const struct s return NT_STATUS_NO_MEMORY; } - if((security_info_sent & SECINFO_DACL) && - (psd->type & SEC_DESC_DACL_PRESENT) && - (psd->dacl == NULL)) { - struct security_ace ace; - - /* We can't have NULL DACL in POSIX. - Use Everyone -> full access. */ - - init_sec_ace(&ace, - &global_sid_World, - SEC_ACE_TYPE_ACCESS_ALLOWED, - GENERIC_ALL_ACCESS, - 0); - psd->dacl = make_sec_acl(talloc_tos(), - NT4_ACL_REVISION, - 1, - &ace); - if (psd->dacl == NULL) { - return NT_STATUS_NO_MEMORY; - } - security_acl_map_generic(psd->dacl, &file_generic_mapping); - } - /* * Get the current state of the file. */ @@ -3959,6 +3944,39 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const struct s create_file_sids(&fsp->fsp_name->st, &file_owner_sid, &file_grp_sid); + if((security_info_sent & SECINFO_DACL) && + (psd->type & SEC_DESC_DACL_PRESENT) && + (psd->dacl == NULL)) { + struct security_ace ace[3]; + + /* We can't have NULL DACL in POSIX. + Use owner/group/Everyone -> full access. */ + + init_sec_ace(&ace[0], + &file_owner_sid, + SEC_ACE_TYPE_ACCESS_ALLOWED, + GENERIC_ALL_ACCESS, + 0); + init_sec_ace(&ace[1], + &file_grp_sid, + SEC_ACE_TYPE_ACCESS_ALLOWED, + GENERIC_ALL_ACCESS, + 0); + init_sec_ace(&ace[2], + &global_sid_World, + SEC_ACE_TYPE_ACCESS_ALLOWED, + GENERIC_ALL_ACCESS, + 0); + psd->dacl = make_sec_acl(talloc_tos(), + NT4_ACL_REVISION, + 3, + ace); + if (psd->dacl == NULL) { + return NT_STATUS_NO_MEMORY; + } + security_acl_map_generic(psd->dacl, &file_generic_mapping); + } + acl_perms = unpack_canon_ace(fsp, &fsp->fsp_name->st, &file_owner_sid, &file_grp_sid, &file_ace_list, &dir_ace_list, security_info_sent, psd); @@ -4803,3 +4821,113 @@ struct security_descriptor *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fna return ret_sd; } + +/* Stolen shamelessly from pvfs_default_acl() in source4 :-). */ + +NTSTATUS make_default_filesystem_acl(TALLOC_CTX *ctx, + const char *name, + SMB_STRUCT_STAT *psbuf, + struct security_descriptor **ppdesc) +{ + struct dom_sid owner_sid, group_sid; + size_t size = 0; + struct security_ace aces[4]; + uint32_t access_mask = 0; + mode_t mode = psbuf->st_ex_mode; + struct security_acl *new_dacl = NULL; + int idx = 0; + + DEBUG(10,("make_default_filesystem_acl: file %s mode = 0%o\n", + name, (int)mode )); + + uid_to_sid(&owner_sid, psbuf->st_ex_uid); + gid_to_sid(&group_sid, psbuf->st_ex_gid); + + /* + We provide up to 4 ACEs + - Owner + - Group + - Everyone + - NT System + */ + + if (mode & S_IRUSR) { + if (mode & S_IWUSR) { + access_mask |= SEC_RIGHTS_FILE_ALL; + } else { + access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE; + } + } + if (mode & S_IWUSR) { + access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE; + } + + init_sec_ace(&aces[idx], + &owner_sid, + SEC_ACE_TYPE_ACCESS_ALLOWED, + access_mask, + 0); + idx++; + + access_mask = 0; + if (mode & S_IRGRP) { + access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE; + } + if (mode & S_IWGRP) { + /* note that delete is not granted - this matches posix behaviour */ + access_mask |= SEC_RIGHTS_FILE_WRITE; + } + if (access_mask) { + init_sec_ace(&aces[idx], + &group_sid, + SEC_ACE_TYPE_ACCESS_ALLOWED, + access_mask, + 0); + idx++; + } + + access_mask = 0; + if (mode & S_IROTH) { + access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE; + } + if (mode & S_IWOTH) { + access_mask |= SEC_RIGHTS_FILE_WRITE; + } + if (access_mask) { + init_sec_ace(&aces[idx], + &global_sid_World, + SEC_ACE_TYPE_ACCESS_ALLOWED, + access_mask, + 0); + idx++; + } + + init_sec_ace(&aces[idx], + &global_sid_System, + SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_RIGHTS_FILE_ALL, + 0); + idx++; + + new_dacl = make_sec_acl(ctx, + NT4_ACL_REVISION, + idx, + aces); + + if (!new_dacl) { + return NT_STATUS_NO_MEMORY; + } + + *ppdesc = make_sec_desc(ctx, + SECURITY_DESCRIPTOR_REVISION_1, + SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT, + &owner_sid, + &group_sid, + NULL, + new_dacl, + &size); + if (!*ppdesc) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} -- Samba Shared Repository