LCOV - code coverage report
Current view: top level - libcli/security - secdesc.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 172 253 68.0 %
Date: 2024-02-28 12: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 "replace.h"
      24             : #include "lib/util/debug.h"
      25             : #include "lib/util/fault.h"
      26             : #include "librpc/gen_ndr/ndr_security.h"
      27             : #include "libcli/security/security.h"
      28             : 
      29             : /* Map generic permissions to file object specific permissions */
      30             : 
      31             : const struct generic_mapping file_generic_mapping = {
      32             :         FILE_GENERIC_READ,
      33             :         FILE_GENERIC_WRITE,
      34             :         FILE_GENERIC_EXECUTE,
      35             :         FILE_GENERIC_ALL
      36             : };
      37             : 
      38             : /*******************************************************************
      39             :  Given a security_descriptor return the sec_info.
      40             : ********************************************************************/
      41             : 
      42         165 : uint32_t get_sec_info(const struct security_descriptor *sd)
      43             : {
      44         165 :         uint32_t sec_info = 0;
      45             : 
      46         165 :         SMB_ASSERT(sd);
      47             : 
      48         165 :         if (sd->owner_sid != NULL) {
      49         138 :                 sec_info |= SECINFO_OWNER;
      50             :         }
      51         165 :         if (sd->group_sid != NULL) {
      52         138 :                 sec_info |= SECINFO_GROUP;
      53             :         }
      54         165 :         if (sd->sacl != NULL) {
      55           0 :                 sec_info |= SECINFO_SACL;
      56             :         }
      57         165 :         if (sd->dacl != NULL) {
      58         142 :                 sec_info |= SECINFO_DACL;
      59             :         }
      60             : 
      61         165 :         if (sd->type & SEC_DESC_SACL_PROTECTED) {
      62           0 :                 sec_info |= SECINFO_PROTECTED_SACL;
      63         165 :         } else if (sd->type & SEC_DESC_SACL_AUTO_INHERITED) {
      64           0 :                 sec_info |= SECINFO_UNPROTECTED_SACL;
      65             :         }
      66         165 :         if (sd->type & SEC_DESC_DACL_PROTECTED) {
      67           0 :                 sec_info |= SECINFO_PROTECTED_DACL;
      68         165 :         } else if (sd->type & SEC_DESC_DACL_AUTO_INHERITED) {
      69           0 :                 sec_info |= SECINFO_UNPROTECTED_DACL;
      70             :         }
      71             : 
      72         165 :         return sec_info;
      73             : }
      74             : 
      75             : 
      76             : /*******************************************************************
      77             :  Merge part of security descriptor old_sec in to the empty sections of
      78             :  security descriptor new_sec.
      79             : ********************************************************************/
      80             : 
      81           0 : struct sec_desc_buf *sec_desc_merge_buf(TALLOC_CTX *ctx, struct sec_desc_buf *new_sdb, struct sec_desc_buf *old_sdb)
      82             : {
      83           0 :         struct dom_sid *owner_sid, *group_sid;
      84           0 :         struct sec_desc_buf *return_sdb;
      85           0 :         struct security_acl *dacl, *sacl;
      86           0 :         struct security_descriptor *psd = NULL;
      87           0 :         uint16_t secdesc_type;
      88           0 :         size_t secdesc_size;
      89             : 
      90             :         /* Copy over owner and group sids.  There seems to be no flag for
      91             :            this so just check the pointer values. */
      92             : 
      93           0 :         owner_sid = new_sdb->sd->owner_sid ? new_sdb->sd->owner_sid :
      94           0 :                 old_sdb->sd->owner_sid;
      95             : 
      96           0 :         group_sid = new_sdb->sd->group_sid ? new_sdb->sd->group_sid :
      97           0 :                 old_sdb->sd->group_sid;
      98             : 
      99           0 :         secdesc_type = new_sdb->sd->type;
     100             : 
     101             :         /* Ignore changes to the system ACL.  This has the effect of making
     102             :            changes through the security tab audit button not sticking.
     103             :            Perhaps in future Samba could implement these settings somehow. */
     104             : 
     105           0 :         sacl = NULL;
     106           0 :         secdesc_type &= ~SEC_DESC_SACL_PRESENT;
     107             : 
     108             :         /* Copy across discretionary ACL */
     109             : 
     110           0 :         if (secdesc_type & SEC_DESC_DACL_PRESENT) {
     111           0 :                 dacl = new_sdb->sd->dacl;
     112             :         } else {
     113           0 :                 dacl = old_sdb->sd->dacl;
     114             :         }
     115             : 
     116             :         /* Create new security descriptor from bits */
     117             : 
     118           0 :         psd = make_sec_desc(ctx, new_sdb->sd->revision, secdesc_type,
     119             :                             owner_sid, group_sid, sacl, dacl, &secdesc_size);
     120             : 
     121           0 :         return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);
     122             : 
     123           0 :         return(return_sdb);
     124             : }
     125             : 
     126         120 : struct security_descriptor *sec_desc_merge(TALLOC_CTX *ctx, struct security_descriptor *new_sdb, struct security_descriptor *old_sdb)
     127             : {
     128           0 :         struct dom_sid *owner_sid, *group_sid;
     129           0 :         struct security_acl *dacl, *sacl;
     130         120 :         struct security_descriptor *psd = NULL;
     131           0 :         uint16_t secdesc_type;
     132           0 :         size_t secdesc_size;
     133             : 
     134             :         /* Copy over owner and group sids.  There seems to be no flag for
     135             :            this so just check the pointer values. */
     136             : 
     137         120 :         owner_sid = new_sdb->owner_sid ? new_sdb->owner_sid :
     138             :                 old_sdb->owner_sid;
     139             : 
     140         120 :         group_sid = new_sdb->group_sid ? new_sdb->group_sid :
     141             :                 old_sdb->group_sid;
     142             : 
     143         120 :         secdesc_type = new_sdb->type;
     144             : 
     145             :         /* Ignore changes to the system ACL.  This has the effect of making
     146             :            changes through the security tab audit button not sticking.
     147             :            Perhaps in future Samba could implement these settings somehow. */
     148             : 
     149         120 :         sacl = NULL;
     150         120 :         secdesc_type &= ~SEC_DESC_SACL_PRESENT;
     151             : 
     152             :         /* Copy across discretionary ACL */
     153             : 
     154         120 :         if (secdesc_type & SEC_DESC_DACL_PRESENT) {
     155         120 :                 dacl = new_sdb->dacl;
     156             :         } else {
     157           0 :                 dacl = old_sdb->dacl;
     158             :         }
     159             : 
     160             :         /* Create new security descriptor from bits */
     161         120 :         psd = make_sec_desc(ctx, new_sdb->revision, secdesc_type,
     162             :                             owner_sid, group_sid, sacl, dacl, &secdesc_size);
     163             : 
     164         120 :         return psd;
     165             : }
     166             : 
     167             : /*******************************************************************
     168             :  Creates a struct security_descriptor structure
     169             : ********************************************************************/
     170     1600547 : struct security_descriptor *make_sec_desc(TALLOC_CTX *ctx,
     171             :                         enum security_descriptor_revision revision,
     172             :                         uint16_t type,
     173             :                         const struct dom_sid *owner_sid, const struct dom_sid *grp_sid,
     174             :                         struct security_acl *sacl, struct security_acl *dacl, size_t *sd_size)
     175             : {
     176        4819 :         struct security_descriptor *dst;
     177             : 
     178     1600547 :         if (sd_size != NULL) {
     179     1600547 :                 *sd_size = 0;
     180             :         }
     181             : 
     182     1600547 :         dst = security_descriptor_initialise(ctx);
     183     1600547 :         if (dst == NULL) {
     184           0 :                 return NULL;
     185             :         }
     186             : 
     187     1600547 :         dst->revision = revision;
     188     1600547 :         dst->type = type;
     189             : 
     190     1600547 :         if (sacl != NULL) {
     191         112 :                 dst->sacl = security_acl_dup(dst, sacl);
     192         112 :                 if (dst->sacl == NULL) {
     193           0 :                         goto err_sd_free;
     194             :                 }
     195         112 :                 dst->type |= SEC_DESC_SACL_PRESENT;
     196             :         }
     197             : 
     198     1600547 :         if (dacl != NULL) {
     199     1600387 :                 dst->dacl = security_acl_dup(dst, dacl);
     200     1600387 :                 if (dst->dacl == NULL) {
     201           0 :                         goto err_sd_free;
     202             :                 }
     203     1600387 :                 dst->type |= SEC_DESC_DACL_PRESENT;
     204             :         }
     205             : 
     206     1600547 :         if (owner_sid != NULL) {
     207     1419417 :                 dst->owner_sid = dom_sid_dup(dst, owner_sid);
     208     1419417 :                 if (dst->owner_sid == NULL) {
     209           0 :                         goto err_sd_free;
     210             :                 }
     211             :         }
     212             : 
     213     1600547 :         if (grp_sid != NULL) {
     214     1402987 :                 dst->group_sid = dom_sid_dup(dst, grp_sid);
     215     1402987 :                 if (dst->group_sid == NULL) {
     216           0 :                         goto err_sd_free;
     217             :                 }
     218             :         }
     219             : 
     220     1600547 :         if (sd_size != NULL) {
     221     1600547 :                 *sd_size = ndr_size_security_descriptor(dst, 0);
     222             :         }
     223             : 
     224     1595728 :         return dst;
     225             : 
     226           0 : err_sd_free:
     227           0 :         talloc_free(dst);
     228           0 :         return NULL;
     229             : }
     230             : 
     231             : /*******************************************************************
     232             :  Convert a secdesc into a byte stream
     233             : ********************************************************************/
     234       20037 : NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx,
     235             :                            const struct security_descriptor *secdesc,
     236             :                            uint8_t **data, size_t *len)
     237             : {
     238          12 :         DATA_BLOB blob;
     239          12 :         enum ndr_err_code ndr_err;
     240             : 
     241       20037 :         ndr_err = ndr_push_struct_blob(
     242             :                 &blob, mem_ctx, secdesc,
     243             :                 (ndr_push_flags_fn_t)ndr_push_security_descriptor);
     244             : 
     245       20037 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     246           0 :                 DEBUG(0, ("ndr_push_security_descriptor failed: %s\n",
     247             :                           ndr_errstr(ndr_err)));
     248           0 :                 return ndr_map_error2ntstatus(ndr_err);
     249             :         }
     250             : 
     251       20037 :         *data = blob.data;
     252       20037 :         *len = blob.length;
     253       20037 :         return NT_STATUS_OK;
     254             : }
     255             : 
     256             : /*******************************************************************
     257             :  Convert a secdesc_buf into a byte stream
     258             : ********************************************************************/
     259             : 
     260           0 : NTSTATUS marshall_sec_desc_buf(TALLOC_CTX *mem_ctx,
     261             :                                const struct sec_desc_buf *secdesc_buf,
     262             :                                uint8_t **data, size_t *len)
     263             : {
     264           0 :         DATA_BLOB blob;
     265           0 :         enum ndr_err_code ndr_err;
     266             : 
     267           0 :         ndr_err = ndr_push_struct_blob(
     268             :                 &blob, mem_ctx, secdesc_buf,
     269             :                 (ndr_push_flags_fn_t)ndr_push_sec_desc_buf);
     270             : 
     271           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     272           0 :                 DEBUG(0, ("ndr_push_sec_desc_buf failed: %s\n",
     273             :                           ndr_errstr(ndr_err)));
     274           0 :                 return ndr_map_error2ntstatus(ndr_err);
     275             :         }
     276             : 
     277           0 :         *data = blob.data;
     278           0 :         *len = blob.length;
     279           0 :         return NT_STATUS_OK;
     280             : }
     281             : 
     282             : /*******************************************************************
     283             :  Parse a byte stream into a secdesc
     284             : ********************************************************************/
     285       20478 : NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len,
     286             :                              struct security_descriptor **psecdesc)
     287             : {
     288           3 :         DATA_BLOB blob;
     289           3 :         enum ndr_err_code ndr_err;
     290           3 :         struct security_descriptor *result;
     291             : 
     292       20478 :         if ((data == NULL) || (len == 0)) {
     293           0 :                 return NT_STATUS_INVALID_PARAMETER;
     294             :         }
     295             : 
     296       20478 :         result = talloc_zero(mem_ctx, struct security_descriptor);
     297       20478 :         if (result == NULL) {
     298           0 :                 return NT_STATUS_NO_MEMORY;
     299             :         }
     300             : 
     301       20478 :         blob = data_blob_const(data, len);
     302             : 
     303       20478 :         ndr_err = ndr_pull_struct_blob(&blob, result, result,
     304             :                 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
     305             : 
     306       20478 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     307           0 :                 DEBUG(0, ("ndr_pull_security_descriptor failed: %s\n",
     308             :                           ndr_errstr(ndr_err)));
     309           0 :                 TALLOC_FREE(result);
     310           0 :                 return ndr_map_error2ntstatus(ndr_err);
     311             :         }
     312             : 
     313       20478 :         *psecdesc = result;
     314       20478 :         return NT_STATUS_OK;
     315             : }
     316             : 
     317             : /*******************************************************************
     318             :  Parse a byte stream into a sec_desc_buf
     319             : ********************************************************************/
     320             : 
     321           0 : NTSTATUS unmarshall_sec_desc_buf(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len,
     322             :                                  struct sec_desc_buf **psecdesc_buf)
     323             : {
     324           0 :         DATA_BLOB blob;
     325           0 :         enum ndr_err_code ndr_err;
     326           0 :         struct sec_desc_buf *result;
     327             : 
     328           0 :         if ((data == NULL) || (len == 0)) {
     329           0 :                 return NT_STATUS_INVALID_PARAMETER;
     330             :         }
     331             : 
     332           0 :         result = talloc_zero(mem_ctx, struct sec_desc_buf);
     333           0 :         if (result == NULL) {
     334           0 :                 return NT_STATUS_NO_MEMORY;
     335             :         }
     336             : 
     337           0 :         blob = data_blob_const(data, len);
     338             : 
     339           0 :         ndr_err = ndr_pull_struct_blob(&blob, result, result,
     340             :                 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
     341             : 
     342           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     343           0 :                 DEBUG(0, ("ndr_pull_sec_desc_buf failed: %s\n",
     344             :                           ndr_errstr(ndr_err)));
     345           0 :                 TALLOC_FREE(result);
     346           0 :                 return ndr_map_error2ntstatus(ndr_err);
     347             :         }
     348             : 
     349           0 :         *psecdesc_buf = result;
     350           0 :         return NT_STATUS_OK;
     351             : }
     352             : 
     353             : /*******************************************************************
     354             :  Creates a struct security_descriptor structure with typical defaults.
     355             : ********************************************************************/
     356             : 
     357      447305 : struct security_descriptor *make_standard_sec_desc(TALLOC_CTX *ctx, const struct dom_sid *owner_sid, const struct dom_sid *grp_sid,
     358             :                                  struct security_acl *dacl, size_t *sd_size)
     359             : {
     360      447305 :         return make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
     361             :                              SEC_DESC_SELF_RELATIVE, owner_sid, grp_sid, NULL,
     362             :                              dacl, sd_size);
     363             : }
     364             : 
     365             : /*******************************************************************
     366             :  Creates a struct sec_desc_buf structure.
     367             : ********************************************************************/
     368             : 
     369         504 : struct sec_desc_buf *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, struct security_descriptor *sec_desc)
     370             : {
     371           0 :         struct sec_desc_buf *dst;
     372             : 
     373         504 :         if((dst = talloc_zero(ctx, struct sec_desc_buf)) == NULL)
     374           0 :                 return NULL;
     375             : 
     376             :         /* max buffer size (allocated size) */
     377         504 :         dst->sd_size = (uint32_t)len;
     378             : 
     379         504 :         if (sec_desc != NULL) {
     380         504 :                 dst->sd = security_descriptor_copy(ctx, sec_desc);
     381         504 :                 if (dst->sd == NULL) {
     382           0 :                         return NULL;
     383             :                 }
     384             :         }
     385             : 
     386         504 :         return dst;
     387             : }
     388             : 
     389             : /*
     390             :  * Determine if an struct security_ace is inheritable
     391             :  */
     392             : 
     393     1289925 : static bool is_inheritable_ace(const struct security_ace *ace,
     394             :                                 bool container)
     395             : {
     396     1289925 :         if (!container) {
     397     1050149 :                 return ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0);
     398             :         }
     399             : 
     400      239776 :         if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
     401       44477 :                 return true;
     402             :         }
     403             : 
     404      195027 :         if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
     405         132 :                         !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
     406          88 :                 return true;
     407             :         }
     408             : 
     409      191777 :         return false;
     410             : }
     411             : 
     412             : /*
     413             :  * Does a security descriptor have any inheritable components for
     414             :  * the newly created type ?
     415             :  */
     416             : 
     417      212054 : bool sd_has_inheritable_components(const struct security_descriptor *parent_ctr, bool container)
     418             : {
     419        1284 :         unsigned int i;
     420      212054 :         const struct security_acl *the_acl = parent_ctr->dacl;
     421             : 
     422      212054 :         if (the_acl == NULL) {
     423           0 :                 return false;
     424             :         }
     425             : 
     426      543698 :         for (i = 0; i < the_acl->num_aces; i++) {
     427      489922 :                 const struct security_ace *ace = &the_acl->aces[i];
     428             : 
     429      492901 :                 if (is_inheritable_ace(ace, container)) {
     430      157933 :                         return true;
     431             :                 }
     432             :         }
     433       52837 :         return false;
     434             : }
     435             : 
     436             : /* Create a child security descriptor using another security descriptor as
     437             :    the parent container.  This child object can either be a container or
     438             :    non-container object. */
     439             : 
     440      157854 : NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
     441             :                                         struct security_descriptor **ppsd,
     442             :                                         size_t *psize,
     443             :                                         const struct security_descriptor *parent_ctr,
     444             :                                         const struct dom_sid *owner_sid,
     445             :                                         const struct dom_sid *group_sid,
     446             :                                         bool container)
     447             : {
     448      157854 :         struct security_acl *new_dacl = NULL, *the_acl = NULL;
     449      157854 :         struct security_ace *new_ace_list = NULL;
     450      157854 :         unsigned int new_ace_list_ndx = 0, i;
     451      157854 :         bool set_inherited_flags = (parent_ctr->type & SEC_DESC_DACL_AUTO_INHERITED);
     452             : 
     453      157854 :         *ppsd = NULL;
     454      157854 :         *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      157854 :         the_acl = parent_ctr->dacl;
     461             : 
     462      157854 :         if (the_acl->num_aces) {
     463      157854 :                 if (2*the_acl->num_aces < the_acl->num_aces) {
     464           0 :                         return NT_STATUS_NO_MEMORY;
     465             :                 }
     466             : 
     467      157854 :                 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      957857 :         for (i = 0; i < the_acl->num_aces; i++) {
     476      800003 :                 const struct security_ace *ace = &the_acl->aces[i];
     477      800003 :                 struct security_ace *new_ace = &new_ace_list[new_ace_list_ndx];
     478      800003 :                 const struct dom_sid *ptrustee = &ace->trustee;
     479      800003 :                 const struct dom_sid *creator = NULL;
     480      800003 :                 uint8_t new_flags = ace->flags;
     481        1956 :                 struct dom_sid_buf sidbuf1, sidbuf2;
     482             : 
     483      800003 :                 if (!is_inheritable_ace(ace, container)) {
     484      321253 :                         continue;
     485             :                 }
     486             : 
     487             :                 /* see the RAW-ACLS inheritance test for details on these rules */
     488      478750 :                 if (!container) {
     489      443691 :                         new_flags = 0;
     490             :                 } else {
     491             :                         /*
     492             :                          * We need to remove SEC_ACE_FLAG_INHERITED_ACE here
     493             :                          * if present because it should only be set if the
     494             :                          * parent has the AUTO_INHERITED bit set in the
     495             :                          * type/control field. If we don't it will slip through
     496             :                          * and create DACLs with incorrectly ordered ACEs
     497             :                          * when there are CREATOR_OWNER or CREATOR_GROUP
     498             :                          * ACEs.
     499             :                          */
     500       34228 :                         new_flags &= ~(SEC_ACE_FLAG_INHERIT_ONLY
     501             :                                         | SEC_ACE_FLAG_INHERITED_ACE);
     502             : 
     503       34228 :                         if (!(new_flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
     504          44 :                                 new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
     505             :                         }
     506       34228 :                         if (new_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
     507          88 :                                 new_flags = 0;
     508             :                         }
     509             :                 }
     510             : 
     511             :                 /* The CREATOR sids are special when inherited */
     512      478750 :                 if (dom_sid_equal(ptrustee, &global_sid_Creator_Owner)) {
     513      156782 :                         creator = &global_sid_Creator_Owner;
     514      156782 :                         ptrustee = owner_sid;
     515      321623 :                 } else if (dom_sid_equal(ptrustee, &global_sid_Creator_Group)) {
     516      155343 :                         creator = &global_sid_Creator_Group;
     517      155343 :                         ptrustee = group_sid;
     518             :                 }
     519             : 
     520      478750 :                 if (creator && container &&
     521       18704 :                                 (new_flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
     522             : 
     523             :                         /* First add the regular ACE entry. */
     524       18708 :                         init_sec_ace(new_ace, ptrustee, ace->type,
     525       18708 :                                 ace->access_mask,
     526             :                                 set_inherited_flags ? SEC_ACE_FLAG_INHERITED_ACE : 0);
     527             : 
     528       18708 :                         DEBUG(5,("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x"
     529             :                                  " inherited as %s:%d/0x%02x/0x%08x\n",
     530             :                                  dom_sid_str_buf(&ace->trustee, &sidbuf1),
     531             :                                  ace->type, ace->flags, ace->access_mask,
     532             :                                  dom_sid_str_buf(&new_ace->trustee, &sidbuf2),
     533             :                                  new_ace->type, new_ace->flags,
     534             :                                  new_ace->access_mask));
     535             : 
     536       18708 :                         new_ace_list_ndx++;
     537             : 
     538             :                         /* Now add the extra creator ACE. */
     539       18708 :                         new_ace = &new_ace_list[new_ace_list_ndx];
     540             : 
     541       18708 :                         ptrustee = creator;
     542       18708 :                         new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
     543             : 
     544      460042 :                 } else if (container &&
     545       15520 :                                 !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
     546       15432 :                         ptrustee = &ace->trustee;
     547             :                 }
     548             : 
     549      479785 :                 init_sec_ace(new_ace, ptrustee, ace->type,
     550      479785 :                              ace->access_mask, new_flags |
     551             :                                 (set_inherited_flags ? SEC_ACE_FLAG_INHERITED_ACE : 0));
     552             : 
     553      478750 :                 DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
     554             :                           " inherited as %s:%d/0x%02x/0x%08x\n",
     555             :                           dom_sid_str_buf(&ace->trustee, &sidbuf1),
     556             :                           ace->type, ace->flags, ace->access_mask,
     557             :                           dom_sid_str_buf(&new_ace->trustee, &sidbuf2),
     558             :                           new_ace->type, new_ace->flags,
     559             :                           new_ace->access_mask));
     560             : 
     561      478750 :                 new_ace_list_ndx++;
     562             :         }
     563             : 
     564             :         /*
     565             :          * remove duplicates
     566             :          */
     567      497458 :         for (i=1; i < new_ace_list_ndx;) {
     568      339604 :                 struct security_ace *ai = &new_ace_list[i];
     569         826 :                 unsigned int remaining, j;
     570      339604 :                 bool remove_ace = false;
     571             : 
     572      905642 :                 for (j=0; j < i; j++) {
     573      567007 :                         struct security_ace *aj = &new_ace_list[j];
     574             : 
     575      567007 :                         if (!security_ace_equal(ai, aj)) {
     576      566038 :                                 continue;
     577             :                         }
     578             : 
     579         969 :                         remove_ace = true;
     580         969 :                         break;
     581             :                 }
     582             : 
     583      339604 :                 if (!remove_ace) {
     584      338635 :                         i++;
     585      338635 :                         continue;
     586             :                 }
     587             : 
     588         969 :                 new_ace_list_ndx--;
     589         969 :                 remaining = new_ace_list_ndx - i;
     590         969 :                 if (remaining == 0) {
     591          51 :                         ZERO_STRUCT(new_ace_list[i]);
     592          51 :                         continue;
     593             :                 }
     594        2089 :                 memmove(&new_ace_list[i], &new_ace_list[i+1],
     595             :                         sizeof(new_ace_list[i]) * remaining);
     596             :         }
     597             : 
     598             :         /* Create child security descriptor to return */
     599      157854 :         if (new_ace_list_ndx) {
     600      157854 :                 new_dacl = make_sec_acl(ctx,
     601             :                                 NT4_ACL_REVISION,
     602             :                                 new_ace_list_ndx,
     603             :                                 new_ace_list);
     604             : 
     605      157854 :                 if (!new_dacl) {
     606           0 :                         return NT_STATUS_NO_MEMORY;
     607             :                 }
     608             :         }
     609             : 
     610      158199 :         *ppsd = make_sec_desc(ctx,
     611             :                         SECURITY_DESCRIPTOR_REVISION_1,
     612             :                         SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT|
     613             :                                 (set_inherited_flags ? SEC_DESC_DACL_AUTO_INHERITED : 0),
     614             :                         owner_sid,
     615             :                         group_sid,
     616             :                         NULL,
     617             :                         new_dacl,
     618             :                         psize);
     619      157854 :         if (!*ppsd) {
     620           0 :                 return NT_STATUS_NO_MEMORY;
     621             :         }
     622      157854 :         return NT_STATUS_OK;
     623             : }

Generated by: LCOV version 1.14