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