Coverage Report

Created: 2026-04-01 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/libcli/security/create_descriptor.c
Line
Count
Source
1
/*
2
   Copyright (C) Nadezhda Ivanova 2009
3
4
   This program is free software; you can redistribute it and/or modify
5
   it under the terms of the GNU General Public License as published by
6
   the Free Software Foundation; either version 3 of the License, or
7
   (at your option) any later version.
8
9
   This program is distributed in the hope that it will be useful,
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
   GNU General Public License for more details.
13
14
   You should have received a copy of the GNU General Public License
15
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
*/
17
18
/*
19
 *  Name: create_descriptor
20
 *
21
 *  Component: routines for calculating and creating security descriptors
22
 *  as described in MS-DTYP 2.5.3.x
23
 *
24
 *  Description:
25
 *
26
 *
27
 *  Author: Nadezhda Ivanova
28
 */
29
#include "replace.h"
30
#include "lib/util/debug.h"
31
#include "libcli/security/security.h"
32
#include "librpc/gen_ndr/ndr_security.h"
33
34
/* Todos:
35
 * build the security token dacl as follows:
36
 * SYSTEM: GA, OWNER: GA, LOGIN_SID:GW|GE
37
 * Need session id information for the login SID. Probably
38
 * the best place for this is during token creation
39
 *
40
 * Implement SD Invariants
41
 * ACE sorting rules
42
 * LDAP_SERVER_SD_FLAGS_OID control
43
 * ADTS 7.1.3.3 needs to be clarified
44
 */
45
46
/* the mapping function for generic rights for DS.(GA,GR,GW,GX)
47
 * The mapping function is passed as an argument to the
48
 * descriptor calculating routine and depends on the security
49
 * manager that calls the calculating routine.
50
 * TODO: need similar mappings for the file system and
51
 * registry security managers in order to make this code
52
 * generic for all security managers
53
 */
54
55
uint32_t map_generic_rights_ds(uint32_t access_mask)
56
0
{
57
0
  if (access_mask & SEC_GENERIC_ALL) {
58
0
    access_mask |= SEC_ADS_GENERIC_ALL;
59
0
    access_mask &= ~SEC_GENERIC_ALL;
60
0
  }
61
62
0
  if (access_mask & SEC_GENERIC_EXECUTE) {
63
0
    access_mask |= SEC_ADS_GENERIC_EXECUTE;
64
0
    access_mask &= ~SEC_GENERIC_EXECUTE;
65
0
  }
66
67
0
  if (access_mask & SEC_GENERIC_WRITE) {
68
0
    access_mask |= SEC_ADS_GENERIC_WRITE;
69
0
    access_mask &= ~SEC_GENERIC_WRITE;
70
0
  }
71
72
0
  if (access_mask & SEC_GENERIC_READ) {
73
0
    access_mask |= SEC_ADS_GENERIC_READ;
74
0
    access_mask &= ~SEC_GENERIC_READ;
75
0
  }
76
77
0
  return access_mask;
78
0
}
79
80
/* Not sure what this has to be,
81
* and it does not seem to have any influence */
82
static bool object_in_list(const struct GUID *object_list, const struct GUID *object)
83
0
{
84
0
  size_t i;
85
86
0
  if (object_list == NULL) {
87
0
    return true;
88
0
  }
89
90
0
  if (GUID_all_zero(object)) {
91
0
    return true;
92
0
  }
93
94
0
  for (i=0; ; i++) {
95
0
    if (GUID_all_zero(&object_list[i])) {
96
0
      return false;
97
0
    }
98
0
    if (!GUID_equal(&object_list[i], object)) {
99
0
      continue;
100
0
    }
101
102
0
    return true;
103
0
  }
104
105
0
  return false;
106
0
}
107
108
/* returns true if the ACE contains generic information
109
 * that needs to be processed additionally */
110
111
static bool desc_ace_has_generic(const struct security_ace *ace)
112
0
{
113
0
  if (ace->access_mask & SEC_GENERIC_ALL || ace->access_mask & SEC_GENERIC_READ ||
114
0
      ace->access_mask & SEC_GENERIC_WRITE || ace->access_mask & SEC_GENERIC_EXECUTE) {
115
0
    return true;
116
0
  }
117
0
  if (dom_sid_equal(&ace->trustee, &global_sid_Creator_Owner) ||
118
0
      dom_sid_equal(&ace->trustee, &global_sid_Creator_Group)) {
119
0
    return true;
120
0
  }
121
0
  return false;
122
0
}
123
124
/* creates an ace in which the generic information is expanded */
125
126
static void desc_expand_generic(struct security_ace *new_ace,
127
        const struct dom_sid *owner,
128
        const struct dom_sid *group)
