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