xref: /reactos/dll/win32/samsrv/security.c (revision 9393fc32)
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