Coverage Report

Created: 2026-09-03 07:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/libcli/security/security_descriptor.c
Line
Count
Source
1
/*
2
   Unix SMB/CIFS implementation.
3
4
   security descriptor utility functions
5
6
   Copyright (C) Andrew Tridgell    2004
7
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
*/
21
22
#include "replace.h"
23
#include "libcli/security/security.h"
24
#include "librpc/ndr/libndr.h"
25
#include "librpc/gen_ndr/ndr_security.h"
26
27
/*
28
  return a blank security descriptor (no owners, dacl or sacl)
29
*/
30
struct security_descriptor *security_descriptor_initialise(TALLOC_CTX *mem_ctx)
31
20.0k
{
32
20.0k
  struct security_descriptor *sd;
33
34
20.0k
  sd = talloc(mem_ctx, struct security_descriptor);
35
20.0k
  if (!sd) {
36
0
    return NULL;
37
0
  }
38
20.0k
  *sd = (struct security_descriptor){
39
20.0k
    .revision = SD_REVISION,
40
41
    /*
42
     * we mark as self relative, even though it isn't
43
     * while it remains a pointer in memory because this
44
     * simplifies the ndr code later.  All SDs that we
45
     * store/emit are in fact SELF_RELATIVE
46
     */
47
20.0k
    .type = SEC_DESC_SELF_RELATIVE,
48
20.0k
  };
49
50
20.0k
  return sd;
51
20.0k
}
52
53
struct security_acl *security_acl_dup(TALLOC_CTX *mem_ctx,
54
               const struct security_acl *oacl)
55
0
{
56
0
  struct security_acl *nacl;
57
0
  enum ndr_err_code ndr_err;
58
59
0
  if (oacl == NULL) {
60
0
    return NULL;
61
0
  }
62
63
0
  if (oacl->aces == NULL && oacl->num_aces > 0) {
64
0
    return NULL;
65
0
  }
66
67
0
  nacl = talloc (mem_ctx, struct security_acl);
68
0
  if (nacl == NULL) {
69
0
    return NULL;
70
0
  }
71
72
0
  ndr_err = ndr_deepcopy_struct(security_acl, oacl, nacl, nacl);
73
0
  if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
74
0
    goto failed;
75
0
  }
76
77
0
  return nacl;
78
79
0
 failed:
80
0
  talloc_free (nacl);
81
0
  return NULL;
82
83
0
}
84
85
struct security_acl *security_acl_concatenate(TALLOC_CTX *mem_ctx,
86
                                              const struct security_acl *acl1,
87
                                              const struct security_acl *acl2)
88
0
{
89
0
        struct security_acl *nacl;
90
0
        uint32_t i;
91
92
0
        if (!acl1 && !acl2)
93
0
                return NULL;
94
95
0
        if (!acl1){
96
0
                nacl = security_acl_dup(mem_ctx, acl2);
97
0
                return nacl;
98
0
        }
99
100
0
        if (!acl2){
101
0
                nacl = security_acl_dup(mem_ctx, acl1);
102
0
                return nacl;
103
0
        }
104
105
0
        nacl = talloc (mem_ctx, struct security_acl);
106
0
        if (nacl == NULL) {
107
0
                return NULL;
108
0
        }
109
110
0
        nacl->revision = acl1->revision;
111
0
        nacl->size = acl1->size + acl2->size;
112
0
        nacl->num_aces = acl1->num_aces + acl2->num_aces;
113
114
0
        if (nacl->num_aces == 0)
115
0
                return nacl;
116
117
0
        nacl->aces = (struct security_ace *)talloc_array (mem_ctx, struct security_ace, acl1->num_aces+acl2->num_aces);
118
0
        if ((nacl->aces == NULL) && (nacl->num_aces > 0)) {
119
0
                goto failed;
120
0
        }
121
122
0
        for (i = 0; i < acl1->num_aces; i++)
123
0
                nacl->aces[i] = acl1->aces[i];
124
0
        for (i = 0; i < acl2->num_aces; i++)
125
0
                nacl->aces[i + acl1->num_aces] = acl2->aces[i];
126
127
0
        return nacl;
128
129
0
 failed:
130
0
        talloc_free (nacl);
131
0
        return NULL;
132
133
0
}
134
135
/*
136
   talloc and copy a security descriptor
137
 */
