Thomas Weidenmueller <w3seek@reactos.com>
[reactos.git] / reactos / lib / 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/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 #define __NTDRIVER__
15 #include <ddk/ntddk.h>
16 #include <ntdll/rtl.h>
17 #include <string.h>
18
19
20 #define NDEBUG
21 #include <debug.h>
22
23 /* FUNCTIONS ***************************************************************/
24
25 BOOLEAN STDCALL
26 RtlValidSid(IN PSID Sid_)
27 {
28 PISID Sid = Sid_;
29
30 PAGED_CODE_RTL();
31
32 if ((Sid->Revision != SID_REVISION) ||
33 (Sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES))
34 {
35 return FALSE;
36 }
37
38 return TRUE;
39 }
40
41
42 /*
43 * @implemented
44 */
45 ULONG STDCALL
46 RtlLengthRequiredSid(IN UCHAR SubAuthorityCount)
47 {
48 PAGED_CODE_RTL();
49
50 return (sizeof(SID) + (SubAuthorityCount - 1) * sizeof(ULONG));
51 }
52
53
54 /*
55 * @implemented
56 */
57 NTSTATUS STDCALL
58 RtlInitializeSid(IN PSID Sid_,
59 IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
60 IN UCHAR SubAuthorityCount)
61 {
62 PISID Sid = Sid_;
63
64 PAGED_CODE_RTL();
65
66 Sid->Revision = SID_REVISION;
67 Sid->SubAuthorityCount = SubAuthorityCount;
68 memcpy(&Sid->IdentifierAuthority,
69 IdentifierAuthority,
70 sizeof(SID_IDENTIFIER_AUTHORITY));
71
72 return STATUS_SUCCESS;
73 }
74
75
76 /*
77 * @implemented
78 */
79 PULONG STDCALL
80 RtlSubAuthoritySid(IN PSID Sid_,
81 IN ULONG SubAuthority)
82 {
83 PISID Sid = Sid_;
84
85 PAGED_CODE_RTL();
86
87 return &Sid->SubAuthority[SubAuthority];
88 }
89
90
91 /*
92 * @implemented
93 */
94 PUCHAR STDCALL
95 RtlSubAuthorityCountSid(IN PSID Sid_)
96 {
97 PISID Sid = Sid_;
98
99 PAGED_CODE_RTL();
100
101 return &Sid->SubAuthorityCount;
102 }
103
104
105 /*
106 * @implemented
107 */
108 BOOLEAN STDCALL
109 RtlEqualSid(IN PSID Sid1_,
110 IN PSID Sid2_)
111 {
112 PISID Sid1 = Sid1_;
113 PISID Sid2 = Sid2_;
114
115 PAGED_CODE_RTL();
116
117 if (Sid1->Revision != Sid2->Revision)
118 {
119 return(FALSE);
120 }
121 if ((*RtlSubAuthorityCountSid(Sid1)) != (*RtlSubAuthorityCountSid(Sid2)))
122 {
123 return(FALSE);
124 }
125 if (RtlCompareMemory(Sid1, Sid2, RtlLengthSid(Sid1)) != RtlLengthSid(Sid1))
126 {
127 return(FALSE);
128 }
129 return(TRUE);
130 }
131
132
133 /*
134 * @implemented
135 */
136 ULONG STDCALL
137 RtlLengthSid(IN PSID Sid_)
138 {
139 PISID Sid = Sid_;
140
141 PAGED_CODE_RTL();
142
143 return (sizeof(SID) + (Sid->SubAuthorityCount-1) * sizeof(ULONG));
144 }
145
146
147 /*
148 * @implemented
149 */
150 NTSTATUS STDCALL
151 RtlCopySid(ULONG BufferLength,
152 PSID Dest,
153 PSID Src)
154 {
155 PAGED_CODE_RTL();
156
157 if (BufferLength < RtlLengthSid(Src))
158 {
159 return STATUS_UNSUCCESSFUL;
160 }
161
162 memmove(Dest,
163 Src,
164 RtlLengthSid(Src));
165
166 return STATUS_SUCCESS;
167 }
168
169
170 /*
171 * @implemented
172 */
173 NTSTATUS STDCALL
174 RtlCopySidAndAttributesArray(ULONG Count,
175 PSID_AND_ATTRIBUTES Src,
176 ULONG SidAreaSize,
177 PSID_AND_ATTRIBUTES Dest,
178 PVOID SidArea,
179 PVOID* RemainingSidArea,
180 PULONG RemainingSidAreaSize)
181 {
182 ULONG SidLength;
183 ULONG Length;
184 ULONG i;
185
186 PAGED_CODE_RTL();
187
188 Length = SidAreaSize;
189
190 for (i=0; i<Count; i++)
191 {
192 if (RtlLengthSid(Src[i].Sid) > Length)
193 {
194 return(STATUS_BUFFER_TOO_SMALL);
195 }
196 SidLength = RtlLengthSid(Src[i].Sid);
197 Length = Length - SidLength;
198 Dest[i].Sid = SidArea;
199 Dest[i].Attributes = Src[i].Attributes;
200 RtlCopySid(SidLength,
201 SidArea,
202 Src[i].Sid);
203 SidArea = (PVOID)((ULONG_PTR)SidArea + SidLength);
204 }
205 *RemainingSidArea = SidArea;
206 *RemainingSidAreaSize = Length;
207 return(STATUS_SUCCESS);
208 }
209
210
211 /*
212 * @implemented
213 */
214 PSID_IDENTIFIER_AUTHORITY STDCALL
215 RtlIdentifierAuthoritySid(IN PSID Sid_)
216 {
217 PISID Sid = Sid_;
218
219 PAGED_CODE_RTL();
220
221 return &Sid->IdentifierAuthority;
222 }
223
224
225 /*
226 * @implemented
227 */
228 NTSTATUS STDCALL
229 RtlAllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
230 UCHAR SubAuthorityCount,
231 ULONG SubAuthority0,
232 ULONG SubAuthority1,
233 ULONG SubAuthority2,
234 ULONG SubAuthority3,
235 ULONG SubAuthority4,
236 ULONG SubAuthority5,
237 ULONG SubAuthority6,
238 ULONG SubAuthority7,
239 PSID *Sid)
240 {
241 PISID pSid;
242
243 PAGED_CODE_RTL();
244
245 if (SubAuthorityCount > 8)
246 return STATUS_INVALID_SID;
247
248 if (Sid == NULL)
249 return STATUS_INVALID_PARAMETER;
250
251 pSid = (PSID)ExAllocatePool(PagedPool,
252 sizeof(SID) + (SubAuthorityCount - 1) * sizeof(ULONG));
253 if (pSid == NULL)
254 return STATUS_NO_MEMORY;
255
256 pSid->Revision = SID_REVISION;
257 pSid->SubAuthorityCount = SubAuthorityCount;
258 memcpy(&pSid->IdentifierAuthority,
259 IdentifierAuthority,
260 sizeof(SID_IDENTIFIER_AUTHORITY));
261
262 switch (SubAuthorityCount)
263 {
264 case 8:
265 pSid->SubAuthority[7] = SubAuthority7;
266 case 7:
267 pSid->SubAuthority[6] = SubAuthority6;
268 case 6:
269 pSid->SubAuthority[5] = SubAuthority5;
270 case 5:
271 pSid->SubAuthority[4] = SubAuthority4;
272 case 4:
273 pSid->SubAuthority[3] = SubAuthority3;
274 case 3:
275 pSid->SubAuthority[2] = SubAuthority2;
276 case 2:
277 pSid->SubAuthority[1] = SubAuthority1;
278 case 1:
279 pSid->SubAuthority[0] = SubAuthority0;
280 break;
281 }
282
283 *Sid = pSid;
284
285 return STATUS_SUCCESS;
286 }
287
288
289 /*
290 * @implemented
291 *
292 * RETURNS
293 * Docs says FreeSid does NOT return a value
294 * even thou it's defined to return a PVOID...
295 */
296 PVOID STDCALL
297 RtlFreeSid(IN PSID Sid)
298 {
299 PAGED_CODE_RTL();
300
301 ExFreePool(Sid);
302 return NULL;
303 }
304
305
306 /*
307 * @implemented
308 */
309 BOOLEAN STDCALL
310 RtlEqualPrefixSid(IN PSID Sid1_,
311 IN PSID Sid2_)
312 {
313 PISID Sid1 = Sid1_;
314 PISID Sid2 = Sid2_;
315
316 PAGED_CODE_RTL();
317
318 return(Sid1->SubAuthorityCount == Sid2->SubAuthorityCount &&
319 !RtlCompareMemory(Sid1, Sid2,
320 (Sid1->SubAuthorityCount - 1) * sizeof(DWORD) + 8));
321 }
322
323
324 /*
325 * @implemented
326 */
327 NTSTATUS STDCALL
328 RtlConvertSidToUnicodeString(PUNICODE_STRING String,
329 PSID Sid_,
330 BOOLEAN AllocateBuffer)
331 {
332 WCHAR Buffer[256];
333 PWSTR wcs;
334 ULONG Length;
335 ULONG i;
336 PISID Sid = Sid_;
337
338 PAGED_CODE_RTL();
339
340 if (RtlValidSid (Sid) == FALSE)
341 return STATUS_INVALID_SID;
342
343 wcs = Buffer;
344 wcs += swprintf (wcs, L"S-%u-", Sid->Revision);
345 if (Sid->IdentifierAuthority.Value[0] == 0 &&
346 Sid->IdentifierAuthority.Value[1] == 0)
347 {
348 wcs += swprintf (wcs,
349 L"%lu",
350 (ULONG)Sid->IdentifierAuthority.Value[2] << 24 |
351 (ULONG)Sid->IdentifierAuthority.Value[3] << 16 |
352 (ULONG)Sid->IdentifierAuthority.Value[4] << 8 |
353 (ULONG)Sid->IdentifierAuthority.Value[5]);
354 }
355 else
356 {
357 wcs += swprintf (wcs,
358 L"0x%02hx%02hx%02hx%02hx%02hx%02hx",
359 Sid->IdentifierAuthority.Value[0],
360 Sid->IdentifierAuthority.Value[1],
361 Sid->IdentifierAuthority.Value[2],
362 Sid->IdentifierAuthority.Value[3],
363 Sid->IdentifierAuthority.Value[4],
364 Sid->IdentifierAuthority.Value[5]);
365 }
366
367 for (i = 0; i < Sid->SubAuthorityCount; i++)
368 {
369 wcs += swprintf (wcs,
370 L"-%u",
371 Sid->SubAuthority[i]);
372 }
373
374 Length = (wcs - Buffer) * sizeof(WCHAR);
375 if (AllocateBuffer)
376 {
377 String->Buffer = ExAllocatePool(PagedPool,Length + sizeof(WCHAR));
378 if (String->Buffer == NULL)
379 return STATUS_NO_MEMORY;
380 String->MaximumLength = Length + sizeof(WCHAR);
381 }
382 else
383 {
384 if (Length > String->MaximumLength)
385 return STATUS_BUFFER_TOO_SMALL;
386 }
387
388 String->Length = Length;
389 RtlCopyMemory (String->Buffer,
390 Buffer,
391 Length);
392 if (Length < String->MaximumLength)
393 String->Buffer[Length / sizeof(WCHAR)] = 0;
394
395 return STATUS_SUCCESS;
396 }
397
398 /* EOF */