From ff3a020a5fab1aaabe0d19c4b12978860a2ac3ba Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 22 Apr 2009 06:15:21 -0400 Subject: [PATCH 1/1] 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. --- source3/smbd/posix_acls.c | 55 ++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 2f84a831c6c..39fb32f654c 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 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); } /* -- 2.34.1