138
struct security_descriptor *security_descriptor_copy(TALLOC_CTX *mem_ctx,
139
                 const struct security_descriptor *osd)
140
0
{
141
0
  struct security_descriptor *nsd;
142
143
0
  nsd = talloc_zero(mem_ctx, struct security_descriptor);
144
0
  if (!nsd) {
145
0
    return NULL;
146
0
  }
147
148
0
  if (osd->owner_sid) {
149
0
    nsd->owner_sid = dom_sid_dup(nsd, osd->owner_sid);
150
0
    if (nsd->owner_sid == NULL) {
151
0
      goto failed;
152
0
    }
153
0
  }
154
155
0
  if (osd->group_sid) {
156
0
    nsd->group_sid = dom_sid_dup(nsd, osd->group_sid);
157
0
    if (nsd->group_sid == NULL) {
158
0
      goto failed;
159
0
    }
160
0
  }
161
162
0
  if (osd->sacl) {
163
0
    nsd->sacl = security_acl_dup(nsd, osd->sacl);
164
0
    if (nsd->sacl == NULL) {
165
0
      goto failed;
166
0
    }
167
0
  }
168
169
0
  if (osd->dacl) {
170
0
    nsd->dacl = security_acl_dup(nsd, osd->dacl);
171
0
    if (nsd->dacl == NULL) {
172
0
      goto failed;
173
0
    }
174
0
  }
175
176
0
  nsd->revision = osd->revision;
177
0
  nsd->type = osd->type;
178
179
0
  return nsd;
180
181
0
 failed:
182
0
  talloc_free(nsd);
183
184
0
  return NULL;
185
0
}
186
187
NTSTATUS security_descriptor_for_client(TALLOC_CTX *mem_ctx,
188
          const struct security_descriptor *ssd,
189
          uint32_t sec_info,
190
          uint32_t access_granted,
191
          struct security_descriptor **_csd)
192
0
{
193
0
  struct security_descriptor *csd = NULL;
194
0
  uint32_t access_required = 0;
195
196
0
  *_csd = NULL;
197
198
0
  if (sec_info & (SECINFO_OWNER|SECINFO_GROUP)) {
199
0
    access_required |= SEC_STD_READ_CONTROL;
200
0
  }
201
0
  if (sec_info & SECINFO_DACL) {
202
0
    access_required |= SEC_STD_READ_CONTROL;
203
0
  }
204
0
  if (sec_info & SECINFO_SACL) {
205
0
    access_required |= SEC_FLAG_SYSTEM_SECURITY;
206
0
  }
207
208
0
  if (access_required & (~access_granted)) {
209
0
    return NT_STATUS_ACCESS_DENIED;
210
0
  }
211
212
  /*
213
   * make a copy...
214
   */
215
0
  csd = security_descriptor_copy(mem_ctx, ssd);
216
0
  if (csd == NULL) {
217
0
    return NT_STATUS_NO_MEMORY;
218
0
  }
219
220
  /*
221
   * ... and remove everything not wanted
222
   */
223
224
0
  if (!(sec_info & SECINFO_OWNER)) {
225
0
    TALLOC_FREE(csd->owner_sid);
226
0
    csd->type &= ~SEC_DESC_OWNER_DEFAULTED;
227
0
  }
228
0
  if (!(sec_info & SECINFO_GROUP)) {
229
0
    TALLOC_FREE(csd->group_sid);
230
0
    csd->type &= ~SEC_DESC_GROUP_DEFAULTED;
231
0
  }
232
0
  if (!(sec_info & SECINFO_DACL)) {
233
0
    TALLOC_FREE(csd->dacl);
234
0
    csd->type &= ~(
235
0
      SEC_DESC_DACL_PRESENT |
236
0
      SEC_DESC_DACL_DEFAULTED|
237
0
      SEC_DESC_DACL_AUTO_INHERIT_REQ |
238
0
      SEC_DESC_DACL_AUTO_INHERITED |
239
0
      SEC_DESC_DACL_PROTECTED |
240
0
      SEC_DESC_DACL_TRUSTED);
241
0
  }
242
0
  if (!(sec_info & SECINFO_SACL)) {
243
0
    TALLOC_FREE(csd->sacl);
244
0
    csd->type &= ~(
245
0
      SEC_DESC_SACL_PRESENT |
246
0
      SEC_DESC_SACL_DEFAULTED |
247
0
      SEC_DESC_SACL_AUTO_INHERIT_REQ |
248
0
      SEC_DESC_SACL_AUTO_INHERITED |
249
0
      SEC_DESC_SACL_PROTECTED |
250
0
      SEC_DESC_SERVER_SECURITY);
251
0
  }
252
253
0
  *_csd = csd;
254
0
  return NT_STATUS_OK;
255
0
}
256
257
/*
258
  add an ACE to an ACL of a security_descriptor
259
*/
260
261
static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd,
262
              bool add_to_sacl,
