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