129
0
{
130
0
  new_ace->access_mask = map_generic_rights_ds(new_ace->access_mask);
131
0
  if (dom_sid_equal(&new_ace->trustee, &global_sid_Creator_Owner)) {
132
0
    new_ace->trustee = *owner;
133
0
  }
134
0
  if (dom_sid_equal(&new_ace->trustee, &global_sid_Creator_Group)) {
135
0
    new_ace->trustee = *group;
136
0
  }
137
0
  new_ace->flags = 0x0;
138
0
}
139
140
static struct security_acl *calculate_inherited_from_parent(
141
  TALLOC_CTX *mem_ctx,
142
  struct security_acl *acl,
143
  bool is_container,
144
  const struct dom_sid *owner,
145
  const struct dom_sid *group,
146
  struct GUID *object_list)
147
0
{
148
0
  uint32_t i;
149
0
  struct security_acl *tmp_acl = NULL;
150
151
0
  if (!acl) {
152
0
    return NULL;
153
0
  }
154
0
  tmp_acl = talloc_zero(mem_ctx, struct security_acl);
155
0
  if (!tmp_acl) {
156
0
    return NULL;
157
0
  }
158
159
0
  for (i=0; i < acl->num_aces; i++) {
160
0
    const struct security_ace *ace = &acl->aces[i];
161
0
    const struct GUID *inherited_object = NULL;
162
0
    const struct GUID *inherited_property = NULL;
163
0
    struct security_ace *tmp_ace = NULL;
164
0
    bool applies = false;
165
0
    bool inherited_only = false;
166
0
    bool expand_ace = false;
167
0
    bool expand_only = false;
168
169
0
    if (is_container && (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
170
0
      applies = true;
171
0
    } else if (!is_container && (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
172
0
      applies = true;
173
0
    }
174
175
0
    if (!applies) {
176
      /*
177
       * If the ace doesn't apply to the
178
       * current node, we should only keep
179
       * it as SEC_ACE_FLAG_OBJECT_INHERIT
180
       * on a container. We'll add
181
       * SEC_ACE_FLAG_INHERITED_ACE
182
       * and SEC_ACE_FLAG_INHERIT_ONLY below.
183
       *
184
       * Otherwise we should completely ignore it.
185
       */
186
0
      if (!(ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
187
0
        continue;
188
0
      }
189
0
    }
190
191
0
    switch (ace->type) {
192
0
    case SEC_ACE_TYPE_ACCESS_ALLOWED:
193
0
    case SEC_ACE_TYPE_ACCESS_DENIED:
194
0
    case SEC_ACE_TYPE_SYSTEM_AUDIT:
195
0
    case SEC_ACE_TYPE_SYSTEM_ALARM:
196
0
    case SEC_ACE_TYPE_ALLOWED_COMPOUND:
197
0
      break;
198
199
0
    case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
200
0
    case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
201
0
    case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
202
0
    case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
203
0
    case SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT:
204
0
    case SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT:
205
0
    case SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT:
206
0
      if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
207
0
        inherited_property = &ace->object.object.type.type;
208
0
      }
209
0
      if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) {
210
0
        inherited_object = &ace->object.object.inherited_type.inherited_type;
211
0
      }
212
213
0
      if (inherited_object != NULL && !object_in_list(object_list, inherited_object)) {
214
        /*
215
         * An explicit object class schemaId is given,
216
         * but doesn't belong to the current object.
217
         */
218
0
        applies = false;
219
0
      }
220
221
0
      break;
222
223
0
    case SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK:
224
0
    case SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK:
225
0
    case SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK:
226
0
      break;
227
0
    case SEC_ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE:
228
0
      break;
229
0
    case SEC_ACE_TYPE_SYSTEM_ALARM_CALLBACK:
230
0
    case SEC_ACE_TYPE_SYSTEM_ALARM_CALLBACK_OBJECT:
231
0
    case SEC_ACE_TYPE_SYSTEM_MANDATORY_LABEL:
232
0
    case SEC_ACE_TYPE_SYSTEM_SCOPED_POLICY_ID:
233
0
    default:
234
0
      DBG_WARNING("ACE type %d is not handled\n", ace->type);
235
0
      TALLOC_FREE(tmp_acl);
236
0
      return NULL;
237
0
    }
238
239
0
    if (ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
240
0
      if (!applies) {
241
        /*
242
         * If the ACE doesn't apply to
243
         * the current object, we should
244
         * ignore it as it should not be
245
         * inherited any further
246
         */
247
0
        continue;
248
0
      }
249
      /*
250
       * We should only keep the expanded version
251
       * of the ACE on the current object.
252
       */
253
0
      expand_ace = true;
254
0
      expand_only = true;
255
0
    } else if (applies) {
256
      /*
257
       * We check if should also add
258
       * the expanded version of the ACE
259
       * in addition, in case we should
260
       * expand generic access bits or
261
       * special sids.
262
       *
263
       * In that case we need to
264
       * keep the original ACE with
265
       * SEC_ACE_FLAG_INHERIT_ONLY.
266
       */
267
0
      expand_ace = desc_ace_has_generic(ace);
268
0
      if (expand_ace) {
269
0
        inherited_only = true;
270
0
      }
271
0
    } else {
272
      /*
273
       * If the ACE doesn't apply
274
       * to the current object,
275
       * we need to keep it with
276
       * SEC_ACE_FLAG_INHERIT_ONLY
277
       * in order to apply them to
278
       * grandchildren
279
       */
280
0
      inherited_only = true;
281
0
    }
282
283
0
    if (expand_ace) {
284
0
      tmp_acl->aces = talloc_realloc(tmp_acl,
285
0
                   tmp_acl->aces,
286
0
                   struct security_ace,
287
0
                   tmp_acl->num_aces+1);
288
0
      if (tmp_acl->aces == NULL) {
289
0
        TALLOC_FREE(tmp_acl);
290
0
        return NULL;
291
0
      }
292
293
0
      tmp_ace = &tmp_acl->aces[tmp_acl->num_aces];
294
0
      tmp_acl->num_aces++;
295
296
0
      *tmp_ace = *ace;
297
298
      /*
299
       * Expand generic access bits as well as special
300
       * sids.
301
       */
302
0
      desc_expand_generic(tmp_ace, owner, group);
303
304
      /*
305
       * Expanded ACEs are marked as inherited,
306
       * but never inherited any further to
307
       * grandchildren.
308
       */
309
0
      tmp_ace->flags |= SEC_ACE_FLAG_INHERITED_ACE;
310
0
      tmp_ace->flags &= ~SEC_ACE_FLAG_CONTAINER_INHERIT;
311
0
      tmp_ace->flags &= ~SEC_ACE_FLAG_OBJECT_INHERIT;
312
0
      tmp_ace->flags &= ~SEC_ACE_FLAG_NO_PROPAGATE_INHERIT;
313
314
      /*
315
       * Expanded ACEs never have an explicit
316
       * object class schemaId, so clear it
317
       * if present.
318
       */
319
0
      if (inherited_object != NULL) {
320
0
        tmp_ace->object.object.flags &= ~SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT;
321
0
      }
322
323
      /*
324
       * If the ACE had an explicit object class
325
       * schemaId, but no attribute/propertySet
326
       * we need to downgrade the _OBJECT variants
327
       * to the normal ones.
328
       */
329
0
      if (inherited_property == NULL) {
330
0
        switch (tmp_ace->type) {
331
0
        case SEC_ACE_TYPE_ACCESS_ALLOWED:
332
0
        case SEC_ACE_TYPE_ACCESS_DENIED:
333
0
        case SEC_ACE_TYPE_SYSTEM_AUDIT:
334
0
        case SEC_ACE_TYPE_SYSTEM_ALARM:
335
0
        case SEC_ACE_TYPE_ALLOWED_COMPOUND:
336
0
          break;
337
0
        case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
338
0
          tmp_ace->type = SEC_ACE_TYPE_ACCESS_ALLOWED;
339
0
          break;
340
0
        case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
341
0
          tmp_ace->type = SEC_ACE_TYPE_ACCESS_DENIED;
342
0
          break;
343
0
        case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
344
0
          tmp_ace->type = SEC_ACE_TYPE_SYSTEM_ALARM;
345
0
          break;
346
0
        case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
347
0
          tmp_ace->type = SEC_ACE_TYPE_SYSTEM_AUDIT;
348
0
          break;
349
0
        case SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT:
350
0
          tmp_ace->type = SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK;
351
0
          break;
352
0
        case SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT:
353
0
          tmp_ace->type = SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK;
354
0
          break;
355
0
        case SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT:
356
0
          tmp_ace->type = SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK;
357
0
          break;
358
0
        default:
359
          /*
360
           * SEC_ACE_TYPE_SYSTEM_ALARM_CALLBACK_OBJECT
361
           * is reserved.
362
           */
363
0
          break;
364
0
        }
365
0
      }
366
367
0
      if (expand_only) {
368
0
        continue;
369
0
      }
370
0
    }
371
372
0
    tmp_acl->aces = talloc_realloc(tmp_acl,
373
0
                 tmp_acl->aces,
374
0
                 struct security_ace,
375
0
                 tmp_acl->num_aces+1);
376
0
    if (tmp_acl->aces == NULL) {
377
0
      TALLOC_FREE(tmp_acl);
378
0
      return NULL;
379
0
    }
380
381
0
    tmp_ace = &tmp_acl->aces[tmp_acl->num_aces];
382
0
    tmp_acl->num_aces++;
383
384
0
    *tmp_ace = *ace;
385
0
    tmp_ace->flags |= SEC_ACE_FLAG_INHERITED_ACE;
386
387
0
    if (inherited_only) {
388
0
      tmp_ace->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
389
0
    } else {
390
0
      tmp_ace->flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;
391
0
    }
392
393
0
    if (ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
394
0
      tmp_ace->flags &= ~SEC_ACE_FLAG_CONTAINER_INHERIT;
395
0
      tmp_ace->flags &= ~SEC_ACE_FLAG_OBJECT_INHERIT;
396
0
      tmp_ace->flags &= ~SEC_ACE_FLAG_NO_PROPAGATE_INHERIT;
397
0
    }
398
0
  }
399
0
  if (tmp_acl->num_aces == 0) {
400
0
    TALLOC_FREE(tmp_acl);
401
0
    return NULL;
402
0
  }
403
0
  if (acl) {
404
0
    tmp_acl->revision = acl->revision;
405
0
  }
406
0
  return tmp_acl;
407
0
}
408
409
static struct security_acl *process_user_acl(TALLOC_CTX *mem_ctx,
410
               struct security_acl *acl,
411
               bool is_container,
412
               const struct dom_sid *owner,
413
               const struct dom_sid *group,
414
               struct GUID *object_list,
415
               bool is_protected)
416
0
{
417
0
  uint32_t i;
418
0
  TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
419
0
  struct security_acl *tmp_acl = talloc_zero(tmp_ctx, struct security_acl);
420
0
  struct security_acl *new_acl;
421
422
0
  if (!acl)
423
0
    return NULL;
424
425
0
  if (!tmp_acl)
426
0
    return NULL;
427
428
0
  tmp_acl->revision = acl->revision;
429
0
  DBG_DEBUG("acl revision %d\n", acl->revision);
430
431
0
  for (i=0; i < acl->num_aces; i++){
432
0
    struct security_ace *ace = &acl->aces[i];
433
    /* Remove ID flags from user-provided ACEs
434
     * if we break inheritance, ignore them otherwise */
435
0
    if (ace->flags & SEC_ACE_FLAG_INHERITED_ACE) {
436
0
      if (is_protected) {
437
0
        ace->flags &= ~SEC_ACE_FLAG_INHERITED_ACE;
438
0
      } else {
439
0
        continue;
440
0
      }
441
0
    }
442
443
0
    if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY &&
444
0
        !(ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT ||
445
0
          ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT))
446
0
      continue;
447
448
0
    tmp_acl->aces = talloc_realloc(tmp_acl,
449
0
                 tmp_acl->aces,
450
0
                 struct security_ace,
451
0
                 tmp_acl->num_aces+1);
452
0
    tmp_acl->aces[tmp_acl->num_aces] = *ace;
453
0
    tmp_acl->num_aces++;
454
0
    if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
455
0
      continue;
456
0
    }
457
    /* if the ACE contains CO, CG, GA, GE, GR or GW, and is inheritable
458
     * it has to be expanded to two aces, the original as IO,
459
     * and another one where these are translated */
460
0
    if (desc_ace_has_generic(ace)) {
461
0
      if (!(ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
462
0
        desc_expand_generic(&tmp_acl->aces[tmp_acl->num_aces-1],
463
0
                owner,
464
0
                group);
465
0
      } else {
466
        /*The original ACE becomes read only */
467
0
        tmp_acl->aces[tmp_acl->num_aces-1].flags |= SEC_ACE_FLAG_INHERIT_ONLY;
468
0
        tmp_acl->aces = talloc_realloc(tmp_acl, tmp_acl->aces,
469
0
                     struct security_ace,
470
0
                     tmp_acl->num_aces+1);
471
        /* add a new ACE with expanded generic info */
472
0
        tmp_acl->aces[tmp_acl->num_aces] = *ace;
473
0
        desc_expand_generic(&tmp_acl->aces[tmp_acl->num_aces],
474
0
                owner,
475
0
                group);
476
0
        tmp_acl->num_aces++;
477
0
      }
478
0
    }
479
0
  }
480
0
  new_acl = security_acl_dup(mem_ctx,tmp_acl);
481
482
0
  if (new_acl)
483
0
    new_acl->revision = acl->revision;
484
485
0
  talloc_free(tmp_ctx);
486
0
  return new_acl;
487
0
}
488
489
static void cr_descr_log_descriptor(struct security_descriptor *sd,
490
            const char *message,
491
            int level)