263
              const struct security_ace *ace,
264
              ssize_t _idx)
265
0
{
266
0
  struct security_acl *acl = NULL;
267
0
  ssize_t idx;
268
269
0
  if (add_to_sacl) {
270
0
    acl = sd->sacl;
271
0
  } else {
272
0
    acl = sd->dacl;
273
0
  }
274
275
0
  if (acl == NULL) {
276
0
    acl = talloc(sd, struct security_acl);
277
0
    if (acl == NULL) {
278
0
      return NT_STATUS_NO_MEMORY;
279
0
    }
280
0
    acl->revision = SECURITY_ACL_REVISION_NT4;
281
0
    acl->size     = 0;
282
0
    acl->num_aces = 0;
283
0
    acl->aces     = NULL;
284
0
  }
285
286
0
  if (_idx < 0) {
287
0
    idx = (acl->num_aces + 1) + _idx;
288
0
  } else {
289
0
    idx = _idx;
290
0
  }
291
292
0
  if (idx < 0) {
293
0
    return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
294
0
  }
295
0
  if (idx > acl->num_aces) {
296
0
    return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
297
0
  }
298
299
0
  acl->aces = talloc_realloc(acl, acl->aces,
300
0
           struct security_ace, acl->num_aces+1);
301
0
  if (acl->aces == NULL) {
302
0
    return NT_STATUS_NO_MEMORY;
303
0
  }
304
305
0
  ARRAY_INSERT_ELEMENT(acl->aces, acl->num_aces, *ace, idx);
306
0
  acl->num_aces++;
307
308
0
  if (sec_ace_object(acl->aces[idx].type)) {
309
0
    acl->revision = SECURITY_ACL_REVISION_ADS;
310
0
  }
311
312
0
  if (add_to_sacl) {
313
0
    sd->sacl = acl;
314
0
    sd->type |= SEC_DESC_SACL_PRESENT;
315
0
  } else {
316
0
    sd->dacl = acl;
317
0
    sd->type |= SEC_DESC_DACL_PRESENT;
318
0
  }
319
320
0
  return NT_STATUS_OK;
321
0
}
322
323
/*
324
  add an ACE to the SACL of a security_descriptor
325
*/
326
327
NTSTATUS security_descriptor_sacl_add(struct security_descriptor *sd,
328
              const struct security_ace *ace)
329
0
{
330
0
  return security_descriptor_acl_add(sd, true, ace, -1);
331
0
}
332
333
/*
334
  insert an ACE at a given index to the SACL of a security_descriptor
335
336
  idx can be negative, which means it's related to the new size from the
337
  end, so -1 means the ace is appended at the end.
338
*/
339
340
NTSTATUS security_descriptor_sacl_insert(struct security_descriptor *sd,
341
           const struct security_ace *ace,
342
           ssize_t idx)
343
0
{
344
0
  return security_descriptor_acl_add(sd, true, ace, idx);
345
0
}
346
347
/*
348
  add an ACE to the DACL of a security_descriptor
349
*/
350
351
NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd,
352
              const struct security_ace *ace)
353
0
{
354
0
  return security_descriptor_acl_add(sd, false, ace, -1);
355
0
}
356
357
/*
358
  insert an ACE at a given index to the DACL of a security_descriptor
359
360
  idx can be negative, which means it's related to the new size from the
361
  end, so -1 means the ace is appended at the end.
362
*/
363
364
NTSTATUS security_descriptor_dacl_insert(struct security_descriptor *sd,
365
           const struct security_ace *ace,
366
           ssize_t idx)
