- NDK fix: don't undef a million status codes, instead, have apps define WIN32_NO_STATUS.
[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 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 (sizeof(SID) - (ANYSIZE_ARRAY * sizeof(ULONG)) +
46 (SubAuthorityCount * sizeof(ULONG)));
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 &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 (sizeof(SID) - sizeof(Sid->SubAuthority) +
136 (Sid->SubAuthorityCount * sizeof(ULONG)));
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
309 PAGED_CODE_RTL();
310
311 return(Sid1->SubAuthorityCount == Sid2->SubAuthorityCount &&
312 !RtlCompareMemory(Sid1, Sid2,
313 (Sid1->SubAuthorityCount - 1) * sizeof(DWORD) + 8));
314 }
315
316
317 /*
318 * @implemented
319 */
320 NTSTATUS NTAPI
321 RtlConvertSidToUnicodeString(PUNICODE_STRING String,
322 PSID Sid_,
323 BOOLEAN AllocateBuffer)
324 {
325 WCHAR Buffer[256];
326 PWSTR wcs;
327 ULONG Length;
328 ULONG i;
329 PISID Sid = Sid_;
330
331 PAGED_CODE_RTL();
332
333 if (RtlValidSid (Sid) == FALSE)
334 return STATUS_INVALID_SID;
335
336 wcs = Buffer;
337 wcs += swprintf (wcs, L"S-%u-", Sid->Revision);
338 if (Sid->IdentifierAuthority.Value[0] == 0 &&
339 Sid->IdentifierAuthority.Value[1] == 0)
340 {
341 wcs += swprintf (wcs,
342 L"%lu",
343 (ULONG)Sid->IdentifierAuthority.Value[2] << 24 |
344 (ULONG)Sid->IdentifierAuthority.Value[3] << 16 |
345 (ULONG)Sid->IdentifierAuthority.Value[4] << 8 |
346 (ULONG)Sid->IdentifierAuthority.Value[5]);
347 }
348 else
349 {
350 wcs += swprintf (wcs,
351 L"0x%02hx%02hx%02hx%02hx%02hx%02hx",
352 Sid->IdentifierAuthority.Value[0],
353 Sid->IdentifierAuthority.Value[1],
354 Sid->IdentifierAuthority.Value[2],
355 Sid->IdentifierAuthority.Value[3],
356 Sid->IdentifierAuthority.Value[4],
357 Sid->IdentifierAuthority.Value[5]);
358 }
359
360 for (i = 0; i < Sid->SubAuthorityCount; i++)
361 {
362 wcs += swprintf (wcs,
363 L"-%u",
364 Sid->SubAuthority[i]);
365 }
366
367 if (AllocateBuffer)
368 {
369 if (!RtlCreateUnicodeString(String,
370 Buffer))
371 {
372 return STATUS_NO_MEMORY;
373 }
374 }
375 else
376 {
377 Length = (wcs - Buffer) * sizeof(WCHAR);
378
379 if (Length > String->MaximumLength)
380 return STATUS_BUFFER_TOO_SMALL;
381
382 String->Length = Length;
383 RtlCopyMemory (String->Buffer,
384 Buffer,
385 Length);
386 if (Length < String->MaximumLength)
387 String->Buffer[Length / sizeof(WCHAR)] = 0;
388 }
389
390 return STATUS_SUCCESS;
391 }
392
393 /* EOF */