492
0
{
493
0
  if (sd) {
494
0
    DEBUG(level,("%s: %s\n", message,
495
0
           ndr_print_struct_string(0,(ndr_print_fn_t)ndr_print_security_descriptor,
496
0
                 "", sd)));
497
0
  }
498
0
  else {
499
0
    DEBUG(level,("%s: NULL\n", message));
500
0
  }
501
0
}
502
503
#if 0
504
static void cr_descr_log_acl(struct security_acl *acl,
505
            const char *message,
506
            int level)
507
{
508
  if (acl) {
509
    DEBUG(level,("%s: %s\n", message,
510
           ndr_print_struct_string(0,(ndr_print_fn_t)ndr_print_security_acl,
511
                 "", acl)));
512
  }
513
  else {
514
    DEBUG(level,("%s: NULL\n", message));
515
  }
516
}
517
#endif
518
519
static bool compute_acl(struct security_descriptor *parent_sd,
520
      struct security_descriptor *creator_sd,
521
      bool is_container,
522
      uint32_t inherit_flags,
523
      struct GUID *object_list,
524
      uint32_t (*generic_map)(uint32_t access_mask),
525
      struct security_token *token,
526
      struct security_descriptor *new_sd) /* INOUT argument */
527
0
{
528
0
  struct security_acl *user_dacl, *user_sacl, *inherited_dacl, *inherited_sacl;
529
0
  int level = 10;
530
531
0
  if (!parent_sd || !(inherit_flags & SEC_DACL_AUTO_INHERIT)) {
532
0
    inherited_dacl = NULL;
533
0
  } else if (creator_sd && (creator_sd->type & SEC_DESC_DACL_PROTECTED)) {
534
0
    inherited_dacl = NULL;
535
0
  } else {
536
0
    inherited_dacl = calculate_inherited_from_parent(new_sd,
537
0
                 parent_sd->dacl,
538
0
                 is_container,
539
0
                 new_sd->owner_sid,
540
0
                 new_sd->group_sid,
541
0
                 object_list);
542
0
  }
543
544
545
0
  if (!parent_sd || !(inherit_flags & SEC_SACL_AUTO_INHERIT)) {
546
0
    inherited_sacl = NULL;
547
0
  } else if (creator_sd && (creator_sd->type & SEC_DESC_SACL_PROTECTED)) {
548
0
    inherited_sacl = NULL;
549
0
  } else {
550
0
    inherited_sacl = calculate_inherited_from_parent(new_sd,
551
0
                 parent_sd->sacl,
552
0
                 is_container,
553
0
                 new_sd->owner_sid,
554
0
                 new_sd->group_sid,
555
0
                 object_list);
556
0
  }
557
558
0
  if (!creator_sd || (inherit_flags & SEC_DEFAULT_DESCRIPTOR)) {
559
0
    user_dacl = NULL;
560
0
    user_sacl = NULL;
561
0
  } else {
562
0
    user_dacl = process_user_acl(new_sd,
563
0
               creator_sd->dacl,
564
0
               is_container,
565
0
               new_sd->owner_sid,
566
0
               new_sd->group_sid,
567
0
               object_list,
568
0
               creator_sd->type & SEC_DESC_DACL_PROTECTED);
569
0
    user_sacl = process_user_acl(new_sd,
570
0
               creator_sd->sacl,
571
0
               is_container,
572
0
               new_sd->owner_sid,
573
0
               new_sd->group_sid,
574
0
               object_list,
575
0
               creator_sd->type & SEC_DESC_SACL_PROTECTED);
576
0
  }
577
0
  cr_descr_log_descriptor(parent_sd, __location__"parent_sd", level);
578
0
  cr_descr_log_descriptor(creator_sd,__location__ "creator_sd", level);
579
580
0
  new_sd->dacl = security_acl_concatenate(new_sd, user_dacl, inherited_dacl);
581
0
  if (new_sd->dacl) {
582
0
    new_sd->type |= SEC_DESC_DACL_PRESENT;
583
0
  }
584
0
  if (inherited_dacl) {
585
0
    new_sd->type |= SEC_DESC_DACL_AUTO_INHERITED;
586
0
  }
587
588
0
  new_sd->sacl = security_acl_concatenate(new_sd, user_sacl, inherited_sacl);
589
0
  if (new_sd->sacl) {
590
0
    new_sd->type |= SEC_DESC_SACL_PRESENT;
591
0
  }
592
0
  if (inherited_sacl) {
593
0
    new_sd->type |= SEC_DESC_SACL_AUTO_INHERITED;
594
0
  }
595
  /* This is a hack to handle the fact that
596
   * apprantly any AI flag provided by the user is preserved */
597
0
  if (creator_sd)
598
0
    new_sd->type |= creator_sd->type;
599
0
  cr_descr_log_descriptor(new_sd, __location__"final sd", level);
600
0
  return true;
601
0
}
602
603
struct security_descriptor *create_security_descriptor(
604
  TALLOC_CTX *mem_ctx,
605
  struct security_descriptor *parent_sd,
606
  struct security_descriptor *creator_sd,
607
  bool is_container,
608
  struct GUID *object_list,
609
  uint32_t inherit_flags,
610
  struct security_token *token,
611
  const struct dom_sid
612
    *default_owner, /* valid only for DS, NULL for the other RSs */
613
  const struct dom_sid
614
    *default_group, /* valid only for DS, NULL for the other RSs */
615
  uint32_t (*generic_map)(uint32_t access_mask))
