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