367
0
{
368
0
  return security_descriptor_acl_add(sd, false, ace, idx);
369
0
}
370
371
/*
372
  delete the ACE corresponding to the given trustee in an ACL of a
373
  security_descriptor
374
*/
375
376
static NTSTATUS security_descriptor_acl_del(struct security_descriptor *sd,
377
              bool sacl_del,
378
              const struct dom_sid *trustee)
379
0
{
380
0
  uint32_t i;
381
0
  bool found = false;
382
0
  struct security_acl *acl = NULL;
383
384
0
  if (sacl_del) {
385
0
    acl = sd->sacl;
386
0
  } else {
387
0
    acl = sd->dacl;
388
0
  }
389
390
0
  if (acl == NULL) {
391
0
    return NT_STATUS_OBJECT_NAME_NOT_FOUND;
392
0
  }
393
394
  /* there can be multiple ace's for one trustee */
395
396
0
  i = 0;
397
398
0
  while (i<acl->num_aces) {
399
0
    if (dom_sid_equal(trustee, &acl->aces[i].trustee)) {
400
0
      ARRAY_DEL_ELEMENT(acl->aces, i, acl->num_aces);
401
0
      acl->num_aces--;
402
0
      if (acl->num_aces == 0) {
403
0
        acl->aces = NULL;
404
0
      }
405
0
      found = true;
406
0
    } else {
407
0
      i += 1;
408
0
    }
409
0
  }
410
411
0
  if (!found) {
412
0
    return NT_STATUS_OBJECT_NAME_NOT_FOUND;
413
0
  }
414
415
0
  acl->revision = SECURITY_ACL_REVISION_NT4;
416
417
0
  for (i=0;i<acl->num_aces;i++) {
418
0
    if (sec_ace_object(acl->aces[i].type)) {
419
0
      acl->revision = SECURITY_ACL_REVISION_ADS;
420
0
      break;
421
0
    }
422
0
  }
423
424
0
  return NT_STATUS_OK;
425
0
}
426
427
/*
428
  delete the ACE corresponding to the given trustee in the DACL of a
429
  security_descriptor
430
*/
431
432
NTSTATUS security_descriptor_dacl_del(struct security_descriptor *sd,
433
              const struct dom_sid *trustee)
434
0
{
435
0
  return security_descriptor_acl_del(sd, false, trustee);
436
0
}
437
438
/*
439
  delete the ACE corresponding to the given trustee in the SACL of a
440
  security_descriptor
441
*/
442
443
NTSTATUS security_descriptor_sacl_del(struct security_descriptor *sd,
444
              const struct dom_sid *trustee)
445
0
{
446
0
  return security_descriptor_acl_del(sd, true, trustee);
447
0
}
448
449
/*
450
  delete the given ACE in the SACL or DACL of a security_descriptor
451
*/
452
static NTSTATUS security_descriptor_acl_del_ace(struct security_descriptor *sd,
453
            bool sacl_del,
454
            const struct security_ace *ace)
455
0
{
456
0
  uint32_t i;
457
0
  bool found = false;
458
0
  struct security_acl *acl = NULL;
459
460
0
  if (sacl_del) {
461
0
    acl = sd->sacl;
462
0
  } else {
463
0
    acl = sd->dacl;
464
0
  }
465
466
0
  if (acl == NULL) {
467
0
    return NT_STATUS_OBJECT_NAME_NOT_FOUND;
468
0
  }
469
470
0
  for (i=0;i<acl->num_aces;i++) {
471
0
    if (security_ace_equal(ace, &acl->aces[i])) {
472
0
      ARRAY_DEL_ELEMENT(acl->aces, i, acl->num_aces);
473
0
      acl->num_aces--;
474
0
      if (acl->num_aces == 0) {
475
0
        acl->aces = NULL;
476
0
      }
477
0
      found = true;
478
0
      i--;
479
0
    }
480
0
  }
481
482
0
  if (!found) {
483
0
    return NT_STATUS_OBJECT_NAME_NOT_FOUND;
484
0
  }
485
486
0
  acl->revision = SECURITY_ACL_REVISION_NT4;
487
488
0
  for (i=0;i<acl->num_aces;i++) {
489
0
    if (sec_ace_object(acl->aces[i].type)) {
490
0
      acl->revision = SECURITY_ACL_REVISION_ADS;
491
0
      break;
492
0
    }
493
0
  }
494
495
0
  return NT_STATUS_OK;
496
0
}
497
498
NTSTATUS security_descriptor_dacl_del_ace(struct security_descriptor *sd,
499
            const struct security_ace *ace)
