ReactOS  0.4.13-dev-92-gf251225
sd.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * PURPOSE: Security descriptor functions
5  * FILE: lib/rtl/sd.c
6  * PROGRAMER: David Welch <welch@cwcom.net>
7  */
8 
9 /* INCLUDES *****************************************************************/
10 
11 #include <rtl.h>
12 #include "../../ntoskrnl/include/internal/se.h"
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* PRIVATE FUNCTIONS **********************************************************/
17 
18 BOOLEAN
19 NTAPI
21  IN ULONG Length,
22  IN ULONG MinLength,
23  OUT PULONG MaxLength)
24 {
25  /* Assume failure */
26  *MaxLength = 0;
27 
28  /* Reject out of bounds lengths */
29  if (Offset < sizeof(SECURITY_DESCRIPTOR_RELATIVE)) return FALSE;
30  if (Offset >= Length) return FALSE;
31 
32  /* Reject insufficient lengths */
33  if ((Length - Offset) < MinLength) return FALSE;
34 
35  /* Reject unaligned offsets */
36  if (ALIGN_DOWN(Offset, ULONG) != Offset) return FALSE;
37 
38  /* Return length that is safe to read */
39  *MaxLength = Length - Offset;
40  return TRUE;
41 }
42 
43 VOID
44 NTAPI
46  OUT PSID *Owner,
50  OUT PACL *Dacl,
52  OUT PACL *Sacl,
54 {
56 
57  /* Get the owner */
59  if (*Owner)
60  {
61  /* There's an owner, so align the size */
62  *OwnerSize = ROUND_UP(RtlLengthSid(*Owner), sizeof(ULONG));
63  }
64  else
65  {
66  /* No owner, no size */
67  *OwnerSize = 0;
68  }
69 
70  /* Get the group */
72  if (*PrimaryGroup)
73  {
74  /* There's a group, so align the size */
76  }
77  else
78  {
79  /* No group, no size */
80  *PrimaryGroupSize = 0;
81  }
82 
83  /* Get the DACL */
85  if (*Dacl)
86  {
87  /* There's a DACL, align the size */
88  *DaclSize = ROUND_UP((*Dacl)->AclSize, sizeof(ULONG));
89  }
90  else
91  {
92  /* No DACL, no size */
93  *DaclSize = 0;
94  }
95 
96  /* Get the SACL */
98  if (*Sacl)
99  {
100  /* There's a SACL, align the size */
101  *SaclSize = ROUND_UP((*Sacl)->AclSize, sizeof(ULONG));
102  }
103  else
104  {
105  /* No SACL, no size */
106  *SaclSize = 0;
107  }
108 }
109 
110 /* PUBLIC FUNCTIONS ***********************************************************/
111 
112 /*
113  * @implemented
114  */
115 NTSTATUS
116 NTAPI
118  IN ULONG Revision)
119 {
121  PAGED_CODE_RTL();
122 
123  /* Fail on invalid revisions */
125 
126  /* Setup an empty SD */
127  RtlZeroMemory(Sd, sizeof(*Sd));
129 
130  /* All good */
131  return STATUS_SUCCESS;
132 }
133 
134 /*
135  * @implemented
136  */
137 NTSTATUS
138 NTAPI
140  IN ULONG Revision)
141 {
142  PAGED_CODE_RTL();
143 
144  /* Fail on invalid revisions */
146 
147  /* Setup an empty SD */
151 
152  /* All good */
153  return STATUS_SUCCESS;
154 }
155 
156 /*
157  * @implemented
158  */
159 ULONG
160 NTAPI
162 {
164  PSID Owner, Group;
165  PACL Sacl, Dacl;
166  ULONG Length;
167  PAGED_CODE_RTL();
168 
169  /* Start with the initial length of the SD itself */
171  if (Sd->Control & SE_SELF_RELATIVE)
172  {
174  }
175  else
176  {
177  Length = sizeof(SECURITY_DESCRIPTOR);
178  }
179 
180  /* Add the length of the individual subcomponents */
182  if (Owner) Length += ROUND_UP(RtlLengthSid(Owner), sizeof(ULONG));
184  if (Group) Length += ROUND_UP(RtlLengthSid(Group), sizeof(ULONG));
186  if (Dacl) Length += ROUND_UP(Dacl->AclSize, sizeof(ULONG));
188  if (Sacl) Length += ROUND_UP(Sacl->AclSize, sizeof(ULONG));
189 
190  /* Return the final length */
191  return Length;
192 }
193 
194 /*
195  * @implemented
196  */
197 NTSTATUS
198 NTAPI
201  OUT PACL* Dacl,
203 {
205  PAGED_CODE_RTL();
206 
207  /* Fail on invalid revisions */
209 
210  /* Is there a DACL? */
212  if (*DaclPresent)
213  {
214  /* Yes, return it, and check if defaulted */
217  }
218 
219  /* All good */
220  return STATUS_SUCCESS;
221 }
222 
223 /*
224  * @implemented
225  */
226 NTSTATUS
227 NTAPI
230  OUT PACL* Sacl,
232 {
234  PAGED_CODE_RTL();
235 
236  /* Fail on invalid revisions */
238 
239  /* Is there a SACL? */
241  if (*SaclPresent)
242  {
243  /* Yes, return it, and check if defaulted */
246  }
247 
248  /* All good */
249  return STATUS_SUCCESS;
250 }
251 
252 /*
253  * @implemented
254  */
255 NTSTATUS
256 NTAPI
258  OUT PSID* Owner,
260 {
262  PAGED_CODE_RTL();
263 
264  /* Fail on invalid revision */
266 
267  /* Get the owner and if defaulted */
270 
271  /* All good */
272  return STATUS_SUCCESS;
273 }
274 
275 /*
276  * @implemented
277  */
278 NTSTATUS
279 NTAPI
281  OUT PSID* Group,
283 {
285  PAGED_CODE_RTL();
286 
287  /* Fail on invalid revision */
289 
290  /* Get the group and if defaulted */
293 
294  /* All good */
295  return STATUS_SUCCESS;
296 }
297 
298 /*
299  * @implemented
300  */
301 NTSTATUS
302 NTAPI
305  IN PACL Dacl,
307 {
309  PAGED_CODE_RTL();
310 
311  /* Fail on invalid revision */
313 
314  /* Fail on relative descriptors */
316 
317  /* Is there a DACL? */
318  if (!DaclPresent)
319  {
320  /* Caller is destroying the DACL, unset the flag and we're done */
321  Sd->Control = Sd->Control & ~SE_DACL_PRESENT;
322  return STATUS_SUCCESS;
323  }
324 
325  /* Caller is setting a new DACL, set the pointer and flag */
326  Sd->Dacl = Dacl;
327  Sd->Control |= SE_DACL_PRESENT;
328 
329  /* Set if defaulted */
330  Sd->Control &= ~SE_DACL_DEFAULTED;
332 
333  /* All good */
334  return STATUS_SUCCESS;
335 }
336 
337 /*
338  * @implemented
339  */
340 NTSTATUS
341 NTAPI
344  IN PACL Sacl,
346 {
348  PAGED_CODE_RTL();
349 
350  /* Fail on invalid revision */
352 
353  /* Fail on relative descriptors */
355 
356  /* Is there a SACL? */
357  if (!SaclPresent)
358  {
359  /* Caller is clearing the SACL, unset the flag and we're done */
360  Sd->Control = Sd->Control & ~SE_SACL_PRESENT;
361  return STATUS_SUCCESS;
362  }
363 
364  /* Caller is setting a new SACL, set it and the flag */
365  Sd->Sacl = Sacl;
366  Sd->Control |= SE_SACL_PRESENT;
367 
368  /* Set if defaulted */
369  Sd->Control &= ~SE_SACL_DEFAULTED;
371 
372  /* All good */
373  return STATUS_SUCCESS;
374 }
375 
376 /*
377  * @implemented
378  */
379 NTSTATUS
380 NTAPI
382  IN PSID Owner,
384 {
386  PAGED_CODE_RTL();
387 
388  /* Fail on invalid revision */
390 
391  /* Fail on relative descriptors */
393 
394  /* Owner being set or cleared */
395  Sd->Owner = Owner;
396 
397  /* Set if defaulted */
398  Sd->Control &= ~SE_OWNER_DEFAULTED;
400 
401  /* All good */
402  return STATUS_SUCCESS;
403 }
404 
405 /*
406  * @implemented
407  */
408 NTSTATUS
409 NTAPI
411  IN PSID Group,
413 {
415  PAGED_CODE_RTL();
416 
417  /* Fail on invalid revision */
419 
420  /* Fail on relative descriptors */
422 
423  /* Group being set or cleared */
424  Sd->Group = Group;
425 
426  /* Set if defaulted */
427  Sd->Control &= ~SE_GROUP_DEFAULTED;
429 
430  /* All good */
431  return STATUS_SUCCESS;
432 }
433 
434 /*
435  * @implemented
436  */
437 NTSTATUS
438 NTAPI
442 {
444  PAGED_CODE_RTL();
445 
446  /* Read current revision, even if invalid */
447  *Revision = Sd->Revision;
448 
449  /* Fail on invalid revision */
451 
452  /* Read current control */
453  *Control = Sd->Control;
454 
455  /* All good */
456  return STATUS_SUCCESS;
457 }
458 
459 /*
460  * @implemented
461  */
462 NTSTATUS
463 NTAPI
465  IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
466  IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet)
467 {
469 
470  /* Check for invalid bits */
471  if ((ControlBitsOfInterest & ~(SE_DACL_UNTRUSTED |
478  SE_SACL_PROTECTED)) ||
479  (ControlBitsToSet & ~ControlBitsOfInterest))
480  {
481  /* Fail */
483  }
484 
485  /* Zero the 'bits of interest' */
486  Sd->Control &= ~ControlBitsOfInterest;
487 
488  /* Set the 'bits to set' */
489  Sd->Control |= (ControlBitsToSet & ControlBitsOfInterest);
490 
491  /* All good */
492  return STATUS_SUCCESS;
493 }
494 
495 /*
496  * @implemented
497  */
498 BOOLEAN
499 NTAPI
501  OUT PUCHAR RMControl)
502 {
504  PAGED_CODE_RTL();
505 
506  /* Check if there's no valid RM control */
507  if (!(Sd->Control & SE_RM_CONTROL_VALID))
508  {
509  /* Fail and return nothing */
510  *RMControl = 0;
511  return FALSE;
512  }
513 
514  /* Return it, ironically the member is "should be zero" */
515  *RMControl = Sd->Sbz1;
516  return TRUE;
517 }
518 
519 /*
520  * @implemented
521  */
522 VOID
523 NTAPI
525  IN PUCHAR RMControl)
526 {
528  PAGED_CODE_RTL();
529 
530  /* RM Control is being cleared or set */
531  if (!RMControl)
532  {
533  /* Clear it */
535  Sd->Sbz1 = 0;
536  }
537  else
538  {
539  /* Set it */
541  Sd->Sbz1 = *RMControl;
542  }
543 }
544 
545 /*
546  * @implemented
547  */
548 NTSTATUS
549 NTAPI
553 {
555  PAGED_CODE_RTL();
556 
557  /* Always return revision, even if invalid */
558  *Revision = Sd->Revision;
559 
560  /* Fail on invalid revision */
562 
563  /* Mask out flags which are not attributes */
572 
573  /* Call the newer API */
575 }
576 
577 /*
578  * @implemented
579  */
580 NTSTATUS
581 NTAPI
583  OUT PSECURITY_DESCRIPTOR *pDestinationSecurityDescriptor)
584 {
585  PSID Owner, Group;
586  PACL Dacl, Sacl;
587  DWORD OwnerLength, GroupLength, DaclLength, SaclLength, TotalLength;
588  PISECURITY_DESCRIPTOR Sd = pSourceSecurityDescriptor;
589 
590  /* Get all the components */
592  &Owner,
593  &OwnerLength,
594  &Group,
595  &GroupLength,
596  &Dacl,
597  &DaclLength,
598  &Sacl,
599  &SaclLength);
600 
601  /* Add up their lengths */
603  OwnerLength +
604  GroupLength +
605  DaclLength +
606  SaclLength;
607 
608  /* Allocate a copy */
609  *pDestinationSecurityDescriptor = RtlAllocateHeap(RtlGetProcessHeap(),
610  0,
611  TotalLength);
612  if (*pDestinationSecurityDescriptor == NULL) return STATUS_NO_MEMORY;
613 
614  /* Copy the old in the new */
615  RtlCopyMemory(*pDestinationSecurityDescriptor, Sd, TotalLength);
616 
617  /* All good */
618  return STATUS_SUCCESS;
619 }
620 
621 /*
622  * @implemented
623  */
624 NTSTATUS
625 NTAPI
629 {
631  PAGED_CODE_RTL();
632 
633  /* Can't already be relative */
635 
636  /* Call the other API */
639  BufferLength);
640 }
641 
642 /*
643  * @implemented
644  */
645 NTSTATUS
646 NTAPI
648  OUT PSECURITY_DESCRIPTOR SelfRelativeSD,
650 {
651  PSID Owner, Group;
652  PACL Sacl, Dacl;
653  ULONG OwnerLength, GroupLength, SaclLength, DaclLength, TotalLength;
654  ULONG_PTR Current;
657  PAGED_CODE_RTL();
658 
659  /* Query all components */
661  &Owner,
662  &OwnerLength,
663  &Group,
664  &GroupLength,
665  &Dacl,
666  &DaclLength,
667  &Sacl,
668  &SaclLength);
669 
670  /* Calculate final length */
672  OwnerLength +
673  GroupLength +
674  SaclLength +
675  DaclLength;
676 
677  /* Is there enough space? */
678  if (*BufferLength < TotalLength)
679  {
680  /* Nope, return how much is needed */
683  }
684 
685  /* Start fresh */
686  RtlZeroMemory(RelSd, TotalLength);
687 
688  /* Copy the header fields */
689  RtlCopyMemory(RelSd,
690  Sd,
692 
693  /* Set the current copy pointer */
694  Current = (ULONG_PTR)(RelSd + 1);
695 
696  /* Is there a SACL? */
697  if (SaclLength)
698  {
699  /* Copy it */
700  RtlCopyMemory((PVOID)Current, Sacl, SaclLength);
701  RelSd->Sacl = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
702  Current += SaclLength;
703  }
704 
705  /* Is there a DACL? */
706  if (DaclLength)
707  {
708  /* Copy it */
709  RtlCopyMemory((PVOID)Current, Dacl, DaclLength);
710  RelSd->Dacl = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
711  Current += DaclLength;
712  }
713 
714  /* Is there an owner? */
715  if (OwnerLength)
716  {
717  /* Copy it */
718  RtlCopyMemory((PVOID)Current, Owner, OwnerLength);
719  RelSd->Owner = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
720  Current += OwnerLength;
721  }
722 
723  /* Is there a group? */
724  if (GroupLength)
725  {
726  /* Copy it */
727  RtlCopyMemory((PVOID)Current, Group, GroupLength);
728  RelSd->Group = (ULONG_PTR)Current - (ULONG_PTR)RelSd;
729  }
730 
731  /* Mark it as relative */
732  RelSd->Control |= SE_SELF_RELATIVE;
733 
734  /* All good */
735  return STATUS_SUCCESS;
736 }
737 
738 /*
739  * @implemented
740  */
741 NTSTATUS
742 NTAPI
744  OUT PSECURITY_DESCRIPTOR AbsoluteSD,
745  IN PULONG AbsoluteSDSize,
746  IN PACL Dacl,
748  IN PACL Sacl,
750  IN PSID Owner,
754 {
756  PISECURITY_DESCRIPTOR RelSd = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
757  ULONG OwnerLength, GroupLength, DaclLength, SaclLength;
758  PSID pOwner, pGroup;
759  PACL pDacl, pSacl;
760  PAGED_CODE_RTL();
761 
762  /* Must be relative, otherwiise fail */
763  if (!(RelSd->Control & SE_SELF_RELATIVE)) return STATUS_BAD_DESCRIPTOR_FORMAT;
764 
765  /* Get all the components */
767  &pOwner,
768  &OwnerLength,
769  &pGroup,
770  &GroupLength,
771  &pDacl,
772  &DaclLength,
773  &pSacl,
774  &SaclLength);
775 
776  /* Fail if there's not enough space */
777  if (!(Sd) ||
778  (sizeof(SECURITY_DESCRIPTOR) > *AbsoluteSDSize) ||
779  (OwnerLength > *OwnerSize) ||
781  (DaclLength > *DaclSize) ||
782  (SaclLength > *SaclSize))
783  {
784  /* Return how much space is needed for each components */
785  *AbsoluteSDSize = sizeof(SECURITY_DESCRIPTOR);
786  *OwnerSize = OwnerLength;
788  *DaclSize = DaclLength;
789  *SaclSize = SaclLength;
791  }
792 
793  /* Copy the header fields */
794  RtlMoveMemory(Sd, RelSd, sizeof(SECURITY_DESCRIPTOR_RELATIVE));
795 
796  /* Wipe out the pointers and the relative flag */
797  Sd->Owner = NULL;
798  Sd->Group = NULL;
799  Sd->Sacl = NULL;
800  Sd->Dacl = NULL;
801  Sd->Control &= ~SE_SELF_RELATIVE;
802 
803  /* Is there an owner? */
804  if (pOwner)
805  {
806  /* Copy it */
807  RtlMoveMemory(Owner, pOwner, RtlLengthSid(pOwner));
808  Sd->Owner = Owner;
809  }
810 
811  /* Is there a group? */
812  if (pGroup)
813  {
814  /* Copy it */
815  RtlMoveMemory(PrimaryGroup, pGroup, RtlLengthSid(pGroup));
816  Sd->Group = PrimaryGroup;
817  }
818 
819  /* Is there a DACL? */
820  if (pDacl)
821  {
822  /* Copy it */
823  RtlMoveMemory(Dacl, pDacl, pDacl->AclSize);
824  Sd->Dacl = Dacl;
825  }
826 
827  /* Is there a SACL? */
828  if (pSacl)
829  {
830  /* Copy it */
831  RtlMoveMemory(Sacl, pSacl, pSacl->AclSize);
832  Sd->Sacl = Sacl;
833  }
834 
835  /* All good */
836  return STATUS_SUCCESS;
837 }
838 
839 /*
840  * @implemented
841  */
842 NTSTATUS
843 NTAPI
846 {
847  PISECURITY_DESCRIPTOR Sd = (PISECURITY_DESCRIPTOR)SelfRelativeSD;
849  PVOID DataStart, DataEnd;
850  LONG MoveDelta;
851  ULONG DataSize, OwnerLength, GroupLength, DaclLength, SaclLength;
852  PSID pOwner, pGroup;
853  PACL pDacl, pSacl;
854  PAGED_CODE_RTL();
855 
856  /* Need input */
857  if (!RelSd) return STATUS_INVALID_PARAMETER_1;
858 
859  /* Need to know how much space we have */
861 
862  /* Input must be relative */
863  if (!(RelSd->Control & SE_SELF_RELATIVE)) return STATUS_BAD_DESCRIPTOR_FORMAT;
864 
865  /* Query all the component sizes */
867  &pOwner,
868  &OwnerLength,
869  &pGroup,
870  &GroupLength,
871  &pDacl,
872  &DaclLength,
873  &pSacl,
874  &SaclLength);
875 
876  /*
877  * Check if there's a difference in structure layout between relatiev and
878  * absolute descriptors. On 32-bit, there won't be, since an offset is the
879  * same size as a pointer (32-bit), but on 64-bit, the offsets remain 32-bit
880  * as they are not SIZE_T, but ULONG, while the pointers now become 64-bit
881  * and thus the structure is different */
882  MoveDelta = sizeof(SECURITY_DESCRIPTOR) - sizeof(SECURITY_DESCRIPTOR_RELATIVE);
883  if (!MoveDelta)
884  {
885  /* So on 32-bit, simply clear the flag... */
886  Sd->Control &= ~SE_SELF_RELATIVE;
887 
888  /* Ensure we're *really* on 32-bit */
889  ASSERT(sizeof(Sd->Owner) == sizeof(RelSd->Owner));
890  ASSERT(sizeof(Sd->Group) == sizeof(RelSd->Group));
891  ASSERT(sizeof(Sd->Sacl) == sizeof(RelSd->Sacl));
892  ASSERT(sizeof(Sd->Dacl) == sizeof(RelSd->Dacl));
893 
894  /* And simply set pointers where there used to be offsets */
895  Sd->Owner = pOwner;
896  Sd->Group = pGroup;
897  Sd->Sacl = pSacl;
898  Sd->Dacl = pDacl;
899  return STATUS_SUCCESS;
900  }
901 
902  /*
903  * Calculate the start and end of the data area, we simply just move the
904  * data by the difference between the size of the relative and absolute
905  * security descriptor structure
906  */
907  DataStart = pOwner;
908  DataEnd = (PVOID)((ULONG_PTR)pOwner + OwnerLength);
909 
910  /* Is there a group? */
911  if (pGroup)
912  {
913  /* Is the group higher than where we started? */
914  if (((ULONG_PTR)pGroup < (ULONG_PTR)DataStart) || !DataStart)
915  {
916  /* Update the start pointer */
917  DataStart = pGroup;
918  }
919 
920  /* Is the group beyond where we ended? */
921  if (((ULONG_PTR)pGroup + GroupLength > (ULONG_PTR)DataEnd) || !DataEnd)
922  {
923  /* Update the end pointer */
924  DataEnd = (PVOID)((ULONG_PTR)pGroup + GroupLength);
925  }
926  }
927 
928  /* Is there a DACL? */
929  if (pDacl)
930  {
931  /* Is the DACL higher than where we started? */
932  if (((ULONG_PTR)pDacl < (ULONG_PTR)DataStart) || !DataStart)
933  {
934  /* Update the start pointer */
935  DataStart = pDacl;
936  }
937 
938  /* Is the DACL beyond where we ended? */
939  if (((ULONG_PTR)pDacl + DaclLength > (ULONG_PTR)DataEnd) || !DataEnd)
940  {
941  /* Update the end pointer */
942  DataEnd = (PVOID)((ULONG_PTR)pDacl + DaclLength);
943  }
944  }
945 
946  /* Is there a SACL? */
947  if (pSacl)
948  {
949  /* Is the SACL higher than where we started? */
950  if (((ULONG_PTR)pSacl < (ULONG_PTR)DataStart) || !DataStart)
951  {
952  /* Update the start pointer */
953  DataStart = pSacl;
954  }
955 
956  /* Is the SACL beyond where we ended? */
957  if (((ULONG_PTR)pSacl + SaclLength > (ULONG_PTR)DataEnd) || !DataEnd)
958  {
959  /* Update the end pointer */
960  DataEnd = (PVOID)((ULONG_PTR)pSacl + SaclLength);
961  }
962  }
963 
964  /* Sanity check */
965  ASSERT((ULONG_PTR)DataEnd >= (ULONG_PTR)DataStart);
966 
967  /* Now compute the difference between relative and absolute */
968  DataSize = (ULONG)((ULONG_PTR)DataEnd - (ULONG_PTR)DataStart);
969 
970  /* Is the new buffer large enough for this difference? */
971  if (*BufferSize < sizeof(SECURITY_DESCRIPTOR) + DataSize)
972  {
973  /* Nope, bail out */
976  }
977 
978  /* Is there anything actually to copy? */
979  if (DataSize)
980  {
981  /*
982  * There must be at least one SID or ACL in the security descriptor!
983  * Also the data area must be located somewhere after the end of the
984  * SECURITY_DESCRIPTOR_RELATIVE structure
985  */
986  ASSERT(DataStart != NULL);
987  ASSERT((ULONG_PTR)DataStart >= (ULONG_PTR)(RelSd + 1));
988 
989  /* It's time to move the data */
990  RtlMoveMemory((PVOID)(Sd + 1),
991  DataStart,
992  DataSize);
993  }
994 
995  /* Is there an owner? */
996  if (pOwner)
997  {
998  /* Set the pointer to the relative position */
999  Sd->Owner = (PSID)((LONG_PTR)pOwner + MoveDelta);
1000  }
1001  else
1002  {
1003  /* No owner, clear the pointer */
1004  Sd->Owner = NULL;
1005  }
1006 
1007  /* Is there a group */
1008  if (pGroup)
1009  {
1010  /* Set the pointer to the relative position */
1011  Sd->Group = (PSID)((LONG_PTR)pGroup + MoveDelta);
1012  }
1013  else
1014  {
1015  /* No group, clear the pointer */
1016  Sd->Group = NULL;
1017  }
1018 
1019  /* Is there a SACL? */
1020  if (pSacl)
1021  {
1022  /* Set the pointer to the relative position */
1023  Sd->Sacl = (PACL)((LONG_PTR)pSacl + MoveDelta);
1024  }
1025  else
1026  {
1027  /* No SACL, clear the pointer */
1028  Sd->Sacl = NULL;
1029  }
1030 
1031  /* Is there a DACL? */
1032  if (pDacl)
1033  {
1034  /* Set the pointer to the relative position */
1035  Sd->Dacl = (PACL)((LONG_PTR)pDacl + MoveDelta);
1036  }
1037  else
1038  {
1039  /* No DACL, clear the pointer */
1040  Sd->Dacl = NULL;
1041  }
1042 
1043  /* Clear the self-relative flag */
1044  Sd->Control &= ~SE_SELF_RELATIVE;
1045 
1046  /* All good */
1047  return STATUS_SUCCESS;
1048 }
1049 
1050 /*
1051  * @implemented
1052  */
1053 BOOLEAN
1054 NTAPI
1056 {
1058  PSID Owner, Group;
1059  PACL Sacl, Dacl;
1060  PAGED_CODE_RTL();
1061 
1062  _SEH2_TRY
1063  {
1064  /* Fail on bad revisions */
1066 
1067  /* Owner SID must be valid if present */
1069  if ((Owner) && (!RtlValidSid(Owner))) _SEH2_YIELD(return FALSE);
1070 
1071  /* Group SID must be valid if present */
1073  if ((Group) && (!RtlValidSid(Group))) _SEH2_YIELD(return FALSE);
1074 
1075  /* DACL must be valid if present */
1077  if ((Dacl) && (!RtlValidAcl(Dacl))) _SEH2_YIELD(return FALSE);
1078 
1079  /* SACL must be valid if present */
1081  if ((Sacl) && (!RtlValidAcl(Sacl))) _SEH2_YIELD(return FALSE);
1082  }
1084  {
1085  /* Access fault, bail out */
1086  _SEH2_YIELD(return FALSE);
1087  }
1088  _SEH2_END;
1089 
1090  /* All good */
1091  return TRUE;
1092 }
1093 
1094 /*
1095  * @implemented
1096  */
1097 BOOLEAN
1098 NTAPI
1102 {
1103  PISECURITY_DESCRIPTOR_RELATIVE Sd = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptorInput;
1104  PSID Owner, Group;
1105  PACL Dacl, Sacl;
1106  ULONG Length;
1107  PAGED_CODE_RTL();
1108 
1109  /* Note that Windows allows no DACL/SACL even if RequiredInfo wants it */
1110 
1111  /* Do we have enough space, is the revision vaild, and is this SD relative? */
1114  !(Sd->Control & SE_SELF_RELATIVE))
1115  {
1116  /* Nope, bail out */
1117  return FALSE;
1118  }
1119 
1120  /* Is there an owner? */
1121  if (Sd->Owner)
1122  {
1123  /* Try to access it */
1126  sizeof(SID),
1127  &Length))
1128  {
1129  /* It's beyond the buffer, fail */
1130  return FALSE;
1131  }
1132 
1133  /* Read the owner, check if it's valid and if the buffer contains it */
1134  Owner = (PSID)((ULONG_PTR)Sd->Owner + (ULONG_PTR)Sd);
1135  if (!RtlValidSid(Owner) || (Length < RtlLengthSid(Owner))) return FALSE;
1136  }
1138  {
1139  /* No owner but the caller expects one, fail */
1140  return FALSE;
1141  }
1142 
1143  /* Is there a group? */
1144  if (Sd->Group)
1145  {
1146  /* Try to access it */
1149  sizeof(SID),
1150  &Length))
1151  {
1152  /* It's beyond the buffer, fail */
1153  return FALSE;
1154  }
1155 
1156  /* Read the group, check if it's valid and if the buffer contains it */
1157  Group = (PSID)((ULONG_PTR)Sd->Group + (ULONG_PTR)Sd);
1158  if (!RtlValidSid(Group) || (Length < RtlLengthSid(Group))) return FALSE;
1159  }
1161  {
1162  /* No group, but the caller expects one, fail */
1163  return FALSE;
1164  }
1165 
1166  /* Is there a DACL? */
1167  if ((Sd->Control & SE_DACL_PRESENT) == SE_DACL_PRESENT)
1168  {
1169  /* Try to access it */
1172  sizeof(ACL),
1173  &Length))
1174  {
1175  /* It's beyond the buffer, fail */
1176  return FALSE;
1177  }
1178 
1179  /* Read the DACL, check if it's valid and if the buffer contains it */
1180  Dacl = (PSID)((ULONG_PTR)Sd->Dacl + (ULONG_PTR)Sd);
1181  if (!(RtlValidAcl(Dacl)) || (Length < Dacl->AclSize)) return FALSE;
1182  }
1183 
1184  /* Is there a SACL? */
1185  if ((Sd->Control & SE_SACL_PRESENT) == SE_SACL_PRESENT)
1186  {
1187  /* Try to access it */
1190  sizeof(ACL),
1191  &Length))
1192  {
1193  /* It's beyond the buffer, fail */
1194  return FALSE;
1195  }
1196 
1197  /* Read the SACL, check if it's valid and if the buffer contains it */
1198  Sacl = (PSID)((ULONG_PTR)Sd->Sacl + (ULONG_PTR)Sd);
1199  if (!(RtlValidAcl(Sacl)) || (Length < Sacl->AclSize)) return FALSE;
1200  }
1201 
1202  /* All good */
1203  return TRUE;
1204 }
1205 
1206 /* EOF */
NTSTATUS NTAPI RtlGetSaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PBOOLEAN SaclPresent, OUT PACL *Sacl, OUT PBOOLEAN SaclDefaulted)
Definition: sd.c:228
#define IN
Definition: typedefs.h:38
#define SE_SACL_PRESENT
Definition: setypes.h:769
_In_opt_ PSID _In_opt_ BOOLEAN OwnerDefaulted
Definition: rtlfuncs.h:1630
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS NTAPI RtlSetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest, IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet)
Definition: sd.c:464
NTSTATUS NTAPI RtlSetOwnerSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSID Owner, IN BOOLEAN OwnerDefaulted)
Definition: sd.c:381
#define STATUS_INVALID_SECURITY_DESCR
Definition: ntstatus.h:343
#define SE_SELF_RELATIVE
Definition: setypes.h:780
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
WORD * PSECURITY_DESCRIPTOR_CONTROL
Definition: lsa.idl:37
_In_ BOOLEAN _In_opt_ PACL _In_opt_ BOOLEAN DaclDefaulted
Definition: rtlfuncs.h:1595
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:182
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
USHORT AclSize
Definition: ms-dtyp.idl:296
_In_opt_ PSID Group
Definition: rtlfuncs.h:1606
unsigned char * PUCHAR
Definition: retypes.h:3
VOID NTAPI RtlSetSecurityDescriptorRMControl(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PUCHAR RMControl)
Definition: sd.c:524
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI RtlSetAttributesSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN SECURITY_DESCRIPTOR_CONTROL Control, OUT PULONG Revision)
Definition: sd.c:550
NTSTATUS NTAPI RtlCreateSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN ULONG Revision)
Definition: sd.c:117
NTSTATUS NTAPI RtlCreateSecurityDescriptorRelative(IN PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor, IN ULONG Revision)
Definition: sd.c:139
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
#define PAGED_CODE_RTL()
Definition: rtlp.h:16
#define SE_DACL_PRESENT
Definition: setypes.h:767
_In_ ULONG TotalLength
Definition: usbdlib.h:145
NTSTATUS NTAPI RtlSelfRelativeToAbsoluteSD2(IN OUT PSECURITY_DESCRIPTOR SelfRelativeSD, OUT PULONG BufferSize)
Definition: sd.c:844
_In_ ULONG SecurityDescriptorLength
Definition: rtlfuncs.h:1674
NTSTATUS NTAPI RtlAbsoluteToSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor, IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, IN PULONG BufferLength)
Definition: sd.c:626
_In_ ULONG Revision
Definition: rtlfuncs.h:1104
#define SE_DACL_AUTO_INHERITED
Definition: setypes.h:775
_In_ BOOLEAN DaclPresent
Definition: rtlfuncs.h:1595
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define SE_OWNER_DEFAULTED
Definition: setypes.h:765
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID _Inout_ PULONG _Out_writes_bytes_to_opt_ PrimaryGroupSize PSID _Inout_ PULONG PrimaryGroupSize
Definition: rtlfuncs.h:1559
_SEH2_TRY
Definition: create.c:4250
NTSTATUS NTAPI RtlSetDaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN DaclPresent, IN PACL Dacl, IN BOOLEAN DaclDefaulted)
Definition: sd.c:303
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
long LONG
Definition: pedump.c:60
DWORD SECURITY_INFORMATION
Definition: ms-dtyp.idl:311
_In_ ULONG BufferLength
Definition: usbdlib.h:225
WORD SECURITY_DESCRIPTOR_CONTROL
Definition: lsa.idl:37
FORCEINLINE PACL SepGetSaclFromDescriptor(PVOID _Descriptor)
Definition: se.h:88
NTSYSAPI BOOLEAN NTAPI RtlValidAcl(PACL Acl)
_Out_ PBOOLEAN SaclPresent
Definition: rtlfuncs.h:2415
struct _SECURITY_DESCRIPTOR_RELATIVE * PISECURITY_DESCRIPTOR_RELATIVE
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
_In_ ULONG _In_ SECURITY_INFORMATION RequiredInformation
Definition: rtlfuncs.h:1674
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:462
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG SaclSize
Definition: rtlfuncs.h:1555
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
void * PVOID
Definition: retypes.h:9
NTSYSAPI BOOLEAN NTAPI RtlValidSid(IN PSID Sid)
Definition: sid.c:21
NTSTATUS NTAPI RtlMakeSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSD, OUT PSECURITY_DESCRIPTOR SelfRelativeSD, IN OUT PULONG BufferLength)
Definition: sd.c:647
#define SE_DACL_DEFAULTED
Definition: setypes.h:768
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
struct _ACL * PACL
Definition: security.c:104
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID _Inout_ PULONG _Out_writes_bytes_to_opt_ PrimaryGroupSize PSID PrimaryGroup
Definition: rtlfuncs.h:1559
FORCEINLINE PSID SepGetOwnerFromDescriptor(PVOID _Descriptor)
Definition: se.h:48
BOOLEAN NTAPI RtlpValidateSDOffsetAndSize(IN ULONG Offset, IN ULONG Length, IN ULONG MinLength, OUT PULONG MaxLength)
Definition: sd.c:20
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define SE_SACL_AUTO_INHERIT_REQ
Definition: setypes.h:774
#define ALIGN_DOWN(size, type)
Definition: umtypes.h:88
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor
Definition: rtlfuncs.h:1551
#define SE_DACL_PROTECTED
Definition: setypes.h:777
#define BufferSize
Definition: classpnp.h:419
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
struct _SID * PSID
Definition: eventlog.c:35
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Out_writes_bytes_to_opt_ BufferLength PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor
Definition: rtlfuncs.h:1094
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1553
NTSTATUS NTAPI RtlSetGroupSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSID Group, IN BOOLEAN GroupDefaulted)
Definition: sd.c:410
char * PBOOLEAN
Definition: retypes.h:11
#define SE_SACL_PROTECTED
Definition: setypes.h:778
VOID NTAPI RtlpQuerySecurityDescriptor(IN PISECURITY_DESCRIPTOR SecurityDescriptor, OUT PSID *Owner, OUT PULONG OwnerSize, OUT PSID *PrimaryGroup, OUT PULONG PrimaryGroupSize, OUT PACL *Dacl, OUT PULONG DaclSize, OUT PACL *Sacl, OUT PULONG SaclSize)
Definition: sd.c:45
#define STATUS_BAD_DESCRIPTOR_FORMAT
Definition: ntstatus.h:453
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:461
NTSTATUS NTAPI RtlGetGroupSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PSID *Group, OUT PBOOLEAN GroupDefaulted)
Definition: sd.c:280
struct _SECURITY_DESCRIPTOR_RELATIVE SECURITY_DESCRIPTOR_RELATIVE
struct _SECURITY_DESCRIPTOR SECURITY_DESCRIPTOR
#define SE_GROUP_DEFAULTED
Definition: setypes.h:766
#define SE_SERVER_SECURITY
Definition: setypes.h:772
NTSTATUS NTAPI RtlSelfRelativeToAbsoluteSD(IN PSECURITY_DESCRIPTOR SelfRelativeSD, OUT PSECURITY_DESCRIPTOR AbsoluteSD, IN PULONG AbsoluteSDSize, IN PACL Dacl, IN PULONG DaclSize, IN PACL Sacl, IN PULONG SaclSize, IN PSID Owner, IN PULONG OwnerSize, IN PSID PrimaryGroup, IN PULONG PrimaryGroupSize)
Definition: sd.c:743
static const WCHAR Control[]
Definition: interface.c:27
BOOLEAN NTAPI RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInput, IN ULONG SecurityDescriptorLength, IN SECURITY_INFORMATION RequiredInformation)
Definition: sd.c:1099
NTSTATUS NTAPI RtlGetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PSECURITY_DESCRIPTOR_CONTROL Control, OUT PULONG Revision)
Definition: sd.c:439
FORCEINLINE PSID SepGetGroupFromDescriptor(PVOID _Descriptor)
Definition: se.h:29
FORCEINLINE PACL SepGetDaclFromDescriptor(PVOID _Descriptor)
Definition: se.h:67
_SEH2_END
Definition: create.c:4424
#define SE_DACL_UNTRUSTED
Definition: setypes.h:771
BOOLEAN NTAPI RtlValidSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: sd.c:1055
SECURITY_DESCRIPTOR_CONTROL Control
Definition: setypes.h:785
#define SE_SACL_AUTO_INHERITED
Definition: setypes.h:776
NTSTATUS NTAPI RtlSetSaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN SaclPresent, IN PACL Sacl, IN BOOLEAN SaclDefaulted)
Definition: sd.c:342
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID _Inout_ PULONG OwnerSize
Definition: rtlfuncs.h:1557
#define OWNER_SECURITY_INFORMATION
Definition: setypes.h:123
unsigned int * PULONG
Definition: retypes.h:1
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1557
NTSTATUS NTAPI RtlGetOwnerSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PSID *Owner, OUT PBOOLEAN OwnerDefaulted)
Definition: sd.c:257
NTSTATUS NTAPI RtlGetDaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PBOOLEAN DaclPresent, OUT PACL *Dacl, OUT PBOOLEAN DaclDefaulted)
Definition: sd.c:199
BOOLEAN NTAPI RtlGetSecurityDescriptorRMControl(IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PUCHAR RMControl)
Definition: sd.c:500
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1553
#define SE_RM_CONTROL_VALID
Definition: setypes.h:779
#define OUT
Definition: typedefs.h:39
#define SE_DACL_AUTO_INHERIT_REQ
Definition: setypes.h:773
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL Sacl
Definition: rtlfuncs.h:1555
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
_In_ ULONG _In_ CONST SOCKADDR _In_ int GroupLength
Definition: ws2tcpip.h:710
#define SE_SACL_DEFAULTED
Definition: setypes.h:770
_Out_ PBOOLEAN _Out_ PACL _Out_ PBOOLEAN SaclDefaulted
Definition: rtlfuncs.h:2415
_In_opt_ PSID _In_opt_ BOOLEAN GroupDefaulted
Definition: rtlfuncs.h:1606
return STATUS_SUCCESS
Definition: btrfs.c:2725
ULONG NTAPI RtlLengthSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: sd.c:161
NTSTATUS NTAPI RtlCopySecurityDescriptor(IN PSECURITY_DESCRIPTOR pSourceSecurityDescriptor, OUT PSECURITY_DESCRIPTOR *pDestinationSecurityDescriptor)
Definition: sd.c:582
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4733
#define STATUS_UNKNOWN_REVISION
Definition: ntstatus.h:310
struct _SECURITY_DESCRIPTOR * PISECURITY_DESCRIPTOR