- Fixed the freeing of memory from boot load drivers.
[reactos.git] / reactos / ntoskrnl / se / sd.c
1 /* $Id: sd.c,v 1.11 2003/10/12 17:05:50 hbirr Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Security manager
6 * FILE: kernel/se/sd.c
7 * PROGRAMER: David Welch <welch@cwcom.net>
8 * REVISION HISTORY:
9 * 26/07/98: Added stubs for security functions
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/se.h>
16
17 #include <internal/debug.h>
18
19 /* GLOBALS ******************************************************************/
20
21 PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL;
22 PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd = NULL;
23 PSECURITY_DESCRIPTOR SePublicOpenSd = NULL;
24 PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd = NULL;
25 PSECURITY_DESCRIPTOR SeSystemDefaultSd = NULL;
26 PSECURITY_DESCRIPTOR SeUnrestrictedSd = NULL;
27
28 /* FUNCTIONS ***************************************************************/
29
30 BOOLEAN INIT_FUNCTION
31 SepInitSDs(VOID)
32 {
33 /* Create PublicDefaultSd */
34 SePublicDefaultSd = ExAllocatePool(NonPagedPool,
35 sizeof(SECURITY_DESCRIPTOR));
36 if (SePublicDefaultSd == NULL)
37 return(FALSE);
38
39 RtlCreateSecurityDescriptor(SePublicDefaultSd,
40 SECURITY_DESCRIPTOR_REVISION);
41 RtlSetDaclSecurityDescriptor(SePublicDefaultSd,
42 TRUE,
43 SePublicDefaultDacl,
44 FALSE);
45
46 /* Create PublicDefaultUnrestrictedSd */
47 SePublicDefaultUnrestrictedSd = ExAllocatePool(NonPagedPool,
48 sizeof(SECURITY_DESCRIPTOR));
49 if (SePublicDefaultUnrestrictedSd == NULL)
50 return(FALSE);
51
52 RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd,
53 SECURITY_DESCRIPTOR_REVISION);
54 RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd,
55 TRUE,
56 SePublicDefaultUnrestrictedDacl,
57 FALSE);
58
59 /* Create PublicOpenSd */
60 SePublicOpenSd = ExAllocatePool(NonPagedPool,
61 sizeof(SECURITY_DESCRIPTOR));
62 if (SePublicOpenSd == NULL)
63 return(FALSE);
64
65 RtlCreateSecurityDescriptor(SePublicOpenSd,
66 SECURITY_DESCRIPTOR_REVISION);
67 RtlSetDaclSecurityDescriptor(SePublicOpenSd,
68 TRUE,
69 SePublicOpenDacl,
70 FALSE);
71
72 /* Create PublicOpenUnrestrictedSd */
73 SePublicOpenUnrestrictedSd = ExAllocatePool(NonPagedPool,
74 sizeof(SECURITY_DESCRIPTOR));
75 if (SePublicOpenUnrestrictedSd == NULL)
76 return(FALSE);
77
78 RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd,
79 SECURITY_DESCRIPTOR_REVISION);
80 RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd,
81 TRUE,
82 SePublicOpenUnrestrictedDacl,
83 FALSE);
84
85 /* Create SystemDefaultSd */
86 SeSystemDefaultSd = ExAllocatePool(NonPagedPool,
87 sizeof(SECURITY_DESCRIPTOR));
88 if (SeSystemDefaultSd == NULL)
89 return(FALSE);
90
91 RtlCreateSecurityDescriptor(SeSystemDefaultSd,
92 SECURITY_DESCRIPTOR_REVISION);
93 RtlSetDaclSecurityDescriptor(SeSystemDefaultSd,
94 TRUE,
95 SeSystemDefaultDacl,
96 FALSE);
97
98 /* Create UnrestrictedSd */
99 SeUnrestrictedSd = ExAllocatePool(NonPagedPool,
100 sizeof(SECURITY_DESCRIPTOR));
101 if (SeUnrestrictedSd == NULL)
102 return(FALSE);
103
104 RtlCreateSecurityDescriptor(SeUnrestrictedSd,
105 SECURITY_DESCRIPTOR_REVISION);
106 RtlSetDaclSecurityDescriptor(SeUnrestrictedSd,
107 TRUE,
108 SeUnrestrictedDacl,
109 FALSE);
110
111 return(TRUE);
112 }
113
114
115 /*
116 * @implemented
117 */
118 NTSTATUS STDCALL
119 RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
120 ULONG Revision)
121 {
122 if (Revision != SECURITY_DESCRIPTOR_REVISION)
123 return(STATUS_UNSUCCESSFUL);
124
125 SecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION;
126 SecurityDescriptor->Sbz1 = 0;
127 SecurityDescriptor->Control = 0;
128 SecurityDescriptor->Owner = NULL;
129 SecurityDescriptor->Group = NULL;
130 SecurityDescriptor->Sacl = NULL;
131 SecurityDescriptor->Dacl = NULL;
132
133 return(STATUS_SUCCESS);
134 }
135
136
137 /*
138 * @implemented
139 */
140 ULONG STDCALL
141 RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
142 {
143 PSID Owner;
144 PSID Group;
145 ULONG Length;
146 PACL Dacl;
147 PACL Sacl;
148
149 Length = sizeof(SECURITY_DESCRIPTOR);
150
151 if (SecurityDescriptor->Owner != NULL)
152 {
153 Owner = SecurityDescriptor->Owner;
154 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
155 {
156 Owner = (PSID)((ULONG)Owner +
157 (ULONG)SecurityDescriptor);
158 }
159 Length = Length + ((sizeof(SID) + (Owner->SubAuthorityCount - 1) *
160 sizeof(ULONG) + 3) & 0xfc);
161 }
162
163 if (SecurityDescriptor->Group != NULL)
164 {
165 Group = SecurityDescriptor->Group;
166 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
167 {
168 Group = (PSID)((ULONG)Group + (ULONG)SecurityDescriptor);
169 }
170 Length = Length + ((sizeof(SID) + (Group->SubAuthorityCount - 1) *
171 sizeof(ULONG) + 3) & 0xfc);
172 }
173
174 if (SecurityDescriptor->Control & SE_DACL_PRESENT &&
175 SecurityDescriptor->Dacl != NULL)
176 {
177 Dacl = SecurityDescriptor->Dacl;
178 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
179 {
180 Dacl = (PACL)((ULONG)Dacl + (PVOID)SecurityDescriptor);
181 }
182 Length = Length + ((Dacl->AclSize + 3) & 0xfc);
183 }
184
185 if (SecurityDescriptor->Control & SE_SACL_PRESENT &&
186 SecurityDescriptor->Sacl != NULL)
187 {
188 Sacl = SecurityDescriptor->Sacl;
189 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
190 {
191 Sacl = (PACL)((ULONG)Sacl + (PVOID)SecurityDescriptor);
192 }
193 Length = Length + ((Sacl->AclSize + 3) & 0xfc);
194 }
195
196 return(Length);
197 }
198
199
200 /*
201 * @implemented
202 */
203 NTSTATUS STDCALL
204 RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
205 PBOOLEAN DaclPresent,
206 PACL* Dacl,
207 PBOOLEAN DaclDefaulted)
208 {
209 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
210 {
211 return(STATUS_UNSUCCESSFUL);
212 }
213
214 if (!(SecurityDescriptor->Control & SE_DACL_PRESENT))
215 {
216 *DaclPresent = FALSE;
217 return(STATUS_SUCCESS);
218 }
219 *DaclPresent = TRUE;
220
221 if (SecurityDescriptor->Dacl == NULL)
222 {
223 *Dacl = NULL;
224 }
225 else
226 {
227 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
228 {
229 *Dacl = (PACL)((ULONG)SecurityDescriptor->Dacl +
230 (PVOID)SecurityDescriptor);
231 }
232 else
233 {
234 *Dacl = SecurityDescriptor->Dacl;
235 }
236 }
237
238 if (SecurityDescriptor->Control & SE_DACL_DEFAULTED)
239 {
240 *DaclDefaulted = TRUE;
241 }
242 else
243 {
244 *DaclDefaulted = FALSE;
245 }
246
247 return(STATUS_SUCCESS);
248 }
249
250
251 /*
252 * @implemented
253 */
254 NTSTATUS STDCALL
255 RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
256 BOOLEAN DaclPresent,
257 PACL Dacl,
258 BOOLEAN DaclDefaulted)
259 {
260 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
261 {
262 return(STATUS_UNSUCCESSFUL);
263 }
264
265 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
266 {
267 return(STATUS_UNSUCCESSFUL);
268 }
269
270 if (!DaclPresent)
271 {
272 SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_DACL_PRESENT);
273 return(STATUS_SUCCESS);
274 }
275
276 SecurityDescriptor->Control = SecurityDescriptor->Control | SE_DACL_PRESENT;
277 SecurityDescriptor->Dacl = Dacl;
278 SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_DACL_DEFAULTED);
279
280 if (DaclDefaulted)
281 {
282 SecurityDescriptor->Control = SecurityDescriptor->Control | SE_DACL_DEFAULTED;
283 }
284
285 return(STATUS_SUCCESS);
286 }
287
288
289 /*
290 * @implemented
291 */
292 BOOLEAN STDCALL
293 RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
294 {
295 PSID Owner;
296 PSID Group;
297 PACL Sacl;
298 PACL Dacl;
299
300 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
301 {
302 return(FALSE);
303 }
304
305 Owner = SecurityDescriptor->Owner;
306 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
307 {
308 Owner = (PSID)((ULONG)Owner + (ULONG)SecurityDescriptor);
309 }
310
311 if (!RtlValidSid(Owner))
312 {
313 return(FALSE);
314 }
315
316 Group = SecurityDescriptor->Group;
317 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
318 {
319 Group = (PSID)((ULONG)Group + (ULONG)SecurityDescriptor);
320 }
321
322 if (!RtlValidSid(Group))
323 {
324 return(FALSE);
325 }
326
327 if (SecurityDescriptor->Control & SE_DACL_PRESENT &&
328 SecurityDescriptor->Dacl != NULL)
329 {
330 Dacl = SecurityDescriptor->Dacl;
331 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
332 {
333 Dacl = (PACL)((ULONG)Dacl + (ULONG)SecurityDescriptor);
334 }
335
336 if (!RtlValidAcl(Dacl))
337 {
338 return(FALSE);
339 }
340 }
341
342 if (SecurityDescriptor->Control & SE_SACL_PRESENT &&
343 SecurityDescriptor->Sacl != NULL)
344 {
345 Sacl = SecurityDescriptor->Sacl;
346 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
347 {
348 Sacl = (PACL)((ULONG)Sacl + (ULONG)SecurityDescriptor);
349 }
350
351 if (!RtlValidAcl(Sacl))
352 {
353 return(FALSE);
354 }
355 }
356
357 return(TRUE);
358 }
359
360
361 /*
362 * @implemented
363 */
364 NTSTATUS STDCALL
365 RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
366 PSID Owner,
367 BOOLEAN OwnerDefaulted)
368 {
369 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
370 {
371 return(STATUS_UNSUCCESSFUL);
372 }
373
374 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
375 {
376 return(STATUS_UNSUCCESSFUL);
377 }
378
379 SecurityDescriptor->Owner = Owner;
380 SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_OWNER_DEFAULTED);
381
382 if (OwnerDefaulted)
383 {
384 SecurityDescriptor->Control = SecurityDescriptor->Control | SE_OWNER_DEFAULTED;
385 }
386
387 return(STATUS_SUCCESS);
388 }
389
390
391 /*
392 * @implemented
393 */
394 NTSTATUS STDCALL
395 RtlGetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
396 PSID* Owner,
397 PBOOLEAN OwnerDefaulted)
398 {
399 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
400 {
401 return(STATUS_UNSUCCESSFUL);
402 }
403
404 if (SecurityDescriptor->Owner != NULL)
405 {
406 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
407 {
408 *Owner = (PSID)((ULONG)SecurityDescriptor->Owner +
409 (PVOID)SecurityDescriptor);
410 }
411 else
412 {
413 *Owner = SecurityDescriptor->Owner;
414 }
415 }
416 else
417 {
418 *Owner = NULL;
419 }
420 if (SecurityDescriptor->Control & SE_OWNER_DEFAULTED)
421 {
422 *OwnerDefaulted = 1;
423 }
424 else
425 {
426 *OwnerDefaulted = 0;
427 }
428 return(STATUS_SUCCESS);
429 }
430
431
432 /*
433 * @implemented
434 */
435 NTSTATUS STDCALL
436 RtlSetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
437 PSID Group,
438 BOOLEAN GroupDefaulted)
439 {
440 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
441 {
442 return(STATUS_UNSUCCESSFUL);
443 }
444
445 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
446 {
447 return(STATUS_UNSUCCESSFUL);
448 }
449
450 SecurityDescriptor->Group = Group;
451 SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_GROUP_DEFAULTED);
452
453 if (GroupDefaulted)
454 {
455 SecurityDescriptor->Control = SecurityDescriptor->Control | SE_GROUP_DEFAULTED;
456 }
457
458 return(STATUS_SUCCESS);
459 }
460
461
462 /*
463 * @implemented
464 */
465 NTSTATUS STDCALL
466 RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
467 PSID* Group,
468 PBOOLEAN GroupDefaulted)
469 {
470 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
471 {
472 return(STATUS_UNSUCCESSFUL);
473 }
474
475 if (SecurityDescriptor->Group != NULL)
476 {
477 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
478 {
479 *Group = (PSID)((ULONG)SecurityDescriptor->Group +
480 (PVOID)SecurityDescriptor);
481 }
482 else
483 {
484 *Group = SecurityDescriptor->Group;
485 }
486 }
487 else
488 {
489 *Group = NULL;
490 }
491
492 if (SecurityDescriptor->Control & SE_GROUP_DEFAULTED)
493 {
494 *GroupDefaulted = TRUE;
495 }
496 else
497 {
498 *GroupDefaulted = FALSE;
499 }
500
501 return(STATUS_SUCCESS);
502 }
503
504
505 /*
506 * @implemented
507 */
508 NTSTATUS STDCALL
509 RtlGetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
510 PBOOLEAN SaclPresent,
511 PACL *Sacl,
512 PBOOLEAN SaclDefaulted)
513 {
514 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
515 {
516 return(STATUS_UNSUCCESSFUL);
517 }
518
519 if (!(SecurityDescriptor->Control & SE_SACL_PRESENT))
520 {
521 *SaclPresent = FALSE;
522 return(STATUS_SUCCESS);
523 }
524 *SaclPresent = TRUE;
525
526 if (SecurityDescriptor->Sacl == NULL)
527 {
528 *Sacl = NULL;
529 }
530 else
531 {
532 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
533 {
534 *Sacl = (PACL)((ULONG)SecurityDescriptor->Sacl +
535 (PVOID)SecurityDescriptor);
536 }
537 else
538 {
539 *Sacl = SecurityDescriptor->Sacl;
540 }
541 }
542
543 if (SecurityDescriptor->Control & SE_SACL_DEFAULTED)
544 {
545 *SaclDefaulted = TRUE;
546 }
547 else
548 {
549 *SaclDefaulted = FALSE;
550 }
551
552 return(STATUS_SUCCESS);
553 }
554
555
556 /*
557 * @implemented
558 */
559 NTSTATUS STDCALL
560 RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
561 BOOLEAN SaclPresent,
562 PACL Sacl,
563 BOOLEAN SaclDefaulted)
564 {
565 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION)
566 {
567 return(STATUS_UNSUCCESSFUL);
568 }
569 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
570 {
571 return(STATUS_UNSUCCESSFUL);
572 }
573
574 if (!SaclPresent)
575 {
576 SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_SACL_PRESENT);
577 return(STATUS_SUCCESS);
578 }
579
580 SecurityDescriptor->Control = SecurityDescriptor->Control | SE_SACL_PRESENT;
581 SecurityDescriptor->Sacl = Sacl;
582 SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_SACL_DEFAULTED);
583
584 if (SaclDefaulted)
585 {
586 SecurityDescriptor->Control = SecurityDescriptor->Control | SE_SACL_DEFAULTED;
587 }
588
589 return(STATUS_SUCCESS);
590 }
591
592
593 static VOID
594 RtlpQuerySecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
595 PSID* Owner,
596 PULONG OwnerLength,
597 PSID* Group,
598 PULONG GroupLength,
599 PACL* Dacl,
600 PULONG DaclLength,
601 PACL* Sacl,
602 PULONG SaclLength)
603 {
604 if (SecurityDescriptor->Owner == NULL)
605 {
606 *Owner = NULL;
607 }
608 else
609 {
610 *Owner = SecurityDescriptor->Owner;
611 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
612 {
613 *Owner = (PSID)((ULONG)*Owner + (ULONG)SecurityDescriptor);
614 }
615 }
616
617 if (*Owner != NULL)
618 {
619 *OwnerLength = (RtlLengthSid(*Owner) + 3) & ~3;
620 }
621 else
622 {
623 *OwnerLength = 0;
624 }
625
626 if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
627 SecurityDescriptor->Dacl != NULL)
628 {
629 *Dacl = SecurityDescriptor->Dacl;
630 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
631 {
632 *Dacl = (PACL)((ULONG)*Dacl + (ULONG)SecurityDescriptor);
633 }
634 }
635 else
636 {
637 *Dacl = NULL;
638 }
639
640 if (*Dacl != NULL)
641 {
642 *DaclLength = ((*Dacl)->AclSize + 3) & ~3;
643 }
644 else
645 {
646 *DaclLength = 0;
647 }
648
649 if (SecurityDescriptor->Group != NULL)
650 {
651 *Group = NULL;
652 }
653 else
654 {
655 *Group = SecurityDescriptor->Group;
656 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
657 {
658 *Group = (PSID)((ULONG)*Group + (ULONG)SecurityDescriptor);
659 }
660 }
661
662 if (*Group != NULL)
663 {
664 *GroupLength = (RtlLengthSid(*Group) + 3) & ~3;
665 }
666 else
667 {
668 *GroupLength = 0;
669 }
670
671 if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
672 SecurityDescriptor->Sacl != NULL)
673 {
674 *Sacl = SecurityDescriptor->Sacl;
675 if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
676 {
677 *Sacl = (PACL)((ULONG)*Sacl + (ULONG)SecurityDescriptor);
678 }
679 }
680 else
681 {
682 *Sacl = NULL;
683 }
684
685 if (*Sacl != NULL)
686 {
687 *SaclLength = ((*Sacl)->AclSize + 3) & ~3;
688 }
689 }
690
691
692 /*
693 * @implemented
694 */
695 NTSTATUS STDCALL
696 RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
697 PSECURITY_DESCRIPTOR RelSD,
698 PULONG BufferLength)
699 {
700 PSID Owner;
701 PSID Group;
702 PACL Sacl;
703 PACL Dacl;
704 ULONG OwnerLength;
705 ULONG GroupLength;
706 ULONG SaclLength;
707 ULONG DaclLength;
708 ULONG TotalLength;
709 ULONG Current;
710
711 if (AbsSD->Control & SE_SELF_RELATIVE)
712 {
713 return(STATUS_BAD_DESCRIPTOR_FORMAT);
714 }
715
716 RtlpQuerySecurityDescriptor(AbsSD,
717 &Owner,
718 &OwnerLength,
719 &Group,
720 &GroupLength,
721 &Dacl,
722 &DaclLength,
723 &Sacl,
724 &SaclLength);
725
726 TotalLength = OwnerLength + GroupLength + SaclLength +
727 DaclLength + sizeof(SECURITY_DESCRIPTOR);
728 if (*BufferLength < TotalLength)
729 {
730 return(STATUS_BUFFER_TOO_SMALL);
731 }
732
733 RtlZeroMemory(RelSD,
734 TotalLength);
735 memmove(RelSD,
736 AbsSD,
737 sizeof(SECURITY_DESCRIPTOR));
738 Current = (ULONG)RelSD + sizeof(SECURITY_DESCRIPTOR);
739
740 if (SaclLength != 0)
741 {
742 memmove((PVOID)Current,
743 Sacl,
744 SaclLength);
745 RelSD->Sacl = (PACL)((ULONG)Current - (ULONG)RelSD);
746 Current += SaclLength;
747 }
748
749 if (DaclLength != 0)
750 {
751 memmove((PVOID)Current,
752 Dacl,
753 DaclLength);
754 RelSD->Dacl = (PACL)((ULONG)Current - (ULONG)RelSD);
755 Current += DaclLength;
756 }
757
758 if (OwnerLength != 0)
759 {
760 memmove((PVOID)Current,
761 Owner,
762 OwnerLength);
763 RelSD->Owner = (PSID)((ULONG)Current - (ULONG)RelSD);
764 Current += OwnerLength;
765 }
766
767 if (GroupLength != 0)
768 {
769 memmove((PVOID)Current,
770 Group,
771 GroupLength);
772 RelSD->Group = (PSID)((ULONG)Current - (ULONG)RelSD);
773 }
774
775 RelSD->Control |= SE_SELF_RELATIVE;
776
777 return(STATUS_SUCCESS);
778 }
779
780 /* EOF */