1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: Security Account Manager (SAM) Server
4 * FILE: reactos/dll/win32/samsrv/security.c
5 * PURPOSE: Security descriptor functions
6 *
7 * PROGRAMMERS: Eric Kohl
8 */
9
10 #include "samsrv.h"
11
12 /* GLOBALS *****************************************************************/
13
14 static SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
15 static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
16
17
18 /* FUNCTIONS ***************************************************************/
19
20 NTSTATUS
SampCreateServerSD(OUT PSECURITY_DESCRIPTOR * ServerSd,OUT PULONG Size)21 SampCreateServerSD(OUT PSECURITY_DESCRIPTOR *ServerSd,
22 OUT PULONG Size)
23 {
24 PSECURITY_DESCRIPTOR AbsSD = NULL;
25 PSECURITY_DESCRIPTOR RelSD = NULL;
26 PSID EveryoneSid = NULL;
27 PSID AnonymousSid = NULL;
28 PSID AdministratorsSid = NULL;
29 PACL Dacl = NULL;
30 PACL Sacl = NULL;
31 ULONG DaclSize;
32 ULONG SaclSize;
33 ULONG RelSDSize = 0;
34 NTSTATUS Status = STATUS_SUCCESS;
35
36
37 /* Create the Everyone SID */
38 Status = RtlAllocateAndInitializeSid(&WorldAuthority,
39 1,
40 SECURITY_WORLD_RID,
41 0,
42 0,
43 0,
44 0,
45 0,
46 0,
47 0,
48 &EveryoneSid);
49 ASSERT(NT_SUCCESS(Status));
50 if (!NT_SUCCESS(Status))
51 goto done;
52
53 /* Create the Anonymous SID */
54 Status = RtlAllocateAndInitializeSid(&NtAuthority,
55 1,
56 SECURITY_ANONYMOUS_LOGON_RID,
57 0,
58 0,
59 0,
60 0,
61 0,
62 0,
63 0,
64 &AnonymousSid);
65 ASSERT(NT_SUCCESS(Status));
66 if (!NT_SUCCESS(Status))
67 goto done;
68
69 /* Create the Administrators SID */
70 Status = RtlAllocateAndInitializeSid(&NtAuthority,
71 2,
72 SECURITY_BUILTIN_DOMAIN_RID,
73 DOMAIN_ALIAS_RID_ADMINS,
74 0,
75 0,
76 0,
77 0,
78 0,
79 0,
80 &AdministratorsSid);
81 ASSERT(NT_SUCCESS(Status));
82 if (!NT_SUCCESS(Status))
83 goto done;
84
85
86 /* Allocate a buffer for the absolute SD */
87 AbsSD = RtlAllocateHeap(RtlGetProcessHeap(),
88 HEAP_ZERO_MEMORY,
89 sizeof(SECURITY_DESCRIPTOR));
90 if (AbsSD == NULL)
91 {
92 Status = STATUS_INSUFFICIENT_RESOURCES;
93 ASSERT(Status == STATUS_SUCCESS);
94 goto done;
95 }
96
97 /* Create the absolute SD */
98 Status = RtlCreateSecurityDescriptor(AbsSD,
99 SECURITY_DESCRIPTOR_REVISION);
100 ASSERT(NT_SUCCESS(Status));
101 if (!NT_SUCCESS(Status))
102 goto done;
103
104 /* allocate and create the DACL */
105 DaclSize = sizeof(ACL) +
106 2 * sizeof(ACE) +
107 RtlLengthSid(EveryoneSid) +
108 RtlLengthSid(AdministratorsSid);
109
110 Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
111 HEAP_ZERO_MEMORY,
112 DaclSize);
113 if (Dacl == NULL)
114 {
115 Status = STATUS_INSUFFICIENT_RESOURCES;
116 ASSERT(Status == STATUS_SUCCESS);
117 goto done;
118 }
119
120 Status = RtlCreateAcl(Dacl,
121 DaclSize,
122 ACL_REVISION);
123 ASSERT(NT_SUCCESS(Status));
124 if (!NT_SUCCESS(Status))
125 goto done;
126
127 Status = RtlAddAccessAllowedAce(Dacl,
128 ACL_REVISION,
129 SAM_SERVER_READ | SAM_SERVER_EXECUTE,
130 EveryoneSid);
131 ASSERT(NT_SUCCESS(Status));
132 if (!NT_SUCCESS(Status))
133 goto done;
134
135 Status = RtlAddAccessAllowedAce(Dacl,
136 ACL_REVISION,
137 SAM_SERVER_ALL_ACCESS,
138 AdministratorsSid);
139 ASSERT(Status == STATUS_SUCCESS);
140 if (!NT_SUCCESS(Status))
141 goto done;
142
143 /* Set the DACL */
144 Status = RtlSetDaclSecurityDescriptor(AbsSD,
145 TRUE,
146 Dacl,
147 FALSE);
148 ASSERT(Status == STATUS_SUCCESS);
149 if (!NT_SUCCESS(Status))
150 goto done;
151
152 /* allocate and create the SACL */
153 SaclSize = sizeof(ACL) +
154 2 * sizeof(ACE) +
155 RtlLengthSid(EveryoneSid) +
156 RtlLengthSid(AnonymousSid);
157
158 Sacl = RtlAllocateHeap(RtlGetProcessHeap(),
159 HEAP_ZERO_MEMORY,
160 DaclSize);
161 if (Sacl == NULL)
162 {
163 Status = STATUS_INSUFFICIENT_RESOURCES;
164 ASSERT(Status == STATUS_SUCCESS);
165 goto done;
166 }
167
168 Status = RtlCreateAcl(Sacl,
169 SaclSize,
170 ACL_REVISION);
171 ASSERT(Status == STATUS_SUCCESS);
172 if (!NT_SUCCESS(Status))
173 goto done;
174
175 Status = RtlAddAuditAccessAce(Sacl,
176 ACL_REVISION,
177 ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE |
178 SAM_SERVER_CREATE_DOMAIN | SAM_SERVER_INITIALIZE |
179 SAM_SERVER_SHUTDOWN,
180 EveryoneSid,
181 TRUE,
182 TRUE);
183 ASSERT(Status == STATUS_SUCCESS);
184 if (!NT_SUCCESS(Status))
185 goto done;
186
187 Status = RtlAddAuditAccessAce(Sacl,
188 ACL_REVISION,
189 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
190 AnonymousSid,
191 TRUE,
192 TRUE);
193 ASSERT(Status == STATUS_SUCCESS);
194 if (!NT_SUCCESS(Status))
195 goto done;
196
197 /* Set the SACL */
198 Status = RtlSetSaclSecurityDescriptor(AbsSD,
199 TRUE,
200 Sacl,
201 FALSE);
202 ASSERT(Status == STATUS_SUCCESS);
203 if (!NT_SUCCESS(Status))
204 goto done;
205
206 /* Set the owner SID */
207 Status = RtlSetOwnerSecurityDescriptor(AbsSD,
208 AdministratorsSid,
209 FALSE);
210 ASSERT(Status == STATUS_SUCCESS);
211 if (!NT_SUCCESS(Status))
212 goto done;
213
214 /* Set the group SID */
215 Status = RtlSetGroupSecurityDescriptor(AbsSD,
216 AdministratorsSid,
217 FALSE);
218 ASSERT(Status == STATUS_SUCCESS);
219 if (!NT_SUCCESS(Status))
220 goto done;
221
222 /* Get the reqired buffer size for the self-relative SD */
223 Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
224 NULL,
225 &RelSDSize);
226 if (Status != STATUS_BUFFER_TOO_SMALL)
227 goto done;
228
229 /* Allocate a buffer for the self-relative SD */
230 RelSD = RtlAllocateHeap(RtlGetProcessHeap(),
231 HEAP_ZERO_MEMORY,
232 RelSDSize);
233 if (RelSD == NULL)
234 {
235 Status = STATUS_INSUFFICIENT_RESOURCES;
236 ASSERT(Status == STATUS_SUCCESS);
237 goto done;
238 }
239
240 /* Convert the absolute SD to self-relative format */
241 Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
242 RelSD,
243 &RelSDSize);
244 if (Status == STATUS_BUFFER_TOO_SMALL)
245 {
246 ASSERT(Status == STATUS_SUCCESS);
247 goto done;
248 }
249
250 *ServerSd = RelSD;
251 *Size = RelSDSize;
252
253 done:
254 if (!NT_SUCCESS(Status))
255 {
256 if (RelSD != NULL)
257 RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD);
258 }
259
260 if (EveryoneSid != NULL)
261 RtlFreeSid(EveryoneSid);
262
263 if (AnonymousSid != NULL)
264 RtlFreeSid(AnonymousSid);
265
266 if (AdministratorsSid != NULL)
267 RtlFreeSid(AdministratorsSid);
268
269 if (Dacl != NULL)
270 RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
271
272 if (Sacl != NULL)
273 RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl);
274
275 if (AbsSD != NULL)
276 RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD);
277
278 return Status;
279 }
280
281
282 NTSTATUS
SampCreateBuiltinDomainSD(OUT PSECURITY_DESCRIPTOR * ServerSd,OUT PULONG Size)283 SampCreateBuiltinDomainSD(OUT PSECURITY_DESCRIPTOR *ServerSd,
284 OUT PULONG Size)
285 {
286 PSECURITY_DESCRIPTOR AbsSD = NULL;
287 PSECURITY_DESCRIPTOR RelSD = NULL;
288 PSID EveryoneSid = NULL;
289 PSID AnonymousSid = NULL;
290 PSID AdministratorsSid = NULL;
291 PACL Dacl = NULL;
292 PACL Sacl = NULL;
293 ULONG DaclSize;
294 ULONG SaclSize;
295 ULONG RelSDSize = 0;
296 NTSTATUS Status = STATUS_SUCCESS;
297
298
299 /* Create the Everyone SID */
300 Status = RtlAllocateAndInitializeSid(&WorldAuthority,
301 1,
302 SECURITY_WORLD_RID,
303 0,
304 0,
305 0,
306 0,
307 0,
308 0,
309 0,
310 &EveryoneSid);
311 ASSERT(NT_SUCCESS(Status));
312 if (!NT_SUCCESS(Status))
313 goto done;
314
315 /* Create the Anonymous SID */
316 Status = RtlAllocateAndInitializeSid(&NtAuthority,
317 1,
318 SECURITY_ANONYMOUS_LOGON_RID,
319 0,
320 0,
321 0,
322 0,
323 0,
324 0,
325 0,
326 &AnonymousSid);
327 ASSERT(NT_SUCCESS(Status));
328 if (!NT_SUCCESS(Status))
329 goto done;
330
331 /* Create the Administrators SID */
332 Status = RtlAllocateAndInitializeSid(&NtAuthority,
333 2,
334 SECURITY_BUILTIN_DOMAIN_RID,
335 DOMAIN_ALIAS_RID_ADMINS,
336 0,
337 0,
338 0,
339 0,
340 0,
341 0,
342 &AdministratorsSid);
343 ASSERT(NT_SUCCESS(Status));
344 if (!NT_SUCCESS(Status))
345 goto done;
346
347
348 /* Allocate a buffer for the absolute SD */
349 AbsSD = RtlAllocateHeap(RtlGetProcessHeap(),
350 HEAP_ZERO_MEMORY,
351 sizeof(SECURITY_DESCRIPTOR));
352 if (AbsSD == NULL)
353 {
354 Status = STATUS_INSUFFICIENT_RESOURCES;
355 ASSERT(Status == STATUS_SUCCESS);
356 goto done;
357 }
358
359 /* Create the absolute SD */
360 Status = RtlCreateSecurityDescriptor(AbsSD,
361 SECURITY_DESCRIPTOR_REVISION);
362 ASSERT(NT_SUCCESS(Status));
363 if (!NT_SUCCESS(Status))
364 goto done;
365
366 /* allocate and create the DACL */
367 DaclSize = sizeof(ACL) +
368 2 * sizeof(ACE) +
369 RtlLengthSid(EveryoneSid) +
370 RtlLengthSid(AdministratorsSid);
371
372 Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
373 HEAP_ZERO_MEMORY,
374 DaclSize);
375 if (Dacl == NULL)
376 {
377 Status = STATUS_INSUFFICIENT_RESOURCES;
378 ASSERT(Status == STATUS_SUCCESS);
379 goto done;
380 }
381
382 Status = RtlCreateAcl(Dacl,
383 DaclSize,
384 ACL_REVISION);
385 ASSERT(NT_SUCCESS(Status));
386 if (!NT_SUCCESS(Status))
387 goto done;
388
389 Status = RtlAddAccessAllowedAce(Dacl,
390 ACL_REVISION,
391 DOMAIN_READ | DOMAIN_EXECUTE,
392 EveryoneSid);
393 ASSERT(NT_SUCCESS(Status));
394 if (!NT_SUCCESS(Status))
395 goto done;
396
397 Status = RtlAddAccessAllowedAce(Dacl,
398 ACL_REVISION,
399 SAM_SERVER_ALL_ACCESS,
400 AdministratorsSid);
401 ASSERT(Status == STATUS_SUCCESS);
402 if (!NT_SUCCESS(Status))
403 goto done;
404
405 /* Set the DACL */
406 Status = RtlSetDaclSecurityDescriptor(AbsSD,
407 TRUE,
408 Dacl,
409 FALSE);
410 ASSERT(Status == STATUS_SUCCESS);
411 if (!NT_SUCCESS(Status))
412 goto done;
413
414 /* allocate and create the SACL */
415 SaclSize = sizeof(ACL) +
416 2 * sizeof(ACE) +
417 RtlLengthSid(EveryoneSid) +
418 RtlLengthSid(AnonymousSid);
419
420 Sacl = RtlAllocateHeap(RtlGetProcessHeap(),
421 HEAP_ZERO_MEMORY,
422 DaclSize);
423 if (Sacl == NULL)
424 {
425 Status = STATUS_INSUFFICIENT_RESOURCES;
426 ASSERT(Status == STATUS_SUCCESS);
427 goto done;
428 }
429
430 Status = RtlCreateAcl(Sacl,
431 SaclSize,
432 ACL_REVISION);
433 ASSERT(Status == STATUS_SUCCESS);
434 if (!NT_SUCCESS(Status))
435 goto done;
436
437 Status = RtlAddAuditAccessAce(Sacl,
438 ACL_REVISION,
439 ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE |
440 SAM_SERVER_CREATE_DOMAIN | SAM_SERVER_INITIALIZE |
441 SAM_SERVER_SHUTDOWN,
442 EveryoneSid,
443 TRUE,
444 TRUE);
445 ASSERT(Status == STATUS_SUCCESS);
446 if (!NT_SUCCESS(Status))
447 goto done;
448
449 Status = RtlAddAuditAccessAce(Sacl,
450 ACL_REVISION,
451 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
452 AnonymousSid,
453 TRUE,
454 TRUE);
455 ASSERT(Status == STATUS_SUCCESS);
456 if (!NT_SUCCESS(Status))
457 goto done;
458
459 /* Set the SACL */
460 Status = RtlSetSaclSecurityDescriptor(AbsSD,
461 TRUE,
462 Sacl,
463 FALSE);
464 ASSERT(Status == STATUS_SUCCESS);
465 if (!NT_SUCCESS(Status))
466 goto done;
467
468 /* Set the owner SID */
469 Status = RtlSetOwnerSecurityDescriptor(AbsSD,
470 AdministratorsSid,
471 FALSE);
472 ASSERT(Status == STATUS_SUCCESS);
473 if (!NT_SUCCESS(Status))
474 goto done;
475
476 /* Set the group SID */
477 Status = RtlSetGroupSecurityDescriptor(AbsSD,
478 AdministratorsSid,
479 FALSE);
480 ASSERT(Status == STATUS_SUCCESS);
481 if (!NT_SUCCESS(Status))
482 goto done;
483
484 /* Get the reqired buffer size for the self-relative SD */
485 Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
486 NULL,
487 &RelSDSize);
488 if (Status != STATUS_BUFFER_TOO_SMALL)
489 goto done;
490
491 /* Allocate a buffer for the self-relative SD */
492 RelSD = RtlAllocateHeap(RtlGetProcessHeap(),
493 HEAP_ZERO_MEMORY,
494 RelSDSize);
495 if (RelSD == NULL)
496 {
497 Status = STATUS_INSUFFICIENT_RESOURCES;
498 ASSERT(Status == STATUS_SUCCESS);
499 goto done;
500 }
501
502 /* Convert the absolute SD to self-relative format */
503 Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
504 RelSD,
505 &RelSDSize);
506 if (Status == STATUS_BUFFER_TOO_SMALL)
507 {
508 ASSERT(Status == STATUS_SUCCESS);
509 goto done;
510 }
511
512 *ServerSd = RelSD;
513 *Size = RelSDSize;
514
515 done:
516 if (!NT_SUCCESS(Status))
517 {
518 if (RelSD != NULL)
519 RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD);
520 }
521
522 if (EveryoneSid != NULL)
523 RtlFreeSid(EveryoneSid);
524
525 if (AnonymousSid != NULL)
526 RtlFreeSid(AnonymousSid);
527
528 if (AdministratorsSid != NULL)
529 RtlFreeSid(AdministratorsSid);
530
531 if (Dacl != NULL)
532 RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
533
534 if (Sacl != NULL)
535 RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl);
536
537 if (AbsSD != NULL)
538 RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD);
539
540 return Status;
541 }
542
543
544 NTSTATUS
SampCreateAccountDomainSD(OUT PSECURITY_DESCRIPTOR * ServerSd,OUT PULONG Size)545 SampCreateAccountDomainSD(OUT PSECURITY_DESCRIPTOR *ServerSd,
546 OUT PULONG Size)
547 {
548 PSECURITY_DESCRIPTOR AbsSD = NULL;
549 PSECURITY_DESCRIPTOR RelSD = NULL;
550 PSID EveryoneSid = NULL;
551 PSID AnonymousSid = NULL;
552 PSID AdministratorsSid = NULL;
553 PSID UsersSid = NULL;
554 PSID GuestsSid = NULL;
555 PACL Dacl = NULL;
556 PACL Sacl = NULL;
557 ULONG DaclSize;
558 ULONG SaclSize;
559 ULONG RelSDSize = 0;
560 NTSTATUS Status = STATUS_SUCCESS;
561
562
563 /* Create the Everyone SID */
564 Status = RtlAllocateAndInitializeSid(&WorldAuthority,
565 1,
566 SECURITY_WORLD_RID,
567 0,
568 0,
569 0,
570 0,
571 0,
572 0,
573 0,
574 &EveryoneSid);
575 ASSERT(NT_SUCCESS(Status));
576 if (!NT_SUCCESS(Status))
577 goto done;
578
579 /* Create the Anonymous SID */
580 Status = RtlAllocateAndInitializeSid(&NtAuthority,
581 1,
582 SECURITY_ANONYMOUS_LOGON_RID,
583 0,
584 0,
585 0,
586 0,
587 0,
588 0,
589 0,
590 &AnonymousSid);
591 ASSERT(NT_SUCCESS(Status));
592 if (!NT_SUCCESS(Status))
593 goto done;
594
595 /* Create the Administrators SID */
596 Status = RtlAllocateAndInitializeSid(&NtAuthority,
597 2,
598 SECURITY_BUILTIN_DOMAIN_RID,
599 DOMAIN_ALIAS_RID_ADMINS,
600 0,
601 0,
602 0,
603 0,
604 0,
605 0,
606 &AdministratorsSid);
607 ASSERT(NT_SUCCESS(Status));
608 if (!NT_SUCCESS(Status))
609 goto done;
610
611 /* Create the Users SID */
612 Status = RtlAllocateAndInitializeSid(&NtAuthority,
613 2,
614 SECURITY_BUILTIN_DOMAIN_RID,
615 DOMAIN_ALIAS_RID_USERS,
616 0,
617 0,
618 0,
619 0,
620 0,
621 0,
622 &UsersSid);
623 ASSERT(NT_SUCCESS(Status));
624 if (!NT_SUCCESS(Status))
625 goto done;
626
627 /* Create the Guests SID */
628 Status = RtlAllocateAndInitializeSid(&NtAuthority,
629 2,
630 SECURITY_BUILTIN_DOMAIN_RID,
631 DOMAIN_ALIAS_RID_GUESTS,
632 0,
633 0,
634 0,
635 0,
636 0,
637 0,
638 &GuestsSid);
639 ASSERT(NT_SUCCESS(Status));
640 if (!NT_SUCCESS(Status))
641 goto done;
642
643
644 /* Allocate a buffer for the absolute SD */
645 AbsSD = RtlAllocateHeap(RtlGetProcessHeap(),
646 HEAP_ZERO_MEMORY,
647 sizeof(SECURITY_DESCRIPTOR));
648 if (AbsSD == NULL)
649 {
650 Status = STATUS_INSUFFICIENT_RESOURCES;
651 ASSERT(Status == STATUS_SUCCESS);
652 goto done;
653 }
654
655 /* Create the absolute SD */
656 Status = RtlCreateSecurityDescriptor(AbsSD,
657 SECURITY_DESCRIPTOR_REVISION);
658 ASSERT(NT_SUCCESS(Status));
659 if (!NT_SUCCESS(Status))
660 goto done;
661
662 /* allocate and create the DACL */
663 DaclSize = sizeof(ACL) +
664 4 * sizeof(ACE) +
665 RtlLengthSid(EveryoneSid) +
666 RtlLengthSid(AdministratorsSid) +
667 RtlLengthSid(UsersSid) +
668 RtlLengthSid(GuestsSid);
669
670 Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
671 HEAP_ZERO_MEMORY,
672 DaclSize);
673 if (Dacl == NULL)
674 {
675 Status = STATUS_INSUFFICIENT_RESOURCES;
676 ASSERT(Status == STATUS_SUCCESS);
677 goto done;
678 }
679
680 Status = RtlCreateAcl(Dacl,
681 DaclSize,
682 ACL_REVISION);
683 ASSERT(NT_SUCCESS(Status));
684 if (!NT_SUCCESS(Status))
685 goto done;
686
687 Status = RtlAddAccessAllowedAce(Dacl,
688 ACL_REVISION,
689 DOMAIN_READ | DOMAIN_EXECUTE,
690 EveryoneSid);
691 ASSERT(NT_SUCCESS(Status));
692 if (!NT_SUCCESS(Status))
693 goto done;
694
695 Status = RtlAddAccessAllowedAce(Dacl,
696 ACL_REVISION,
697 DOMAIN_READ | DOMAIN_EXECUTE,
698 UsersSid);
699 ASSERT(NT_SUCCESS(Status));
700 if (!NT_SUCCESS(Status))
701 goto done;
702
703 Status = RtlAddAccessAllowedAce(Dacl,
704 ACL_REVISION,
705 DOMAIN_ALL_ACCESS & ~DOMAIN_CREATE_GROUP,
706 AdministratorsSid);
707 ASSERT(Status == STATUS_SUCCESS);
708 if (!NT_SUCCESS(Status))
709 goto done;
710
711 Status = RtlAddAccessAllowedAce(Dacl,
712 ACL_REVISION,
713 DOMAIN_READ | DOMAIN_EXECUTE | DOMAIN_CREATE_USER | DOMAIN_CREATE_ALIAS,
714 GuestsSid);
715 ASSERT(Status == STATUS_SUCCESS);
716 if (!NT_SUCCESS(Status))
717 goto done;
718
719 /* Set the DACL */
720 Status = RtlSetDaclSecurityDescriptor(AbsSD,
721 TRUE,
722 Dacl,
723 FALSE);
724 ASSERT(Status == STATUS_SUCCESS);
725 if (!NT_SUCCESS(Status))
726 goto done;
727
728 /* allocate and create the SACL */
729 SaclSize = sizeof(ACL) +
730 2 * sizeof(ACE) +
731 RtlLengthSid(EveryoneSid) +
732 RtlLengthSid(AnonymousSid);
733
734 Sacl = RtlAllocateHeap(RtlGetProcessHeap(),
735 HEAP_ZERO_MEMORY,
736 DaclSize);
737 if (Sacl == NULL)
738 {
739 Status = STATUS_INSUFFICIENT_RESOURCES;
740 ASSERT(Status == STATUS_SUCCESS);
741 goto done;
742 }
743
744 Status = RtlCreateAcl(Sacl,
745 SaclSize,
746 ACL_REVISION);
747 ASSERT(Status == STATUS_SUCCESS);
748 if (!NT_SUCCESS(Status))
749 goto done;
750
751 Status = RtlAddAuditAccessAce(Sacl,
752 ACL_REVISION,
753 ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE |
754 SAM_SERVER_CREATE_DOMAIN | SAM_SERVER_INITIALIZE |
755 SAM_SERVER_SHUTDOWN,
756 EveryoneSid,
757 TRUE,
758 TRUE);
759 ASSERT(Status == STATUS_SUCCESS);
760 if (!NT_SUCCESS(Status))
761 goto done;
762
763 Status = RtlAddAuditAccessAce(Sacl,
764 ACL_REVISION,
765 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
766 AnonymousSid,
767 TRUE,
768 TRUE);
769 ASSERT(Status == STATUS_SUCCESS);
770 if (!NT_SUCCESS(Status))
771 goto done;
772
773 /* Set the SACL */
774 Status = RtlSetSaclSecurityDescriptor(AbsSD,
775 TRUE,
776 Sacl,
777 FALSE);
778 ASSERT(Status == STATUS_SUCCESS);
779 if (!NT_SUCCESS(Status))
780 goto done;
781
782 /* Set the owner SID */
783 Status = RtlSetOwnerSecurityDescriptor(AbsSD,
784 AdministratorsSid,
785 FALSE);
786 ASSERT(Status == STATUS_SUCCESS);
787 if (!NT_SUCCESS(Status))
788 goto done;
789
790 /* Set the group SID */
791 Status = RtlSetGroupSecurityDescriptor(AbsSD,
792 AdministratorsSid,
793 FALSE);
794 ASSERT(Status == STATUS_SUCCESS);
795 if (!NT_SUCCESS(Status))
796 goto done;
797
798 /* Get the reqired buffer size for the self-relative SD */
799 Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
800 NULL,
801 &RelSDSize);
802 if (Status != STATUS_BUFFER_TOO_SMALL)
803 goto done;
804
805 /* Allocate a buffer for the self-relative SD */
806 RelSD = RtlAllocateHeap(RtlGetProcessHeap(),
807 HEAP_ZERO_MEMORY,
808 RelSDSize);
809 if (RelSD == NULL)
810 {
811 Status = STATUS_INSUFFICIENT_RESOURCES;
812 ASSERT(Status == STATUS_SUCCESS);
813 goto done;
814 }
815
816 /* Convert the absolute SD to self-relative format */
817 Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
818 RelSD,
819 &RelSDSize);
820 if (Status == STATUS_BUFFER_TOO_SMALL)
821 {
822 ASSERT(Status == STATUS_SUCCESS);
823 goto done;
824 }
825
826 *ServerSd = RelSD;
827 *Size = RelSDSize;
828
829 done:
830 if (!NT_SUCCESS(Status))
831 {
832 if (RelSD != NULL)
833 RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD);
834 }
835
836 if (EveryoneSid != NULL)
837 RtlFreeSid(EveryoneSid);
838
839 if (AnonymousSid != NULL)
840 RtlFreeSid(AnonymousSid);
841
842 if (AdministratorsSid != NULL)
843 RtlFreeSid(AdministratorsSid);
844
845 if (Dacl != NULL)
846 RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
847
848 if (Sacl != NULL)
849 RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl);
850
851 if (AbsSD != NULL)
852 RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD);
853
854 return Status;
855 }
856
857
858 NTSTATUS
SampCreateAliasSD(OUT PSECURITY_DESCRIPTOR * AliasSd,OUT PULONG Size)859 SampCreateAliasSD(OUT PSECURITY_DESCRIPTOR *AliasSd,
860 OUT PULONG Size)
861 {
862 PSECURITY_DESCRIPTOR AbsSD = NULL;
863 PSECURITY_DESCRIPTOR RelSD = NULL;
864 PSID EveryoneSid = NULL;
865 PSID AnonymousSid = NULL;
866 PSID AdministratorsSid = NULL;
867 PSID AccountOperatorsSid = NULL;
868 PACL Dacl = NULL;
869 PACL Sacl = NULL;
870 ULONG DaclSize;
871 ULONG SaclSize;
872 ULONG RelSDSize = 0;
873 NTSTATUS Status = STATUS_SUCCESS;
874
875
876 /* Create the Everyone SID */
877 Status = RtlAllocateAndInitializeSid(&WorldAuthority,
878 1,
879 SECURITY_WORLD_RID,
880 0,
881 0,
882 0,
883 0,
884 0,
885 0,
886 0,
887 &EveryoneSid);
888 ASSERT(NT_SUCCESS(Status));
889 if (!NT_SUCCESS(Status))
890 goto done;
891
892 /* Create the Anonymous SID */
893 Status = RtlAllocateAndInitializeSid(&NtAuthority,
894 1,
895 SECURITY_ANONYMOUS_LOGON_RID,
896 0,
897 0,
898 0,
899 0,
900 0,
901 0,
902 0,
903 &AnonymousSid);
904 ASSERT(NT_SUCCESS(Status));
905 if (!NT_SUCCESS(Status))
906 goto done;
907
908 /* Create the Administrators SID */
909 Status = RtlAllocateAndInitializeSid(&NtAuthority,
910 2,
911 SECURITY_BUILTIN_DOMAIN_RID,
912 DOMAIN_ALIAS_RID_ADMINS,
913 0,
914 0,
915 0,
916 0,
917 0,
918 0,
919 &AdministratorsSid);
920 ASSERT(NT_SUCCESS(Status));
921 if (!NT_SUCCESS(Status))
922 goto done;
923
924 /* Create the Account Operators SID */
925 Status = RtlAllocateAndInitializeSid(&NtAuthority,
926 2,
927 SECURITY_BUILTIN_DOMAIN_RID,
928 DOMAIN_ALIAS_RID_ACCOUNT_OPS,
929 0,
930 0,
931 0,
932 0,
933 0,
934 0,
935 &AccountOperatorsSid);
936 ASSERT(NT_SUCCESS(Status));
937 if (!NT_SUCCESS(Status))
938 goto done;
939
940 /* Allocate a buffer for the absolute SD */
941 AbsSD = RtlAllocateHeap(RtlGetProcessHeap(),
942 HEAP_ZERO_MEMORY,
943 sizeof(SECURITY_DESCRIPTOR));
944 if (AbsSD == NULL)
945 {
946 Status = STATUS_INSUFFICIENT_RESOURCES;
947 ASSERT(Status == STATUS_SUCCESS);
948 goto done;
949 }
950
951 /* Create the absolute SD */
952 Status = RtlCreateSecurityDescriptor(AbsSD,
953 SECURITY_DESCRIPTOR_REVISION);
954 ASSERT(NT_SUCCESS(Status));
955 if (!NT_SUCCESS(Status))
956 goto done;
957
958 /* allocate and create the DACL */
959 DaclSize = sizeof(ACL) +
960 3 * sizeof(ACE) +
961 RtlLengthSid(EveryoneSid) +
962 RtlLengthSid(AdministratorsSid) +
963 RtlLengthSid(AccountOperatorsSid);
964
965 Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
966 HEAP_ZERO_MEMORY,
967 DaclSize);
968 if (Dacl == NULL)
969 {
970 Status = STATUS_INSUFFICIENT_RESOURCES;
971 ASSERT(Status == STATUS_SUCCESS);
972 goto done;
973 }
974
975 Status = RtlCreateAcl(Dacl,
976 DaclSize,
977 ACL_REVISION);
978 ASSERT(NT_SUCCESS(Status));
979 if (!NT_SUCCESS(Status))
980 goto done;
981
982 Status = RtlAddAccessAllowedAce(Dacl,
983 ACL_REVISION,
984 READ_CONTROL | ALIAS_READ_INFORMATION | ALIAS_LIST_MEMBERS,
985 EveryoneSid);
986 ASSERT(NT_SUCCESS(Status));
987 if (!NT_SUCCESS(Status))
988 goto done;
989
990 Status = RtlAddAccessAllowedAce(Dacl,
991 ACL_REVISION,
992 ALIAS_ALL_ACCESS,
993 AdministratorsSid);
994 ASSERT(Status == STATUS_SUCCESS);
995 if (!NT_SUCCESS(Status))
996 goto done;
997
998 Status = RtlAddAccessAllowedAce(Dacl,
999 ACL_REVISION,
1000 ALIAS_ALL_ACCESS,
1001 AccountOperatorsSid);
1002 ASSERT(Status == STATUS_SUCCESS);
1003 if (!NT_SUCCESS(Status))
1004 goto done;
1005
1006 /* Set the DACL */
1007 Status = RtlSetDaclSecurityDescriptor(AbsSD,
1008 TRUE,
1009 Dacl,
1010 FALSE);
1011 ASSERT(Status == STATUS_SUCCESS);
1012 if (!NT_SUCCESS(Status))
1013 goto done;
1014
1015 /* allocate and create the SACL */
1016 SaclSize = sizeof(ACL) +
1017 2 * sizeof(ACE) +
1018 RtlLengthSid(EveryoneSid) +
1019 RtlLengthSid(AnonymousSid);
1020
1021 Sacl = RtlAllocateHeap(RtlGetProcessHeap(),
1022 HEAP_ZERO_MEMORY,
1023 DaclSize);
1024 if (Sacl == NULL)
1025 {
1026 Status = STATUS_INSUFFICIENT_RESOURCES;
1027 ASSERT(Status == STATUS_SUCCESS);
1028 goto done;
1029 }
1030
1031 Status = RtlCreateAcl(Sacl,
1032 SaclSize,
1033 ACL_REVISION);
1034 ASSERT(Status == STATUS_SUCCESS);
1035 if (!NT_SUCCESS(Status))
1036 goto done;
1037
1038 Status = RtlAddAuditAccessAce(Sacl,
1039 ACL_REVISION,
1040 ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE |
1041 ALIAS_WRITE_ACCOUNT | ALIAS_REMOVE_MEMBER |
1042 ALIAS_ADD_MEMBER,
1043 EveryoneSid,
1044 TRUE,
1045 TRUE);
1046 ASSERT(Status == STATUS_SUCCESS);
1047 if (!NT_SUCCESS(Status))
1048 goto done;
1049
1050 Status = RtlAddAuditAccessAce(Sacl,
1051 ACL_REVISION,
1052 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
1053 AnonymousSid,
1054 TRUE,
1055 TRUE);
1056 ASSERT(Status == STATUS_SUCCESS);
1057 if (!NT_SUCCESS(Status))
1058 goto done;
1059
1060 /* Set the SACL */
1061 Status = RtlSetSaclSecurityDescriptor(AbsSD,
1062 TRUE,
1063 Sacl,
1064 FALSE);
1065 ASSERT(Status == STATUS_SUCCESS);
1066 if (!NT_SUCCESS(Status))
1067 goto done;
1068
1069 /* Set the owner SID */
1070 Status = RtlSetOwnerSecurityDescriptor(AbsSD,
1071 AdministratorsSid,
1072 FALSE);
1073 ASSERT(Status == STATUS_SUCCESS);
1074 if (!NT_SUCCESS(Status))
1075 goto done;
1076
1077 /* Set the group SID */
1078 Status = RtlSetGroupSecurityDescriptor(AbsSD,
1079 AdministratorsSid,
1080 FALSE);
1081 ASSERT(Status == STATUS_SUCCESS);
1082 if (!NT_SUCCESS(Status))
1083 goto done;
1084
1085 /* Get the reqired buffer size for the self-relative SD */
1086 Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
1087 NULL,
1088 &RelSDSize);
1089 if (Status != STATUS_BUFFER_TOO_SMALL)
1090 goto done;
1091
1092 /* Allocate a buffer for the self-relative SD */
1093 RelSD = RtlAllocateHeap(RtlGetProcessHeap(),
1094 HEAP_ZERO_MEMORY,
1095 RelSDSize);
1096 if (RelSD == NULL)
1097 {
1098 Status = STATUS_INSUFFICIENT_RESOURCES;
1099 ASSERT(Status == STATUS_SUCCESS);
1100 goto done;
1101 }
1102
1103 /* Convert the absolute SD to self-relative format */
1104 Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
1105 RelSD,
1106 &RelSDSize);
1107 if (Status == STATUS_BUFFER_TOO_SMALL)
1108 {
1109 ASSERT(Status == STATUS_SUCCESS);
1110 goto done;
1111 }
1112
1113 *AliasSd = RelSD;
1114 *Size = RelSDSize;
1115
1116 done:
1117 if (!NT_SUCCESS(Status))
1118 {
1119 if (RelSD != NULL)
1120 RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD);
1121 }
1122
1123 if (EveryoneSid != NULL)
1124 RtlFreeSid(EveryoneSid);
1125
1126 if (AnonymousSid != NULL)
1127 RtlFreeSid(AnonymousSid);
1128
1129 if (AdministratorsSid != NULL)
1130 RtlFreeSid(AdministratorsSid);
1131
1132 if (Dacl != NULL)
1133 RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
1134
1135 if (Sacl != NULL)
1136 RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl);
1137
1138 if (AbsSD != NULL)
1139 RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD);
1140
1141 return Status;
1142 }
1143
1144
1145 NTSTATUS
SampCreateGroupSD(OUT PSECURITY_DESCRIPTOR * GroupSd,OUT PULONG Size)1146 SampCreateGroupSD(OUT PSECURITY_DESCRIPTOR *GroupSd,
1147 OUT PULONG Size)
1148 {
1149 PSECURITY_DESCRIPTOR AbsSD = NULL;
1150 PSECURITY_DESCRIPTOR RelSD = NULL;
1151 PSID EveryoneSid = NULL;
1152 PSID AnonymousSid = NULL;
1153 PSID AdministratorsSid = NULL;
1154 PSID AccountOperatorsSid = NULL;
1155 PACL Dacl = NULL;
1156 PACL Sacl = NULL;
1157 ULONG DaclSize;
1158 ULONG SaclSize;
1159 ULONG RelSDSize = 0;
1160 NTSTATUS Status = STATUS_SUCCESS;
1161
1162
1163 /* Create the Everyone SID */
1164 Status = RtlAllocateAndInitializeSid(&WorldAuthority,
1165 1,
1166 SECURITY_WORLD_RID,
1167 0,
1168 0,
1169 0,
1170 0,
1171 0,
1172 0,
1173 0,
1174 &EveryoneSid);
1175 ASSERT(NT_SUCCESS(Status));
1176 if (!NT_SUCCESS(Status))
1177 goto done;
1178
1179 /* Create the Anonymous SID */
1180 Status = RtlAllocateAndInitializeSid(&NtAuthority,
1181 1,
1182 SECURITY_ANONYMOUS_LOGON_RID,
1183 0,
1184 0,
1185 0,
1186 0,
1187 0,
1188 0,
1189 0,
1190 &AnonymousSid);
1191 ASSERT(NT_SUCCESS(Status));
1192 if (!NT_SUCCESS(Status))
1193 goto done;
1194
1195 /* Create the Administrators SID */
1196 Status = RtlAllocateAndInitializeSid(&NtAuthority,
1197 2,
1198 SECURITY_BUILTIN_DOMAIN_RID,
1199 DOMAIN_ALIAS_RID_ADMINS,
1200 0,
1201 0,
1202 0,
1203 0,
1204 0,
1205 0,
1206 &AdministratorsSid);
1207 ASSERT(NT_SUCCESS(Status));
1208 if (!NT_SUCCESS(Status))
1209 goto done;
1210
1211 /* Create the Account Operators SID */
1212 Status = RtlAllocateAndInitializeSid(&NtAuthority,
1213 2,
1214 SECURITY_BUILTIN_DOMAIN_RID,
1215 DOMAIN_ALIAS_RID_ACCOUNT_OPS,
1216 0,
1217 0,
1218 0,
1219 0,
1220 0,
1221 0,
1222 &AccountOperatorsSid);
1223 ASSERT(NT_SUCCESS(Status));
1224 if (!NT_SUCCESS(Status))
1225 goto done;
1226
1227 /* Allocate a buffer for the absolute SD */
1228 AbsSD = RtlAllocateHeap(RtlGetProcessHeap(),
1229 HEAP_ZERO_MEMORY,
1230 sizeof(SECURITY_DESCRIPTOR));
1231 if (AbsSD == NULL)
1232 {
1233 Status = STATUS_INSUFFICIENT_RESOURCES;
1234 ASSERT(Status == STATUS_SUCCESS);
1235 goto done;
1236 }
1237
1238 /* Create the absolute SD */
1239 Status = RtlCreateSecurityDescriptor(AbsSD,
1240 SECURITY_DESCRIPTOR_REVISION);
1241 ASSERT(NT_SUCCESS(Status));
1242 if (!NT_SUCCESS(Status))
1243 goto done;
1244
1245 /* allocate and create the DACL */
1246 DaclSize = sizeof(ACL) +
1247 3 * sizeof(ACE) +
1248 RtlLengthSid(EveryoneSid) +
1249 RtlLengthSid(AdministratorsSid) +
1250 RtlLengthSid(AccountOperatorsSid);
1251
1252 Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
1253 HEAP_ZERO_MEMORY,
1254 DaclSize);
1255 if (Dacl == NULL)
1256 {
1257 Status = STATUS_INSUFFICIENT_RESOURCES;
1258 ASSERT(Status == STATUS_SUCCESS);
1259 goto done;
1260 }
1261
1262 Status = RtlCreateAcl(Dacl,
1263 DaclSize,
1264 ACL_REVISION);
1265 ASSERT(NT_SUCCESS(Status));
1266 if (!NT_SUCCESS(Status))
1267 goto done;
1268
1269 Status = RtlAddAccessAllowedAce(Dacl,
1270 ACL_REVISION,
1271 READ_CONTROL | GROUP_LIST_MEMBERS | GROUP_READ_INFORMATION,
1272 EveryoneSid);
1273 ASSERT(NT_SUCCESS(Status));
1274 if (!NT_SUCCESS(Status))
1275 goto done;
1276
1277 Status = RtlAddAccessAllowedAce(Dacl,
1278 ACL_REVISION,
1279 GROUP_ALL_ACCESS,
1280 AdministratorsSid);
1281 ASSERT(Status == STATUS_SUCCESS);
1282 if (!NT_SUCCESS(Status))
1283 goto done;
1284
1285 Status = RtlAddAccessAllowedAce(Dacl,
1286 ACL_REVISION,
1287 GROUP_ALL_ACCESS,
1288 AccountOperatorsSid);
1289 ASSERT(Status == STATUS_SUCCESS);
1290 if (!NT_SUCCESS(Status))
1291 goto done;
1292
1293 /* Set the DACL */
1294 Status = RtlSetDaclSecurityDescriptor(AbsSD,
1295 TRUE,
1296 Dacl,
1297 FALSE);
1298 ASSERT(Status == STATUS_SUCCESS);
1299 if (!NT_SUCCESS(Status))
1300 goto done;
1301
1302 /* allocate and create the SACL */
1303 SaclSize = sizeof(ACL) +
1304 2 * sizeof(ACE) +
1305 RtlLengthSid(EveryoneSid) +
1306 RtlLengthSid(AnonymousSid);
1307
1308 Sacl = RtlAllocateHeap(RtlGetProcessHeap(),
1309 HEAP_ZERO_MEMORY,
1310 DaclSize);
1311 if (Sacl == NULL)
1312 {
1313 Status = STATUS_INSUFFICIENT_RESOURCES;
1314 ASSERT(Status == STATUS_SUCCESS);
1315 goto done;
1316 }
1317
1318 Status = RtlCreateAcl(Sacl,
1319 SaclSize,
1320 ACL_REVISION);
1321 ASSERT(Status == STATUS_SUCCESS);
1322 if (!NT_SUCCESS(Status))
1323 goto done;
1324
1325 Status = RtlAddAuditAccessAce(Sacl,
1326 ACL_REVISION,
1327 ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE |
1328 GROUP_REMOVE_MEMBER | GROUP_ADD_MEMBER |
1329 GROUP_WRITE_ACCOUNT,
1330 EveryoneSid,
1331 TRUE,
1332 TRUE);
1333 ASSERT(Status == STATUS_SUCCESS);
1334 if (!NT_SUCCESS(Status))
1335 goto done;
1336
1337 Status = RtlAddAuditAccessAce(Sacl,
1338 ACL_REVISION,
1339 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
1340 AnonymousSid,
1341 TRUE,
1342 TRUE);
1343 ASSERT(Status == STATUS_SUCCESS);
1344 if (!NT_SUCCESS(Status))
1345 goto done;
1346
1347 /* Set the SACL */
1348 Status = RtlSetSaclSecurityDescriptor(AbsSD,
1349 TRUE,
1350 Sacl,
1351 FALSE);
1352 ASSERT(Status == STATUS_SUCCESS);
1353 if (!NT_SUCCESS(Status))
1354 goto done;
1355
1356 /* Set the owner SID */
1357 Status = RtlSetOwnerSecurityDescriptor(AbsSD,
1358 AdministratorsSid,
1359 FALSE);
1360 ASSERT(Status == STATUS_SUCCESS);
1361 if (!NT_SUCCESS(Status))
1362 goto done;
1363
1364 /* Set the group SID */
1365 Status = RtlSetGroupSecurityDescriptor(AbsSD,
1366 AdministratorsSid,
1367 FALSE);
1368 ASSERT(Status == STATUS_SUCCESS);
1369 if (!NT_SUCCESS(Status))
1370 goto done;
1371
1372 /* Get the reqired buffer size for the self-relative SD */
1373 Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
1374 NULL,
1375 &RelSDSize);
1376 if (Status != STATUS_BUFFER_TOO_SMALL)
1377 goto done;
1378
1379 /* Allocate a buffer for the self-relative SD */
1380 RelSD = RtlAllocateHeap(RtlGetProcessHeap(),
1381 HEAP_ZERO_MEMORY,
1382 RelSDSize);
1383 if (RelSD == NULL)
1384 {
1385 Status = STATUS_INSUFFICIENT_RESOURCES;
1386 ASSERT(Status == STATUS_SUCCESS);
1387 goto done;
1388 }
1389
1390 /* Convert the absolute SD to self-relative format */
1391 Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
1392 RelSD,
1393 &RelSDSize);
1394 if (Status == STATUS_BUFFER_TOO_SMALL)
1395 {
1396 ASSERT(Status == STATUS_SUCCESS);
1397 goto done;
1398 }
1399
1400 *GroupSd = RelSD;
1401 *Size = RelSDSize;
1402
1403 done:
1404 if (!NT_SUCCESS(Status))
1405 {
1406 if (RelSD != NULL)
1407 RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD);
1408 }
1409
1410 if (EveryoneSid != NULL)
1411 RtlFreeSid(EveryoneSid);
1412
1413 if (AnonymousSid != NULL)
1414 RtlFreeSid(AnonymousSid);
1415
1416 if (AdministratorsSid != NULL)
1417 RtlFreeSid(AdministratorsSid);
1418
1419 if (Dacl != NULL)
1420 RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
1421
1422 if (Sacl != NULL)
1423 RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl);
1424
1425 if (AbsSD != NULL)
1426 RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD);
1427
1428 return Status;
1429 }
1430
1431
1432 NTSTATUS
SampCreateUserSD(IN PSID UserSid,OUT PSECURITY_DESCRIPTOR * UserSd,OUT PULONG Size)1433 SampCreateUserSD(IN PSID UserSid,
1434 OUT PSECURITY_DESCRIPTOR *UserSd,
1435 OUT PULONG Size)
1436 {
1437 PSECURITY_DESCRIPTOR AbsSD = NULL;
1438 PSECURITY_DESCRIPTOR RelSD = NULL;
1439 PSID EveryoneSid = NULL;
1440 PSID AnonymousSid = NULL;
1441 PSID AdministratorsSid = NULL;
1442 PACL Dacl = NULL;
1443 PACL Sacl = NULL;
1444 ULONG DaclSize;
1445 ULONG SaclSize;
1446 ULONG RelSDSize = 0;
1447 NTSTATUS Status = STATUS_SUCCESS;
1448
1449
1450 /* Create the Everyone SID */
1451 Status = RtlAllocateAndInitializeSid(&WorldAuthority,
1452 1,
1453 SECURITY_WORLD_RID,
1454 0,
1455 0,
1456 0,
1457 0,
1458 0,
1459 0,
1460 0,
1461 &EveryoneSid);
1462 ASSERT(NT_SUCCESS(Status));
1463 if (!NT_SUCCESS(Status))
1464 goto done;
1465
1466 /* Create the Anonymous SID */
1467 Status = RtlAllocateAndInitializeSid(&NtAuthority,
1468 1,
1469 SECURITY_ANONYMOUS_LOGON_RID,
1470 0,
1471 0,
1472 0,
1473 0,
1474 0,
1475 0,
1476 0,
1477 &AnonymousSid);
1478 ASSERT(NT_SUCCESS(Status));
1479 if (!NT_SUCCESS(Status))
1480 goto done;
1481
1482 /* Create the Administrators SID */
1483 Status = RtlAllocateAndInitializeSid(&NtAuthority,
1484 2,
1485 SECURITY_BUILTIN_DOMAIN_RID,
1486 DOMAIN_ALIAS_RID_ADMINS,
1487 0,
1488 0,
1489 0,
1490 0,
1491 0,
1492 0,
1493 &AdministratorsSid);
1494 ASSERT(NT_SUCCESS(Status));
1495 if (!NT_SUCCESS(Status))
1496 goto done;
1497
1498 /* Allocate a buffer for the absolute SD */
1499 AbsSD = RtlAllocateHeap(RtlGetProcessHeap(),
1500 HEAP_ZERO_MEMORY,
1501 sizeof(SECURITY_DESCRIPTOR));
1502 if (AbsSD == NULL)
1503 {
1504 Status = STATUS_INSUFFICIENT_RESOURCES;
1505 ASSERT(Status == STATUS_SUCCESS);
1506 goto done;
1507 }
1508
1509 /* Create the absolute SD */
1510 Status = RtlCreateSecurityDescriptor(AbsSD,
1511 SECURITY_DESCRIPTOR_REVISION);
1512 ASSERT(NT_SUCCESS(Status));
1513 if (!NT_SUCCESS(Status))
1514 goto done;
1515
1516 /* allocate and create the DACL */
1517 DaclSize = sizeof(ACL) +
1518 3 * sizeof(ACE) +
1519 RtlLengthSid(EveryoneSid) +
1520 RtlLengthSid(AdministratorsSid) +
1521 RtlLengthSid(UserSid);
1522
1523 Dacl = RtlAllocateHeap(RtlGetProcessHeap(),
1524 HEAP_ZERO_MEMORY,
1525 DaclSize);
1526 if (Dacl == NULL)
1527 {
1528 Status = STATUS_INSUFFICIENT_RESOURCES;
1529 ASSERT(Status == STATUS_SUCCESS);
1530 goto done;
1531 }
1532
1533 Status = RtlCreateAcl(Dacl,
1534 DaclSize,
1535 ACL_REVISION);
1536 ASSERT(NT_SUCCESS(Status));
1537 if (!NT_SUCCESS(Status))
1538 goto done;
1539
1540 Status = RtlAddAccessAllowedAce(Dacl,
1541 ACL_REVISION,
1542 READ_CONTROL | USER_READ_GROUP_INFORMATION | USER_LIST_GROUPS |
1543 USER_CHANGE_PASSWORD | USER_READ_ACCOUNT | USER_READ_LOGON |
1544 USER_READ_PREFERENCES | USER_READ_GENERAL,
1545 EveryoneSid);
1546 ASSERT(NT_SUCCESS(Status));
1547 if (!NT_SUCCESS(Status))
1548 goto done;
1549
1550 Status = RtlAddAccessAllowedAce(Dacl,
1551 ACL_REVISION,
1552 USER_ALL_ACCESS,
1553 AdministratorsSid);
1554 ASSERT(Status == STATUS_SUCCESS);
1555 if (!NT_SUCCESS(Status))
1556 goto done;
1557
1558 Status = RtlAddAccessAllowedAce(Dacl,
1559 ACL_REVISION,
1560 READ_CONTROL | USER_CHANGE_PASSWORD | USER_WRITE_PREFERENCES,
1561 UserSid);
1562 ASSERT(Status == STATUS_SUCCESS);
1563 if (!NT_SUCCESS(Status))
1564 goto done;
1565
1566 /* Set the DACL */
1567 Status = RtlSetDaclSecurityDescriptor(AbsSD,
1568 TRUE,
1569 Dacl,
1570 FALSE);
1571 ASSERT(Status == STATUS_SUCCESS);
1572 if (!NT_SUCCESS(Status))
1573 goto done;
1574
1575 /* allocate and create the SACL */
1576 SaclSize = sizeof(ACL) +
1577 2 * sizeof(ACE) +
1578 RtlLengthSid(EveryoneSid) +
1579 RtlLengthSid(AnonymousSid);
1580
1581 Sacl = RtlAllocateHeap(RtlGetProcessHeap(),
1582 HEAP_ZERO_MEMORY,
1583 DaclSize);
1584 if (Sacl == NULL)
1585 {
1586 Status = STATUS_INSUFFICIENT_RESOURCES;
1587 ASSERT(Status == STATUS_SUCCESS);
1588 goto done;
1589 }
1590
1591 Status = RtlCreateAcl(Sacl,
1592 SaclSize,
1593 ACL_REVISION);
1594 ASSERT(Status == STATUS_SUCCESS);
1595 if (!NT_SUCCESS(Status))
1596 goto done;
1597
1598 Status = RtlAddAuditAccessAce(Sacl,
1599 ACL_REVISION,
1600 ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE |
1601 USER_CHANGE_PASSWORD | USER_WRITE_PREFERENCES,
1602 EveryoneSid,
1603 TRUE,
1604 TRUE);
1605 ASSERT(Status == STATUS_SUCCESS);
1606 if (!NT_SUCCESS(Status))
1607 goto done;
1608
1609 Status = RtlAddAuditAccessAce(Sacl,
1610 ACL_REVISION,
1611 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
1612 AnonymousSid,
1613 TRUE,
1614 TRUE);
1615 ASSERT(Status == STATUS_SUCCESS);
1616 if (!NT_SUCCESS(Status))
1617 goto done;
1618
1619 /* Set the SACL */
1620 Status = RtlSetSaclSecurityDescriptor(AbsSD,
1621 TRUE,
1622 Sacl,
1623 FALSE);
1624 ASSERT(Status == STATUS_SUCCESS);
1625 if (!NT_SUCCESS(Status))
1626 goto done;
1627
1628 /* Set the owner SID */
1629 Status = RtlSetOwnerSecurityDescriptor(AbsSD,
1630 AdministratorsSid,
1631 FALSE);
1632 ASSERT(Status == STATUS_SUCCESS);
1633 if (!NT_SUCCESS(Status))
1634 goto done;
1635
1636 /* Set the group SID */
1637 Status = RtlSetGroupSecurityDescriptor(AbsSD,
1638 AdministratorsSid,
1639 FALSE);
1640 ASSERT(Status == STATUS_SUCCESS);
1641 if (!NT_SUCCESS(Status))
1642 goto done;
1643
1644 /* Get the reqired buffer size for the self-relative SD */
1645 Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
1646 NULL,
1647 &RelSDSize);
1648 if (Status != STATUS_BUFFER_TOO_SMALL)
1649 goto done;
1650
1651 /* Allocate a buffer for the self-relative SD */
1652 RelSD = RtlAllocateHeap(RtlGetProcessHeap(),
1653 HEAP_ZERO_MEMORY,
1654 RelSDSize);
1655 if (RelSD == NULL)
1656 {
1657 Status = STATUS_INSUFFICIENT_RESOURCES;
1658 ASSERT(Status == STATUS_SUCCESS);
1659 goto done;
1660 }
1661
1662 /* Convert the absolute SD to self-relative format */
1663 Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
1664 RelSD,
1665 &RelSDSize);
1666 if (Status == STATUS_BUFFER_TOO_SMALL)
1667 {
1668 ASSERT(Status == STATUS_SUCCESS);
1669 goto done;
1670 }
1671
1672 *UserSd = RelSD;
1673 *Size = RelSDSize;
1674
1675 done:
1676 if (!NT_SUCCESS(Status))
1677 {
1678 if (RelSD != NULL)
1679 RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD);
1680 }
1681
1682 if (EveryoneSid != NULL)
1683 RtlFreeSid(EveryoneSid);
1684
1685 if (AnonymousSid != NULL)
1686 RtlFreeSid(AnonymousSid);
1687
1688 if (AdministratorsSid != NULL)
1689 RtlFreeSid(AdministratorsSid);
1690
1691 if (Dacl != NULL)
1692 RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl);
1693
1694 if (Sacl != NULL)
1695 RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl);
1696
1697 if (AbsSD != NULL)
1698 RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD);
1699
1700 return Status;
1701 }
1702
1703 /* EOF */
1704