X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source3%2Fsmbd%2Fposix_acls.c;h=951046c56253034882f4121894088a6e632fb1d8;hb=2d81c9e957a21191c5b4e2b28a4599052c1357a1;hp=427cfc9a0d341524d179c5235e3ec800fe41e65e;hpb=1fb1c67fb9392364887ba8963f18d10b27d1cfa0;p=sfrench%2Fsamba-autobuild%2F.git diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 427cfc9a0d3..951046c5625 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -725,7 +725,7 @@ static int map_acl_perms_to_permset(connection_struct *conn, mode_t mode, SMB_AC Function to create owner and group SIDs from a SMB_STRUCT_STAT. ****************************************************************************/ -static void create_file_sids(const SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid) +void create_file_sids(const SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid) { uid_to_sid( powner_sid, psbuf->st_uid ); gid_to_sid( pgroup_sid, psbuf->st_gid ); @@ -870,7 +870,7 @@ static void merge_aces( canon_ace **pp_list_head ) Check if we need to return NT4.x compatible ACL entries. ****************************************************************************/ -static bool nt4_compatible_acls(void) +bool nt4_compatible_acls(void) { int compat = lp_acl_compatibility(); @@ -890,13 +890,12 @@ static bool nt4_compatible_acls(void) not get. Deny entries are implicit on get with ace->perms = 0. ****************************************************************************/ -static SEC_ACCESS map_canon_ace_perms(int snum, +static uint32_t map_canon_ace_perms(int snum, enum security_ace_type *pacl_type, mode_t perms, bool directory_ace) { - SEC_ACCESS sa; - uint32 nt_mask = 0; + uint32_t nt_mask = 0; *pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED; @@ -935,8 +934,7 @@ static SEC_ACCESS map_canon_ace_perms(int snum, DEBUG(10,("map_canon_ace_perms: Mapped (UNIX) %x to (NT) %x\n", (unsigned int)perms, (unsigned int)nt_mask )); - init_sec_access(&sa,nt_mask); - return sa; + return nt_mask; } /**************************************************************************** @@ -988,7 +986,7 @@ static mode_t map_nt_perms( uint32 *mask, int type) Unpack a SEC_DESC into a UNIX owner and group. ****************************************************************************/ -NTSTATUS unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, SEC_DESC *psd) +NTSTATUS unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, const SEC_DESC *psd) { DOM_SID owner_sid; DOM_SID grp_sid; @@ -1329,11 +1327,13 @@ static void check_owning_objs(canon_ace *ace, DOM_SID *pfile_owner_sid, DOM_SID Unpack a SEC_DESC into two canonical ace lists. ****************************************************************************/ -static bool create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst, - DOM_SID *pfile_owner_sid, - DOM_SID *pfile_grp_sid, - canon_ace **ppfile_ace, canon_ace **ppdir_ace, - SEC_ACL *dacl) +static bool create_canon_ace_lists(files_struct *fsp, + SMB_STRUCT_STAT *pst, + DOM_SID *pfile_owner_sid, + DOM_SID *pfile_grp_sid, + canon_ace **ppfile_ace, + canon_ace **ppdir_ace, + const SEC_ACL *dacl) { bool all_aces_are_inherit_only = (fsp->is_directory ? True : False); canon_ace *file_ace = NULL; @@ -2016,12 +2016,14 @@ static mode_t create_default_mode(files_struct *fsp, bool interitable_mode) succeeding. ****************************************************************************/ -static bool unpack_canon_ace(files_struct *fsp, - SMB_STRUCT_STAT *pst, - DOM_SID *pfile_owner_sid, - DOM_SID *pfile_grp_sid, - canon_ace **ppfile_ace, canon_ace **ppdir_ace, - uint32 security_info_sent, SEC_DESC *psd) +static bool unpack_canon_ace(files_struct *fsp, + SMB_STRUCT_STAT *pst, + DOM_SID *pfile_owner_sid, + DOM_SID *pfile_grp_sid, + canon_ace **ppfile_ace, + canon_ace **ppdir_ace, + uint32 security_info_sent, + const SEC_DESC *psd) { canon_ace *file_ace = NULL; canon_ace *dir_ace = NULL; @@ -2958,9 +2960,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, */ for (ace = file_ace; ace != NULL; ace = ace->next) { - SEC_ACCESS acc; - - acc = map_canon_ace_perms(SNUM(conn), + uint32_t acc = map_canon_ace_perms(SNUM(conn), &nt_acl_type, ace->perms, S_ISDIR(sbuf->st_mode)); @@ -2975,19 +2975,14 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, /* The User must have access to a profile share - even * if we can't map the SID. */ if (lp_profile_acls(SNUM(conn))) { - SEC_ACCESS acc; - - init_sec_access(&acc,FILE_GENERIC_ALL); init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, - acc, 0); + FILE_GENERIC_ALL, 0); } for (ace = dir_ace; ace != NULL; ace = ace->next) { - SEC_ACCESS acc; - - acc = map_canon_ace_perms(SNUM(conn), + uint32_t acc = map_canon_ace_perms(SNUM(conn), &nt_acl_type, ace->perms, S_ISDIR(sbuf->st_mode)); @@ -3005,10 +3000,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, /* The User must have access to a profile share - even * if we can't map the SID. */ if (lp_profile_acls(SNUM(conn))) { - SEC_ACCESS acc; - - init_sec_access(&acc,FILE_GENERIC_ALL); - init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, + init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_ALL, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT| SEC_ACE_FLAG_INHERIT_ONLY|0); } @@ -3199,7 +3191,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) return -1; } - if (!NT_STATUS_IS_OK(open_file_fchmod(conn,fname,&st,&fsp))) { + if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, fname, &st, &fsp))) { return -1; } @@ -3214,56 +3206,63 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) ret = SMB_VFS_FCHOWN(fsp, uid, (gid_t)-1); unbecome_root(); - close_file_fchmod(fsp); + close_file_fchmod(NULL, fsp); return ret; } +#if 0 +/* Disable this - prevents ACL inheritance from the ACL editor. JRA. */ + /**************************************************************************** Take care of parent ACL inheritance. ****************************************************************************/ -static NTSTATUS append_parent_acl(files_struct *fsp, - SMB_STRUCT_STAT *psbuf, - SEC_DESC *psd, +NTSTATUS append_parent_acl(files_struct *fsp, + const SEC_DESC *pcsd, SEC_DESC **pp_new_sd) { SEC_DESC *parent_sd = NULL; files_struct *parent_fsp = NULL; - TALLOC_CTX *mem_ctx = talloc_parent(psd); + TALLOC_CTX *mem_ctx = talloc_tos(); char *parent_name = NULL; SEC_ACE *new_ace = NULL; - unsigned int num_aces = psd->dacl->num_aces; + unsigned int num_aces = pcsd->dacl->num_aces; SMB_STRUCT_STAT sbuf; NTSTATUS status; int info; unsigned int i, j; - bool is_dacl_protected = (psd->type & SE_DESC_DACL_PROTECTED); + SEC_DESC *psd = dup_sec_desc(talloc_tos(), pcsd); + bool is_dacl_protected = (pcsd->type & SE_DESC_DACL_PROTECTED); ZERO_STRUCT(sbuf); - if (mem_ctx == NULL) { + if (psd == NULL) { return NT_STATUS_NO_MEMORY; } - if (!parent_dirname_talloc(mem_ctx, - fsp->fsp_name, - &parent_name, - NULL)) { + if (!parent_dirname(mem_ctx, fsp->fsp_name, &parent_name, NULL)) { return NT_STATUS_NO_MEMORY; } - status = open_directory(fsp->conn, - NULL, - parent_name, - &sbuf, - FILE_READ_ATTRIBUTES, /* Just a stat open */ - FILE_SHARE_NONE, /* Ignored for stat opens */ - FILE_OPEN, - 0, - INTERNAL_OPEN_ONLY, - &info, - &parent_fsp); + status = SMB_VFS_CREATE_FILE( + fsp->conn, /* conn */ + NULL, /* req */ + 0, /* root_dir_fid */ + parent_name, /* fname */ + 0, /* create_file_flags */ + FILE_READ_ATTRIBUTES, /* access_mask */ + FILE_SHARE_NONE, /* share_access */ + FILE_OPEN, /* create_disposition*/ + FILE_DIRECTORY_FILE, /* create_options */ + 0, /* file_attributes */ + INTERNAL_OPEN_ONLY, /* oplock_request */ + 0, /* allocation_size */ + NULL, /* sd */ + NULL, /* ea_list */ + &parent_fsp, /* result */ + &info, /* pinfo */ + &sbuf); /* psbuf */ if (!NT_STATUS_IS_OK(status)) { return status; @@ -3272,7 +3271,7 @@ static NTSTATUS append_parent_acl(files_struct *fsp, status = SMB_VFS_GET_NT_ACL(parent_fsp->conn, parent_fsp->fsp_name, DACL_SECURITY_INFORMATION, &parent_sd ); - close_file(parent_fsp, NORMAL_CLOSE); + close_file(NULL, parent_fsp, NORMAL_CLOSE); if (!NT_STATUS_IS_OK(status)) { return status; @@ -3398,12 +3397,15 @@ static NTSTATUS append_parent_acl(files_struct *fsp, parent_name)); } - parent_sd->dacl->aces = new_ace; - parent_sd->dacl->num_aces = i; + psd->dacl->aces = new_ace; + psd->dacl->num_aces = i; + psd->type &= ~(SE_DESC_DACL_AUTO_INHERITED| + SE_DESC_DACL_AUTO_INHERIT_REQ); - *pp_new_sd = parent_sd; + *pp_new_sd = psd; return status; } +#endif /**************************************************************************** Reply to set a security descriptor on an fsp. security_info_sent is the @@ -3411,7 +3413,7 @@ static NTSTATUS append_parent_acl(files_struct *fsp, This should be the only external function needed for the UNIX style set ACL. ****************************************************************************/ -NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) +NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC *psd) { connection_struct *conn = fsp->conn; uid_t user = (uid_t)-1; @@ -3426,7 +3428,6 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) NTSTATUS status; uid_t orig_uid; gid_t orig_gid; - bool need_chown = False; DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name )); @@ -3462,14 +3463,12 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) } /* - * Do we need to chown ? + * Do we need to chown ? If so this must be done first as the incoming + * CREATOR_OWNER acl will be relative to the *new* owner, not the old. + * Noticed by Simo. */ if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (gid_t)-1) && (orig_gid != grp))) { - need_chown = True; - } - - if (need_chown && (user == (uid_t)-1 || user == current_user.ut.uid)) { DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", fsp->fsp_name, (unsigned int)user, (unsigned int)grp )); @@ -3509,24 +3508,31 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) orig_mode = sbuf.st_mode; orig_uid = sbuf.st_uid; orig_gid = sbuf.st_gid; - - /* We did chown already, drop the flag */ - need_chown = False; } create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid); +#if 0 + /* Disable this - prevents ACL inheritance from the ACL editor. JRA. */ + + /* See here: http://www.codeproject.com/KB/winsdk/accessctrl2.aspx + * for details and also the log trace in bug #4308. JRA. + */ + if ((security_info_sent & DACL_SECURITY_INFORMATION) && psd->dacl != NULL && (psd->type & (SE_DESC_DACL_AUTO_INHERITED| SE_DESC_DACL_AUTO_INHERIT_REQ))== (SE_DESC_DACL_AUTO_INHERITED| SE_DESC_DACL_AUTO_INHERIT_REQ) ) { - status = append_parent_acl(fsp, &sbuf, psd, &psd); + SEC_DESC *new_sd = NULL; + status = append_parent_acl(fsp, psd, &new_sd); if (!NT_STATUS_IS_OK(status)) { return status; } + psd = new_sd; } +#endif acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid, &file_ace_list, &dir_ace_list, security_info_sent, psd); @@ -3652,24 +3658,9 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) } free_canon_ace_list(file_ace_list); - free_canon_ace_list(dir_ace_list); + free_canon_ace_list(dir_ace_list); } - /* Any chown pending? */ - if (need_chown) { - DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", - fsp->fsp_name, (unsigned int)user, (unsigned int)grp )); - - if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) { - DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n", - fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) )); - if (errno == EPERM) { - return NT_STATUS_INVALID_OWNER; - } - return map_nt_error_from_unix(errno); - } - } - return NT_STATUS_OK; } @@ -4301,7 +4292,7 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname) finfo.fh->fd = -1; finfo.fsp_name = CONST_DISCARD(char *,fname); - if (!NT_STATUS_IS_OK(posix_fget_nt_acl( &finfo, DACL_SECURITY_INFORMATION, &psd))) { + if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, DACL_SECURITY_INFORMATION, &psd))) { DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n")); conn_free_internal( conn ); return NULL;