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