500
0
{
501
0
  return security_descriptor_acl_del_ace(sd, false, ace);
502
0
}
503
504
NTSTATUS security_descriptor_sacl_del_ace(struct security_descriptor *sd,
505
            const struct security_ace *ace)
506
0
{
507
0
  return security_descriptor_acl_del_ace(sd, true, ace);
508
0
}
509
510
static bool security_ace_object_equal(const struct security_ace_object *object1,
511
              const struct security_ace_object *object2)
512
6.14k
{
513
6.14k
  if (object1 == object2) {
514
0
    return true;
515
0
  }
516
6.14k
  if ((object1 == NULL) || (object2 == NULL)) {
517
0
    return false;
518
0
  }
519
6.14k
  if (object1->flags != object2->flags) {
520
0
    return false;
521
0
  }
522
6.14k
  if (object1->flags & SEC_ACE_OBJECT_TYPE_PRESENT
523
486
      && !GUID_equal(&object1->type.type, &object2->type.type)) {
524
0
    return false;
525
0
  }
526
6.14k
  if (object1->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT
527
547
      && !GUID_equal(&object1->inherited_type.inherited_type,
528
547
         &object2->inherited_type.inherited_type)) {
529
0
    return false;
530
0
  }
531
532
6.14k
  return true;
533
6.14k
}
534
535
536
static bool security_ace_claim_equal(const struct CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 *claim1,
537
             const struct CLAIM_SECURITY_ATTRIBUTE_RELATIVE_V1 *claim2)
538
2.26k
{
539
2.26k
  uint32_t i;
540
541
2.26k
  if (claim1 == claim2) {
542
0
    return true;
543
0
  }
544
2.26k
  if (claim1 == NULL || claim2 == NULL) {
545
0
    return false;
546
0
  }
547
2.26k
  if (claim1->name != NULL && claim2->name != NULL) {
548
2.26k
    if (strcasecmp_m(claim1->name, claim2->name) != 0) {
549
0
      return false;
550
0
    }
551
2.26k
  } else if (claim1->name != NULL || claim2->name != NULL) {
552
0
    return false;
553
0
  }
554
2.26k
  if (claim1->value_type != claim2->value_type) {
555
0
    return false;
556
0
  }
557
2.26k
  if (claim1->flags != claim2->flags) {
558
0
    return false;
559
0
  }
560
2.26k
  if (claim1->value_count != claim2->value_count) {
561
0
    return false;
562
0
  }
563
17.4k
  for (i = 0; i < claim1->value_count; ++i) {
564
15.1k
    const union claim_values *values1 = claim1->values;
565
15.1k
    const union claim_values *values2 = claim2->values;
566
567
15.1k
    switch (claim1->value_type) {
568
1.19k
    case CLAIM_SECURITY_ATTRIBUTE_TYPE_INT64:
569
1.19k
      if (values1[i].int_value != NULL && values2[i].int_value != NULL) {
570
1.19k
        if (*values1[i].int_value != *values2[i].int_value) {
571
0
          return false;
572
0
        }
573
1.19k
      } else if (values1[i].int_value != NULL || values2[i].int_value != NULL) {
574
0
        return false;
575
0
      }
576
1.19k
      break;
577
8.05k
    case CLAIM_SECURITY_ATTRIBUTE_TYPE_UINT64:
578
8.05k
    case CLAIM_SECURITY_ATTRIBUTE_TYPE_BOOLEAN:
579
8.05k
      if (values1[i].uint_value != NULL && values2[i].uint_value != NULL) {
580
8.05k
        if (*values1[i].uint_value != *values2[i].uint_value) {
581
0
          return false;
582
0
        }
583
8.05k
      } else if (values1[i].uint_value != NULL || values2[i].uint_value != NULL) {
584
0
        return false;
585
0
      }
586
8.05k
      break;
587
8.05k
    case CLAIM_SECURITY_ATTRIBUTE_TYPE_STRING:
588
1.15k
      if (values1[i].string_value != NULL && values2[i].string_value != NULL) {
589
1.15k
        if (strcasecmp_m(values1[i].string_value, values2[i].string_value) != 0) {
590
0
          return false;
591
0
        }
592
1.15k
      } else if (values1[i].string_value != NULL || values2[i].string_value != NULL) {
593
0
        return false;
594
0
      }
595
1.15k
      break;
596
3.83k
    case CLAIM_SECURITY_ATTRIBUTE_TYPE_SID:
597
3.83k
      if (values1[i].sid_value != NULL && values2[i].sid_value != NULL) {
598
3.83k
        if (data_blob_cmp(values1[i].sid_value, values2[i].sid_value) != 0) {
599
0
          return false;
600
0
        }
601
3.83k
      } else if (values1[i].sid_value != NULL || values2[i].sid_value != NULL) {
602
0
        return false;
603
0
      }
604
3.83k
      break;
605
3.83k
    case CLAIM_SECURITY_ATTRIBUTE_TYPE_OCTET_STRING:
606
912
      if (values1[i].octet_value != NULL && values2[i].octet_value != NULL) {
607
912
        if (data_blob_cmp(values1[i].octet_value, values2[i].octet_value) != 0) {
608
0
          return false;
609
0
        }
610
912
      } else if (values1[i].octet_value != NULL || values2[i].octet_value != NULL) {
611
0
        return false;
612
0
      }
613
912
      break;
614
912
    default:
615
0
      break;
616
15.1k
    }
617
15.1k
  }
618
619
2.26k
  return true;
620
2.26k
}
621
622
/*
623
  compare two security ace structures
624
*/
625
bool security_ace_equal(const struct security_ace *ace1,
626
      const struct security_ace *ace2)
