ReactOS  0.4.13-dev-247-g0f29b3f
sid.c
Go to the documentation of this file.
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 #define NDEBUG
13 #include <debug.h>
14 
15 #define TAG_SID 'diSp'
16 
17 /* FUNCTIONS ***************************************************************/
18 
19 BOOLEAN
20 NTAPI
22 {
23  PISID Sid = Sid_;
25 
26  /* Use SEH in case any pointer is invalid */
27  _SEH2_TRY
28  {
29  /* Validate the revision and subauthority count */
30  if ((Sid) &&
31  (((Sid->Revision & 0xF) != SID_REVISION) ||
33  {
34  /* It's not, fail */
35  _SEH2_YIELD(return FALSE);
36  }
37  }
39  {
40  /* Access violation, SID is not valid */
41  _SEH2_YIELD(return FALSE);
42  }
43  _SEH2_END;
44 
45  /* All good */
46  return TRUE;
47 }
48 
49 /*
50  * @implemented
51  */
52 ULONG
53 NTAPI
55 {
57 
58  /* Return the required length */
59  return (ULONG)FIELD_OFFSET(SID,
60  SubAuthority[SubAuthorityCount]);
61 }
62 
63 /*
64  * @implemented
65  */
67 NTAPI
71 {
72  PISID Sid = Sid_;
74 
75  /* Fill out the header */
79 
80  /* All good */
81  return STATUS_SUCCESS;
82 }
83 
84 /*
85  * @implemented
86  */
87 PULONG
88 NTAPI
90  IN ULONG SubAuthority)
91 {
92  PISID Sid = Sid_;
94 
95  /* Return the offset */
96  return (PULONG)&Sid->SubAuthority[SubAuthority];
97 }
98 
99 /*
100  * @implemented
101  */
102 PUCHAR
103 NTAPI
105 {
106  PISID Sid = Sid_;
107  PAGED_CODE_RTL();
108 
109  /* Return the offset to the count */
110  return &Sid->SubAuthorityCount;
111 }
112 
113 /*
114  * @implemented
115  */
117 NTAPI
119 {
120  PISID Sid = Sid_;
121  PAGED_CODE_RTL();
122 
123  /* Return the offset to the identifier authority */
124  return &Sid->IdentifierAuthority;
125 }
126 
127 /*
128  * @implemented
129  */
130 BOOLEAN
131 NTAPI
133  IN PSID Sid2_)
134 {
135  PISID Sid1 = Sid1_, Sid2 = Sid2_;
136  PAGED_CODE_RTL();
137 
138  /* Quick compare of the revision and the count */
139  if (*(PUSHORT)&Sid1->Revision != *(PUSHORT)&Sid2->Revision) return FALSE;
140 
141  /* Get the length and compare it the long way */
142  return RtlEqualMemory(Sid1, Sid2, RtlLengthSid(Sid1));
143 }
144 
145 /*
146  * @implemented
147  */
148 ULONG
149 NTAPI
151 {
152  PISID Sid = Sid_;
153  PAGED_CODE_RTL();
154 
155  /* The offset to the last index + 1 (since it's a count) is the length */
156  return (ULONG)FIELD_OFFSET(SID,
157  SubAuthority[Sid->SubAuthorityCount]);
158 }
159 
160 /*
161  * @implemented
162  */
163 NTSTATUS
164 NTAPI
166  IN PSID Dest,
167  IN PSID Src)
168 {
169  ULONG SidLength;
170  PAGED_CODE_RTL();
171 
172  /* Make sure the buffer is large enough*/
173  SidLength = RtlLengthSid(Src);
174  if (SidLength > BufferLength) return STATUS_BUFFER_TOO_SMALL;
175 
176  /* And then copy the SID */
177  RtlMoveMemory(Dest, Src, SidLength);
178  return STATUS_SUCCESS;
179 }
180 
181 /*
182  * @implemented
183  */
184 PVOID
185 NTAPI
187 {
188  PAGED_CODE_RTL();
189 
190  /* Free the SID and always return NULL */
192  return NULL;
193 }
194 
195 /*
196  * @implemented
197  */
198 BOOLEAN
199 NTAPI
201  IN PSID Sid2_)
202 {
203  PISID Sid1 = Sid1_, Sid2 = Sid2_;
204  ULONG i;
205  PAGED_CODE_RTL();
206 
207  /* Revisions have to match */
208  if (Sid1->Revision != Sid2->Revision) return FALSE;
209 
210  /* The identifier authorities have to match */
211  if ((Sid1->IdentifierAuthority.Value[0] == Sid2->IdentifierAuthority.Value[0]) &&
217  {
218  /* The subauthority counts have to match */
220  {
221  /* If there aren't any in SID1, means none in SID2 either, so equal */
222  if (!Sid1->SubAuthorityCount) return TRUE;
223 
224  /* Now compare all the subauthority values BUT the last one */
225  for (i = 0; (i + 1) < Sid1->SubAuthorityCount; i++)
226  {
227  /* Does any mismatch? */
228  if (Sid1->SubAuthority[i] != Sid2->SubAuthority[i])
229  {
230  /* Prefix doesn't match, fail */
231  return FALSE;
232  }
233  }
234 
235  /* Everything that should matches, does, return success */
236  return TRUE;
237  }
238  }
239 
240  /* Identifiers don't match, fail */
241  return FALSE;
242 }
243 
244 /*
245  * @implemented
246  */
247 NTSTATUS
248 NTAPI
251  IN ULONG SidAreaSize,
252  IN PSID_AND_ATTRIBUTES Dest,
253  IN PSID SidArea,
254  OUT PSID* RemainingSidArea,
255  OUT PULONG RemainingSidAreaSize)
256 {
257  ULONG SidLength, i;
258  PAGED_CODE_RTL();
259 
260  /* Loop all the attributes */
261  for (i = 0; i < Count; i++)
262  {
263  /* Make sure this SID can fit in the buffer */
264  SidLength = RtlLengthSid(Src[i].Sid);
265  if (SidLength > SidAreaSize) return STATUS_BUFFER_TOO_SMALL;
266 
267  /* Consume remaining buffer space for this SID */
268  SidAreaSize -= SidLength;
269 
270  /* Copy the SID and attributes */
271  Dest[i].Sid = SidArea;
272  Dest[i].Attributes = Src[i].Attributes;
273  RtlCopySid(SidLength, SidArea, Src[i].Sid);
274 
275  /* Push the buffer area where the SID will reset */
276  SidArea = (PSID)((ULONG_PTR)SidArea + SidLength);
277  }
278 
279  /* Return how much space is left, and where the buffer is at now */
280  *RemainingSidArea = SidArea;
281  *RemainingSidAreaSize = SidAreaSize;
282  return STATUS_SUCCESS;
283 }
284 
285 /*
286  * @implemented
287  */
288 NTSTATUS
289 NTAPI
292  IN ULONG SubAuthority0,
293  IN ULONG SubAuthority1,
294  IN ULONG SubAuthority2,
295  IN ULONG SubAuthority3,
296  IN ULONG SubAuthority4,
297  IN ULONG SubAuthority5,
298  IN ULONG SubAuthority6,
299  IN ULONG SubAuthority7,
300  OUT PSID *Sid)
301 {
302  PISID pSid;
303  PAGED_CODE_RTL();
304 
305  /* SIDs can only have up to 8 subauthorities */
306  if (SubAuthorityCount > 8) return STATUS_INVALID_SID;
307 
308  /* Allocate memory to hold the SID */
310  if (!pSid) return STATUS_NO_MEMORY;
311 
312  /* Fill out the header */
316 
317  /* Iteraratively drop into each successive lower count */
318  switch (SubAuthorityCount)
319  {
320  /* And copy the needed subahority */
321  case 8: pSid->SubAuthority[7] = SubAuthority7;
322  case 7: pSid->SubAuthority[6] = SubAuthority6;
323  case 6: pSid->SubAuthority[5] = SubAuthority5;
324  case 5: pSid->SubAuthority[4] = SubAuthority4;
325  case 4: pSid->SubAuthority[3] = SubAuthority3;
326  case 3: pSid->SubAuthority[2] = SubAuthority2;
327  case 2: pSid->SubAuthority[1] = SubAuthority1;
328  case 1: pSid->SubAuthority[0] = SubAuthority0;
329  default: break;
330  }
331 
332  /* Return the allocated SID */
333  *Sid = pSid;
334  return STATUS_SUCCESS;
335 }
336 
337 /*
338  * @implemented
339  */
340 NTSTATUS
341 NTAPI
343  IN PSID Sid_,
344  IN BOOLEAN AllocateBuffer)
345 {
346  WCHAR Buffer[256];
347  PWSTR wcs;
348  SIZE_T Length;
349  ULONG i;
350  PISID Sid = Sid_;
351  PAGED_CODE_RTL();
352 
353  if (!RtlValidSid(Sid)) return STATUS_INVALID_SID;
354 
355  wcs = Buffer;
356  wcs += swprintf(wcs, L"S-1-");
357 
358  if ((Sid->IdentifierAuthority.Value[0] == 0) &&
359  (Sid->IdentifierAuthority.Value[1] == 0))
360  {
361  wcs += swprintf(wcs,
362  L"%lu",
363  (ULONG)Sid->IdentifierAuthority.Value[2] << 24 |
364  (ULONG)Sid->IdentifierAuthority.Value[3] << 16 |
365  (ULONG)Sid->IdentifierAuthority.Value[4] << 8 |
367  }
368  else
369  {
370  wcs += swprintf(wcs,
371  L"0x%02hx%02hx%02hx%02hx%02hx%02hx",
378  }
379 
380  for (i = 0; i < Sid->SubAuthorityCount; i++)
381  {
382  wcs += swprintf(wcs, L"-%u", Sid->SubAuthority[i]);
383  }
384 
385  if (AllocateBuffer)
386  {
388  }
389  else
390  {
391  Length = (wcs - Buffer) * sizeof(WCHAR);
392 
393  if (Length > String->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
394 
395  String->Length = (USHORT)Length;
396  RtlCopyMemory(String->Buffer, Buffer, Length);
397 
399  {
400  String->Buffer[Length / sizeof(WCHAR)] = UNICODE_NULL;
401  }
402  }
403 
404  return STATUS_SUCCESS;
405 }
406 
407 /* EOF */
PUCHAR NTAPI RtlSubAuthorityCountSid(IN PSID Sid_)
Definition: sid.c:104
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS NTAPI RtlCopySid(IN ULONG BufferLength, IN PSID Dest, IN PSID Src)
Definition: sid.c:165
NTSTATUS NTAPI RtlAllocateAndInitializeSid(IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount, IN ULONG SubAuthority0, IN ULONG SubAuthority1, IN ULONG SubAuthority2, IN ULONG SubAuthority3, IN ULONG SubAuthority4, IN ULONG SubAuthority5, IN ULONG SubAuthority6, IN ULONG SubAuthority7, OUT PSID *Sid)
Definition: sid.c:290
wchar_t wcs[5]
* PSID_IDENTIFIER_AUTHORITY
Definition: setypes.h:436
uint16_t * PWSTR
Definition: typedefs.h:54
NTSTATUS NTAPI RtlCopySidAndAttributesArray(IN ULONG Count, IN PSID_AND_ATTRIBUTES Src, IN ULONG SidAreaSize, IN PSID_AND_ATTRIBUTES Dest, IN PSID SidArea, OUT PSID *RemainingSidArea, OUT PULONG RemainingSidAreaSize)
Definition: sid.c:249
unsigned char * PUCHAR
Definition: retypes.h:3
#define SID_REVISION
Definition: setypes.h:453
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define TAG_SID
Definition: sid.c:15
static WCHAR String[]
Definition: stringtable.c:55
VOID NTAPI RtlpFreeMemory(_In_ PVOID Mem, _In_ ULONG Tag)
Definition: rtlcompat.c:45
#define PAGED_CODE_RTL()
Definition: rtlp.h:16
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
_SEH2_TRY
Definition: create.c:4250
BOOLEAN NTAPI RtlEqualSid(IN PSID Sid1_, IN PSID Sid2_)
Definition: sid.c:132
uint32_t ULONG_PTR
Definition: typedefs.h:63
PULONG NTAPI RtlSubAuthoritySid(IN PSID Sid_, IN ULONG SubAuthority)
Definition: sid.c:89
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS NTAPI RtlConvertSidToUnicodeString(IN PUNICODE_STRING String, IN PSID Sid_, IN BOOLEAN AllocateBuffer)
Definition: sid.c:342
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
PVOID NTAPI RtlpAllocateMemory(_In_ ULONG Bytes, _In_ ULONG Tag)
Definition: rtlcompat.c:34
_In_ ULONG BufferLength
Definition: usbdlib.h:225
PVOID NTAPI RtlFreeSid(IN PSID Sid)
Definition: sid.c:186
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
#define SID_MAX_SUB_AUTHORITIES
Definition: setypes.h:454
smooth NULL
Definition: ftsmooth.c:416
ULONG NTAPI RtlLengthSid(IN PSID Sid_)
Definition: sid.c:150
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1104
Definition: bufpool.h:45
#define STATUS_INVALID_SID
Definition: ntstatus.h:342
BOOLEAN NTAPI RtlValidSid(IN PSID Sid_)
Definition: sid.c:21
BOOLEAN NTAPI RtlEqualPrefixSid(IN PSID Sid1_, IN PSID Sid2_)
Definition: sid.c:200
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define swprintf(buf, format,...)
Definition: sprintf.c:56
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
struct _SID * PSID
Definition: eventlog.c:35
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
static const WCHAR L[]
Definition: oid.c:1250
ULONG NTAPI RtlLengthRequiredSid(IN ULONG SubAuthorityCount)
Definition: sid.c:54
_In_ PSID_IDENTIFIER_AUTHORITY _In_ UCHAR SubAuthorityCount
Definition: rtlfuncs.h:1487
DWORD SubAuthority[*]
Definition: ms-dtyp.idl:202
UnicodeString MaximumLength
Definition: rtlfuncs.h:2982
ULONG_PTR SIZE_T
Definition: typedefs.h:78
_SEH2_END
Definition: create.c:4424
NTSTATUS NTAPI RtlInitializeSid(IN PSID Sid_, IN PSID_IDENTIFIER_AUTHORITY IdentifierAuthority, IN UCHAR SubAuthorityCount)
Definition: sid.c:68
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
BYTE SubAuthorityCount
Definition: ms-dtyp.idl:200
unsigned int * PULONG
Definition: retypes.h:1
static PSID pSid
Definition: security.c:74
#define OUT
Definition: typedefs.h:39
unsigned int ULONG
Definition: retypes.h:1
PSID_IDENTIFIER_AUTHORITY NTAPI RtlIdentifierAuthoritySid(IN PSID Sid_)
Definition: sid.c:118
SID_IDENTIFIER_AUTHORITY IdentifierAuthority
Definition: ms-dtyp.idl:201
_In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority
Definition: rtlfuncs.h:1487
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
BYTE Revision
Definition: ms-dtyp.idl:199
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2745
_In_ PSID Sid2
Definition: rtlfuncs.h:1757
unsigned short * PUSHORT
Definition: retypes.h:2