616
0
{
617
0
  struct security_descriptor *new_sd;
618
0
  const struct dom_sid *new_owner = NULL;
619
0
  const struct dom_sid *new_group = NULL;
620
621
0
  new_sd = security_descriptor_initialise(mem_ctx);
622
0
  if (!new_sd) {
623
0
    return NULL;
624
0
  }
625
626
0
  if (!creator_sd || !creator_sd->owner_sid) {
627
0
    if ((inherit_flags & SEC_OWNER_FROM_PARENT) && parent_sd) {
628
0
      new_owner = parent_sd->owner_sid;
629
0
    } else if (!default_owner) {
630
0
      new_owner = &token->sids[PRIMARY_USER_SID_INDEX];
631
0
    } else {
632
0
      new_owner = default_owner;
633
0
      new_sd->type |= SEC_DESC_OWNER_DEFAULTED;
634
0
    }
635
0
  } else {
636
0
    new_owner = creator_sd->owner_sid;
637
0
  }
638
639
0
  if (!creator_sd || !creator_sd->group_sid){
640
0
    if ((inherit_flags & SEC_GROUP_FROM_PARENT) && parent_sd) {
641
0
      new_group = parent_sd->group_sid;
642
0
    } else if (!default_group && token->num_sids > PRIMARY_GROUP_SID_INDEX) {
643
0
      new_group = &token->sids[PRIMARY_GROUP_SID_INDEX];
644
0
    } else if (!default_group) {
645
      /* This will happen only for anonymous, which has no other groups */
646
0
      new_group = &token->sids[PRIMARY_USER_SID_INDEX];
647
0
    } else {
648
0
      new_group = default_group;
649
0
      new_sd->type |= SEC_DESC_GROUP_DEFAULTED;
650
0
    }
651
0
  } else {
652
0
    new_group = creator_sd->group_sid;
653
0
  }
654
655
0
  new_sd->owner_sid = dom_sid_dup(new_sd, new_owner);
656
0
  new_sd->group_sid = dom_sid_dup(new_sd, new_group);
657
0
  if (!new_sd->owner_sid || !new_sd->group_sid){
658
0
    talloc_free(new_sd);
659
0
    return NULL;
660
0
  }
661
662
0
  if (!compute_acl(parent_sd, creator_sd,
663
0
       is_container, inherit_flags, object_list,
664
0
       generic_map,token,new_sd)){
665
0
    talloc_free(new_sd);
666
0
    return NULL;
667
0
  }
668
669
0
  return new_sd;
670
0
}