627
13.0k
{
628
13.0k
  if (ace1 == ace2) {
629
0
    return true;
630
0
  }
631
13.0k
  if ((ace1 == NULL) || (ace2 == NULL)) {
632
0
    return false;
633
0
  }
634
13.0k
  if (ace1->type != ace2->type) {
635
0
    return false;
636
0
  }
637
13.0k
  if (ace1->flags != ace2->flags) {
638
0
    return false;
639
0
  }
640
13.0k
  if (ace1->access_mask != ace2->access_mask) {
641
0
    return false;
642
0
  }
643
13.0k
  if (sec_ace_object(ace1->type) &&
644
6.14k
      !security_ace_object_equal(&ace1->object.object,
645
6.14k
               &ace2->object.object))
646
0
  {
647
0
    return false;
648
0
  }
649
13.0k
  if (!dom_sid_equal(&ace1->trustee, &ace2->trustee)) {
650
0
    return false;
651
0
  }
652
653
13.0k
  if (sec_ace_callback(ace1->type)) {
654
3.67k
    if (data_blob_cmp(&ace1->coda.conditions, &ace2->coda.conditions) != 0) {
655
0
      return false;
656
0
    }
657
9.40k
  } else if (sec_ace_resource(ace1->type)) {
658
2.26k
    if (!security_ace_claim_equal(&ace1->coda.claim, &ace2->coda.claim)) {
659
0
      return false;
660
0
    }
661
7.14k
  } else {
662
    /*
663
     * Don’t require ace1->coda.ignored to match ace2->coda.ignored.
664
     */
665
7.14k
  }
666
667
13.0k
  return true;
668
13.0k
}
669
670
671
/*
672
  compare two security acl structures
673
*/
674
bool security_acl_equal(const struct security_acl *acl1,
675
      const struct security_acl *acl2)
