summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2003-06-20 01:12:20 +0000
committerJeremy Allison <jra@samba.org>2003-06-20 01:12:20 +0000
commit9251afe35bc402bbab816d7c33673d4ef3fb0351 (patch)
treecca0bf840cbeac0d8295fa44ed18c9f553968628 /source3
parentc7e45a8586d58eb8b0f38ce44707de5313ec9cba (diff)
downloadsamba-9251afe35bc402bbab816d7c33673d4ef3fb0351.tar.gz
samba-9251afe35bc402bbab816d7c33673d4ef3fb0351.tar.bz2
samba-9251afe35bc402bbab816d7c33673d4ef3fb0351.zip
Mapping of Windows ACL inheritance and protected bits onto extended attributes
if available. Adds new parameter "map acl inheritance" (docs coming soon) off by default. Allows W2K acl inheritance dialogs to work correctly on POSIX acls. Jeremy. (This used to be commit a83595e80ae539135fa1a65d6066b10ac94fbad1)
Diffstat (limited to 'source3')
-rw-r--r--source3/param/loadparm.c3
-rw-r--r--source3/smbd/posix_acls.c477
2 files changed, 464 insertions, 16 deletions
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 1a71b2472c..8289c45b6a 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -413,6 +413,7 @@ typedef struct
BOOL bNTAclSupport;
BOOL bUseSendfile;
BOOL bProfileAcls;
+ BOOL bMap_acl_inherit;
param_opt_struct *param_opt;
char dummy[3]; /* for alignment */
@@ -956,6 +957,7 @@ static struct parm_struct parm_table[] = {
{"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
{"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
{"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
+ {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
@@ -1831,6 +1833,7 @@ FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
FN_LOCAL_BOOL(lp_use_sendfile, bUseSendfile)
FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
+FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 12eef46595..9f15bf1560 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -42,10 +42,446 @@ typedef struct canon_ace {
enum ace_owner owner_type;
enum ace_attribute attr;
posix_id unix_ug;
+ BOOL inherited;
} canon_ace;
#define ALL_ACE_PERMS (S_IRUSR|S_IWUSR|S_IXUSR)
+/*
+ * EA format of user.SAMBA_PAI (Samba_Posix_Acl_Interitance)
+ * attribute on disk.
+ *
+ * | 1 | 1 | 2 | 2 | ....
+ * +------+------+-------------+---------------------+-------------+--------------------+
+ * | vers | flag | num_entries | num_default_entries | ..entries.. | default_entries... |
+ * +------+------+-------------+---------------------+-------------+--------------------+
+ */
+
+#define SAMBA_POSIX_INHERITANCE_EA_NAME "user.SAMBA_PAI"
+
+#define PAI_VERSION_OFFSET 0
+#define PAI_FLAG_OFFSET 1
+#define PAI_NUM_ENTRIES_OFFSET 2
+#define PAI_NUM_DEFAULT_ENTRIES_OFFSET 4
+#define PAI_ENTRIES_BASE 6
+
+#define PAI_VERSION 1
+#define PAI_ACL_FLAG_PROTECTED 0x1
+#define PAI_ENTRY_LENGTH 5
+
+/*
+ * In memory format of user.SAMBA_PAI attribute.
+ */
+
+struct pai_entry {
+ struct pai_entry *next, *prev;
+ enum ace_owner owner_type;
+ posix_id unix_ug;
+};
+
+struct pai_val {
+ BOOL protected;
+ unsigned int num_entries;
+ struct pai_entry *entry_list;
+ unsigned int num_def_entries;
+ struct pai_entry *def_entry_list;
+};
+
+/************************************************************************
+ Return a uint32 of the pai_entry principal.
+************************************************************************/
+
+static uint32 get_pai_entry_val(struct pai_entry *paie)
+{
+ switch (paie->owner_type) {
+ case UID_ACE:
+ DEBUG(10,("get_pai_entry_val: uid = %u\n", (unsigned int)paie->unix_ug.uid ));
+ return (uint32)paie->unix_ug.uid;
+ case GID_ACE:
+ DEBUG(10,("get_pai_entry_val: gid = %u\n", (unsigned int)paie->unix_ug.gid ));
+ return (uint32)paie->unix_ug.gid;
+ case WORLD_ACE:
+ default:
+ DEBUG(10,("get_pai_entry_val: world ace\n"));
+ return (uint32)-1;
+ }
+}
+
+/************************************************************************
+ Return a uint32 of the entry principal.
+************************************************************************/
+
+static uint32 get_entry_val(canon_ace *ace_entry)
+{
+ switch (ace_entry->owner_type) {
+ case UID_ACE:
+ DEBUG(10,("get_entry_val: uid = %u\n", (unsigned int)ace_entry->unix_ug.uid ));
+ return (uint32)ace_entry->unix_ug.uid;
+ case GID_ACE:
+ DEBUG(10,("get_entry_val: gid = %u\n", (unsigned int)ace_entry->unix_ug.gid ));
+ return (uint32)ace_entry->unix_ug.gid;
+ case WORLD_ACE:
+ default:
+ DEBUG(10,("get_entry_val: world ace\n"));
+ return (uint32)-1;
+ }
+}
+
+/************************************************************************
+ Count the inherited entries.
+************************************************************************/
+
+static unsigned int num_inherited_entries(canon_ace *ace_list)
+{
+ unsigned int num_entries = 0;
+
+ for (; ace_list; ace_list = ace_list->next)
+ if (ace_list->inherited)
+ num_entries++;
+ return num_entries;
+}
+
+/************************************************************************
+ Create the on-disk format. Caller must free.
+************************************************************************/
+
+static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, BOOL protected, size_t *store_size)
+{
+ char *pai_buf = NULL;
+ canon_ace *ace_list = NULL;
+ char *entry_offset = NULL;
+ unsigned int num_entries = 0;
+ unsigned int num_def_entries = 0;
+
+ for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next)
+ if (ace_list->inherited)
+ num_entries++;
+
+ for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next)
+ if (ace_list->inherited)
+ num_def_entries++;
+
+ *store_size = PAI_ENTRIES_BASE + ((num_entries + num_def_entries)*PAI_ENTRY_LENGTH);
+
+ pai_buf = malloc(*store_size);
+ if (!pai_buf) {
+ return NULL;
+ }
+
+ /* Set up the header. */
+ memset(pai_buf, '\0', PAI_ENTRIES_BASE);
+ SCVAL(pai_buf,PAI_VERSION_OFFSET,PAI_VERSION);
+ SCVAL(pai_buf,PAI_FLAG_OFFSET,(protected ? PAI_ACL_FLAG_PROTECTED : 0));
+ SSVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET,num_entries);
+ SSVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET,num_def_entries);
+
+ entry_offset = pai_buf + PAI_ENTRIES_BASE;
+
+ for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next) {
+ if (ace_list->inherited) {
+ uint8 type_val = (unsigned char)ace_list->owner_type;
+ uint32 entry_val = get_entry_val(ace_list);
+
+ SCVAL(entry_offset,0,type_val);
+ SIVAL(entry_offset,1,entry_val);
+ entry_offset += PAI_ENTRY_LENGTH;
+ }
+ }
+
+ for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next) {
+ if (ace_list->inherited) {
+ uint8 type_val = (unsigned char)ace_list->owner_type;
+ uint32 entry_val = get_entry_val(ace_list);
+
+ SCVAL(entry_offset,0,type_val);
+ SIVAL(entry_offset,1,entry_val);
+ entry_offset += PAI_ENTRY_LENGTH;
+ }
+ }
+
+ return pai_buf;
+}
+
+/************************************************************************
+ Store the user.SAMBA_PAI attribute on disk.
+************************************************************************/
+
+static void store_inheritance_attributes(files_struct *fsp, canon_ace *file_ace_list,
+ canon_ace *dir_ace_list, BOOL protected)
+{
+ int ret;
+ size_t store_size;
+ char *pai_buf;
+
+ if (!lp_map_acl_inherit(SNUM(fsp->conn)))
+ return;
+
+ /*
+ * Don't store if this ACL isn't protected and
+ * none of the entries in it are marked as inherited.
+ */
+
+ if (!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->fd != -1)
+ SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME);
+ else
+ SMB_VFS_REMOVEXATTR(fsp->conn, fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME);
+ return;
+ }
+
+ pai_buf = create_pai_buf(file_ace_list, dir_ace_list, protected, &store_size);
+
+ if (fsp->fd != -1)
+ ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, 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,
+ pai_buf, store_size, 0);
+
+ SAFE_FREE(pai_buf);
+
+ DEBUG(10,("store_inheritance_attribute:%s for file %s\n", protected ? " (protected)" : "", fsp->fsp_name));
+ if (ret == -1 && errno != ENOSYS)
+ DEBUG(1,("store_inheritance_attribute: Error %s\n", strerror(errno) ));
+}
+
+/************************************************************************
+ Delete the in memory inheritance info.
+************************************************************************/
+
+static void free_inherited_info(struct pai_val *pal)
+{
+ if (pal) {
+ struct pai_entry *paie, *paie_next;
+ for (paie = pal->entry_list; paie; paie = paie_next) {
+ paie_next = paie->next;
+ SAFE_FREE(paie);
+ }
+ for (paie = pal->def_entry_list; paie; paie = paie_next) {
+ paie_next = paie->next;
+ SAFE_FREE(paie);
+ }
+ SAFE_FREE(pal);
+ }
+}
+
+/************************************************************************
+ Was this ACL protected ?
+************************************************************************/
+
+static BOOL get_protected_flag(struct pai_val *pal)
+{
+ if (!pal)
+ return False;
+ return pal->protected;
+}
+
+/************************************************************************
+ Was this ACE inherited ?
+************************************************************************/
+
+static BOOL get_inherited_flag(struct pai_val *pal, canon_ace *ace_entry, BOOL default_ace)
+{
+ struct pai_entry *paie;
+
+ if (!pal)
+ return False;
+
+ /* If the entry exists it is inherited. */
+ for (paie = (default_ace ? pal->def_entry_list : pal->entry_list); paie; paie = paie->next) {
+ if (ace_entry->owner_type == paie->owner_type &&
+ get_entry_val(ace_entry) == get_pai_entry_val(paie))
+ return True;
+ }
+ return False;
+}
+
+/************************************************************************
+ Ensure an attribute just read is valid.
+************************************************************************/
+
+static BOOL check_pai_ok(char *pai_buf, size_t pai_buf_data_size)
+{
+ uint16 num_entries;
+ uint16 num_def_entries;
+
+ if (pai_buf_data_size < PAI_ENTRIES_BASE) {
+ /* Corrupted - too small. */
+ return False;
+ }
+
+ if (CVAL(pai_buf,PAI_VERSION_OFFSET) != PAI_VERSION)
+ return False;
+
+ num_entries = SVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET);
+ num_def_entries = SVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET);
+
+ /* Check the entry lists match. */
+ /* Each entry is 5 bytes (type plus 4 bytes of uid or gid). */
+
+ if (((num_entries + num_def_entries)*PAI_ENTRY_LENGTH) + PAI_ENTRIES_BASE != pai_buf_data_size)
+ return False;
+
+ return True;
+}
+
+
+/************************************************************************
+ Convert to in-memory format.
+************************************************************************/
+
+static struct pai_val *create_pai_val(char *buf, size_t size)
+{
+ char *entry_offset;
+ struct pai_val *paiv = NULL;
+ int i;
+
+ if (!check_pai_ok(buf, size))
+ return NULL;
+
+ paiv = malloc(sizeof(struct pai_val));
+ if (!paiv)
+ return NULL;
+
+ memset(paiv, '\0', sizeof(struct pai_val));
+
+ paiv->protected = (CVAL(buf,PAI_FLAG_OFFSET) == PAI_ACL_FLAG_PROTECTED);
+
+ paiv->num_entries = SVAL(buf,PAI_NUM_ENTRIES_OFFSET);
+ paiv->num_def_entries = SVAL(buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET);
+
+ entry_offset = buf + PAI_ENTRIES_BASE;
+
+ DEBUG(10,("create_pai_val:%s num_entries = %u, num_def_entries = %u\n",
+ paiv->protected ? " (protected)" : "", paiv->num_entries, paiv->num_def_entries ));
+
+ for (i = 0; i < paiv->num_entries; i++) {
+ struct pai_entry *paie;
+
+ paie = malloc(sizeof(struct pai_entry));
+ if (!paie) {
+ free_inherited_info(paiv);
+ return NULL;
+ }
+
+ paie->owner_type = (enum ace_owner)CVAL(entry_offset,0);
+ switch( paie->owner_type) {
+ case UID_ACE:
+ paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1);
+ DEBUG(10,("create_pai_val: uid = %u\n", (unsigned int)paie->unix_ug.uid ));
+ break;
+ case GID_ACE:
+ paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1);
+ DEBUG(10,("create_pai_val: gid = %u\n", (unsigned int)paie->unix_ug.gid ));
+ break;
+ case WORLD_ACE:
+ paie->unix_ug.world = -1;
+ DEBUG(10,("create_pai_val: world ace\n"));
+ break;
+ default:
+ free_inherited_info(paiv);
+ return NULL;
+ }
+ entry_offset += PAI_ENTRY_LENGTH;
+ DLIST_ADD(paiv->entry_list, paie);
+ }
+
+ for (i = 0; i < paiv->num_def_entries; i++) {
+ struct pai_entry *paie;
+
+ paie = malloc(sizeof(struct pai_entry));
+ if (!paie) {
+ free_inherited_info(paiv);
+ return NULL;
+ }
+
+ paie->owner_type = (enum ace_owner)CVAL(entry_offset,0);
+ switch( paie->owner_type) {
+ case UID_ACE:
+ paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1);
+ DEBUG(10,("create_pai_val: (def) uid = %u\n", (unsigned int)paie->unix_ug.uid ));
+ break;
+ case GID_ACE:
+ paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1);
+ DEBUG(10,("create_pai_val: (def) gid = %u\n", (unsigned int)paie->unix_ug.gid ));
+ break;
+ case WORLD_ACE:
+ paie->unix_ug.world = -1;
+ DEBUG(10,("create_pai_val: (def) world ace\n"));
+ break;
+ default:
+ free_inherited_info(paiv);
+ return NULL;
+ }
+ entry_offset += PAI_ENTRY_LENGTH;
+ DLIST_ADD(paiv->def_entry_list, paie);
+ }
+
+ return paiv;
+}
+
+/************************************************************************
+ Load the user.SAMBA_PAI attribute.
+************************************************************************/
+
+static struct pai_val *load_inherited_info(files_struct *fsp)
+{
+ char *pai_buf;
+ size_t pai_buf_size = 1024;
+ struct pai_val *paiv = NULL;
+ ssize_t ret;
+
+ if (!lp_map_acl_inherit(SNUM(fsp->conn)))
+ return NULL;
+
+ if ((pai_buf = malloc(pai_buf_size)) == NULL)
+ return NULL;
+
+ do {
+ if (fsp->fd != -1)
+ ret = SMB_VFS_FGETXATTR(fsp, fsp->fd, 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,
+ 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 = malloc(pai_buf_size)) == NULL)
+ return NULL;
+ }
+ } while (ret == -1);
+
+ DEBUG(10,("load_inherited_info: ret = %d for file %s\n", ret, fsp->fsp_name));
+
+ 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->protected)
+ DEBUG(10,("load_inherited_info: ACL is protected for file %s\n", fsp->fsp_name));
+
+ SAFE_FREE(pai_buf);
+ return paiv;
+}
+
/****************************************************************************
Functions to manipulate the internal ACE format.
****************************************************************************/
@@ -106,7 +542,7 @@ static void print_canon_ace(canon_ace *pace, int num)
dbgtext( "SID = %s ", sid_to_string( str, &pace->trustee));
if (pace->owner_type == UID_ACE) {
const char *u_name = uidtoname(pace->unix_ug.uid);
- dbgtext( "uid %u (%s) ", (unsigned int)pace->unix_ug.uid, u_name);
+ dbgtext( "uid %u (%s) %s", (unsigned int)pace->unix_ug.uid, u_name, pace->inherited ? "(inherited) " : "");
} else if (pace->owner_type == GID_ACE) {
char *g_name = gidtoname(pace->unix_ug.gid);
dbgtext( "gid %u (%s) ", (unsigned int)pace->unix_ug.gid, g_name);
@@ -949,6 +1385,7 @@ static BOOL create_canon_ace_lists(files_struct *fsp,
current_ace->perms |= map_nt_perms( psa->info, S_IRUSR);
current_ace->attr = (psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED) ? ALLOW_ACE : DENY_ACE;
+ current_ace->inherited = ((psa->flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False);
/*
* Now add the created ace to either the file list, the directory
@@ -1616,7 +2053,7 @@ static void arrange_posix_perms( char *filename, canon_ace **pp_list_head)
****************************************************************************/
static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf,
- DOM_SID *powner, DOM_SID *pgroup, SMB_ACL_TYPE_T the_acl_type)
+ DOM_SID *powner, DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type)
{
extern DOM_SID global_sid_World;
connection_struct *conn = fsp->conn;
@@ -1723,6 +2160,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
ace->trustee = sid;
ace->unix_ug = unix_ug;
ace->owner_type = owner_type;
+ ace->inherited = get_inherited_flag(pal, ace, (the_acl_type == SMB_ACL_TYPE_DEFAULT));
DLIST_ADD(list_head, ace);
}
@@ -1908,6 +2346,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
if( DEBUGLVL( 10 ))
print_canon_ace( p_ace, i);
+
}
if (needs_mask && !got_mask_entry) {
@@ -2186,6 +2625,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
canon_ace *file_ace = NULL;
canon_ace *dir_ace = NULL;
size_t num_profile_acls = 0;
+ struct pai_val *pal = NULL;
*ppdesc = NULL;
@@ -2228,6 +2668,8 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
posix_acl ? "present" : "absent",
dir_acl ? "present" : "absent" ));
+ pal = load_inherited_info(fsp);
+
/*
* Get the owner, group and world SIDs.
*/
@@ -2241,7 +2683,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
create_file_sids(&sbuf, &owner_sid, &group_sid);
}
- if (security_info & DACL_SECURITY_INFORMATION) {
+ if ((security_info & DACL_SECURITY_INFORMATION) && !(security_info & PROTECTED_DACL_SECURITY_INFORMATION)) {
/*
* In the optimum case Creator Owner and Creator Group would be used for
@@ -2253,7 +2695,7 @@ size_t 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, SMB_ACL_TYPE_ACCESS );
+ file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, pal, SMB_ACL_TYPE_ACCESS );
/* We must have *some* ACLS. */
@@ -2265,7 +2707,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
if (fsp->is_directory && dir_acl) {
dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf,
&global_sid_Creator_Owner,
- &global_sid_Creator_Group, SMB_ACL_TYPE_DEFAULT );
+ &global_sid_Creator_Group, pal, SMB_ACL_TYPE_DEFAULT );
}
/*
@@ -2347,7 +2789,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
SEC_ACCESS acc;
acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
- init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0);
+ init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, ace->inherited ? SEC_ACE_FLAG_INHERITED_ACE : 0);
}
/* The User must have access to a profile share - even if we can't map the SID. */
@@ -2355,7 +2797,8 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
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);
+ init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ acc, 0);
}
ace = dir_ace;
@@ -2365,7 +2808,9 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc,
- SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
+ SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
+ SEC_ACE_FLAG_INHERIT_ONLY|
+ (ace->inherited ? SEC_ACE_FLAG_INHERITED_ACE : 0));
}
/* The User must have access to a profile share - even if we can't map the SID. */
@@ -2375,7 +2820,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
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,
SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
- SEC_ACE_FLAG_INHERIT_ONLY);
+ SEC_ACE_FLAG_INHERIT_ONLY|0);
}
/*
@@ -2412,11 +2857,6 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n"));
sd_size = 0;
} else {
-#if 1
- /*
- * JRA. Setting this flag causes W2K clients not to
- * propagate ACL sets down a directory tree correctly.
- */
/*
* Windows 2000: The DACL_PROTECTED flag in the security
* descriptor marks the ACL as non-inheriting, i.e., no
@@ -2426,8 +2866,8 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
* any ACEs that are inherited dynamically. The DACL_PROTECTED
* flag doesn't seem to bother Windows NT.
*/
- (*ppdesc)->type |= SE_DESC_DACL_PROTECTED;
-#endif
+ if (get_protected_flag(pal))
+ (*ppdesc)->type |= SE_DESC_DACL_PROTECTED;
}
done:
@@ -2438,6 +2878,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
+ free_inherited_info(pal);
SAFE_FREE(nt_ace_list);
return sd_size;
@@ -2660,6 +3101,10 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
}
}
+ if (acl_set_support)
+ store_inheritance_attributes(fsp, file_ace_list, dir_ace_list,
+ (psd->type & SE_DESC_DACL_PROTECTED) ? True : False);
+
/*
* If we cannot set using POSIX ACLs we fall back to checking if we need to chmod.
*/