From bb89f8cb94802bb2f9b43c1c63fd55ee2de9b09e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 28 Oct 2007 01:14:51 +0200 Subject: Change apply_default_perms() to not take an fsp. This is a first change in a series: Pass what is needed instead of files_struct pointers to some functions. This is in preparation of introducing two variants of get_nt_acl - one for fname (which does not need an fsp), one for file descriptor. This changes apply_default_perms to take share_params (rather thatn snum) and an is_directory flag instead of an fsp. Michael (This used to be commit d7e2e93758f6598a0459db3255300558618f066e) --- source3/smbd/posix_acls.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index ccfed69721..ca83d85399 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -999,20 +999,21 @@ NTSTATUS unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_i Ensure the enforced permissions for this share apply. ****************************************************************************/ -static void apply_default_perms(const files_struct *fsp, canon_ace *pace, mode_t type) +static void apply_default_perms(const struct share_params *params, + const bool is_directory, canon_ace *pace, + mode_t type) { - int snum = SNUM(fsp->conn); mode_t and_bits = (mode_t)0; mode_t or_bits = (mode_t)0; /* Get the initial bits to apply. */ - if (fsp->is_directory) { - and_bits = lp_dir_security_mask(snum); - or_bits = lp_force_dir_security_mode(snum); + if (is_directory) { + and_bits = lp_dir_security_mask(params->service); + or_bits = lp_force_dir_security_mode(params->service); } else { - and_bits = lp_security_mask(snum); - or_bits = lp_force_security_mode(snum); + and_bits = lp_security_mask(params->service); + or_bits = lp_force_security_mode(params->service); } /* Now bounce them into the S_USR space. */ @@ -1020,7 +1021,7 @@ static void apply_default_perms(const files_struct *fsp, canon_ace *pace, mode_t case S_IRUSR: /* Ensure owner has read access. */ pace->perms |= S_IRUSR; - if (fsp->is_directory) + if (is_directory) pace->perms |= (S_IWUSR|S_IXUSR); and_bits = unix_perms_to_acl_perms(and_bits, S_IRUSR, S_IWUSR, S_IXUSR); or_bits = unix_perms_to_acl_perms(or_bits, S_IRUSR, S_IWUSR, S_IXUSR); @@ -1092,7 +1093,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, if (pace->type == SMB_ACL_USER_OBJ) { if (setting_acl) - apply_default_perms(fsp, pace, S_IRUSR); + apply_default_perms(fsp->conn->params, fsp->is_directory, pace, S_IRUSR); got_user = True; } else if (pace->type == SMB_ACL_GROUP_OBJ) { @@ -1102,7 +1103,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, */ if (setting_acl) - apply_default_perms(fsp, pace, S_IRGRP); + apply_default_perms(fsp->conn->params, fsp->is_directory, pace, S_IRGRP); got_grp = True; } else if (pace->type == SMB_ACL_OTHER) { @@ -1112,7 +1113,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, */ if (setting_acl) - apply_default_perms(fsp, pace, S_IROTH); + apply_default_perms(fsp->conn->params, fsp->is_directory, pace, S_IROTH); got_other = True; pace_other = pace; } @@ -1155,7 +1156,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, pace->perms = 0; } - apply_default_perms(fsp, pace, S_IRUSR); + apply_default_perms(fsp->conn->params, fsp->is_directory, pace, S_IRUSR); } else { pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRUSR, S_IWUSR, S_IXUSR); } @@ -1181,7 +1182,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, pace->perms = pace_other->perms; else pace->perms = 0; - apply_default_perms(fsp, pace, S_IRGRP); + apply_default_perms(fsp->conn->params, fsp->is_directory, pace, S_IRGRP); } else { pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRGRP, S_IWGRP, S_IXGRP); } @@ -1203,7 +1204,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, pace->attr = ALLOW_ACE; if (setting_acl) { pace->perms = 0; - apply_default_perms(fsp, pace, S_IROTH); + apply_default_perms(fsp->conn->params, fsp->is_directory, pace, S_IROTH); } else pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IROTH, S_IWOTH, S_IXOTH); -- cgit From c5d21d1a651aa02c7b3e2fbaa89b8364bdfbfa68 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 28 Oct 2007 01:24:41 +0200 Subject: Change ensure_canon_entry_valid() to not take and fsp. Convert ensure_canon_entry_valid() to take share_params and an is_directory flag instead of an files_struct pointer. Michael (This used to be commit bdb208124bd703edee03ac4d2a4ec45ecdfc135e) --- source3/smbd/posix_acls.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index ca83d85399..7be4ee1c80 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -1077,7 +1077,8 @@ static bool uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace ) ****************************************************************************/ static bool ensure_canon_entry_valid(canon_ace **pp_ace, - const files_struct *fsp, + const struct share_params *params, + const bool is_directory, const DOM_SID *pfile_owner_sid, const DOM_SID *pfile_grp_sid, const SMB_STRUCT_STAT *pst, @@ -1093,7 +1094,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, if (pace->type == SMB_ACL_USER_OBJ) { if (setting_acl) - apply_default_perms(fsp->conn->params, fsp->is_directory, pace, S_IRUSR); + apply_default_perms(params, is_directory, pace, S_IRUSR); got_user = True; } else if (pace->type == SMB_ACL_GROUP_OBJ) { @@ -1103,7 +1104,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, */ if (setting_acl) - apply_default_perms(fsp->conn->params, fsp->is_directory, pace, S_IRGRP); + apply_default_perms(params, is_directory, pace, S_IRGRP); got_grp = True; } else if (pace->type == SMB_ACL_OTHER) { @@ -1113,7 +1114,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, */ if (setting_acl) - apply_default_perms(fsp->conn->params, fsp->is_directory, pace, S_IROTH); + apply_default_perms(params, is_directory, pace, S_IROTH); got_other = True; pace_other = pace; } @@ -1156,7 +1157,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, pace->perms = 0; } - apply_default_perms(fsp->conn->params, fsp->is_directory, pace, S_IRUSR); + apply_default_perms(params, is_directory, pace, S_IRUSR); } else { pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRUSR, S_IWUSR, S_IXUSR); } @@ -1182,7 +1183,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, pace->perms = pace_other->perms; else pace->perms = 0; - apply_default_perms(fsp->conn->params, fsp->is_directory, pace, S_IRGRP); + apply_default_perms(params, is_directory, pace, S_IRGRP); } else { pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IRGRP, S_IWGRP, S_IXGRP); } @@ -1204,7 +1205,7 @@ static bool ensure_canon_entry_valid(canon_ace **pp_ace, pace->attr = ALLOW_ACE; if (setting_acl) { pace->perms = 0; - apply_default_perms(fsp->conn->params, fsp->is_directory, pace, S_IROTH); + apply_default_perms(params, is_directory, pace, S_IROTH); } else pace->perms = unix_perms_to_acl_perms(pst->st_mode, S_IROTH, S_IWOTH, S_IXOTH); @@ -2015,7 +2016,7 @@ static bool unpack_canon_ace(files_struct *fsp, pst->st_mode = create_default_mode(fsp, False); - if (!ensure_canon_entry_valid(&file_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst, True)) { + if (!ensure_canon_entry_valid(&file_ace, fsp->conn->params, fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) { free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); return False; @@ -2031,7 +2032,7 @@ static bool unpack_canon_ace(files_struct *fsp, pst->st_mode = create_default_mode(fsp, True); - if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst, True)) { + if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp->conn->params, fsp->is_directory, pfile_owner_sid, pfile_grp_sid, pst, True)) { free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); return False; @@ -2227,7 +2228,7 @@ static canon_ace *canonicalise_acl( const files_struct *fsp, SMB_ACL_T posix_acl * This next call will ensure we have at least a user/group/world set. */ - if (!ensure_canon_entry_valid(&list_head, fsp, powner, pgroup, psbuf, False)) + if (!ensure_canon_entry_valid(&list_head, fsp->conn->params, fsp->is_directory, powner, pgroup, psbuf, False)) goto fail; /* -- cgit From 13e0788714c1a5a3ce62597d04d3034ca14d031e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 28 Oct 2007 01:38:59 +0200 Subject: Change canonicalise_acl() to not take an fsp. Convert canonicalise_acl() to take connection_struct, is_directory and file name instead of files_struct pointer. Michael (This used to be commit d579a7f84fd47a3f00215725cecd65b21a5ff2e0) --- source3/smbd/posix_acls.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 7be4ee1c80..1b91823ea2 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -2110,10 +2110,11 @@ static void arrange_posix_perms(const char *filename, canon_ace **pp_list_head) Create a linked list of canonical ACE entries. ****************************************************************************/ -static canon_ace *canonicalise_acl( const files_struct *fsp, SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf, +static canon_ace *canonicalise_acl(const struct connection_struct *conn, + const bool is_directory, const char *fname, + SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf, const DOM_SID *powner, const DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type) { - connection_struct *conn = fsp->conn; mode_t acl_mask = (S_IRUSR|S_IWUSR|S_IXUSR); canon_ace *list_head = NULL; canon_ace *ace = NULL; @@ -2228,7 +2229,7 @@ static canon_ace *canonicalise_acl( const files_struct *fsp, SMB_ACL_T posix_acl * This next call will ensure we have at least a user/group/world set. */ - if (!ensure_canon_entry_valid(&list_head, fsp->conn->params, fsp->is_directory, powner, pgroup, psbuf, False)) + if (!ensure_canon_entry_valid(&list_head, conn->params, is_directory, powner, pgroup, psbuf, False)) goto fail; /* @@ -2254,7 +2255,7 @@ static canon_ace *canonicalise_acl( const files_struct *fsp, SMB_ACL_T posix_acl } } - arrange_posix_perms(fsp->fsp_name,&list_head ); + arrange_posix_perms(fname,&list_head ); print_canon_ace_list( "canonicalise_acl: ace entries after arrange", list_head ); @@ -2816,7 +2817,10 @@ NTSTATUS get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) */ /* Create the canon_ace lists. */ - file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, pal, SMB_ACL_TYPE_ACCESS ); + file_ace = canonicalise_acl(fsp->conn, fsp->is_directory, + fsp->fsp_name, posix_acl, &sbuf, + &owner_sid, &group_sid, pal, + SMB_ACL_TYPE_ACCESS); /* We must have *some* ACLS. */ @@ -2826,9 +2830,12 @@ NTSTATUS get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) } if (fsp->is_directory && def_acl) { - dir_ace = canonicalise_acl(fsp, def_acl, &sbuf, - &global_sid_Creator_Owner, - &global_sid_Creator_Group, pal, SMB_ACL_TYPE_DEFAULT ); + dir_ace = canonicalise_acl(fsp->conn, fsp->is_directory, + fsp->fsp_name, def_acl, + &sbuf, + &global_sid_Creator_Owner, + &global_sid_Creator_Group, + pal, SMB_ACL_TYPE_DEFAULT); } /* -- cgit From a7e15d41c66e811777e52fbfa19df817d8617d5a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 6 Nov 2007 06:20:51 +0100 Subject: Remove the "is_directory" parameter from canonicalise_acl(): It can be retrieved from the stat buffer. Michael (This used to be commit b0ae830bf57dcaec00b2a2eabfec7221a3b7f791) --- source3/smbd/posix_acls.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 1b91823ea2..57a3ff9766 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -2110,10 +2110,10 @@ static void arrange_posix_perms(const char *filename, canon_ace **pp_list_head) Create a linked list of canonical ACE entries. ****************************************************************************/ -static canon_ace *canonicalise_acl(const struct connection_struct *conn, - const bool is_directory, const char *fname, - SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf, - const DOM_SID *powner, const DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type) +static canon_ace *canonicalise_acl(struct connection_struct *conn, + const char *fname, SMB_ACL_T posix_acl, + const SMB_STRUCT_STAT *psbuf, + const DOM_SID *powner, const DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type) { mode_t acl_mask = (S_IRUSR|S_IWUSR|S_IXUSR); canon_ace *list_head = NULL; @@ -2229,7 +2229,9 @@ static canon_ace *canonicalise_acl(const struct connection_struct *conn, * This next call will ensure we have at least a user/group/world set. */ - if (!ensure_canon_entry_valid(&list_head, conn->params, is_directory, powner, pgroup, psbuf, False)) + if (!ensure_canon_entry_valid(&list_head, conn->params, + S_ISDIR(psbuf->st_mode), powner, pgroup, + psbuf, False)) goto fail; /* @@ -2817,7 +2819,7 @@ NTSTATUS get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) */ /* Create the canon_ace lists. */ - file_ace = canonicalise_acl(fsp->conn, fsp->is_directory, + file_ace = canonicalise_acl(fsp->conn, fsp->fsp_name, posix_acl, &sbuf, &owner_sid, &group_sid, pal, SMB_ACL_TYPE_ACCESS); @@ -2830,7 +2832,7 @@ NTSTATUS get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) } if (fsp->is_directory && def_acl) { - dir_ace = canonicalise_acl(fsp->conn, fsp->is_directory, + dir_ace = canonicalise_acl(fsp->conn, fsp->fsp_name, def_acl, &sbuf, &global_sid_Creator_Owner, -- cgit From 8e2323e391e312e0f0284c918e2bb8567c035e20 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 6 Nov 2007 08:01:31 +0100 Subject: Split get_nt_acl() into two functions: fsp- and non-fsp variant. Replace smbd/posix_acls.c:get_nt_acl() by two funcions: posix_get_nt_acl() and posix_fget_nt_acl(). The first takes a connection struct and a file name instead of a files_struct pointer. This is in preparation of changing the vfs api for SMB_VFS_GET_NT_ACL. Michael (This used to be commit 50c82cc1456736fa634fb656e63555319742f725) --- source3/smbd/posix_acls.c | 211 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 148 insertions(+), 63 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 57a3ff9766..d9782cfdb8 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -430,7 +430,7 @@ static struct pai_val *create_pai_val(char *buf, size_t size) Load the user.SAMBA_PAI attribute. ************************************************************************/ -static struct pai_val *load_inherited_info(files_struct *fsp) +static struct pai_val *fload_inherited_info(files_struct *fsp) { char *pai_buf; size_t pai_buf_size = 1024; @@ -490,6 +490,71 @@ static struct pai_val *load_inherited_info(files_struct *fsp) return paiv; } +/************************************************************************ + Load the user.SAMBA_PAI attribute. +************************************************************************/ + +static struct pai_val *load_inherited_info(const struct connection_struct *conn, + const char *fname) +{ + char *pai_buf; + size_t pai_buf_size = 1024; + struct pai_val *paiv = NULL; + ssize_t ret; + + if (!lp_map_acl_inherit(SNUM(conn))) { + return NULL; + } + + if ((pai_buf = (char *)SMB_MALLOC(pai_buf_size)) == NULL) { + return NULL; + } + + do { + ret = SMB_VFS_GETXATTR(conn, fname, + SAMBA_POSIX_INHERITANCE_EA_NAME, + pai_buf, pai_buf_size); + + if (ret == -1) { + if (errno != ERANGE) { + break; + } + /* Buffer too small - enlarge it. */ + pai_buf_size *= 2; + SAFE_FREE(pai_buf); + if (pai_buf_size > 1024*1024) { + return NULL; /* Limit malloc to 1mb. */ + } + if ((pai_buf = (char *)SMB_MALLOC(pai_buf_size)) == NULL) + return NULL; + } + } while (ret == -1); + + DEBUG(10,("load_inherited_info: ret = %lu for file %s\n", (unsigned long)ret, fname)); + + if (ret == -1) { + /* No attribute or not supported. */ +#if defined(ENOATTR) + if (errno != ENOATTR) + DEBUG(10,("load_inherited_info: Error %s\n", strerror(errno) )); +#else + if (errno != ENOSYS) + DEBUG(10,("load_inherited_info: Error %s\n", strerror(errno) )); +#endif + SAFE_FREE(pai_buf); + return NULL; + } + + paiv = create_pai_val(pai_buf, ret); + + if (paiv && paiv->pai_protected) { + DEBUG(10,("load_inherited_info: ACL is protected for file %s\n", fname)); + } + + SAFE_FREE(pai_buf); + return paiv; +} + /**************************************************************************** Functions to manipulate the internal ACE format. ****************************************************************************/ @@ -2724,6 +2789,7 @@ static size_t merge_default_aces( SEC_ACE *nt_ace_list, size_t num_aces) return num_aces; } + /**************************************************************************** Reply to query a security descriptor from an fsp. If it succeeds it allocates the space for the return elements and returns the size needed to return the @@ -2731,11 +2797,15 @@ static size_t merge_default_aces( SEC_ACE *nt_ace_list, size_t num_aces) the UNIX style get ACL. ****************************************************************************/ -NTSTATUS get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) +static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, + const char *name, + const SMB_STRUCT_STAT *sbuf, + struct pai_val *pal, + SMB_ACL_T posix_acl, + SMB_ACL_T def_acl, + uint32_t security_info, + SEC_DESC **ppdesc) { - connection_struct *conn = fsp->conn; - SMB_STRUCT_STAT sbuf; - SEC_ACE *nt_ace_list = NULL; DOM_SID owner_sid; DOM_SID group_sid; size_t sd_size = 0; @@ -2743,57 +2813,12 @@ NTSTATUS get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) size_t num_acls = 0; size_t num_def_acls = 0; size_t num_aces = 0; - SMB_ACL_T posix_acl = NULL; - SMB_ACL_T def_acl = NULL; canon_ace *file_ace = NULL; canon_ace *dir_ace = NULL; + SEC_ACE *nt_ace_list = NULL; size_t num_profile_acls = 0; - struct pai_val *pal = NULL; SEC_DESC *psd = NULL; - *ppdesc = NULL; - - DEBUG(10,("get_nt_acl: called for file %s\n", fsp->fsp_name )); - - if(fsp->is_directory || fsp->fh->fd == -1) { - - /* Get the stat struct for the owner info. */ - if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) { - return map_nt_error_from_unix(errno); - } - /* - * Get the ACL from the path. - */ - - posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_ACCESS); - - /* - * If it's a directory get the default POSIX ACL. - */ - - if(fsp->is_directory) { - def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT); - def_acl = free_empty_sys_acl(conn, def_acl); - } - - } else { - - /* Get the stat struct for the owner info. */ - if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) { - return map_nt_error_from_unix(errno); - } - /* - * Get the ACL from the fd. - */ - posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd); - } - - DEBUG(5,("get_nt_acl : file ACL %s, directory ACL %s\n", - posix_acl ? "present" : "absent", - def_acl ? "present" : "absent" )); - - pal = load_inherited_info(fsp); - /* * Get the owner, group and world SIDs. */ @@ -2804,7 +2829,7 @@ NTSTATUS get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) sid_copy(&group_sid, &global_sid_Builtin_Users); num_profile_acls = 2; } else { - create_file_sids(&sbuf, &owner_sid, &group_sid); + create_file_sids(sbuf, &owner_sid, &group_sid); } if ((security_info & DACL_SECURITY_INFORMATION) && !(security_info & PROTECTED_DACL_SECURITY_INFORMATION)) { @@ -2819,22 +2844,20 @@ NTSTATUS get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) */ /* Create the canon_ace lists. */ - file_ace = canonicalise_acl(fsp->conn, - fsp->fsp_name, posix_acl, &sbuf, + file_ace = canonicalise_acl(conn, name, posix_acl, sbuf, &owner_sid, &group_sid, pal, SMB_ACL_TYPE_ACCESS); /* We must have *some* ACLS. */ if (count_canon_ace_list(file_ace) == 0) { - DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", fsp->fsp_name )); + DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", name)); goto done; } - if (fsp->is_directory && def_acl) { - dir_ace = canonicalise_acl(fsp->conn, - fsp->fsp_name, def_acl, - &sbuf, + if (S_ISDIR(sbuf->st_mode) && def_acl) { + dir_ace = canonicalise_acl(conn, name, def_acl, + sbuf, &global_sid_Creator_Owner, &global_sid_Creator_Group, pal, SMB_ACL_TYPE_DEFAULT); @@ -2921,7 +2944,7 @@ NTSTATUS get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) acc = map_canon_ace_perms(SNUM(conn), &nt_acl_type, ace->perms, - fsp->is_directory); + S_ISDIR(sbuf->st_mode)); init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, @@ -2950,7 +2973,7 @@ NTSTATUS get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) acc = map_canon_ace_perms(SNUM(conn), &nt_acl_type, ace->perms, - fsp->is_directory); + S_ISDIR(sbuf->st_mode)); init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, @@ -3039,6 +3062,69 @@ NTSTATUS get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) return NT_STATUS_OK; } +NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, + SEC_DESC **ppdesc) +{ + SMB_STRUCT_STAT sbuf; + SMB_ACL_T posix_acl = NULL; + struct pai_val *pal; + + *ppdesc = NULL; + + DEBUG(10,("posix_fget_nt_acl: called for file %s\n", fsp->fsp_name )); + + /* can it happen that fsp_name == NULL ? */ + if (fsp->is_directory || fsp->fh->fd == -1) { + return posix_get_nt_acl(fsp->conn, fsp->fsp_name, + security_info, ppdesc); + } + + /* Get the stat struct for the owner info. */ + if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) { + return map_nt_error_from_unix(errno); + } + + /* Get the ACL from the fd. */ + posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd); + + pal = fload_inherited_info(fsp); + + return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name, &sbuf, pal, + posix_acl, NULL, security_info, ppdesc); +} + +NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, + uint32_t security_info, SEC_DESC **ppdesc) +{ + SMB_STRUCT_STAT sbuf; + SMB_ACL_T posix_acl = NULL; + SMB_ACL_T def_acl = NULL; + struct pai_val *pal; + + *ppdesc = NULL; + + DEBUG(10,("posix_get_nt_acl: called for file %s\n", name )); + + /* Get the stat struct for the owner info. */ + if(SMB_VFS_STAT(conn, name, &sbuf) != 0) { + return map_nt_error_from_unix(errno); + } + + /* Get the ACL from the path. */ + posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_ACCESS); + + /* If it's a directory get the default POSIX ACL. */ + if(S_ISDIR(sbuf.st_mode)) { + def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_DEFAULT); + def_acl = free_empty_sys_acl(conn, def_acl); + } + + pal = load_inherited_info(conn, name); + + return posix_get_nt_acl_common(conn, name, &sbuf, pal, posix_acl, + def_acl, security_info, ppdesc); +} + /**************************************************************************** Try to chown a file. We will be able to chown it under the following conditions. @@ -4182,8 +4268,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(get_nt_acl( &finfo, DACL_SECURITY_INFORMATION, - &psd ))) { + if (!NT_STATUS_IS_OK(posix_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; -- cgit From 233eb0e560acb26f8706fd3ab96d4c6379458414 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 5 Dec 2007 09:53:10 +0100 Subject: Change the prototype of the vfs function get_nt_acl(). Up to now, get_nt_acl() took a files_struct pointer (fsp) and a file name. All the underlying functions should need and now do need (after the previous preparatory work), is a connection_struct and a file name. The connection_struct is already there in the vfs_handle passed to the vfs functions. So the files_struct argument can be eliminated. This eliminates the need of calling open_file_stat in a couple of places to produce the fsp needed. Michael (This used to be commit b5f600fab53c9d159a958c59795db3ba4a8acc63) --- source3/smbd/posix_acls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index d9782cfdb8..d8794e2114 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3307,7 +3307,7 @@ static NTSTATUS append_parent_acl(files_struct *fsp, return status; } - status = SMB_VFS_GET_NT_ACL(parent_fsp, parent_fsp->fsp_name, + status = SMB_VFS_GET_NT_ACL(parent_fsp->conn, parent_fsp->fsp_name, DACL_SECURITY_INFORMATION, &parent_sd ); close_file(parent_fsp, NORMAL_CLOSE); -- cgit From 99b86e4a266b99634f6a65015f6df115c421d3e5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 20 Dec 2007 22:27:01 +0100 Subject: Some C++ fixes (This used to be commit 5c392c4c6e277a24d0d477902dc7856b2b46ee53) --- source3/smbd/posix_acls.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index d8794e2114..2810b5e587 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -891,7 +891,7 @@ static bool nt4_compatible_acls(void) ****************************************************************************/ static SEC_ACCESS map_canon_ace_perms(int snum, - int *pacl_type, + enum security_ace_type *pacl_type, mode_t perms, bool directory_ace) { @@ -2869,7 +2869,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, { canon_ace *ace; - int nt_acl_type; + enum security_ace_type nt_acl_type; int i; if (nt4_compatible_acls() && dir_ace) { @@ -3210,7 +3210,7 @@ static NTSTATUS append_ugw_ace(files_struct *fsp, { mode_t perms; SEC_ACCESS acc; - int nt_acl_type; + enum security_ace_type nt_acl_type; DOM_SID trustee; switch (ugw) { -- cgit From 87a684f7fcfa8d9fabc42e33981299d0b33eeeb7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 13:21:26 +0100 Subject: Remove redundant parameter fd from SMB_VFS_FSTAT(). Michael (This used to be commit 0b86c420be94d295f6917a220b5d699f65b46711) --- source3/smbd/posix_acls.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 2810b5e587..f11aa69e08 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3080,7 +3080,7 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, } /* Get the stat struct for the owner info. */ - if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) { + if(SMB_VFS_FSTAT(fsp, &sbuf) != 0) { return map_nt_error_from_unix(errno); } @@ -3429,7 +3429,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) return map_nt_error_from_unix(errno); } else { - if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) + if(SMB_VFS_FSTAT(fsp, &sbuf) != 0) return map_nt_error_from_unix(errno); } @@ -3479,7 +3479,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) if(fsp->fh->fd == -1) ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf); else - ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf); + ret = SMB_VFS_FSTAT(fsp, &sbuf); if(ret != 0) return map_nt_error_from_unix(errno); -- cgit From 670909cb07e38a06bf5db12342b3b1189f0e1ab7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 14:26:00 +0100 Subject: Remove redundant parameter fd from SMB_VFS_FCHOWN(). Michael (This used to be commit fbb193db3e0dc51cb000ae406a68bc547f31d9ab) --- source3/smbd/posix_acls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index f11aa69e08..1aa3001923 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3194,7 +3194,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) become_root(); /* Keep the current file gid the same. */ - ret = SMB_VFS_FCHOWN(fsp, fsp->fh->fd, uid, (gid_t)-1); + ret = SMB_VFS_FCHOWN(fsp, uid, (gid_t)-1); unbecome_root(); close_file_fchmod(fsp); -- cgit From 62e9d503d82d645cf29af643732ad97c0eb8b340 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 23:53:34 +0100 Subject: Remove redundant parameter fd from SMB_VFS_SYS_ACL_GET_FD(). Michael (This used to be commit 42663e8736e1a3dfb57e0aafdcbf5fec880da779) --- source3/smbd/posix_acls.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 1aa3001923..b07033b8ac 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3085,7 +3085,7 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, } /* Get the ACL from the fd. */ - posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd); + posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp); pal = fload_inherited_info(fsp); @@ -3808,13 +3808,13 @@ int fchmod_acl(files_struct *fsp, int fd, mode_t mode) SMB_ACL_T posix_acl = NULL; int ret = -1; - if ((posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fd)) == NULL) + if ((posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp)) == NULL) return -1; if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1) goto done; - ret = SMB_VFS_SYS_ACL_SET_FD(fsp, fd, posix_acl); + ret = SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, posix_acl); done: @@ -4099,7 +4099,7 @@ static bool remove_posix_acl(connection_struct *conn, files_struct *fsp, const c /* Get the current file ACL. */ if (fsp && fsp->fh->fd != -1) { - file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fh->fd); + file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp); } else { file_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_ACCESS); } -- cgit From b2182c11eab0e1b2f0acb5d82aec86d4598573eb Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Jan 2008 01:14:24 +0100 Subject: Remove redundant parameter fd from SMB_VFS_FCHMOD_ACL(). Michael (This used to be commit 7b201c177b3668f54751ba17d6a0b53ed913e7f7) --- source3/smbd/posix_acls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index b07033b8ac..23a246fea7 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3802,7 +3802,7 @@ int inherit_access_acl(connection_struct *conn, const char *inherit_from_dir, and set the mask to rwx. Needed to preserve complex ACLs set by NT. ****************************************************************************/ -int fchmod_acl(files_struct *fsp, int fd, mode_t mode) +int fchmod_acl(files_struct *fsp, mode_t mode) { connection_struct *conn = fsp->conn; SMB_ACL_T posix_acl = NULL; -- cgit From 5921607f2647cec20a6bcebd17c5a0c53449c1ba Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Jan 2008 01:54:19 +0100 Subject: Remove redundant parameter fd from SMB_VFS_SYS_ACL_SET_FD(). Michael (This used to be commit 9296e93588c0e795cae770765050247ac1474a74) --- source3/smbd/posix_acls.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 23a246fea7..b6cb1d2e54 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -2573,7 +2573,7 @@ static bool set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, bool defau } } } else { - if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, the_acl) == -1) { + if (SMB_VFS_SYS_ACL_SET_FD(fsp, the_acl) == -1) { /* * Some systems allow all the above calls and only fail with no ACL support * when attempting to apply the acl. HPUX with HFS is an example of this. JRA. @@ -2589,7 +2589,7 @@ static bool set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, bool defau fsp->fsp_name )); become_root(); - sret = SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, the_acl); + sret = SMB_VFS_SYS_ACL_SET_FD(fsp, the_acl); unbecome_root(); if (sret == 0) { ret = True; @@ -3814,7 +3814,7 @@ int fchmod_acl(files_struct *fsp, mode_t mode) if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1) goto done; - ret = SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, posix_acl); + ret = SMB_VFS_SYS_ACL_SET_FD(fsp, posix_acl); done: @@ -4152,7 +4152,7 @@ static bool remove_posix_acl(connection_struct *conn, files_struct *fsp, const c /* Set the new empty file ACL. */ if (fsp && fsp->fh->fd != -1) { - if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, new_file_acl) == -1) { + if (SMB_VFS_SYS_ACL_SET_FD(fsp, new_file_acl) == -1) { DEBUG(5,("remove_posix_acl: acl_set_file failed on %s (%s)\n", fname, strerror(errno) )); goto done; @@ -4199,7 +4199,7 @@ bool set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char * if (fsp && fsp->fh->fd != -1) { /* The preferred way - use an open fd. */ - if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fh->fd, file_acl) == -1) { + if (SMB_VFS_SYS_ACL_SET_FD(fsp, file_acl) == -1) { DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n", fname, strerror(errno) )); SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl); -- cgit From 50ee744fa445b74136a8f2cef36c2b48ba7ee5f6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Jan 2008 10:00:47 +0100 Subject: Remove redundant parameter fd from SMB_VFS_FGETXATTR(). Michael (This used to be commit 2cb739a82dc6bb194d60718cc74b26ee7c1c46a7) --- source3/smbd/posix_acls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index b6cb1d2e54..be05ebd2ab 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -445,7 +445,7 @@ static struct pai_val *fload_inherited_info(files_struct *fsp) do { if (fsp->fh->fd != -1) - ret = SMB_VFS_FGETXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME, + ret = SMB_VFS_FGETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME, pai_buf, pai_buf_size); else ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME, -- cgit From 1590dd32cfccd9ce73cd798330b5207bcc48bfaf Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Jan 2008 11:29:09 +0100 Subject: Remove redundant parameter fd from SMB_VFS_FREMOVEXATTR(). Michael (This used to be commit bfc3b5a27f707d3e4b8d5d66192891e22365fbb3) --- source3/smbd/posix_acls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index be05ebd2ab..120e82c4b0 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -229,7 +229,7 @@ static void store_inheritance_attributes(files_struct *fsp, canon_ace *file_ace_ if (!pai_protected && num_inherited_entries(file_ace_list) == 0 && num_inherited_entries(dir_ace_list) == 0) { /* Instead just remove the attribute if it exists. */ if (fsp->fh->fd != -1) - SMB_VFS_FREMOVEXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME); + SMB_VFS_FREMOVEXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME); else SMB_VFS_REMOVEXATTR(fsp->conn, fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME); return; -- cgit From aab6704ce803a738ba125895b20a31f242fe2885 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Jan 2008 11:47:33 +0100 Subject: Remove redundant parameter fd from SMB_VFS_FSETXATTR(). Michael (This used to be commit 0bd2643463a9160c8a1c7e1c2f8cca7b89060e09) --- source3/smbd/posix_acls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 120e82c4b0..5f18615f66 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -238,7 +238,7 @@ static void store_inheritance_attributes(files_struct *fsp, canon_ace *file_ace_ pai_buf = create_pai_buf(file_ace_list, dir_ace_list, pai_protected, &store_size); if (fsp->fh->fd != -1) - ret = SMB_VFS_FSETXATTR(fsp, fsp->fh->fd, SAMBA_POSIX_INHERITANCE_EA_NAME, + ret = SMB_VFS_FSETXATTR(fsp, SAMBA_POSIX_INHERITANCE_EA_NAME, pai_buf, store_size, 0); else ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME, -- cgit From 313f7d10b884d083ef9488db739465c54c3f6515 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 16 Jan 2008 12:18:57 +0300 Subject: Merge latest fixes to vfs_gpfs and NFS4 ACLs from Samba 3.0 CTDB branch (from http://samba.org/~tridge/3_0-ctdb) Signed-off-by: Alexander Bokovoy (This used to be commit 1daad835cbfb4615a8fe7a241f4d578f7e69f214) --- source3/smbd/posix_acls.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 5f18615f66..6cec39f9c0 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3413,6 +3413,9 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) bool acl_perms = False; mode_t orig_mode = (mode_t)0; 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 )); @@ -3435,6 +3438,8 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) /* Save the original elements we check against. */ orig_mode = sbuf.st_mode; + orig_uid = sbuf.st_uid; + orig_gid = sbuf.st_gid; /* * Unpack the user/group/world id's. @@ -3449,7 +3454,11 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) * Do we need to chown ? */ - if (((user != (uid_t)-1) && (sbuf.st_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_gid != grp))) { + 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 )); @@ -3487,6 +3496,11 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) /* Save the original elements we check against. */ 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); @@ -3630,6 +3644,21 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) 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; } -- cgit From 70e1ce640370eddb3c3e4f16cb6ae86c9d8e3a5e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jan 2008 12:59:08 -0800 Subject: First part of fix for bug #4929 - worked out by jmcd. Cope with protected ACL set correctly. Jeremy. (This used to be commit f5e50f42e7c79b4f8857602457db5b97886bd19e) --- source3/smbd/posix_acls.c | 109 ++++++++++++---------------------------------- 1 file changed, 29 insertions(+), 80 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 6cec39f9c0..323d6cadb2 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3202,57 +3202,8 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) return ret; } -static NTSTATUS append_ugw_ace(files_struct *fsp, - SMB_STRUCT_STAT *psbuf, - mode_t unx_mode, - int ugw, - SEC_ACE *se) -{ - mode_t perms; - SEC_ACCESS acc; - enum security_ace_type nt_acl_type; - DOM_SID trustee; - - switch (ugw) { - case S_IRUSR: - perms = unix_perms_to_acl_perms(unx_mode, - S_IRUSR, - S_IWUSR, - S_IXUSR); - uid_to_sid(&trustee, psbuf->st_uid ); - break; - case S_IRGRP: - perms = unix_perms_to_acl_perms(unx_mode, - S_IRGRP, - S_IWGRP, - S_IXGRP); - gid_to_sid(&trustee, psbuf->st_gid ); - break; - case S_IROTH: - perms = unix_perms_to_acl_perms(unx_mode, - S_IROTH, - S_IWOTH, - S_IXOTH); - sid_copy(&trustee, &global_sid_World); - break; - default: - return NT_STATUS_INVALID_PARAMETER; - } - acc = map_canon_ace_perms(SNUM(fsp->conn), - &nt_acl_type, - perms, - fsp->is_directory); - - init_sec_ace(se, - &trustee, - nt_acl_type, - acc, - 0); - return NT_STATUS_OK; -} - /**************************************************************************** - If this is an + Take care of parent ACL inheritance. ****************************************************************************/ static NTSTATUS append_parent_acl(files_struct *fsp, @@ -3270,7 +3221,7 @@ static NTSTATUS append_parent_acl(files_struct *fsp, NTSTATUS status; int info; unsigned int i, j; - mode_t unx_mode; + bool is_dacl_protected = (psd->type & SE_DESC_DACL_PROTECTED); ZERO_STRUCT(sbuf); @@ -3285,12 +3236,6 @@ static NTSTATUS append_parent_acl(files_struct *fsp, return NT_STATUS_NO_MEMORY; } - /* Create a default mode for u/g/w. */ - unx_mode = unix_mode(fsp->conn, - aARCH | (fsp->is_directory ? aDIR : 0), - fsp->fsp_name, - parent_name); - status = open_directory(fsp->conn, NULL, parent_name, @@ -3318,20 +3263,23 @@ static NTSTATUS append_parent_acl(files_struct *fsp, /* * Make room for potentially all the ACLs from - * the parent, plus the user/group/other triple. + * the parent. We used to add the ugw triple here, + * as we knew we were dealing with POSIX ACLs. + * We no longer need to do so as we can guarentee + * that a default ACL from the parent directory will + * be well formed for POSIX ACLs if it came from a + * POSIX ACL source, and if we're not writing to a + * POSIX ACL sink then we don't care if it's not well + * formed. JRA. */ - num_aces += parent_sd->dacl->num_aces + 3; + num_aces += parent_sd->dacl->num_aces; if((new_ace = TALLOC_ZERO_ARRAY(mem_ctx, SEC_ACE, num_aces)) == NULL) { return NT_STATUS_NO_MEMORY; } - DEBUG(10,("append_parent_acl: parent ACL has %u entries. New " - "ACL has %u entries\n", - parent_sd->dacl->num_aces, num_aces )); - /* Start by copying in all the given ACE entries. */ for (i = 0; i < psd->dacl->num_aces; i++) { sec_ace_copy(&new_ace[i], &psd->dacl->aces[i]); @@ -3342,23 +3290,6 @@ static NTSTATUS append_parent_acl(files_struct *fsp, * as that really only applies to newly created files. JRA. */ - /* - * Append u/g/w. - */ - - status = append_ugw_ace(fsp, psbuf, unx_mode, S_IRUSR, &new_ace[i++]); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = append_ugw_ace(fsp, psbuf, unx_mode, S_IRGRP, &new_ace[i++]); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = append_ugw_ace(fsp, psbuf, unx_mode, S_IROTH, &new_ace[i++]); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - /* Finally append any inherited ACEs. */ for (j = 0; j < parent_sd->dacl->num_aces; j++) { SEC_ACE *se = &parent_sd->dacl->aces[j]; @@ -3379,6 +3310,24 @@ static NTSTATUS append_parent_acl(files_struct *fsp, continue; } } + + if (is_dacl_protected) { + /* If the DACL is protected it means we must + * not overwrite an existing ACE entry with the + * same SID. This is order N^2. Ouch :-(. JRA. */ + unsigned int k; + for (k = 0; k < psd->dacl->num_aces; k++) { + if (sid_equal(&psd->dacl->aces[k].trustee, + &se->trustee)) { + break; + } + } + if (k < psd->dacl->num_aces) { + /* SID matched. Ignore. */ + continue; + } + } + sec_ace_copy(&new_ace[i], se); if (se->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) { new_ace[i].flags &= ~(SEC_ACE_FLAG_VALID_INHERIT); -- cgit From 47a8e77513686bbc492bbfdebbbd0bfb7f786063 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jan 2008 13:06:11 -0800 Subject: The checks for OI and CI were just wrong.... Fix them. Thanks to Jim for testing this. Jeremy. (This used to be commit e898789e0d819df05b14bcedfa1d230c7a983440) --- source3/smbd/posix_acls.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 323d6cadb2..40979cd6a2 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3293,20 +3293,15 @@ static NTSTATUS append_parent_acl(files_struct *fsp, /* Finally append any inherited ACEs. */ for (j = 0; j < parent_sd->dacl->num_aces; j++) { SEC_ACE *se = &parent_sd->dacl->aces[j]; - uint32 i_flags = se->flags & (SEC_ACE_FLAG_OBJECT_INHERIT| - SEC_ACE_FLAG_CONTAINER_INHERIT| - SEC_ACE_FLAG_INHERIT_ONLY); if (fsp->is_directory) { - if (i_flags == SEC_ACE_FLAG_OBJECT_INHERIT) { - /* Should only apply to a file - ignore. */ + if (!(se->flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) { + /* Doesn't apply to a directory - ignore. */ continue; } } else { - if ((i_flags & (SEC_ACE_FLAG_OBJECT_INHERIT| - SEC_ACE_FLAG_INHERIT_ONLY)) != - SEC_ACE_FLAG_OBJECT_INHERIT) { - /* Should not apply to a file - ignore. */ + if (!(se->flags & SEC_ACE_FLAG_OBJECT_INHERIT)) { + /* Doesn't apply to a file - ignore. */ continue; } } -- cgit From 85a44396a794ae456d4998a9d9dd5ceb37312999 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jan 2008 13:27:00 -0800 Subject: Add debug messages to trace this if needed. Jeremy. (This used to be commit b628269b3260661cb4eeeab8c533b3129827ba62) --- source3/smbd/posix_acls.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 40979cd6a2..dee5d8e7c9 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3297,11 +3297,21 @@ static NTSTATUS append_parent_acl(files_struct *fsp, if (fsp->is_directory) { if (!(se->flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) { /* Doesn't apply to a directory - ignore. */ + DEBUG(10,("append_parent_acl: directory %s " + "ignoring non container " + "inherit flags %u\n", + fsp->fsp_name, + (unsigned int)se->flags )); continue; } } else { if (!(se->flags & SEC_ACE_FLAG_OBJECT_INHERIT)) { /* Doesn't apply to a file - ignore. */ + DEBUG(10,("append_parent_acl: file %s " + "ignoring non object " + "inherit flags %u\n", + fsp->fsp_name, + (unsigned int)se->flags )); continue; } } @@ -3319,6 +3329,10 @@ static NTSTATUS append_parent_acl(files_struct *fsp, } if (k < psd->dacl->num_aces) { /* SID matched. Ignore. */ + DEBUG(10,("append_parent_acl: path %s " + "ignoring protected sid %s\n", + fsp->fsp_name, + sid_string_dbg(&se->trustee))); continue; } } -- cgit From 50c7e98a46a1c97011f37c78db8caddc634d6994 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jan 2008 16:13:53 -0800 Subject: Make explicit in debug we're ignoring flags from the parent SD. Jeremy (This used to be commit 58cfa4b1bdc1ce30cc3befb342cc98ac0e283585) --- source3/smbd/posix_acls.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index dee5d8e7c9..12e611f9cb 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3299,9 +3299,10 @@ static NTSTATUS append_parent_acl(files_struct *fsp, /* Doesn't apply to a directory - ignore. */ DEBUG(10,("append_parent_acl: directory %s " "ignoring non container " - "inherit flags %u\n", + "inherit flags %u from parent %s\n", fsp->fsp_name, - (unsigned int)se->flags )); + (unsigned int)se->flags, + parent_name)); continue; } } else { @@ -3309,9 +3310,10 @@ static NTSTATUS append_parent_acl(files_struct *fsp, /* Doesn't apply to a file - ignore. */ DEBUG(10,("append_parent_acl: file %s " "ignoring non object " - "inherit flags %u\n", + "inherit flags %u from parent %s\n", fsp->fsp_name, - (unsigned int)se->flags )); + (unsigned int)se->flags, + parent_name)); continue; } } @@ -3330,9 +3332,11 @@ static NTSTATUS append_parent_acl(files_struct *fsp, if (k < psd->dacl->num_aces) { /* SID matched. Ignore. */ DEBUG(10,("append_parent_acl: path %s " - "ignoring protected sid %s\n", + "ignoring protected sid %s " + "from parent %s\n", fsp->fsp_name, - sid_string_dbg(&se->trustee))); + sid_string_dbg(&se->trustee), + parent_name)); continue; } } -- cgit From dd67913a999323188f4d8c877ab761ce9d53883d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jan 2008 17:50:07 -0800 Subject: Correctly set flags in ACE's inherited from parent. Still one bug left to find then I'll back-port to 3.0.28. Jeremy. (This used to be commit 3df2f7ca782e418703d82f7a1f3c035a365f9589) --- source3/smbd/posix_acls.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 12e611f9cb..347064362d 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3299,9 +3299,11 @@ static NTSTATUS append_parent_acl(files_struct *fsp, /* Doesn't apply to a directory - ignore. */ DEBUG(10,("append_parent_acl: directory %s " "ignoring non container " - "inherit flags %u from parent %s\n", + "inherit flags %u on ACE with sid %s " + "from parent %s\n", fsp->fsp_name, (unsigned int)se->flags, + sid_string_dbg(&se->trustee), parent_name)); continue; } @@ -3310,9 +3312,11 @@ static NTSTATUS append_parent_acl(files_struct *fsp, /* Doesn't apply to a file - ignore. */ DEBUG(10,("append_parent_acl: file %s " "ignoring non object " - "inherit flags %u from parent %s\n", + "inherit flags %u on ACE with sid %s " + "from parent %s\n", fsp->fsp_name, (unsigned int)se->flags, + sid_string_dbg(&se->trustee), parent_name)); continue; } @@ -3332,7 +3336,7 @@ static NTSTATUS append_parent_acl(files_struct *fsp, if (k < psd->dacl->num_aces) { /* SID matched. Ignore. */ DEBUG(10,("append_parent_acl: path %s " - "ignoring protected sid %s " + "ignoring ACE with protected sid %s " "from parent %s\n", fsp->fsp_name, sid_string_dbg(&se->trustee), @@ -3346,7 +3350,35 @@ static NTSTATUS append_parent_acl(files_struct *fsp, new_ace[i].flags &= ~(SEC_ACE_FLAG_VALID_INHERIT); } new_ace[i].flags |= SEC_ACE_FLAG_INHERITED_ACE; + + if (fsp->is_directory) { + /* + * Strip off any inherit only. It's applied. + */ + new_ace[i].flags &= ~(SEC_ACE_FLAG_INHERIT_ONLY); + if (se->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) { + /* No further inheritance. */ + new_ace[i].flags &= + ~(SEC_ACE_FLAG_CONTAINER_INHERIT| + SEC_ACE_FLAG_OBJECT_INHERIT); + } + } else { + /* + * Strip off any container or inherit + * flags, they can't apply to objects. + */ + new_ace[i].flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT| + SEC_ACE_FLAG_INHERIT_ONLY| + SEC_ACE_FLAG_NO_PROPAGATE_INHERIT); + } i++; + + DEBUG(10,("append_parent_acl: path %s " + "inheriting ACE with sid %s " + "from parent %s\n", + fsp->fsp_name, + sid_string_dbg(&se->trustee), + parent_name)); } parent_sd->dacl->aces = new_ace; -- cgit From fccae57310dcd9b625c4f41be9548d2ed6d81427 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jan 2008 18:13:22 -0800 Subject: Fix a really subtle old, old bug :-). When canonicalizing the NT ACL into a POSIX one, if the group being set is the primary group of the file, map it into a SMB_ACL_GROUP_OBJ, not a SMB_ACL_GROUP. Otherwise we get an extra bogus group entry in the POSIX ACL. Jeremy. (This used to be commit 4d302254fdfce2c267cf6b21f662d5aa2dc9c72c) --- source3/smbd/posix_acls.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 347064362d..9c015261b5 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -1408,12 +1408,12 @@ static bool create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst, psa1->flags |= (psa2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)); psa2->flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT); - + } else if (psa2->flags & SEC_ACE_FLAG_INHERIT_ONLY) { psa2->flags |= (psa1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)); psa1->flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT); - + } } } @@ -1477,7 +1477,13 @@ static bool create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst, current_ace->type = SMB_ACL_USER; } else if (sid_to_gid( ¤t_ace->trustee, ¤t_ace->unix_ug.gid)) { current_ace->owner_type = GID_ACE; - current_ace->type = SMB_ACL_GROUP; + /* If it's the primary group, this is a group_obj, not + * a group. */ + if (current_ace->unix_ug.gid == pst->st_gid) { + current_ace->type = SMB_ACL_GROUP_OBJ; + } else { + current_ace->type = SMB_ACL_GROUP; + } } else { /* * Silently ignore map failures in non-mappable SIDs (NT Authority, BUILTIN etc). -- cgit From 51f62beabd91c94374bcadf70ee1bcad20fd60ad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jan 2008 18:22:43 -0800 Subject: Fix the same bug with user -> user_obj. Jeremy. (This used to be commit c5edf7456955471b8590c2cfa67c7f47a387cdf0) --- source3/smbd/posix_acls.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/smbd/posix_acls.c') diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 9c015261b5..f60329a039 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -1474,7 +1474,13 @@ static bool create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst, } else if (sid_to_uid( ¤t_ace->trustee, ¤t_ace->unix_ug.uid)) { current_ace->owner_type = UID_ACE; - current_ace->type = SMB_ACL_USER; + /* If it's the owning user, this is a user_obj, not + * a user. */ + if (current_ace->unix_ug.uid == pst->st_uid) { + current_ace->type = SMB_ACL_USER_OBJ; + } else { + current_ace->type = SMB_ACL_USER; + } } else if (sid_to_gid( ¤t_ace->trustee, ¤t_ace->unix_ug.gid)) { current_ace->owner_type = GID_ACE; /* If it's the primary group, this is a group_obj, not -- cgit