676
5.84k
{
677
5.84k
  uint32_t i;
678
679
5.84k
  if (acl1 == acl2) return true;
680
2.63k
  if (!acl1 || !acl2) return false;
681
2.63k
  if (acl1->revision != acl2->revision) return false;
682
2.63k
  if (acl1->num_aces != acl2->num_aces) return false;
683
684
15.7k
  for (i=0;i<acl1->num_aces;i++) {
685
13.0k
    if (!security_ace_equal(&acl1->aces[i], &acl2->aces[i])) return false;
686
13.0k
  }
687
2.63k
  return true;
688
2.63k
}
689
690
/*
691
  compare two security descriptors.
692
*/
693
bool security_descriptor_equal(const struct security_descriptor *sd1,
694
             const struct security_descriptor *sd2)
695
2.92k
{
696
2.92k
  if (sd1 == sd2) return true;
697
2.92k
  if (!sd1 || !sd2) return false;
698
2.92k
  if (sd1->revision != sd2->revision) return false;
699
2.92k
  if (sd1->type != sd2->type) return false;
700
701
2.92k
  if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return false;
702
2.92k
  if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return false;
703
2.92k
  if (!security_acl_equal(sd1->sacl, sd2->sacl))      return false;
704
2.92k
  if (!security_acl_equal(sd1->dacl, sd2->dacl))      return false;
705
706
2.92k
  return true;
707
2.92k
}
708
709
/*
710
  compare two security descriptors, but allow certain (missing) parts
711
  to be masked out of the comparison
712
*/
713
bool security_descriptor_mask_equal(const struct security_descriptor *sd1,
714
            const struct security_descriptor *sd2,
715
            uint32_t mask)
716
0
{
717
0
  if (sd1 == sd2) return true;
718
0
  if (!sd1 || !sd2) return false;
719
0
  if (sd1->revision != sd2->revision) return false;
720
0
  if ((sd1->type & mask) != (sd2->type & mask)) return false;
721
722
0
  if (!dom_sid_equal(sd1->owner_sid, sd2->owner_sid)) return false;
723
0
  if (!dom_sid_equal(sd1->group_sid, sd2->group_sid)) return false;
724
0
  if ((mask & SEC_DESC_DACL_PRESENT) && !security_acl_equal(sd1->dacl, sd2->dacl))      return false;
725
0
  if ((mask & SEC_DESC_SACL_PRESENT) && !security_acl_equal(sd1->sacl, sd2->sacl))      return false;
726
727
0
  return true;
728
0
}
729
730
731
static struct security_descriptor *security_descriptor_appendv(struct security_descriptor *sd,
732
                     bool add_ace_to_sacl,
733
                     va_list ap)
734
0
{
735
0
  const char *sidstr;
736
737
0
  while ((sidstr = va_arg(ap, const char *))) {
738
0
    struct dom_sid *sid;
739
0
    struct security_ace *ace = talloc_zero(sd, struct security_ace);
740
0
    NTSTATUS status;
741
742
0
    if (ace == NULL) {
743
0
      talloc_free(sd);
744
0
      return NULL;
745
0
    }
746
0
    ace->type = va_arg(ap, unsigned int);
747
0
    ace->access_mask = va_arg(ap, unsigned int);
748
0
    ace->flags = va_arg(ap, unsigned int);
749
0
    sid = dom_sid_parse_talloc(ace, sidstr);
750
0
    if (sid == NULL) {
751
0
      talloc_free(sd);
752
0
      return NULL;
753
0
    }
754
0
    ace->trustee = *sid;
755
0
    if (add_ace_to_sacl) {
756
0
      status = security_descriptor_sacl_add(sd, ace);
757
0
    } else {
758
0
      status = security_descriptor_dacl_add(sd, ace);
759
0
    }
760
    /* TODO: check: would talloc_free(ace) here be correct? */
761
0
    if (!NT_STATUS_IS_OK(status)) {
762
0
      talloc_free(sd);
763
0
      return NULL;
764
0
    }
765
0
  }
766
767
0
  return sd;
768
0
}
769
770
static struct security_descriptor *security_descriptor_createv(TALLOC_CTX *mem_ctx,
771
                     uint16_t sd_type,
772
                     const char *owner_sid,
773
                     const char *group_sid,
774
                     bool add_ace_to_sacl,
775
                     va_list ap)
