LCOV - code coverage report
Current view: top level - libcli/security - secdesc.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 165 231 71.4 %
Date: 2021-09-23 10:06:22 Functions: 10 13 76.9 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/Netbios implementation.
       3             :  *  SEC_DESC handling functions
       4             :  *  Copyright (C) Andrew Tridgell              1992-1998,
       5             :  *  Copyright (C) Jeremy R. Allison            1995-2003.
       6             :  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
       7             :  *  Copyright (C) Paul Ashton                  1997-1998.
       8             :  *
       9             :  *  This program is free software; you can redistribute it and/or modify
      10             :  *  it under the terms of the GNU General Public License as published by
      11             :  *  the Free Software Foundation; either version 3 of the License, or
      12             :  *  (at your option) any later version.
      13             :  *
      14             :  *  This program is distributed in the hope that it will be useful,
      15             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :  *  GNU General Public License for more details.
      18             :  *
      19             :  *  You should have received a copy of the GNU General Public License
      20             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      21             :  */
      22             : 
      23             : #include "includes.h"
      24             : #include "librpc/gen_ndr/ndr_security.h"
      25             : #include "libcli/security/security.h"
      26             : 
      27             : /* Map generic permissions to file object specific permissions */
      28             : 
      29             : const struct generic_mapping file_generic_mapping = {
      30             :         FILE_GENERIC_READ,
      31             :         FILE_GENERIC_WRITE,
      32             :         FILE_GENERIC_EXECUTE,
      33             :         FILE_GENERIC_ALL
      34             : };
      35             : 
      36             : /*******************************************************************
      37             :  Given a security_descriptor return the sec_info.
      38             : ********************************************************************/
      39             : 
      40         165 : uint32_t get_sec_info(const struct security_descriptor *sd)
      41             : {
      42         165 :         uint32_t sec_info = 0;
      43             : 
      44         165 :         SMB_ASSERT(sd);
      45             : 
      46         165 :         if (sd->owner_sid != NULL) {
      47         138 :                 sec_info |= SECINFO_OWNER;
      48             :         }
      49         165 :         if (sd->group_sid != NULL) {
      50         138 :                 sec_info |= SECINFO_GROUP;
      51             :         }
      52         165 :         if (sd->sacl != NULL) {
      53           0 :                 sec_info |= SECINFO_SACL;
      54             :         }
      55         165 :         if (sd->dacl != NULL) {
      56         142 :                 sec_info |= SECINFO_DACL;
      57             :         }
      58             : 
      59         165 :         if (sd->type & SEC_DESC_SACL_PROTECTED) {
      60           0 :                 sec_info |= SECINFO_PROTECTED_SACL;
      61         165 :         } else if (sd->type & SEC_DESC_SACL_AUTO_INHERITED) {
      62           0 :                 sec_info |= SECINFO_UNPROTECTED_SACL;
      63             :         }
      64         165 :         if (sd->type & SEC_DESC_DACL_PROTECTED) {
      65           0 :                 sec_info |= SECINFO_PROTECTED_DACL;
      66         165 :         } else if (sd->type & SEC_DESC_DACL_AUTO_INHERITED) {
      67           0 :                 sec_info |= SECINFO_UNPROTECTED_DACL;
      68             :         }
      69             : 
      70         165 :         return sec_info;
      71             : }
      72             : 
      73             : 
      74             : /*******************************************************************
      75             :  Merge part of security descriptor old_sec in to the empty sections of
      76             :  security descriptor new_sec.
      77             : ********************************************************************/
      78             : 
      79           0 : struct sec_desc_buf *sec_desc_merge_buf(TALLOC_CTX *ctx, struct sec_desc_buf *new_sdb, struct sec_desc_buf *old_sdb)
      80             : {
      81             :         struct dom_sid *owner_sid, *group_sid;
      82             :         struct sec_desc_buf *return_sdb;
      83             :         struct security_acl *dacl, *sacl;
      84           0 :         struct security_descriptor *psd = NULL;
      85             :         uint16_t secdesc_type;
      86             :         size_t secdesc_size;
      87             : 
      88             :         /* Copy over owner and group sids.  There seems to be no flag for
      89             :            this so just check the pointer values. */
      90             : 
      91           0 :         owner_sid = new_sdb->sd->owner_sid ? new_sdb->sd->owner_sid :
      92           0 :                 old_sdb->sd->owner_sid;
      93             : 
      94           0 :         group_sid = new_sdb->sd->group_sid ? new_sdb->sd->group_sid :
      95           0 :                 old_sdb->sd->group_sid;
      96             : 
      97           0 :         secdesc_type = new_sdb->sd->type;
      98             : 
      99             :         /* Ignore changes to the system ACL.  This has the effect of making
     100             :            changes through the security tab audit button not sticking.
     101             :            Perhaps in future Samba could implement these settings somehow. */
     102             : 
     103           0 :         sacl = NULL;
     104           0 :         secdesc_type &= ~SEC_DESC_SACL_PRESENT;
     105             : 
     106             :         /* Copy across discretionary ACL */
     107             : 
     108           0 :         if (secdesc_type & SEC_DESC_DACL_PRESENT) {
     109           0 :                 dacl = new_sdb->sd->dacl;
     110             :         } else {
     111           0 :                 dacl = old_sdb->sd->dacl;
     112             :         }
     113             : 
     114             :         /* Create new security descriptor from bits */
     115             : 
     116           0 :         psd = make_sec_desc(ctx, new_sdb->sd->revision, secdesc_type,
     117             :                             owner_sid, group_sid, sacl, dacl, &secdesc_size);
     118             : 
     119           0 :         return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);
     120             : 
     121           0 :         return(return_sdb);
     122             : }
     123             : 
     124         120 : struct security_descriptor *sec_desc_merge(TALLOC_CTX *ctx, struct security_descriptor *new_sdb, struct security_descriptor *old_sdb)
     125             : {
     126             :         struct dom_sid *owner_sid, *group_sid;
     127             :         struct security_acl *dacl, *sacl;
     128         120 :         struct security_descriptor *psd = NULL;
     129             :         uint16_t secdesc_type;
     130             :         size_t secdesc_size;
     131             : 
     132             :         /* Copy over owner and group sids.  There seems to be no flag for
     133             :            this so just check the pointer values. */
     134             : 
     135         120 :         owner_sid = new_sdb->owner_sid ? new_sdb->owner_sid :
     136             :                 old_sdb->owner_sid;
     137             : 
     138         120 :         group_sid = new_sdb->group_sid ? new_sdb->group_sid :
     139             :                 old_sdb->group_sid;
     140             : 
     141         120 :         secdesc_type = new_sdb->type;
     142             : 
     143             :         /* Ignore changes to the system ACL.  This has the effect of making
     144             :            changes through the security tab audit button not sticking.
     145             :            Perhaps in future Samba could implement these settings somehow. */
     146             : 
     147         120 :         sacl = NULL;
     148         120 :         secdesc_type &= ~SEC_DESC_SACL_PRESENT;
     149             : 
     150             :         /* Copy across discretionary ACL */
     151             : 
     152         120 :         if (secdesc_type & SEC_DESC_DACL_PRESENT) {
     153         120 :                 dacl = new_sdb->dacl;
     154             :         } else {
     155           0 :                 dacl = old_sdb->dacl;
     156             :         }
     157             : 
     158             :         /* Create new security descriptor from bits */
     159         120 :         psd = make_sec_desc(ctx, new_sdb->revision, secdesc_type,
     160             :                             owner_sid, group_sid, sacl, dacl, &secdesc_size);
     161             : 
     162         120 :         return psd;
     163             : }
     164             : 
     165             : /*******************************************************************
     166             :  Creates a struct security_descriptor structure
     167             : ********************************************************************/
     168     1337335 : struct security_descriptor *make_sec_desc(TALLOC_CTX *ctx,
     169             :                         enum security_descriptor_revision revision,
     170             :                         uint16_t type,
     171             :                         const struct dom_sid *owner_sid, const struct dom_sid *grp_sid,
     172             :                         struct security_acl *sacl, struct security_acl *dacl, size_t *sd_size)
     173             : {
     174             :         struct security_descriptor *dst;
     175             : 
     176     1337335 :         if (sd_size != NULL) {
     177     1337335 :                 *sd_size = 0;
     178             :         }
     179             : 
     180     1337335 :         dst = security_descriptor_initialise(ctx);
     181     1337335 :         if (dst == NULL) {
     182           0 :                 return NULL;
     183             :         }
     184             : 
     185     1337335 :         dst->revision = revision;
     186     1337335 :         dst->type = type;
     187             : 
     188     1337335 :         if (sacl != NULL) {
     189          34 :                 dst->sacl = security_acl_dup(dst, sacl);
     190          34 :                 if (dst->sacl == NULL) {
     191           0 :                         goto err_sd_free;
     192             :                 }
     193          34 :                 dst->type |= SEC_DESC_SACL_PRESENT;
     194             :         }
     195             : 
     196     1337335 :         if (dacl != NULL) {
     197     1337198 :                 dst->dacl = security_acl_dup(dst, dacl);
     198     1337198 :                 if (dst->dacl == NULL) {
     199           0 :                         goto err_sd_free;
     200             :                 }
     201     1337198 :                 dst->type |= SEC_DESC_DACL_PRESENT;
     202             :         }
     203             : 
     204     1337335 :         if (owner_sid != NULL) {
     205     1178861 :                 dst->owner_sid = dom_sid_dup(dst, owner_sid);
     206     1178861 :                 if (dst->owner_sid == NULL) {
     207           0 :                         goto err_sd_free;
     208             :                 }
     209             :         }
     210             : 
     211     1337335 :         if (grp_sid != NULL) {
     212     1166398 :                 dst->group_sid = dom_sid_dup(dst, grp_sid);
     213     1166398 :                 if (dst->group_sid == NULL) {
     214           0 :                         goto err_sd_free;
     215             :                 }
     216             :         }
     217             : 
     218     1337335 :         if (sd_size != NULL) {
     219     1337335 :                 *sd_size = ndr_size_security_descriptor(dst, 0);
     220             :         }
     221             : 
     222     1333991 :         return dst;
     223             : 
     224           0 : err_sd_free:
     225           0 :         talloc_free(dst);
     226           0 :         return NULL;
     227             : }
     228             : 
     229             : /*******************************************************************
     230             :  Convert a secdesc into a byte stream
     231             : ********************************************************************/
     232       16559 : NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx,
     233             :                            const struct security_descriptor *secdesc,
     234             :                            uint8_t **data, size_t *len)
     235             : {
     236             :         DATA_BLOB blob;
     237             :         enum ndr_err_code ndr_err;
     238             : 
     239       16559 :         ndr_err = ndr_push_struct_blob(
     240             :                 &blob, mem_ctx, secdesc,
     241             :                 (ndr_push_flags_fn_t)ndr_push_security_descriptor);
     242             : 
     243       16559 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     244           0 :                 DEBUG(0, ("ndr_push_security_descriptor failed: %s\n",
     245             :                           ndr_errstr(ndr_err)));
     246           0 :                 return ndr_map_error2ntstatus(ndr_err);
     247             :         }
     248             : 
     249       16559 :         *data = blob.data;
     250       16559 :         *len = blob.length;
     251       16559 :         return NT_STATUS_OK;
     252             : }
     253             : 
     254             : /*******************************************************************
     255             :  Convert a secdesc_buf into a byte stream
     256             : ********************************************************************/
     257             : 
     258           0 : NTSTATUS marshall_sec_desc_buf(TALLOC_CTX *mem_ctx,
     259             :                                const struct sec_desc_buf *secdesc_buf,
     260             :                                uint8_t **data, size_t *len)
     261             : {
     262             :         DATA_BLOB blob;
     263             :         enum ndr_err_code ndr_err;
     264             : 
     265           0 :         ndr_err = ndr_push_struct_blob(
     266             :                 &blob, mem_ctx, secdesc_buf,
     267             :                 (ndr_push_flags_fn_t)ndr_push_sec_desc_buf);
     268             : 
     269           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     270           0 :                 DEBUG(0, ("ndr_push_sec_desc_buf failed: %s\n",
     271             :                           ndr_errstr(ndr_err)));
     272           0 :                 return ndr_map_error2ntstatus(ndr_err);
     273             :         }
     274             : 
     275           0 :         *data = blob.data;
     276           0 :         *len = blob.length;
     277           0 :         return NT_STATUS_OK;
     278             : }
     279             : 
     280             : /*******************************************************************
     281             :  Parse a byte stream into a secdesc
     282             : ********************************************************************/
     283       17171 : NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len,
     284             :                              struct security_descriptor **psecdesc)
     285             : {
     286             :         DATA_BLOB blob;
     287             :         enum ndr_err_code ndr_err;
     288             :         struct security_descriptor *result;
     289             : 
     290       17171 :         if ((data == NULL) || (len == 0)) {
     291           0 :                 return NT_STATUS_INVALID_PARAMETER;
     292             :         }
     293             : 
     294       17171 :         result = talloc_zero(mem_ctx, struct security_descriptor);
     295       17171 :         if (result == NULL) {
     296           0 :                 return NT_STATUS_NO_MEMORY;
     297             :         }
     298             : 
     299       17171 :         blob = data_blob_const(data, len);
     300             : 
     301       17171 :         ndr_err = ndr_pull_struct_blob(&blob, result, result,
     302             :                 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     303             : 
     304       17171 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     305           0 :                 DEBUG(0, ("ndr_pull_security_descriptor failed: %s\n",
     306             :                           ndr_errstr(ndr_err)));
     307           0 :                 TALLOC_FREE(result);
     308           0 :                 return ndr_map_error2ntstatus(ndr_err);
     309             :         }
     310             : 
     311       17171 :         *psecdesc = result;
     312       17171 :         return NT_STATUS_OK;
     313             : }
     314             : 
     315             : /*******************************************************************
     316             :  Parse a byte stream into a sec_desc_buf
     317             : ********************************************************************/
     318             : 
     319           0 : NTSTATUS unmarshall_sec_desc_buf(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len,
     320             :                                  struct sec_desc_buf **psecdesc_buf)
     321             : {
     322             :         DATA_BLOB blob;
     323             :         enum ndr_err_code ndr_err;
     324             :         struct sec_desc_buf *result;
     325             : 
     326           0 :         if ((data == NULL) || (len == 0)) {
     327           0 :                 return NT_STATUS_INVALID_PARAMETER;
     328             :         }
     329             : 
     330           0 :         result = talloc_zero(mem_ctx, struct sec_desc_buf);
     331           0 :         if (result == NULL) {
     332           0 :                 return NT_STATUS_NO_MEMORY;
     333             :         }
     334             : 
     335           0 :         blob = data_blob_const(data, len);
     336             : 
     337           0 :         ndr_err = ndr_pull_struct_blob(&blob, result, result,
     338             :                 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
     339             : 
     340           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     341           0 :                 DEBUG(0, ("ndr_pull_sec_desc_buf failed: %s\n",
     342             :                           ndr_errstr(ndr_err)));
     343           0 :                 TALLOC_FREE(result);
     344           0 :                 return ndr_map_error2ntstatus(ndr_err);
     345             :         }
     346             : 
     347           0 :         *psecdesc_buf = result;
     348           0 :         return NT_STATUS_OK;
     349             : }
     350             : 
     351             : /*******************************************************************
     352             :  Creates a struct security_descriptor structure with typical defaults.
     353             : ********************************************************************/
     354             : 
     355      431555 : struct security_descriptor *make_standard_sec_desc(TALLOC_CTX *ctx, const struct dom_sid *owner_sid, const struct dom_sid *grp_sid,
     356             :                                  struct security_acl *dacl, size_t *sd_size)
     357             : {
     358      431555 :         return make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
     359             :                              SEC_DESC_SELF_RELATIVE, owner_sid, grp_sid, NULL,
     360             :                              dacl, sd_size);
     361             : }
     362             : 
     363             : /*******************************************************************
     364             :  Creates a struct sec_desc_buf structure.
     365             : ********************************************************************/
     366             : 
     367        1606 : struct sec_desc_buf *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, struct security_descriptor *sec_desc)
     368             : {
     369             :         struct sec_desc_buf *dst;
     370             : 
     371        1606 :         if((dst = talloc_zero(ctx, struct sec_desc_buf)) == NULL)
     372           0 :                 return NULL;
     373             : 
     374             :         /* max buffer size (allocated size) */
     375        1606 :         dst->sd_size = (uint32_t)len;
     376             : 
     377        1606 :         if (sec_desc != NULL) {
     378        1606 :                 dst->sd = security_descriptor_copy(ctx, sec_desc);
     379        1606 :                 if (dst->sd == NULL) {
     380           0 :                         return NULL;
     381             :                 }
     382             :         }
     383             : 
     384        1606 :         return dst;
     385             : }
     386             : 
     387             : /*
     388             :  * Determine if an struct security_ace is inheritable
     389             :  */
     390             : 
     391     1156031 : static bool is_inheritable_ace(const struct security_ace *ace,
     392             :                                 bool container)
     393             : {
     394     1159440 :         if (!container) {
     395      939581 :                 return ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0);
     396             :         }
     397             : 
     398      219859 :         if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
     399       40663 :                 return true;
     400             :         }
     401             : 
     402      179056 :         if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
     403         132 :                         !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
     404          88 :                 return true;
     405             :         }
     406             : 
     407      176949 :         return false;
     408             : }
     409             : 
     410             : /*
     411             :  * Does a security descriptor have any inheritable components for
     412             :  * the newly created type ?
     413             :  */
     414             : 
     415      191117 : bool sd_has_inheritable_components(const struct security_descriptor *parent_ctr, bool container)
     416             : {
     417             :         unsigned int i;
     418      191117 :         const struct security_acl *the_acl = parent_ctr->dacl;
     419             : 
     420      191117 :         if (the_acl == NULL) {
     421           0 :                 return false;
     422             :         }
     423             : 
     424      490585 :         for (i = 0; i < the_acl->num_aces; i++) {
     425      442117 :                 const struct security_ace *ace = &the_acl->aces[i];
     426             : 
     427      442545 :                 if (is_inheritable_ace(ace, container)) {
     428      141691 :                         return true;
     429             :                 }
     430             :         }
     431       48685 :         return false;
     432             : }
     433             : 
     434             : /* Create a child security descriptor using another security descriptor as
     435             :    the parent container.  This child object can either be a container or
     436             :    non-container object. */
     437             : 
     438      141804 : NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
     439             :                                         struct security_descriptor **ppsd,
     440             :                                         size_t *psize,
     441             :                                         const struct security_descriptor *parent_ctr,
     442             :                                         const struct dom_sid *owner_sid,
     443             :                                         const struct dom_sid *group_sid,
     444             :                                         bool container)
     445             : {
     446      141804 :         struct security_acl *new_dacl = NULL, *the_acl = NULL;
     447      141804 :         struct security_ace *new_ace_list = NULL;
     448      141804 :         unsigned int new_ace_list_ndx = 0, i;
     449      141804 :         bool set_inherited_flags = (parent_ctr->type & SEC_DESC_DACL_AUTO_INHERITED);
     450             : 
     451             :         TALLOC_CTX *frame;
     452             : 
     453      141804 :         *ppsd = NULL;
     454      141804 :         *psize = 0;
     455             : 
     456             :         /* Currently we only process the dacl when creating the child.  The
     457             :            sacl should also be processed but this is left out as sacls are
     458             :            not implemented in Samba at the moment.*/
     459             : 
     460      141804 :         the_acl = parent_ctr->dacl;
     461             : 
     462      141804 :         if (the_acl->num_aces) {
     463      141804 :                 if (2*the_acl->num_aces < the_acl->num_aces) {
     464           0 :                         return NT_STATUS_NO_MEMORY;
     465             :                 }
     466             : 
     467      141804 :                 if (!(new_ace_list = talloc_array(ctx, struct security_ace,
     468             :                                                   2*the_acl->num_aces))) {
     469           0 :                         return NT_STATUS_NO_MEMORY;
     470             :                 }
     471             :         } else {
     472           0 :                 new_ace_list = NULL;
     473             :         }
     474             : 
     475      141804 :         frame = talloc_stackframe();
     476             : 
     477      859127 :         for (i = 0; i < the_acl->num_aces; i++) {
     478      717323 :                 const struct security_ace *ace = &the_acl->aces[i];
     479      717323 :                 struct security_ace *new_ace = &new_ace_list[new_ace_list_ndx];
     480      717323 :                 const struct dom_sid *ptrustee = &ace->trustee;
     481      717323 :                 const struct dom_sid *creator = NULL;
     482      717323 :                 uint8_t new_flags = ace->flags;
     483             :                 struct dom_sid_buf sidbuf1, sidbuf2;
     484             : 
     485      718145 :                 if (!is_inheritable_ace(ace, container)) {
     486      288368 :                         continue;
     487             :                 }
     488             : 
     489             :                 /* see the RAW-ACLS inheritance test for details on these rules */
     490      428955 :                 if (!container) {
     491      397131 :                         new_flags = 0;
     492             :                 } else {
     493             :                         /*
     494             :                          * We need to remove SEC_ACE_FLAG_INHERITED_ACE here
     495             :                          * if present because it should only be set if the
     496             :                          * parent has the AUTO_INHERITED bit set in the
     497             :                          * type/control field. If we don't it will slip through
     498             :                          * and create DACLs with incorrectly ordered ACEs
     499             :                          * when there are CREATOR_OWNER or CREATOR_GROUP
     500             :                          * ACEs.
     501             :                          */
     502       31368 :                         new_flags &= ~(SEC_ACE_FLAG_INHERIT_ONLY
     503             :                                         | SEC_ACE_FLAG_INHERITED_ACE);
     504             : 
     505       31368 :                         if (!(new_flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
     506          44 :                                 new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
     507             :                         }
     508       31368 :                         if (new_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
     509          88 :                                 new_flags = 0;
     510             :                         }
     511             :                 }
     512             : 
     513             :                 /* The CREATOR sids are special when inherited */
     514      428955 :                 if (dom_sid_equal(ptrustee, &global_sid_Creator_Owner)) {
     515      140841 :                         creator = &global_sid_Creator_Owner;
     516      140841 :                         ptrustee = owner_sid;
     517      287897 :                 } else if (dom_sid_equal(ptrustee, &global_sid_Creator_Group)) {
     518      139316 :                         creator = &global_sid_Creator_Group;
     519      139316 :                         ptrustee = group_sid;
     520             :                 }
     521             : 
     522      443068 :                 if (creator && container &&
     523       17462 :                                 (new_flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
     524             : 
     525             :                         /* First add the regular ACE entry. */
     526       17460 :                         init_sec_ace(new_ace, ptrustee, ace->type,
     527        3337 :                                 ace->access_mask,
     528             :                                 set_inherited_flags ? SEC_ACE_FLAG_INHERITED_ACE : 0);
     529             : 
     530       17460 :                         DEBUG(5,("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x"
     531             :                                  " inherited as %s:%d/0x%02x/0x%08x\n",
     532             :                                  dom_sid_str_buf(&ace->trustee, &sidbuf1),
     533             :                                  ace->type, ace->flags, ace->access_mask,
     534             :                                  dom_sid_str_buf(&new_ace->trustee, &sidbuf2),
     535             :                                  new_ace->type, new_ace->flags,
     536             :                                  new_ace->access_mask));
     537             : 
     538       17460 :                         new_ace_list_ndx++;
     539             : 
     540             :                         /* Now add the extra creator ACE. */
     541       17460 :                         new_ace = &new_ace_list[new_ace_list_ndx];
     542             : 
     543       17460 :                         ptrustee = creator;
     544       17460 :                         new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
     545             : 
     546      422613 :                 } else if (container &&
     547       13908 :                                 !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
     548       13820 :                         ptrustee = &ace->trustee;
     549             :                 }
     550             : 
     551      428955 :                 init_sec_ace(new_ace, ptrustee, ace->type,
     552      428955 :                              ace->access_mask, new_flags |
     553             :                                 (set_inherited_flags ? SEC_ACE_FLAG_INHERITED_ACE : 0));
     554             : 
     555      428955 :                 DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
     556             :                           " inherited as %s:%d/0x%02x/0x%08x\n",
     557             :                           dom_sid_str_buf(&ace->trustee, &sidbuf1),
     558             :                           ace->type, ace->flags, ace->access_mask,
     559             :                           dom_sid_str_buf(&new_ace->trustee, &sidbuf2),
     560             :                           new_ace->type, new_ace->flags,
     561             :                           new_ace->access_mask));
     562             : 
     563      428955 :                 new_ace_list_ndx++;
     564             :         }
     565             : 
     566      141804 :         talloc_free(frame);
     567             : 
     568             :         /*
     569             :          * remove duplicates
     570             :          */
     571      560791 :         for (i=1; i < new_ace_list_ndx;) {
     572      304611 :                 struct security_ace *ai = &new_ace_list[i];
     573             :                 unsigned int remaining, j;
     574      304611 :                 bool remove_ace = false;
     575             : 
     576     1457991 :                 for (j=0; j < i; j++) {
     577      504519 :                         struct security_ace *aj = &new_ace_list[j];
     578             : 
     579      504519 :                         if (!security_ace_equal(ai, aj)) {
     580      503690 :                                 continue;
     581             :                         }
     582             : 
     583         829 :                         remove_ace = true;
     584         829 :                         break;
     585             :                 }
     586             : 
     587      304611 :                 if (!remove_ace) {
     588      303782 :                         i++;
     589      303782 :                         continue;
     590             :                 }
     591             : 
     592         829 :                 new_ace_list_ndx--;
     593         829 :                 remaining = new_ace_list_ndx - i;
     594         829 :                 if (remaining == 0) {
     595          30 :                         ZERO_STRUCT(new_ace_list[i]);
     596          30 :                         continue;
     597             :                 }
     598         799 :                 memmove(&new_ace_list[i], &new_ace_list[i+1],
     599             :                         sizeof(new_ace_list[i]) * remaining);
     600             :         }
     601             : 
     602             :         /* Create child security descriptor to return */
     603      141804 :         if (new_ace_list_ndx) {
     604      141804 :                 new_dacl = make_sec_acl(ctx,
     605             :                                 NT4_ACL_REVISION,
     606             :                                 new_ace_list_ndx,
     607             :                                 new_ace_list);
     608             : 
     609      141804 :                 if (!new_dacl) {
     610           0 :                         return NT_STATUS_NO_MEMORY;
     611             :                 }
     612             :         }
     613             : 
     614      141804 :         *ppsd = make_sec_desc(ctx,
     615             :                         SECURITY_DESCRIPTOR_REVISION_1,
     616             :                         SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT|
     617             :                                 (set_inherited_flags ? SEC_DESC_DACL_AUTO_INHERITED : 0),
     618             :                         owner_sid,
     619             :                         group_sid,
     620             :                         NULL,
     621             :                         new_dacl,
     622             :                         psize);
     623      141804 :         if (!*ppsd) {
     624           0 :                 return NT_STATUS_NO_MEMORY;
     625             :         }
     626      141804 :         return NT_STATUS_OK;
     627             : }

Generated by: LCOV version 1.13