root/source3/lib/secdesc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sec_desc_equal
  2. get_sec_info
  3. sec_desc_merge
  4. make_sec_desc
  5. dup_sec_desc
  6. marshall_sec_desc
  7. marshall_sec_desc_buf
  8. unmarshall_sec_desc
  9. unmarshall_sec_desc_buf
  10. make_standard_sec_desc
  11. make_sec_desc_buf
  12. dup_sec_desc_buf
  13. sec_desc_add_sid
  14. sec_desc_mod_sid
  15. sec_desc_del_sid
  16. is_inheritable_ace
  17. se_create_child_secdesc
  18. se_create_child_secdesc_buf

   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 
  25 /* Map generic permissions to file object specific permissions */
  26 
  27 const struct generic_mapping file_generic_mapping = {
  28         FILE_GENERIC_READ,
  29         FILE_GENERIC_WRITE,
  30         FILE_GENERIC_EXECUTE,
  31         FILE_GENERIC_ALL
  32 };
  33 
  34 /*******************************************************************
  35  Compares two SEC_DESC structures
  36 ********************************************************************/
  37 
  38 bool sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
     /* [<][>][^][v][top][bottom][index][help] */
  39 {
  40         /* Trivial case */
  41 
  42         if (!s1 && !s2) {
  43                 goto done;
  44         }
  45 
  46         if (!s1 || !s2) {
  47                 return False;
  48         }
  49 
  50         /* Check top level stuff */
  51 
  52         if (s1->revision != s2->revision) {
  53                 DEBUG(10, ("sec_desc_equal(): revision differs (%d != %d)\n",
  54                            s1->revision, s2->revision));
  55                 return False;
  56         }
  57 
  58         if (s1->type!= s2->type) {
  59                 DEBUG(10, ("sec_desc_equal(): type differs (%d != %d)\n",
  60                            s1->type, s2->type));
  61                 return False;
  62         }
  63 
  64         /* Check owner and group */
  65 
  66         if (!sid_equal(s1->owner_sid, s2->owner_sid)) {
  67                 DEBUG(10, ("sec_desc_equal(): owner differs (%s != %s)\n",
  68                            sid_string_dbg(s1->owner_sid),
  69                            sid_string_dbg(s2->owner_sid)));
  70                 return False;
  71         }
  72 
  73         if (!sid_equal(s1->group_sid, s2->group_sid)) {
  74                 DEBUG(10, ("sec_desc_equal(): group differs (%s != %s)\n",
  75                            sid_string_dbg(s1->group_sid),
  76                            sid_string_dbg(s2->group_sid)));
  77                 return False;
  78         }
  79 
  80         /* Check ACLs present in one but not the other */
  81 
  82         if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
  83             (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl)) {
  84                 DEBUG(10, ("sec_desc_equal(): dacl or sacl not present\n"));
  85                 return False;
  86         }
  87 
  88         /* Sigh - we have to do it the hard way by iterating over all
  89            the ACEs in the ACLs */
  90 
  91         if (!sec_acl_equal(s1->dacl, s2->dacl) ||
  92             !sec_acl_equal(s1->sacl, s2->sacl)) {
  93                 DEBUG(10, ("sec_desc_equal(): dacl/sacl list not equal\n"));
  94                 return False;
  95         }
  96 
  97  done:
  98         DEBUG(10, ("sec_desc_equal(): secdescs are identical\n"));
  99         return True;
 100 }
 101 
 102 /*******************************************************************
 103  Given a security_descriptor return the sec_info.
 104 ********************************************************************/
 105 
 106 uint32_t get_sec_info(const SEC_DESC *sd)
     /* [<][>][^][v][top][bottom][index][help] */
 107 {
 108         uint32_t sec_info = ALL_SECURITY_INFORMATION;
 109 
 110         SMB_ASSERT(sd);
 111 
 112         if (sd->owner_sid == NULL) {
 113                 sec_info &= ~OWNER_SECURITY_INFORMATION;
 114         }
 115         if (sd->group_sid == NULL) {
 116                 sec_info &= ~GROUP_SECURITY_INFORMATION;
 117         }
 118         if (sd->sacl == NULL) {
 119                 sec_info &= ~SACL_SECURITY_INFORMATION;
 120         }
 121         if (sd->dacl == NULL) {
 122                 sec_info &= ~DACL_SECURITY_INFORMATION;
 123         }
 124 
 125         return sec_info;
 126 }
 127 
 128 
 129 /*******************************************************************
 130  Merge part of security descriptor old_sec in to the empty sections of 
 131  security descriptor new_sec.
 132 ********************************************************************/
 133 
 134 SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BUF *old_sdb)
     /* [<][>][^][v][top][bottom][index][help] */
 135 {
 136         DOM_SID *owner_sid, *group_sid;
 137         SEC_DESC_BUF *return_sdb;
 138         SEC_ACL *dacl, *sacl;
 139         SEC_DESC *psd = NULL;
 140         uint16 secdesc_type;
 141         size_t secdesc_size;
 142 
 143         /* Copy over owner and group sids.  There seems to be no flag for
 144            this so just check the pointer values. */
 145 
 146         owner_sid = new_sdb->sd->owner_sid ? new_sdb->sd->owner_sid :
 147                 old_sdb->sd->owner_sid;
 148 
 149         group_sid = new_sdb->sd->group_sid ? new_sdb->sd->group_sid :
 150                 old_sdb->sd->group_sid;
 151         
 152         secdesc_type = new_sdb->sd->type;
 153 
 154         /* Ignore changes to the system ACL.  This has the effect of making
 155            changes through the security tab audit button not sticking. 
 156            Perhaps in future Samba could implement these settings somehow. */
 157 
 158         sacl = NULL;
 159         secdesc_type &= ~SEC_DESC_SACL_PRESENT;
 160 
 161         /* Copy across discretionary ACL */
 162 
 163         if (secdesc_type & SEC_DESC_DACL_PRESENT) {
 164                 dacl = new_sdb->sd->dacl;
 165         } else {
 166                 dacl = old_sdb->sd->dacl;
 167         }
 168 
 169         /* Create new security descriptor from bits */
 170 
 171         psd = make_sec_desc(ctx, new_sdb->sd->revision, secdesc_type,
 172                             owner_sid, group_sid, sacl, dacl, &secdesc_size);
 173 
 174         return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);
 175 
 176         return(return_sdb);
 177 }
 178 
 179 /*******************************************************************
 180  Creates a SEC_DESC structure
 181 ********************************************************************/
 182 
 183 SEC_DESC *make_sec_desc(TALLOC_CTX *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 184                         enum security_descriptor_revision revision,
 185                         uint16 type,
 186                         const DOM_SID *owner_sid, const DOM_SID *grp_sid,
 187                         SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size)
 188 {
 189         SEC_DESC *dst;
 190         uint32 offset     = 0;
 191 
 192         *sd_size = 0;
 193 
 194         if(( dst = TALLOC_ZERO_P(ctx, SEC_DESC)) == NULL)
 195                 return NULL;
 196 
 197         dst->revision = revision;
 198         dst->type = type;
 199 
 200         if (sacl)
 201                 dst->type |= SEC_DESC_SACL_PRESENT;
 202         if (dacl)
 203                 dst->type |= SEC_DESC_DACL_PRESENT;
 204 
 205         dst->owner_sid = NULL;
 206         dst->group_sid   = NULL;
 207         dst->sacl      = NULL;
 208         dst->dacl      = NULL;
 209 
 210         if(owner_sid && ((dst->owner_sid = sid_dup_talloc(dst,owner_sid)) == NULL))
 211                 goto error_exit;
 212 
 213         if(grp_sid && ((dst->group_sid = sid_dup_talloc(dst,grp_sid)) == NULL))
 214                 goto error_exit;
 215 
 216         if(sacl && ((dst->sacl = dup_sec_acl(dst, sacl)) == NULL))
 217                 goto error_exit;
 218 
 219         if(dacl && ((dst->dacl = dup_sec_acl(dst, dacl)) == NULL))
 220                 goto error_exit;
 221 
 222         offset = SEC_DESC_HEADER_SIZE;
 223 
 224         /*
 225          * Work out the linearization sizes.
 226          */
 227 
 228         if (dst->sacl != NULL) {
 229                 offset += dst->sacl->size;
 230         }
 231         if (dst->dacl != NULL) {
 232                 offset += dst->dacl->size;
 233         }
 234 
 235         if (dst->owner_sid != NULL) {
 236                 offset += ndr_size_dom_sid(dst->owner_sid, NULL, 0);
 237         }
 238 
 239         if (dst->group_sid != NULL) {
 240                 offset += ndr_size_dom_sid(dst->group_sid, NULL, 0);
 241         }
 242 
 243         *sd_size = (size_t)offset;
 244         return dst;
 245 
 246 error_exit:
 247 
 248         *sd_size = 0;
 249         return NULL;
 250 }
 251 
 252 /*******************************************************************
 253  Duplicate a SEC_DESC structure.  
 254 ********************************************************************/
 255 
 256 SEC_DESC *dup_sec_desc(TALLOC_CTX *ctx, const SEC_DESC *src)
     /* [<][>][^][v][top][bottom][index][help] */
 257 {
 258         size_t dummy;
 259 
 260         if(src == NULL)
 261                 return NULL;
 262 
 263         return make_sec_desc( ctx, src->revision, src->type,
 264                                 src->owner_sid, src->group_sid, src->sacl,
 265                                 src->dacl, &dummy);
 266 }
 267 
 268 /*******************************************************************
 269  Convert a secdesc into a byte stream
 270 ********************************************************************/
 271 NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 272                            struct security_descriptor *secdesc,
 273                            uint8 **data, size_t *len)
 274 {
 275         DATA_BLOB blob;
 276         enum ndr_err_code ndr_err;
 277 
 278         ndr_err = ndr_push_struct_blob(
 279                 &blob, mem_ctx, NULL, secdesc,
 280                 (ndr_push_flags_fn_t)ndr_push_security_descriptor);
 281 
 282         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 283                 DEBUG(0, ("ndr_push_security_descriptor failed: %s\n",
 284                           ndr_errstr(ndr_err)));
 285                 return ndr_map_error2ntstatus(ndr_err);;
 286         }
 287 
 288         *data = blob.data;
 289         *len = blob.length;
 290         return NT_STATUS_OK;
 291 }
 292 
 293 /*******************************************************************
 294  Convert a secdesc_buf into a byte stream
 295 ********************************************************************/
 296 
 297 NTSTATUS marshall_sec_desc_buf(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 298                                struct sec_desc_buf *secdesc_buf,
 299                                uint8_t **data, size_t *len)
 300 {
 301         DATA_BLOB blob;
 302         enum ndr_err_code ndr_err;
 303 
 304         ndr_err = ndr_push_struct_blob(
 305                 &blob, mem_ctx, NULL, secdesc_buf,
 306                 (ndr_push_flags_fn_t)ndr_push_sec_desc_buf);
 307 
 308         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 309                 DEBUG(0, ("ndr_push_sec_desc_buf failed: %s\n",
 310                           ndr_errstr(ndr_err)));
 311                 return ndr_map_error2ntstatus(ndr_err);;
 312         }
 313 
 314         *data = blob.data;
 315         *len = blob.length;
 316         return NT_STATUS_OK;
 317 }
 318 
 319 /*******************************************************************
 320  Parse a byte stream into a secdesc
 321 ********************************************************************/
 322 NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len,
     /* [<][>][^][v][top][bottom][index][help] */
 323                              struct security_descriptor **psecdesc)
 324 {
 325         DATA_BLOB blob;
 326         enum ndr_err_code ndr_err;
 327         struct security_descriptor *result;
 328 
 329         if ((data == NULL) || (len == 0)) {
 330                 return NT_STATUS_INVALID_PARAMETER;
 331         }
 332 
 333         result = TALLOC_ZERO_P(mem_ctx, struct security_descriptor);
 334         if (result == NULL) {
 335                 return NT_STATUS_NO_MEMORY;
 336         }
 337 
 338         blob = data_blob_const(data, len);
 339 
 340         ndr_err = ndr_pull_struct_blob(
 341                 &blob, result, NULL, result,
 342                 (ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
 343 
 344         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 345                 DEBUG(0, ("ndr_pull_security_descriptor failed: %s\n",
 346                           ndr_errstr(ndr_err)));
 347                 TALLOC_FREE(result);
 348                 return ndr_map_error2ntstatus(ndr_err);;
 349         }
 350 
 351         *psecdesc = result;
 352         return NT_STATUS_OK;
 353 }
 354 
 355 /*******************************************************************
 356  Parse a byte stream into a sec_desc_buf
 357 ********************************************************************/
 358 
 359 NTSTATUS unmarshall_sec_desc_buf(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len,
     /* [<][>][^][v][top][bottom][index][help] */
 360                                  struct sec_desc_buf **psecdesc_buf)
 361 {
 362         DATA_BLOB blob;
 363         enum ndr_err_code ndr_err;
 364         struct sec_desc_buf *result;
 365 
 366         if ((data == NULL) || (len == 0)) {
 367                 return NT_STATUS_INVALID_PARAMETER;
 368         }
 369 
 370         result = TALLOC_ZERO_P(mem_ctx, struct sec_desc_buf);
 371         if (result == NULL) {
 372                 return NT_STATUS_NO_MEMORY;
 373         }
 374 
 375         blob = data_blob_const(data, len);
 376 
 377         ndr_err = ndr_pull_struct_blob(
 378                 &blob, result, NULL, result,
 379                 (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
 380 
 381         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 382                 DEBUG(0, ("ndr_pull_sec_desc_buf failed: %s\n",
 383                           ndr_errstr(ndr_err)));
 384                 TALLOC_FREE(result);
 385                 return ndr_map_error2ntstatus(ndr_err);;
 386         }
 387 
 388         *psecdesc_buf = result;
 389         return NT_STATUS_OK;
 390 }
 391 
 392 /*******************************************************************
 393  Creates a SEC_DESC structure with typical defaults.
 394 ********************************************************************/
 395 
 396 SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, const DOM_SID *owner_sid, const DOM_SID *grp_sid,
     /* [<][>][^][v][top][bottom][index][help] */
 397                                  SEC_ACL *dacl, size_t *sd_size)
 398 {
 399         return make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
 400                              SEC_DESC_SELF_RELATIVE, owner_sid, grp_sid, NULL,
 401                              dacl, sd_size);
 402 }
 403 
 404 /*******************************************************************
 405  Creates a SEC_DESC_BUF structure.
 406 ********************************************************************/
 407 
 408 SEC_DESC_BUF *make_sec_desc_buf(TALLOC_CTX *ctx, size_t len, SEC_DESC *sec_desc)
     /* [<][>][^][v][top][bottom][index][help] */
 409 {
 410         SEC_DESC_BUF *dst;
 411 
 412         if((dst = TALLOC_ZERO_P(ctx, SEC_DESC_BUF)) == NULL)
 413                 return NULL;
 414 
 415         /* max buffer size (allocated size) */
 416         dst->sd_size = (uint32)len;
 417         
 418         if(sec_desc && ((dst->sd = dup_sec_desc(ctx, sec_desc)) == NULL)) {
 419                 return NULL;
 420         }
 421 
 422         return dst;
 423 }
 424 
 425 /*******************************************************************
 426  Duplicates a SEC_DESC_BUF structure.
 427 ********************************************************************/
 428 
 429 SEC_DESC_BUF *dup_sec_desc_buf(TALLOC_CTX *ctx, SEC_DESC_BUF *src)
     /* [<][>][^][v][top][bottom][index][help] */
 430 {
 431         if(src == NULL)
 432                 return NULL;
 433 
 434         return make_sec_desc_buf( ctx, src->sd_size, src->sd);
 435 }
 436 
 437 /*******************************************************************
 438  Add a new SID with its permissions to SEC_DESC.
 439 ********************************************************************/
 440 
 441 NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32 mask, size_t *sd_size)
     /* [<][>][^][v][top][bottom][index][help] */
 442 {
 443         SEC_DESC *sd   = 0;
 444         SEC_ACL  *dacl = 0;
 445         SEC_ACE  *ace  = 0;
 446         NTSTATUS  status;
 447 
 448         if (!ctx || !psd || !sid || !sd_size)
 449                 return NT_STATUS_INVALID_PARAMETER;
 450 
 451         *sd_size = 0;
 452 
 453         status = sec_ace_add_sid(ctx, &ace, psd[0]->dacl->aces, &psd[0]->dacl->num_aces, sid, mask);
 454         
 455         if (!NT_STATUS_IS_OK(status))
 456                 return status;
 457 
 458         if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
 459                 return NT_STATUS_UNSUCCESSFUL;
 460         
 461         if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->type, psd[0]->owner_sid, 
 462                 psd[0]->group_sid, psd[0]->sacl, dacl, sd_size)))
 463                 return NT_STATUS_UNSUCCESSFUL;
 464 
 465         *psd = sd;
 466          sd  = 0;
 467         return NT_STATUS_OK;
 468 }
 469 
 470 /*******************************************************************
 471  Modify a SID's permissions in a SEC_DESC.
 472 ********************************************************************/
 473 
 474 NTSTATUS sec_desc_mod_sid(SEC_DESC *sd, DOM_SID *sid, uint32 mask)
     /* [<][>][^][v][top][bottom][index][help] */
 475 {
 476         NTSTATUS status;
 477 
 478         if (!sd || !sid)
 479                 return NT_STATUS_INVALID_PARAMETER;
 480 
 481         status = sec_ace_mod_sid(sd->dacl->aces, sd->dacl->num_aces, sid, mask);
 482 
 483         if (!NT_STATUS_IS_OK(status))
 484                 return status;
 485         
 486         return NT_STATUS_OK;
 487 }
 488 
 489 /*******************************************************************
 490  Delete a SID from a SEC_DESC.
 491 ********************************************************************/
 492 
 493 NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t *sd_size)
     /* [<][>][^][v][top][bottom][index][help] */
 494 {
 495         SEC_DESC *sd   = 0;
 496         SEC_ACL  *dacl = 0;
 497         SEC_ACE  *ace  = 0;
 498         NTSTATUS  status;
 499 
 500         if (!ctx || !psd[0] || !sid || !sd_size)
 501                 return NT_STATUS_INVALID_PARAMETER;
 502 
 503         *sd_size = 0;
 504         
 505         status = sec_ace_del_sid(ctx, &ace, psd[0]->dacl->aces, &psd[0]->dacl->num_aces, sid);
 506 
 507         if (!NT_STATUS_IS_OK(status))
 508                 return status;
 509 
 510         if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace)))
 511                 return NT_STATUS_UNSUCCESSFUL;
 512         
 513         if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->type, psd[0]->owner_sid, 
 514                 psd[0]->group_sid, psd[0]->sacl, dacl, sd_size)))
 515                 return NT_STATUS_UNSUCCESSFUL;
 516 
 517         *psd = sd;
 518          sd  = 0;
 519         return NT_STATUS_OK;
 520 }
 521 
 522 /*
 523  * Determine if an ACE is inheritable
 524  */
 525 
 526 static bool is_inheritable_ace(const SEC_ACE *ace,
     /* [<][>][^][v][top][bottom][index][help] */
 527                                 bool container)
 528 {
 529         if (!container) {
 530                 return ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0);
 531         }
 532 
 533         if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
 534                 return true;
 535         }
 536 
 537         if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) &&
 538                         !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
 539                 return true;
 540         }
 541 
 542         return false;
 543 }
 544 
 545 /* Create a child security descriptor using another security descriptor as
 546    the parent container.  This child object can either be a container or
 547    non-container object. */
 548 
 549 NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 550                                         SEC_DESC **ppsd,
 551                                         size_t *psize,
 552                                         const SEC_DESC *parent_ctr,
 553                                         const DOM_SID *owner_sid,
 554                                         const DOM_SID *group_sid,
 555                                         bool container)
 556 {
 557         SEC_ACL *new_dacl = NULL, *the_acl = NULL;
 558         SEC_ACE *new_ace_list = NULL;
 559         unsigned int new_ace_list_ndx = 0, i;
 560 
 561         *ppsd = NULL;
 562         *psize = 0;
 563 
 564         /* Currently we only process the dacl when creating the child.  The
 565            sacl should also be processed but this is left out as sacls are
 566            not implemented in Samba at the moment.*/
 567 
 568         the_acl = parent_ctr->dacl;
 569 
 570         if (the_acl->num_aces) {
 571                 if (2*the_acl->num_aces < the_acl->num_aces) {
 572                         return NT_STATUS_NO_MEMORY;
 573                 }
 574 
 575                 if (!(new_ace_list = TALLOC_ARRAY(ctx, SEC_ACE,
 576                                                 2*the_acl->num_aces))) {
 577                         return NT_STATUS_NO_MEMORY;
 578                 }
 579         } else {
 580                 new_ace_list = NULL;
 581         }
 582 
 583         for (i = 0; i < the_acl->num_aces; i++) {
 584                 const SEC_ACE *ace = &the_acl->aces[i];
 585                 SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
 586                 const DOM_SID *ptrustee = &ace->trustee;
 587                 const DOM_SID *creator = NULL;
 588                 uint8 new_flags = ace->flags;
 589 
 590                 if (!is_inheritable_ace(ace, container)) {
 591                         continue;
 592                 }
 593 
 594                 /* see the RAW-ACLS inheritance test for details on these rules */
 595                 if (!container) {
 596                         new_flags = 0;
 597                 } else {
 598                         new_flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
 599 
 600                         if (!(new_flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
 601                                 new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
 602                         }
 603                         if (new_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
 604                                 new_flags = 0;
 605                         }
 606                 }
 607 
 608                 /* The CREATOR sids are special when inherited */
 609                 if (sid_equal(ptrustee, &global_sid_Creator_Owner)) {
 610                         creator = &global_sid_Creator_Owner;
 611                         ptrustee = owner_sid;
 612                 } else if (sid_equal(ptrustee, &global_sid_Creator_Group)) {
 613                         creator = &global_sid_Creator_Group;
 614                         ptrustee = group_sid;
 615                 }
 616 
 617                 if (creator && container &&
 618                                 (new_flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
 619 
 620                         /* First add the regular ACE entry. */
 621                         init_sec_ace(new_ace, ptrustee, ace->type,
 622                                 ace->access_mask, 0);
 623 
 624                         DEBUG(5,("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x"
 625                                 " inherited as %s:%d/0x%02x/0x%08x\n",
 626                                 sid_string_dbg(&ace->trustee),
 627                                 ace->type, ace->flags, ace->access_mask,
 628                                 sid_string_dbg(&new_ace->trustee),
 629                                 new_ace->type, new_ace->flags,
 630                                 new_ace->access_mask));
 631 
 632                         new_ace_list_ndx++;
 633 
 634                         /* Now add the extra creator ACE. */
 635                         new_ace = &new_ace_list[new_ace_list_ndx];
 636 
 637                         ptrustee = creator;
 638                         new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
 639                 } else if (container &&
 640                                 !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
 641                         ptrustee = &ace->trustee;
 642                 }
 643 
 644                 init_sec_ace(new_ace, ptrustee, ace->type,
 645                              ace->access_mask, new_flags);
 646 
 647                 DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
 648                           " inherited as %s:%d/0x%02x/0x%08x\n",
 649                           sid_string_dbg(&ace->trustee),
 650                           ace->type, ace->flags, ace->access_mask,
 651                           sid_string_dbg(&ace->trustee),
 652                           new_ace->type, new_ace->flags,
 653                           new_ace->access_mask));
 654 
 655                 new_ace_list_ndx++;
 656         }
 657 
 658         /* Create child security descriptor to return */
 659         if (new_ace_list_ndx) {
 660                 new_dacl = make_sec_acl(ctx,
 661                                 NT4_ACL_REVISION,
 662                                 new_ace_list_ndx,
 663                                 new_ace_list);
 664 
 665                 if (!new_dacl) {
 666                         return NT_STATUS_NO_MEMORY;
 667                 }
 668         }
 669 
 670         *ppsd = make_sec_desc(ctx,
 671                         SECURITY_DESCRIPTOR_REVISION_1,
 672                         SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
 673                         owner_sid,
 674                         group_sid,
 675                         NULL,
 676                         new_dacl,
 677                         psize);
 678         if (!*ppsd) {
 679                 return NT_STATUS_NO_MEMORY;
 680         }
 681         return NT_STATUS_OK;
 682 }
 683 
 684 NTSTATUS se_create_child_secdesc_buf(TALLOC_CTX *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 685                                         SEC_DESC_BUF **ppsdb,
 686                                         const SEC_DESC *parent_ctr,
 687                                         bool container)
 688 {
 689         NTSTATUS status;
 690         size_t size = 0;
 691         SEC_DESC *sd = NULL;
 692 
 693         *ppsdb = NULL;
 694         status = se_create_child_secdesc(ctx,
 695                                         &sd,
 696                                         &size,
 697                                         parent_ctr,
 698                                         parent_ctr->owner_sid,
 699                                         parent_ctr->group_sid,
 700                                         container);
 701         if (!NT_STATUS_IS_OK(status)) {
 702                 return status;
 703         }
 704 
 705         *ppsdb = make_sec_desc_buf(ctx, size, sd);
 706         if (!*ppsdb) {
 707                 return NT_STATUS_NO_MEMORY;
 708         }
 709         return NT_STATUS_OK;
 710 }

/* [<][>][^][v][top][bottom][index][help] */