776
0
{
777
0
  struct security_descriptor *sd;
778
779
0
  sd = security_descriptor_initialise(mem_ctx);
780
0
  if (sd == NULL) {
781
0
    return NULL;
782
0
  }
783
784
0
  sd->type |= sd_type;
785
786
0
  if (owner_sid) {
787
0
    sd->owner_sid = dom_sid_parse_talloc(sd, owner_sid);
788
0
    if (sd->owner_sid == NULL) {
789
0
      talloc_free(sd);
790
0
      return NULL;
791
0
    }
792
0
  }
793
0
  if (group_sid) {
794
0
    sd->group_sid = dom_sid_parse_talloc(sd, group_sid);
795
0
    if (sd->group_sid == NULL) {
796
0
      talloc_free(sd);
797
0
      return NULL;
798
0
    }
799
0
  }
800
801
0
  return security_descriptor_appendv(sd, add_ace_to_sacl, ap);
802
0
}
803
804
/*
805
  create a security descriptor using string SIDs. This is used by the
806
  torture code to allow the easy creation of complex ACLs
807
  This is a varargs function. The list of DACL ACEs ends with a NULL sid.
808
809
  Each ACE contains a set of 4 parameters:
810
  SID, ACCESS_TYPE, MASK, FLAGS
811
812
  a typical call would be:
813
814
    sd = security_descriptor_dacl_create(mem_ctx,
815
                                         sd_type_flags,
816
                                         mysid,
817
                                         mygroup,
818
                                         SID_NT_AUTHENTICATED_USERS,
819
                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
820
                                         SEC_FILE_ALL,
821
                                         SEC_ACE_FLAG_OBJECT_INHERIT,
822
                                         NULL);
823
  that would create a sd with one DACL ACE
824
*/
825
826
struct security_descriptor *security_descriptor_dacl_create(TALLOC_CTX *mem_ctx,
827
                  uint16_t sd_type,
828
                  const char *owner_sid,
829
                  const char *group_sid,
830
                  ...)
831
0
{
832
0
  struct security_descriptor *sd = NULL;
833
0
  va_list ap;
834
0
  va_start(ap, group_sid);
835
0
  sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid,
836
0
           group_sid, false, ap);
837
0
  va_end(ap);
838
839
0
  return sd;
840
0
}
841
842
struct security_descriptor *security_descriptor_sacl_create(TALLOC_CTX *mem_ctx,
843
                  uint16_t sd_type,
844
                  const char *owner_sid,
845
                  const char *group_sid,
846
                  ...)
847
0
{
848
0
  struct security_descriptor *sd = NULL;
849
0
  va_list ap;
850
0
  va_start(ap, group_sid);
851
0
  sd = security_descriptor_createv(mem_ctx, sd_type, owner_sid,
852
0
           group_sid, true, ap);
853
0
  va_end(ap);
854
855
0
  return sd;
856
0
}
857
858
struct security_ace *security_ace_create(TALLOC_CTX *mem_ctx,
859
           const char *sid_str,
860
           enum security_ace_type type,
861
           uint32_t access_mask,
862
           uint8_t flags)
863
864
0
{
865
0
  struct security_ace *ace;
866
0
  bool ok;
867
868
0
  ace = talloc_zero(mem_ctx, struct security_ace);
869
0
  if (ace == NULL) {
870
0
    return NULL;
871
0
  }
872
873
0
  ok = dom_sid_parse(sid_str, &ace->trustee);
874
0
  if (!ok) {
875
0
    talloc_free(ace);
876
0
    return NULL;
877
0
  }
878
0
  ace->type = type;
879
0
  ace->access_mask = access_mask;
880
0
  ace->flags = flags;
881
882
0
  return ace;
883
0
}
884
885
/*******************************************************************
886
 Check for MS NFS ACEs in a sd
887
*******************************************************************/
888
bool security_descriptor_with_ms_nfs(const struct security_descriptor *psd)
889
0
{
890
0
  uint32_t i;
891
892
0
  if (psd->dacl == NULL) {
893
0
    return false;
894
0
  }
895
896
0
  for (i = 0; i < psd->dacl->num_aces; i++) {
897
0
    if (dom_sid_compare_domain(
898
0
          &global_sid_Unix_NFS,
899
0
          &psd->dacl->aces[i].trustee) == 0) {
900
0
      return true;
901
0
    }
902
0
  }
903
904
0
  return false;
905
0
}