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