:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / ntdll / rtl / sid.c
1 /* $Id$
2  *
3  * COPYRIGHT:         See COPYING in the top level directory
4  * PROJECT:           ReactOS kernel
5  * PURPOSE:           Security manager
6  * FILE:              lib/ntdll/rtl/sid.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 <string.h>
16
17 //#include <internal/debug.h>
18
19 /* FUNCTIONS ***************************************************************/
20
21 BOOLEAN STDCALL
22 RtlValidSid(IN PSID Sid)
23 {
24   if ((Sid->Revision & 0xf) != 1)
25     {
26       return(FALSE);
27     }
28   if (Sid->SubAuthorityCount > 15)
29     {
30       return(FALSE);
31     }
32   return(TRUE);
33 }
34
35
36 ULONG STDCALL
37 RtlLengthRequiredSid(IN UCHAR SubAuthorityCount)
38 {
39   return(sizeof(SID) + (SubAuthorityCount - 1) * sizeof(ULONG));
40 }
41
42
43 NTSTATUS STDCALL
44 RtlInitializeSid(IN PSID Sid,
45                  IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
46                  IN UCHAR SubAuthorityCount)
47 {
48   Sid->Revision = 1;
49   Sid->SubAuthorityCount = SubAuthorityCount;
50   memcpy(&Sid->IdentifierAuthority,
51          IdentifierAuthority,
52          sizeof(SID_IDENTIFIER_AUTHORITY));
53   return(STATUS_SUCCESS);
54 }
55
56
57 PULONG STDCALL
58 RtlSubAuthoritySid(IN PSID Sid,
59                    IN ULONG SubAuthority)
60 {
61   return(&Sid->SubAuthority[SubAuthority]);
62 }
63
64
65 PUCHAR STDCALL
66 RtlSubAuthorityCountSid(IN PSID Sid)
67 {
68   return(&Sid->SubAuthorityCount);
69 }
70
71
72 BOOLEAN STDCALL
73 RtlEqualSid(IN PSID Sid1,
74             IN PSID Sid2)
75 {
76   if (Sid1->Revision != Sid2->Revision)
77     {
78       return(FALSE);
79     }
80   if ((*RtlSubAuthorityCountSid(Sid1)) != (*RtlSubAuthorityCountSid(Sid2)))
81     {
82       return(FALSE);
83     }
84    if (memcmp(Sid1, Sid2, RtlLengthSid(Sid1)) != 0)
85     {
86       return(FALSE);
87     }
88   return(TRUE);
89 }
90
91
92 ULONG STDCALL
93 RtlLengthSid(IN PSID Sid)
94 {
95   return(sizeof(SID) + (Sid->SubAuthorityCount-1)*4);
96 }
97
98
99 NTSTATUS STDCALL
100 RtlCopySid(ULONG BufferLength,
101            PSID Dest,
102            PSID Src)
103 {
104   if (BufferLength < RtlLengthSid(Src))
105     {
106       return(STATUS_UNSUCCESSFUL);
107     }
108   memmove(Dest,
109           Src,
110           RtlLengthSid(Src));
111   return(STATUS_SUCCESS);
112 }
113
114
115 NTSTATUS STDCALL
116 RtlCopySidAndAttributesArray(ULONG Count,
117                              PSID_AND_ATTRIBUTES Src,
118                              ULONG SidAreaSize,
119                              PSID_AND_ATTRIBUTES Dest,
120                              PVOID SidArea,
121                              PVOID* RemainingSidArea,
122                              PULONG RemainingSidAreaSize)
123 {
124   ULONG SidLength;
125   ULONG Length;
126   ULONG i;
127
128   Length = SidAreaSize;
129
130   for (i=0; i<Count; i++)
131     {
132       if (RtlLengthSid(Src[i].Sid) > Length)
133         {
134           return(STATUS_BUFFER_TOO_SMALL);
135         }
136       SidLength = RtlLengthSid(Src[i].Sid);
137       Length = Length - SidLength;
138       Dest[i].Sid = SidArea;
139       Dest[i].Attributes = Src[i].Attributes;
140       RtlCopySid(SidLength,
141                  SidArea,
142                  Src[i].Sid);
143       SidArea = SidArea + SidLength;
144     }
145   *RemainingSidArea = SidArea;
146   *RemainingSidAreaSize = Length;
147   return(STATUS_SUCCESS);
148 }
149
150
151 PSID_IDENTIFIER_AUTHORITY STDCALL
152 RtlIdentifierAuthoritySid(IN PSID Sid)
153 {
154   return(&Sid->IdentifierAuthority);
155 }
156
157
158 NTSTATUS
159 STDCALL
160 RtlAllocateAndInitializeSid (
161         PSID_IDENTIFIER_AUTHORITY       IdentifierAuthority,
162         UCHAR                           SubAuthorityCount,
163         ULONG                           SubAuthority0,
164         ULONG                           SubAuthority1,
165         ULONG                           SubAuthority2,
166         ULONG                           SubAuthority3,
167         ULONG                           SubAuthority4,
168         ULONG                           SubAuthority5,
169         ULONG                           SubAuthority6,
170         ULONG                           SubAuthority7,
171         PSID                            *Sid
172         )
173 {
174         PSID pSid;
175
176         if (SubAuthorityCount > 8)
177                 return STATUS_INVALID_SID;
178
179         if (Sid == NULL)
180                 return STATUS_INVALID_PARAMETER;
181
182         pSid = (PSID)RtlAllocateHeap (RtlGetProcessHeap (),
183                                       0,
184                                       SubAuthorityCount * sizeof(DWORD) + 8);
185         if (pSid == NULL)
186                 return STATUS_NO_MEMORY;
187
188         pSid->Revision = 1;
189         pSid->SubAuthorityCount = SubAuthorityCount;
190         memcpy (&pSid->IdentifierAuthority,
191                 IdentifierAuthority,
192                 sizeof(SID_IDENTIFIER_AUTHORITY));
193
194         switch (SubAuthorityCount)
195         {
196                 case 8:
197                         pSid->SubAuthority[7] = SubAuthority7;
198                 case 7:
199                         pSid->SubAuthority[6] = SubAuthority6;
200                 case 6:
201                         pSid->SubAuthority[5] = SubAuthority5;
202                 case 5:
203                         pSid->SubAuthority[4] = SubAuthority4;
204                 case 4:
205                         pSid->SubAuthority[3] = SubAuthority3;
206                 case 3:
207                         pSid->SubAuthority[2] = SubAuthority2;
208                 case 2:
209                         pSid->SubAuthority[1] = SubAuthority1;
210                 case 1:
211                         pSid->SubAuthority[0] = SubAuthority0;
212                         break;
213         }
214
215         *Sid = pSid;
216
217         return STATUS_SUCCESS;
218 }
219
220
221 PSID STDCALL
222 RtlFreeSid(IN PSID Sid)
223 {
224   RtlFreeHeap(RtlGetProcessHeap(),
225               0,
226               Sid);
227   return(Sid);
228 }
229
230
231 BOOLEAN STDCALL
232 RtlEqualPrefixSid(IN PSID Sid1,
233                   IN PSID Sid2)
234 {
235   return(Sid1->SubAuthorityCount == Sid2->SubAuthorityCount &&
236          !memcmp(Sid1, Sid2,
237                  (Sid1->SubAuthorityCount - 1) * sizeof(DWORD) + 8));
238 }
239
240
241 NTSTATUS STDCALL
242 RtlConvertSidToUnicodeString(PUNICODE_STRING String,
243                              PSID Sid,
244                              BOOLEAN AllocateBuffer)
245 {
246         WCHAR Buffer[256];
247         PWSTR wcs;
248         ULONG Length;
249         BYTE  i;
250
251         if (RtlValidSid (Sid) == FALSE)
252                 return STATUS_INVALID_SID;
253
254         wcs = Buffer;
255         wcs += swprintf (wcs, L"S-%u-", Sid->Revision);
256         if (!Sid->IdentifierAuthority.Value[0] &&
257             !Sid->IdentifierAuthority.Value[1])
258         {
259                 wcs += swprintf (wcs,
260                                  L"%u",
261                                  (DWORD)Sid->IdentifierAuthority.Value[2] << 24 |
262                                  (DWORD)Sid->IdentifierAuthority.Value[3] << 16 |
263                                  (DWORD)Sid->IdentifierAuthority.Value[4] << 8 |
264                                  (DWORD)Sid->IdentifierAuthority.Value[5]);
265         }
266         else
267         {
268                 wcs += swprintf (wcs,
269                                  L"0x%02hx%02hx%02hx%02hx%02hx%02hx",
270                                  Sid->IdentifierAuthority.Value[0],
271                                  Sid->IdentifierAuthority.Value[1],
272                                  Sid->IdentifierAuthority.Value[2],
273                                  Sid->IdentifierAuthority.Value[3],
274                                  Sid->IdentifierAuthority.Value[4],
275                                  Sid->IdentifierAuthority.Value[5]);
276         }
277
278         for (i = 0; i < Sid->SubAuthorityCount; i++)
279         {
280                 wcs += swprintf (wcs,
281                                  L"-%u",
282                                  Sid->SubAuthority[0]);
283         }
284
285         Length = (wcs - Buffer) * sizeof(WCHAR);
286         if(AllocateBuffer)
287         {
288                 String->Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
289                                                   0,
290                                                   Length + sizeof(WCHAR));
291                 if (String->Buffer == NULL)
292                         return STATUS_NO_MEMORY;
293                 String->MaximumLength = Length + sizeof(WCHAR);
294         }
295         else
296         {
297                 if (Length > String->MaximumLength)
298                         return STATUS_BUFFER_TOO_SMALL;
299         }
300
301         String->Length = Length;
302         memmove (String->Buffer,
303                  Buffer,
304                  Length);
305         if (Length < String->MaximumLength)
306                 String->Buffer[Length] = 0;
307
308         return STATUS_SUCCESS;
309 }
310
311 /* EOF */