:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / ntdll / rtl / sd.c
1 /* $Id$
2  *
3  * COPYRIGHT:         See COPYING in the top level directory
4  * PROJECT:           ReactOS kernel
5  * PURPOSE:           Security descriptor functions
6  * FILE:              lib/ntdll/rtl/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
16 #include <ntdll/ntdll.h>
17
18 /* FUNCTIONS ***************************************************************/
19
20 NTSTATUS STDCALL
21 RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
22                             ULONG Revision)
23 {
24   if (Revision != 1)
25     {
26       return(STATUS_UNSUCCESSFUL);
27     }
28
29   SecurityDescriptor->Revision = 1;
30   SecurityDescriptor->Sbz1 = 0;
31   SecurityDescriptor->Control = 0;
32   SecurityDescriptor->Owner = NULL;
33   SecurityDescriptor->Group = NULL;
34   SecurityDescriptor->Sacl = NULL;
35   SecurityDescriptor->Dacl = NULL;
36
37   return(STATUS_SUCCESS);
38 }
39
40 ULONG STDCALL
41 RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
42 {
43   PSID Owner;
44   PSID Group;
45   ULONG Length;
46   PACL Dacl;
47   PACL Sacl;
48
49   Length = sizeof(SECURITY_DESCRIPTOR);
50
51   if (SecurityDescriptor->Owner != NULL)
52     {
53         Owner = SecurityDescriptor->Owner;
54         if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
55           {
56              Owner = (PSID)((ULONG)Owner + 
57                             (ULONG)SecurityDescriptor);
58           }
59         Length = Length + ((sizeof(SID) + (Owner->SubAuthorityCount - 1) * 
60                            sizeof(ULONG) + 3) & 0xfc);
61     }
62
63   if (SecurityDescriptor->Group != NULL)
64     {
65         Group = SecurityDescriptor->Group;
66         if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
67           {
68              Group = (PSID)((ULONG)Group + (ULONG)SecurityDescriptor);
69           }
70         Length = Length + ((sizeof(SID) + (Group->SubAuthorityCount - 1) *
71                            sizeof(ULONG) + 3) & 0xfc);
72     }
73
74   if (SecurityDescriptor->Control & SE_DACL_PRESENT &&
75       SecurityDescriptor->Dacl != NULL)
76     {
77         Dacl = SecurityDescriptor->Dacl;
78         if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
79           {
80              Dacl = (PACL)((ULONG)Dacl + (PVOID)SecurityDescriptor);
81           }
82         Length = Length + ((Dacl->AclSize + 3) & 0xfc);
83     }
84
85   if (SecurityDescriptor->Control & SE_SACL_PRESENT &&
86       SecurityDescriptor->Sacl != NULL)
87     {
88         Sacl = SecurityDescriptor->Sacl;
89         if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
90           {
91              Sacl = (PACL)((ULONG)Sacl + (PVOID)SecurityDescriptor);
92           }
93         Length = Length + ((Sacl->AclSize + 3) & 0xfc);
94     }
95
96   return(Length);
97 }
98
99
100 NTSTATUS STDCALL
101 RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
102                              PBOOLEAN DaclPresent,
103                              PACL* Dacl,
104                              PBOOLEAN DaclDefaulted)
105 {
106    if (SecurityDescriptor->Revision != 1)
107      {
108         return(STATUS_UNSUCCESSFUL);
109      }
110    if (!(SecurityDescriptor->Control & SE_DACL_PRESENT))
111      {
112         *DaclPresent = 0;
113         return(STATUS_SUCCESS);
114      }
115    *DaclPresent = 1;
116    if (SecurityDescriptor->Dacl == NULL)
117      {
118         *Dacl = NULL;
119      }
120    else
121      {
122         if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
123           {
124              *Dacl = (PACL)((ULONG)SecurityDescriptor->Dacl +
125                             (PVOID)SecurityDescriptor);
126           }
127         else
128           {
129              *Dacl = SecurityDescriptor->Dacl;
130           }
131      }
132    if (SecurityDescriptor->Control & SE_DACL_DEFAULTED)
133      {
134         *DaclDefaulted = 1;
135      }
136    else
137      {
138         *DaclDefaulted = 0;
139      }
140    return(STATUS_SUCCESS);
141 }
142
143
144 NTSTATUS STDCALL
145 RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
146                              BOOLEAN DaclPresent,
147                              PACL Dacl,
148                              BOOLEAN DaclDefaulted)
149 {
150    if (SecurityDescriptor->Revision != 1)
151      {
152         return(STATUS_UNSUCCESSFUL);
153      }
154    if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
155      {
156         return(STATUS_UNSUCCESSFUL);
157      }
158    if (!DaclPresent)
159      {
160         SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_DACL_PRESENT);
161         return(STATUS_SUCCESS);
162      }
163    SecurityDescriptor->Control = SecurityDescriptor->Control | SE_DACL_PRESENT;
164    SecurityDescriptor->Dacl = Dacl;
165    SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_DACL_DEFAULTED);
166    if (DaclDefaulted)
167      {
168         SecurityDescriptor->Control = SecurityDescriptor->Control | SE_DACL_DEFAULTED;
169      }
170    return(STATUS_SUCCESS);
171 }
172
173
174 BOOLEAN STDCALL
175 RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor)
176 {
177   PSID Owner;
178   PSID Group;
179   PACL Sacl;
180   PACL Dacl;
181
182   if (SecurityDescriptor->Revision != 1)
183     {
184       return(FALSE);
185     }
186
187   Owner = SecurityDescriptor->Owner;
188   if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
189     {
190       Owner = (PSID)((ULONG)Owner + (ULONG)SecurityDescriptor);
191     }
192
193   if (!RtlValidSid(Owner))
194     {
195       return(FALSE);
196     }
197
198   Group = SecurityDescriptor->Group;
199   if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
200     {
201       Group = (PSID)((ULONG)Group + (ULONG)SecurityDescriptor);
202     }
203
204   if (!RtlValidSid(Group))
205     {
206       return(FALSE);
207     }
208
209   if (SecurityDescriptor->Control & SE_DACL_PRESENT &&
210       SecurityDescriptor->Dacl != NULL)
211     {
212       Dacl = SecurityDescriptor->Dacl;
213       if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
214         {
215           Dacl = (PACL)((ULONG)Dacl + (ULONG)SecurityDescriptor);
216         }
217
218       if (!RtlValidAcl(Dacl))
219         {
220           return(FALSE);
221         }
222     }
223
224   if (SecurityDescriptor->Control & SE_SACL_PRESENT &&
225       SecurityDescriptor->Sacl != NULL)
226     {
227       Sacl = SecurityDescriptor->Sacl;
228       if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
229         {
230           Sacl = (PACL)((ULONG)Sacl + (ULONG)SecurityDescriptor);
231         }
232
233       if (!RtlValidAcl(Sacl))
234         {
235           return(FALSE);
236         }
237     }
238
239   return(TRUE);
240 }
241
242
243 NTSTATUS STDCALL
244 RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
245                               PSID Owner,
246                               BOOLEAN OwnerDefaulted)
247 {
248    if (SecurityDescriptor->Revision != 1)
249      {
250         return(STATUS_UNSUCCESSFUL);
251      }
252    if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
253      {
254         return(STATUS_UNSUCCESSFUL);
255      }
256    SecurityDescriptor->Owner = Owner;
257    SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_OWNER_DEFAULTED);
258    if (OwnerDefaulted)
259      {
260         SecurityDescriptor->Control = SecurityDescriptor->Control | SE_OWNER_DEFAULTED;
261      }
262    return(STATUS_SUCCESS);
263 }
264
265 NTSTATUS STDCALL
266 RtlGetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
267                               PSID* Owner,
268                               PBOOLEAN OwnerDefaulted)
269 {
270    if (SecurityDescriptor->Revision != 1)
271      {
272         return(STATUS_UNSUCCESSFUL);
273      }
274    if (SecurityDescriptor->Owner != NULL)
275      {
276         if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
277           {
278              *Owner = (PSID)((ULONG)SecurityDescriptor->Owner +
279                              (PVOID)SecurityDescriptor);
280           }
281         else
282           {
283              *Owner = SecurityDescriptor->Owner;
284           }
285      }
286    else
287      {
288         *Owner = NULL;
289      }
290    if (SecurityDescriptor->Control & SE_OWNER_DEFAULTED)
291      {
292         *OwnerDefaulted = 1;
293      }
294    else
295      {
296         *OwnerDefaulted = 0;
297      }
298    return(STATUS_SUCCESS);
299 }
300
301 NTSTATUS STDCALL
302 RtlSetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
303                               PSID Group,
304                               BOOLEAN GroupDefaulted)
305 {
306    if (SecurityDescriptor->Revision != 1)
307      {
308         return(STATUS_UNSUCCESSFUL);
309      }
310    if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
311      {
312         return(STATUS_UNSUCCESSFUL);
313      }
314    SecurityDescriptor->Group = Group;
315    SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_GROUP_DEFAULTED);
316    if (GroupDefaulted)
317      {
318         SecurityDescriptor->Control = SecurityDescriptor->Control | SE_GROUP_DEFAULTED;
319      }
320    return(STATUS_SUCCESS);
321 }
322
323 NTSTATUS STDCALL
324 RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
325                               PSID* Group,
326                               PBOOLEAN GroupDefaulted)
327 {
328    if (SecurityDescriptor->Revision != 1)
329      {
330         return(STATUS_UNSUCCESSFUL);
331      }
332    if (SecurityDescriptor->Group != NULL)
333      {
334         if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
335           {
336              *Group = (PSID)((ULONG)SecurityDescriptor->Group +
337                              (PVOID)SecurityDescriptor);
338           }
339         else
340           {
341              *Group = SecurityDescriptor->Group;
342           }
343      }
344    else
345      {
346         *Group = NULL;
347      }
348    if (SecurityDescriptor->Control & SE_GROUP_DEFAULTED)
349      {
350         *GroupDefaulted = 1;
351      }
352    else
353      {
354         *GroupDefaulted = 0;
355      }
356    return(STATUS_SUCCESS);
357 }
358
359
360 static VOID
361 RtlpQuerySecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
362                             PSID* Owner,
363                             PULONG OwnerLength,
364                             PSID* Group,
365                             PULONG GroupLength,
366                             PACL* Dacl,
367                             PULONG DaclLength,
368                             PACL* Sacl,
369                             PULONG SaclLength)
370 {
371   if (SecurityDescriptor->Owner == NULL)
372     {
373       *Owner = NULL;
374     }
375   else
376     {
377       *Owner = SecurityDescriptor->Owner;
378       if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
379         {
380           *Owner = (PSID)((ULONG)*Owner + (ULONG)SecurityDescriptor);
381         }
382     }
383
384   if (*Owner != NULL)
385     {
386       *OwnerLength = (RtlLengthSid(*Owner) + 3) & ~3;
387     }
388   else
389     {
390       *OwnerLength = 0;
391     }
392
393   if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
394       SecurityDescriptor->Dacl != NULL)
395     {
396       *Dacl = SecurityDescriptor->Dacl;
397       if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
398         {
399           *Dacl = (PACL)((ULONG)*Dacl + (ULONG)SecurityDescriptor);
400         }
401     }
402   else
403     {
404       *Dacl = NULL;
405     }
406
407   if (*Dacl != NULL)
408     {
409       *DaclLength = ((*Dacl)->AclSize + 3) & ~3;
410     }
411   else
412     {
413       *DaclLength = 0;
414     }
415
416   if (SecurityDescriptor->Group != NULL)
417     {
418       *Group = NULL;
419     }
420   else
421     {
422       *Group = SecurityDescriptor->Group;
423       if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
424         {
425           *Group = (PSID)((ULONG)*Group + (ULONG)SecurityDescriptor);
426         }
427     }
428
429   if (*Group != NULL)
430     {
431       *GroupLength = (RtlLengthSid(*Group) + 3) & ~3;
432     }
433   else
434     {
435       *GroupLength = 0;
436     }
437
438   if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
439       SecurityDescriptor->Sacl != NULL)
440     {
441       *Sacl = SecurityDescriptor->Sacl;
442       if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
443         {
444           *Sacl = (PACL)((ULONG)*Sacl + (ULONG)SecurityDescriptor);
445         }
446     }
447   else
448     {
449       *Sacl = NULL;
450     }
451
452   if (*Sacl != NULL)
453     {
454       *SaclLength = ((*Sacl)->AclSize + 3) & ~3;
455     }
456 }
457
458
459 NTSTATUS STDCALL
460 RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
461                       PSECURITY_DESCRIPTOR RelSD,
462                       PULONG BufferLength)
463 {
464   PSID Owner;
465   PSID Group;
466   PACL Sacl;
467   PACL Dacl;
468   ULONG OwnerLength;
469   ULONG GroupLength;
470   ULONG SaclLength;
471   ULONG DaclLength;
472   ULONG TotalLength;
473   ULONG Current;
474
475   RtlpQuerySecurityDescriptor(AbsSD,
476                               &Owner,
477                               &OwnerLength,
478                               &Group,
479                               &GroupLength,
480                               &Dacl,
481                               &DaclLength,
482                               &Sacl,
483                               &SaclLength);
484
485   TotalLength = OwnerLength + GroupLength + SaclLength + DaclLength + sizeof(SECURITY_DESCRIPTOR);
486   if (*BufferLength < TotalLength)
487     {
488       return(STATUS_BUFFER_TOO_SMALL);
489     }
490
491   RtlZeroMemory(RelSD,
492                 TotalLength);
493   memmove(RelSD,
494           AbsSD,
495           sizeof(SECURITY_DESCRIPTOR));
496   Current = (ULONG)RelSD + sizeof(SECURITY_DESCRIPTOR);
497
498   if (SaclLength != 0)
499     {
500       memmove((PVOID)Current,
501               Sacl,
502               SaclLength);
503       RelSD->Sacl = (PACL)((ULONG)Current - (ULONG)RelSD);
504       Current += SaclLength;
505     }
506
507   if (DaclLength != 0)
508     {
509       memmove((PVOID)Current,
510               Dacl,
511               DaclLength);
512       RelSD->Dacl = (PACL)((ULONG)Current - (ULONG)RelSD);
513       Current += DaclLength;
514     }
515
516   if (OwnerLength != 0)
517     {
518       memmove((PVOID)Current,
519               Owner,
520               OwnerLength);
521       RelSD->Owner = (PSID)((ULONG)Current - (ULONG)RelSD);
522       Current += OwnerLength;
523     }
524
525   if (GroupLength != 0)
526     {
527       memmove((PVOID)Current,
528               Group,
529               GroupLength);
530       RelSD->Group = (PSID)((ULONG)Current - (ULONG)RelSD);
531     }
532
533   RelSD->Control |= SE_SELF_RELATIVE;
534
535   return(STATUS_SUCCESS);
536 }
537
538
539 NTSTATUS STDCALL
540 RtlAbsoluteToSelfRelativeSD(PSECURITY_DESCRIPTOR AbsSD,
541                             PSECURITY_DESCRIPTOR RelSD,
542                             PULONG BufferLength
543         )
544 {
545   if (AbsSD->Control & SE_SELF_RELATIVE)
546     {
547       return(STATUS_BAD_DESCRIPTOR_FORMAT);
548     }
549
550   return(RtlMakeSelfRelativeSD(AbsSD, RelSD, BufferLength));
551 }
552
553
554 NTSTATUS STDCALL
555 RtlGetControlSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
556                                 PSECURITY_DESCRIPTOR_CONTROL Control,
557                                 PULONG Revision)
558 {
559   *Revision = SecurityDescriptor->Revision;
560
561   if (SecurityDescriptor->Revision != 1)
562     {
563       return(STATUS_UNKNOWN_REVISION);
564     }
565
566   *Control = SecurityDescriptor->Control;
567
568   return(STATUS_SUCCESS);
569 }
570
571
572 NTSTATUS STDCALL
573 RtlGetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
574                              PBOOLEAN SaclPresent,
575                              PACL *Sacl,
576                              PBOOLEAN SaclDefaulted)
577 {
578    if (SecurityDescriptor->Revision != 1)
579      {
580         return(STATUS_UNSUCCESSFUL);
581      }
582    if (!(SecurityDescriptor->Control & SE_SACL_PRESENT))
583      {
584         *SaclPresent = 0;
585         return(STATUS_SUCCESS);
586      }
587    *SaclPresent = 1;
588    if (SecurityDescriptor->Sacl == NULL)
589      {
590         *Sacl = NULL;
591      }
592    else
593      {
594         if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
595           {
596              *Sacl = (PACL)((ULONG)SecurityDescriptor->Sacl +
597                             (PVOID)SecurityDescriptor);
598           }
599         else
600           {
601              *Sacl = SecurityDescriptor->Sacl;
602           }
603      }
604    if (SecurityDescriptor->Control & SE_SACL_DEFAULTED)
605      {
606         *SaclDefaulted = 1;
607      }
608    else
609      {
610         *SaclDefaulted = 0;
611      }
612    return(STATUS_SUCCESS);
613 }
614
615 NTSTATUS STDCALL
616 RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
617                              BOOLEAN SaclPresent,
618                              PACL Sacl,
619                              BOOLEAN SaclDefaulted)
620 {
621    if (SecurityDescriptor->Revision != 1)
622      {
623         return(STATUS_UNSUCCESSFUL);
624      }
625    if (SecurityDescriptor->Control & SE_SELF_RELATIVE)
626      {
627         return(STATUS_UNSUCCESSFUL);
628      }
629    if (!SaclPresent)
630      {
631         SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_SACL_PRESENT);
632         return(STATUS_SUCCESS);
633      }
634    SecurityDescriptor->Control = SecurityDescriptor->Control | SE_SACL_PRESENT;
635    SecurityDescriptor->Sacl = Sacl;
636    SecurityDescriptor->Control = SecurityDescriptor->Control & ~(SE_SACL_DEFAULTED);
637    if (SaclDefaulted)
638      {
639         SecurityDescriptor->Control = SecurityDescriptor->Control | SE_SACL_DEFAULTED;
640      }
641    return(STATUS_SUCCESS);
642 }
643
644 NTSTATUS STDCALL
645 RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR RelSD,
646                             PSECURITY_DESCRIPTOR AbsSD,
647                             PDWORD AbsSDSize,
648                             PACL Dacl,
649                             PDWORD DaclSize,
650                             PACL Sacl,
651                             PDWORD SaclSize,
652                             PSID Owner,
653                             PDWORD OwnerSize,
654                             PSID Group,
655                             PDWORD GroupSize)
656 {
657    UNIMPLEMENTED;
658 }
659
660 /* EOF */