diff options
author | Simo Sorce <ssorce@redhat.com> | 2009-04-22 06:15:21 -0400 |
---|---|---|
committer | Simo Sorce <ssorce@redhat.com> | 2009-04-22 09:58:51 -0400 |
commit | ff3a020a5fab1aaabe0d19c4b12978860a2ac3ba (patch) | |
tree | f3607d2b80e3de2913348b313b975240b3067b86 /source3 | |
parent | b029e0edcf356772c66190af843087f14c88b3f2 (diff) | |
download | samba-ff3a020a5fab1aaabe0d19c4b12978860a2ac3ba.tar.gz samba-ff3a020a5fab1aaabe0d19c4b12978860a2ac3ba.tar.bz2 samba-ff3a020a5fab1aaabe0d19c4b12978860a2ac3ba.zip |
Avoid duplicate aces
When adding arbitrary aces to an nt_ace_list we need to make sure we
are not actually adding a duplicate.
add_or_replace_ace() takes care of doing the right thing.
Diffstat (limited to 'source3')
-rw-r--r-- | source3/smbd/posix_acls.c | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 2f84a831c6..39fb32f654 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3,6 +3,7 @@ SMB NT Security Descriptor / Unix permission conversion. Copyright (C) Jeremy Allison 1994-2009. Copyright (C) Andreas Gruenbacher 2002. + Copyright (C) Simo Sorce <idra@samba.org> 2009. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2972,6 +2973,42 @@ static size_t merge_default_aces( SEC_ACE *nt_ace_list, size_t num_aces) return num_aces; } +/* + * Add or Replace ACE entry. + * In some cases we need to add a specific ACE for compatibility reasons. + * When doing that we must make sure we are not actually creating a duplicate + * entry. So we need to search whether an ACE entry already exist and eventually + * replacce the access mask, or add a completely new entry if none was found. + * + * This function assumes the array has enough space to add a new entry without + * any reallocation of memory. + */ + +static void add_or_replace_ace(SEC_ACE *nt_ace_list, size_t *num_aces, + const DOM_SID *sid, enum security_ace_type type, + uint32_t mask, uint8_t flags) +{ + int i; + + /* first search for a duplicate */ + for (i = 0; i < *num_aces; i++) { + if (sid_equal(&nt_ace_list[i].trustee, sid) && + (nt_ace_list[i].flags == flags)) break; + } + + if (i < *num_aces) { /* found */ + nt_ace_list[i].type = type; + nt_ace_list[i].access_mask = mask; + DEBUG(10, ("Replacing ACE %d with SID %s and flags %02x\n", + i, sid_string_dbg(sid), flags)); + return; + } + + /* not found, append it */ + init_sec_ace(&nt_ace_list[(*num_aces)++], sid, type, mask, flags); +} + + /**************************************************************************** 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 @@ -3132,10 +3169,10 @@ 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))) { - init_sec_ace(&nt_ace_list[num_aces++], - &global_sid_Builtin_Users, - SEC_ACE_TYPE_ACCESS_ALLOWED, - FILE_GENERIC_ALL, 0); + add_or_replace_ace(nt_ace_list, &num_aces, + &global_sid_Builtin_Users, + SEC_ACE_TYPE_ACCESS_ALLOWED, + FILE_GENERIC_ALL, 0); } for (ace = dir_ace; ace != NULL; ace = ace->next) { @@ -3156,9 +3193,13 @@ 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))) { - 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); + add_or_replace_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); } /* |