2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/se/sid.c
5 * PURPOSE: Security manager
7 * PROGRAMMERS: David Welch <welch@cwcom.net>
10 /* INCLUDES *******************************************************************/
16 #define TAG_SID_AND_ATTRIBUTES 'aSeS'
18 #if defined (ALLOC_PRAGMA)
19 #pragma alloc_text(INIT, SepInitSecurityIDs)
22 /* GLOBALS ********************************************************************/
24 SID_IDENTIFIER_AUTHORITY SeNullSidAuthority
= {SECURITY_NULL_SID_AUTHORITY
};
25 SID_IDENTIFIER_AUTHORITY SeWorldSidAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
26 SID_IDENTIFIER_AUTHORITY SeLocalSidAuthority
= {SECURITY_LOCAL_SID_AUTHORITY
};
27 SID_IDENTIFIER_AUTHORITY SeCreatorSidAuthority
= {SECURITY_CREATOR_SID_AUTHORITY
};
28 SID_IDENTIFIER_AUTHORITY SeNtSidAuthority
= {SECURITY_NT_AUTHORITY
};
30 PSID SeNullSid
= NULL
;
31 PSID SeWorldSid
= NULL
;
32 PSID SeLocalSid
= NULL
;
33 PSID SeCreatorOwnerSid
= NULL
;
34 PSID SeCreatorGroupSid
= NULL
;
35 PSID SeCreatorOwnerServerSid
= NULL
;
36 PSID SeCreatorGroupServerSid
= NULL
;
37 PSID SeNtAuthoritySid
= NULL
;
38 PSID SeDialupSid
= NULL
;
39 PSID SeNetworkSid
= NULL
;
40 PSID SeBatchSid
= NULL
;
41 PSID SeInteractiveSid
= NULL
;
42 PSID SeServiceSid
= NULL
;
43 PSID SePrincipalSelfSid
= NULL
;
44 PSID SeLocalSystemSid
= NULL
;
45 PSID SeAuthenticatedUserSid
= NULL
;
46 PSID SeRestrictedCodeSid
= NULL
;
47 PSID SeAliasAdminsSid
= NULL
;
48 PSID SeAliasUsersSid
= NULL
;
49 PSID SeAliasGuestsSid
= NULL
;
50 PSID SeAliasPowerUsersSid
= NULL
;
51 PSID SeAliasAccountOpsSid
= NULL
;
52 PSID SeAliasSystemOpsSid
= NULL
;
53 PSID SeAliasPrintOpsSid
= NULL
;
54 PSID SeAliasBackupOpsSid
= NULL
;
55 PSID SeAuthenticatedUsersSid
= NULL
;
56 PSID SeRestrictedSid
= NULL
;
57 PSID SeAnonymousLogonSid
= NULL
;
59 /* FUNCTIONS ******************************************************************/
63 FreeInitializedSids(VOID
)
65 if (SeNullSid
) ExFreePoolWithTag(SeNullSid
, TAG_SID
);
66 if (SeWorldSid
) ExFreePoolWithTag(SeWorldSid
, TAG_SID
);
67 if (SeLocalSid
) ExFreePoolWithTag(SeLocalSid
, TAG_SID
);
68 if (SeCreatorOwnerSid
) ExFreePoolWithTag(SeCreatorOwnerSid
, TAG_SID
);
69 if (SeCreatorGroupSid
) ExFreePoolWithTag(SeCreatorGroupSid
, TAG_SID
);
70 if (SeCreatorOwnerServerSid
) ExFreePoolWithTag(SeCreatorOwnerServerSid
, TAG_SID
);
71 if (SeCreatorGroupServerSid
) ExFreePoolWithTag(SeCreatorGroupServerSid
, TAG_SID
);
72 if (SeNtAuthoritySid
) ExFreePoolWithTag(SeNtAuthoritySid
, TAG_SID
);
73 if (SeDialupSid
) ExFreePoolWithTag(SeDialupSid
, TAG_SID
);
74 if (SeNetworkSid
) ExFreePoolWithTag(SeNetworkSid
, TAG_SID
);
75 if (SeBatchSid
) ExFreePoolWithTag(SeBatchSid
, TAG_SID
);
76 if (SeInteractiveSid
) ExFreePoolWithTag(SeInteractiveSid
, TAG_SID
);
77 if (SeServiceSid
) ExFreePoolWithTag(SeServiceSid
, TAG_SID
);
78 if (SePrincipalSelfSid
) ExFreePoolWithTag(SePrincipalSelfSid
, TAG_SID
);
79 if (SeLocalSystemSid
) ExFreePoolWithTag(SeLocalSystemSid
, TAG_SID
);
80 if (SeAuthenticatedUserSid
) ExFreePoolWithTag(SeAuthenticatedUserSid
, TAG_SID
);
81 if (SeRestrictedCodeSid
) ExFreePoolWithTag(SeRestrictedCodeSid
, TAG_SID
);
82 if (SeAliasAdminsSid
) ExFreePoolWithTag(SeAliasAdminsSid
, TAG_SID
);
83 if (SeAliasUsersSid
) ExFreePoolWithTag(SeAliasUsersSid
, TAG_SID
);
84 if (SeAliasGuestsSid
) ExFreePoolWithTag(SeAliasGuestsSid
, TAG_SID
);
85 if (SeAliasPowerUsersSid
) ExFreePoolWithTag(SeAliasPowerUsersSid
, TAG_SID
);
86 if (SeAliasAccountOpsSid
) ExFreePoolWithTag(SeAliasAccountOpsSid
, TAG_SID
);
87 if (SeAliasSystemOpsSid
) ExFreePoolWithTag(SeAliasSystemOpsSid
, TAG_SID
);
88 if (SeAliasPrintOpsSid
) ExFreePoolWithTag(SeAliasPrintOpsSid
, TAG_SID
);
89 if (SeAliasBackupOpsSid
) ExFreePoolWithTag(SeAliasBackupOpsSid
, TAG_SID
);
90 if (SeAuthenticatedUsersSid
) ExFreePoolWithTag(SeAuthenticatedUsersSid
, TAG_SID
);
91 if (SeRestrictedSid
) ExFreePoolWithTag(SeRestrictedSid
, TAG_SID
);
92 if (SeAnonymousLogonSid
) ExFreePoolWithTag(SeAnonymousLogonSid
, TAG_SID
);
98 SepInitSecurityIDs(VOID
)
105 SidLength0
= RtlLengthRequiredSid(0);
106 SidLength1
= RtlLengthRequiredSid(1);
107 SidLength2
= RtlLengthRequiredSid(2);
110 SeNullSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
111 SeWorldSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
112 SeLocalSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
113 SeCreatorOwnerSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
114 SeCreatorGroupSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
115 SeCreatorOwnerServerSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
116 SeCreatorGroupServerSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
117 SeNtAuthoritySid
= ExAllocatePoolWithTag(PagedPool
, SidLength0
, TAG_SID
);
118 SeDialupSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
119 SeNetworkSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
120 SeBatchSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
121 SeInteractiveSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
122 SeServiceSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
123 SePrincipalSelfSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
124 SeLocalSystemSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
125 SeAuthenticatedUserSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
126 SeRestrictedCodeSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
127 SeAliasAdminsSid
= ExAllocatePoolWithTag(PagedPool
, SidLength2
, TAG_SID
);
128 SeAliasUsersSid
= ExAllocatePoolWithTag(PagedPool
, SidLength2
, TAG_SID
);
129 SeAliasGuestsSid
= ExAllocatePoolWithTag(PagedPool
, SidLength2
, TAG_SID
);
130 SeAliasPowerUsersSid
= ExAllocatePoolWithTag(PagedPool
, SidLength2
, TAG_SID
);
131 SeAliasAccountOpsSid
= ExAllocatePoolWithTag(PagedPool
, SidLength2
, TAG_SID
);
132 SeAliasSystemOpsSid
= ExAllocatePoolWithTag(PagedPool
, SidLength2
, TAG_SID
);
133 SeAliasPrintOpsSid
= ExAllocatePoolWithTag(PagedPool
, SidLength2
, TAG_SID
);
134 SeAliasBackupOpsSid
= ExAllocatePoolWithTag(PagedPool
, SidLength2
, TAG_SID
);
135 SeAuthenticatedUsersSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
136 SeRestrictedSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
137 SeAnonymousLogonSid
= ExAllocatePoolWithTag(PagedPool
, SidLength1
, TAG_SID
);
139 if (SeNullSid
== NULL
|| SeWorldSid
== NULL
||
140 SeLocalSid
== NULL
|| SeCreatorOwnerSid
== NULL
||
141 SeCreatorGroupSid
== NULL
|| SeCreatorOwnerServerSid
== NULL
||
142 SeCreatorGroupServerSid
== NULL
|| SeNtAuthoritySid
== NULL
||
143 SeDialupSid
== NULL
|| SeNetworkSid
== NULL
|| SeBatchSid
== NULL
||
144 SeInteractiveSid
== NULL
|| SeServiceSid
== NULL
||
145 SePrincipalSelfSid
== NULL
|| SeLocalSystemSid
== NULL
||
146 SeAuthenticatedUserSid
== NULL
|| SeRestrictedCodeSid
== NULL
||
147 SeAliasAdminsSid
== NULL
|| SeAliasUsersSid
== NULL
||
148 SeAliasGuestsSid
== NULL
|| SeAliasPowerUsersSid
== NULL
||
149 SeAliasAccountOpsSid
== NULL
|| SeAliasSystemOpsSid
== NULL
||
150 SeAliasPrintOpsSid
== NULL
|| SeAliasBackupOpsSid
== NULL
||
151 SeAuthenticatedUsersSid
== NULL
|| SeRestrictedSid
== NULL
||
152 SeAnonymousLogonSid
== NULL
)
154 FreeInitializedSids();
158 RtlInitializeSid(SeNullSid
, &SeNullSidAuthority
, 1);
159 RtlInitializeSid(SeWorldSid
, &SeWorldSidAuthority
, 1);
160 RtlInitializeSid(SeLocalSid
, &SeLocalSidAuthority
, 1);
161 RtlInitializeSid(SeCreatorOwnerSid
, &SeCreatorSidAuthority
, 1);
162 RtlInitializeSid(SeCreatorGroupSid
, &SeCreatorSidAuthority
, 1);
163 RtlInitializeSid(SeCreatorOwnerServerSid
, &SeCreatorSidAuthority
, 1);
164 RtlInitializeSid(SeCreatorGroupServerSid
, &SeCreatorSidAuthority
, 1);
165 RtlInitializeSid(SeNtAuthoritySid
, &SeNtSidAuthority
, 0);
166 RtlInitializeSid(SeDialupSid
, &SeNtSidAuthority
, 1);
167 RtlInitializeSid(SeNetworkSid
, &SeNtSidAuthority
, 1);
168 RtlInitializeSid(SeBatchSid
, &SeNtSidAuthority
, 1);
169 RtlInitializeSid(SeInteractiveSid
, &SeNtSidAuthority
, 1);
170 RtlInitializeSid(SeServiceSid
, &SeNtSidAuthority
, 1);
171 RtlInitializeSid(SePrincipalSelfSid
, &SeNtSidAuthority
, 1);
172 RtlInitializeSid(SeLocalSystemSid
, &SeNtSidAuthority
, 1);
173 RtlInitializeSid(SeAuthenticatedUserSid
, &SeNtSidAuthority
, 1);
174 RtlInitializeSid(SeRestrictedCodeSid
, &SeNtSidAuthority
, 1);
175 RtlInitializeSid(SeAliasAdminsSid
, &SeNtSidAuthority
, 2);
176 RtlInitializeSid(SeAliasUsersSid
, &SeNtSidAuthority
, 2);
177 RtlInitializeSid(SeAliasGuestsSid
, &SeNtSidAuthority
, 2);
178 RtlInitializeSid(SeAliasPowerUsersSid
, &SeNtSidAuthority
, 2);
179 RtlInitializeSid(SeAliasAccountOpsSid
, &SeNtSidAuthority
, 2);
180 RtlInitializeSid(SeAliasSystemOpsSid
, &SeNtSidAuthority
, 2);
181 RtlInitializeSid(SeAliasPrintOpsSid
, &SeNtSidAuthority
, 2);
182 RtlInitializeSid(SeAliasBackupOpsSid
, &SeNtSidAuthority
, 2);
183 RtlInitializeSid(SeAuthenticatedUsersSid
, &SeNtSidAuthority
, 1);
184 RtlInitializeSid(SeRestrictedSid
, &SeNtSidAuthority
, 1);
185 RtlInitializeSid(SeAnonymousLogonSid
, &SeNtSidAuthority
, 1);
187 SubAuthority
= RtlSubAuthoritySid(SeNullSid
, 0);
188 *SubAuthority
= SECURITY_NULL_RID
;
189 SubAuthority
= RtlSubAuthoritySid(SeWorldSid
, 0);
190 *SubAuthority
= SECURITY_WORLD_RID
;
191 SubAuthority
= RtlSubAuthoritySid(SeLocalSid
, 0);
192 *SubAuthority
= SECURITY_LOCAL_RID
;
193 SubAuthority
= RtlSubAuthoritySid(SeCreatorOwnerSid
, 0);
194 *SubAuthority
= SECURITY_CREATOR_OWNER_RID
;
195 SubAuthority
= RtlSubAuthoritySid(SeCreatorGroupSid
, 0);
196 *SubAuthority
= SECURITY_CREATOR_GROUP_RID
;
197 SubAuthority
= RtlSubAuthoritySid(SeCreatorOwnerServerSid
, 0);
198 *SubAuthority
= SECURITY_CREATOR_OWNER_SERVER_RID
;
199 SubAuthority
= RtlSubAuthoritySid(SeCreatorGroupServerSid
, 0);
200 *SubAuthority
= SECURITY_CREATOR_GROUP_SERVER_RID
;
201 SubAuthority
= RtlSubAuthoritySid(SeDialupSid
, 0);
202 *SubAuthority
= SECURITY_DIALUP_RID
;
203 SubAuthority
= RtlSubAuthoritySid(SeNetworkSid
, 0);
204 *SubAuthority
= SECURITY_NETWORK_RID
;
205 SubAuthority
= RtlSubAuthoritySid(SeBatchSid
, 0);
206 *SubAuthority
= SECURITY_BATCH_RID
;
207 SubAuthority
= RtlSubAuthoritySid(SeInteractiveSid
, 0);
208 *SubAuthority
= SECURITY_INTERACTIVE_RID
;
209 SubAuthority
= RtlSubAuthoritySid(SeServiceSid
, 0);
210 *SubAuthority
= SECURITY_SERVICE_RID
;
211 SubAuthority
= RtlSubAuthoritySid(SePrincipalSelfSid
, 0);
212 *SubAuthority
= SECURITY_PRINCIPAL_SELF_RID
;
213 SubAuthority
= RtlSubAuthoritySid(SeLocalSystemSid
, 0);
214 *SubAuthority
= SECURITY_LOCAL_SYSTEM_RID
;
215 SubAuthority
= RtlSubAuthoritySid(SeAuthenticatedUserSid
, 0);
216 *SubAuthority
= SECURITY_AUTHENTICATED_USER_RID
;
217 SubAuthority
= RtlSubAuthoritySid(SeRestrictedCodeSid
, 0);
218 *SubAuthority
= SECURITY_RESTRICTED_CODE_RID
;
219 SubAuthority
= RtlSubAuthoritySid(SeAliasAdminsSid
, 0);
220 *SubAuthority
= SECURITY_BUILTIN_DOMAIN_RID
;
221 SubAuthority
= RtlSubAuthoritySid(SeAliasAdminsSid
, 1);
222 *SubAuthority
= DOMAIN_ALIAS_RID_ADMINS
;
223 SubAuthority
= RtlSubAuthoritySid(SeAliasUsersSid
, 0);
224 *SubAuthority
= SECURITY_BUILTIN_DOMAIN_RID
;
225 SubAuthority
= RtlSubAuthoritySid(SeAliasUsersSid
, 1);
226 *SubAuthority
= DOMAIN_ALIAS_RID_USERS
;
227 SubAuthority
= RtlSubAuthoritySid(SeAliasGuestsSid
, 0);
228 *SubAuthority
= SECURITY_BUILTIN_DOMAIN_RID
;
229 SubAuthority
= RtlSubAuthoritySid(SeAliasGuestsSid
, 1);
230 *SubAuthority
= DOMAIN_ALIAS_RID_GUESTS
;
231 SubAuthority
= RtlSubAuthoritySid(SeAliasPowerUsersSid
, 0);
232 *SubAuthority
= SECURITY_BUILTIN_DOMAIN_RID
;
233 SubAuthority
= RtlSubAuthoritySid(SeAliasPowerUsersSid
, 1);
234 *SubAuthority
= DOMAIN_ALIAS_RID_POWER_USERS
;
235 SubAuthority
= RtlSubAuthoritySid(SeAliasAccountOpsSid
, 0);
236 *SubAuthority
= SECURITY_BUILTIN_DOMAIN_RID
;
237 SubAuthority
= RtlSubAuthoritySid(SeAliasAccountOpsSid
, 1);
238 *SubAuthority
= DOMAIN_ALIAS_RID_ACCOUNT_OPS
;
239 SubAuthority
= RtlSubAuthoritySid(SeAliasSystemOpsSid
, 0);
240 *SubAuthority
= SECURITY_BUILTIN_DOMAIN_RID
;
241 SubAuthority
= RtlSubAuthoritySid(SeAliasSystemOpsSid
, 1);
242 *SubAuthority
= DOMAIN_ALIAS_RID_SYSTEM_OPS
;
243 SubAuthority
= RtlSubAuthoritySid(SeAliasPrintOpsSid
, 0);
244 *SubAuthority
= SECURITY_BUILTIN_DOMAIN_RID
;
245 SubAuthority
= RtlSubAuthoritySid(SeAliasPrintOpsSid
, 1);
246 *SubAuthority
= DOMAIN_ALIAS_RID_PRINT_OPS
;
247 SubAuthority
= RtlSubAuthoritySid(SeAliasBackupOpsSid
, 0);
248 *SubAuthority
= SECURITY_BUILTIN_DOMAIN_RID
;
249 SubAuthority
= RtlSubAuthoritySid(SeAliasBackupOpsSid
, 1);
250 *SubAuthority
= DOMAIN_ALIAS_RID_BACKUP_OPS
;
251 SubAuthority
= RtlSubAuthoritySid(SeAuthenticatedUsersSid
, 0);
252 *SubAuthority
= SECURITY_AUTHENTICATED_USER_RID
;
253 SubAuthority
= RtlSubAuthoritySid(SeRestrictedSid
, 0);
254 *SubAuthority
= SECURITY_RESTRICTED_CODE_RID
;
255 SubAuthority
= RtlSubAuthoritySid(SeAnonymousLogonSid
, 0);
256 *SubAuthority
= SECURITY_ANONYMOUS_LOGON_RID
;
263 SepCaptureSid(IN PSID InputSid
,
264 IN KPROCESSOR_MODE AccessMode
,
265 IN POOL_TYPE PoolType
,
266 IN BOOLEAN CaptureIfKernel
,
267 OUT PSID
*CapturedSid
)
270 PISID NewSid
, Sid
= (PISID
)InputSid
;
274 if (AccessMode
!= KernelMode
)
278 ProbeForRead(Sid
, FIELD_OFFSET(SID
, SubAuthority
), sizeof(UCHAR
));
279 SidSize
= RtlLengthRequiredSid(Sid
->SubAuthorityCount
);
280 ProbeForRead(Sid
, SidSize
, sizeof(UCHAR
));
282 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
284 /* Return the exception code */
285 _SEH2_YIELD(return _SEH2_GetExceptionCode());
289 /* allocate a SID and copy it */
290 NewSid
= ExAllocatePoolWithTag(PoolType
, SidSize
, TAG_SID
);
292 return STATUS_INSUFFICIENT_RESOURCES
;
296 RtlCopyMemory(NewSid
, Sid
, SidSize
);
298 *CapturedSid
= NewSid
;
300 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
302 /* Free the SID and return the exception code */
303 ExFreePoolWithTag(NewSid
, TAG_SID
);
304 _SEH2_YIELD(return _SEH2_GetExceptionCode());
308 else if (!CaptureIfKernel
)
310 *CapturedSid
= InputSid
;
314 SidSize
= RtlLengthRequiredSid(Sid
->SubAuthorityCount
);
316 /* allocate a SID and copy it */
317 NewSid
= ExAllocatePoolWithTag(PoolType
, SidSize
, TAG_SID
);
319 return STATUS_INSUFFICIENT_RESOURCES
;
321 RtlCopyMemory(NewSid
, Sid
, SidSize
);
323 *CapturedSid
= NewSid
;
326 return STATUS_SUCCESS
;
331 SepReleaseSid(IN PSID CapturedSid
,
332 IN KPROCESSOR_MODE AccessMode
,
333 IN BOOLEAN CaptureIfKernel
)
337 if (CapturedSid
!= NULL
&&
338 (AccessMode
!= KernelMode
||
339 (AccessMode
== KernelMode
&& CaptureIfKernel
)))
341 ExFreePoolWithTag(CapturedSid
, TAG_SID
);
347 SeCaptureSidAndAttributesArray(
348 _In_ PSID_AND_ATTRIBUTES SrcSidAndAttributes
,
349 _In_ ULONG AttributeCount
,
350 _In_ KPROCESSOR_MODE PreviousMode
,
351 _In_opt_ PVOID AllocatedMem
,
352 _In_ ULONG AllocatedLength
,
353 _In_ POOL_TYPE PoolType
,
354 _In_ BOOLEAN CaptureIfKernel
,
355 _Out_ PSID_AND_ATTRIBUTES
*CapturedSidAndAttributes
,
356 _Out_ PULONG ResultLength
)
358 ULONG ArraySize
, RequiredLength
, SidLength
, i
;
359 PSID_AND_ATTRIBUTES SidAndAttributes
;
365 *CapturedSidAndAttributes
= NULL
;
368 if (AttributeCount
== 0)
370 return STATUS_SUCCESS
;
373 if (AttributeCount
> 0x1000)
375 return STATUS_INVALID_PARAMETER
;
378 if ((PreviousMode
== KernelMode
) && !CaptureIfKernel
)
380 *CapturedSidAndAttributes
= SrcSidAndAttributes
;
381 return STATUS_SUCCESS
;
384 ArraySize
= AttributeCount
* sizeof(SID_AND_ATTRIBUTES
);
385 RequiredLength
= ALIGN_UP_BY(ArraySize
, sizeof(ULONG
));
387 /* Check for user mode data */
388 if (PreviousMode
!= KernelMode
)
392 /* First probe the whole array */
393 ProbeForRead(SrcSidAndAttributes
, ArraySize
, sizeof(ULONG
));
395 /* Loop the array elements */
396 for (i
= 0; i
< AttributeCount
; i
++)
398 /* Get the SID and probe the minimal structure */
399 Sid
= SrcSidAndAttributes
[i
].Sid
;
400 ProbeForRead(Sid
, sizeof(*Sid
), sizeof(ULONG
));
402 /* Verify that the SID is valid */
403 if (((Sid
->Revision
& 0xF) != SID_REVISION
) ||
404 (Sid
->SubAuthorityCount
> SID_MAX_SUB_AUTHORITIES
))
406 return STATUS_INVALID_SID
;
409 /* Calculate the SID length and probe the full SID */
410 SidLength
= RtlLengthRequiredSid(Sid
->SubAuthorityCount
);
411 ProbeForRead(Sid
, SidLength
, sizeof(ULONG
));
413 /* Add the aligned length to the required length */
414 RequiredLength
+= ALIGN_UP_BY(SidLength
, sizeof(ULONG
));
417 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
419 return _SEH2_GetExceptionCode();
425 /* Loop the array elements */
426 for (i
= 0; i
< AttributeCount
; i
++)
428 /* Get the SID and it's length */
429 Sid
= SrcSidAndAttributes
[i
].Sid
;
430 SidLength
= RtlLengthRequiredSid(Sid
->SubAuthorityCount
);
432 /* Add the aligned length to the required length */
433 RequiredLength
+= ALIGN_UP_BY(SidLength
, sizeof(ULONG
));
438 Status
= STATUS_SUCCESS
;
439 *ResultLength
= RequiredLength
;
441 /* Check if we have no buffer */
442 if (AllocatedMem
== NULL
)
444 /* Allocate a new buffer */
445 SidAndAttributes
= ExAllocatePoolWithTag(PoolType
,
447 TAG_SID_AND_ATTRIBUTES
);
448 if (SidAndAttributes
== NULL
)
450 return STATUS_INSUFFICIENT_RESOURCES
;
453 /* Otherwise check if the buffer is large enough */
454 else if (AllocatedLength
>= RequiredLength
)
456 /* Buffer is large enough, use it */
457 SidAndAttributes
= AllocatedMem
;
461 /* Buffer is too small, fail */
462 return STATUS_BUFFER_TOO_SMALL
;
465 *CapturedSidAndAttributes
= SidAndAttributes
;
467 /* Check again for user mode */
468 if (PreviousMode
!= KernelMode
)
472 /* The rest of the data starts after the array */
473 CurrentDest
= (PUCHAR
)SidAndAttributes
;
474 CurrentDest
+= ALIGN_UP_BY(ArraySize
, sizeof(ULONG
));
476 /* Loop the array elements */
477 for (i
= 0; i
< AttributeCount
; i
++)
479 /* Get the SID and it's length */
480 Sid
= SrcSidAndAttributes
[i
].Sid
;
481 SidLength
= RtlLengthRequiredSid(Sid
->SubAuthorityCount
);
483 /* Copy attributes */
484 SidAndAttributes
[i
].Attributes
= SrcSidAndAttributes
[i
].Attributes
;
486 /* Copy the SID to the current destination address */
487 SidAndAttributes
[i
].Sid
= (PSID
)CurrentDest
;
488 RtlCopyMemory(CurrentDest
, SrcSidAndAttributes
[i
].Sid
, SidLength
);
491 NT_ASSERT(RtlLengthSid(SidAndAttributes
[i
].Sid
) == SidLength
);
492 NT_ASSERT(RtlValidSid(SidAndAttributes
[i
].Sid
));
494 /* Update the current destination address */
495 CurrentDest
+= ALIGN_UP_BY(SidLength
, sizeof(ULONG
));
498 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
500 Status
= _SEH2_GetExceptionCode();
506 /* The rest of the data starts after the array */
507 CurrentDest
= (PUCHAR
)SidAndAttributes
;
508 CurrentDest
+= ALIGN_UP_BY(ArraySize
, sizeof(ULONG
));
510 /* Loop the array elements */
511 for (i
= 0; i
< AttributeCount
; i
++)
513 /* Get the SID and it's length */
514 Sid
= SrcSidAndAttributes
[i
].Sid
;
515 SidLength
= RtlLengthRequiredSid(Sid
->SubAuthorityCount
);
517 /* Copy attributes */
518 SidAndAttributes
[i
].Attributes
= SrcSidAndAttributes
[i
].Attributes
;
520 /* Copy the SID to the current destination address */
521 SidAndAttributes
[i
].Sid
= (PSID
)CurrentDest
;
522 RtlCopyMemory(CurrentDest
, SrcSidAndAttributes
[i
].Sid
, SidLength
);
524 /* Update the current destination address */
525 CurrentDest
+= ALIGN_UP_BY(SidLength
, sizeof(ULONG
));
529 /* Check for failure */
530 if (!NT_SUCCESS(Status
))
532 /* Check if we allocated a new array */
533 if (SidAndAttributes
!= AllocatedMem
)
536 ExFreePoolWithTag(SidAndAttributes
, TAG_SID_AND_ATTRIBUTES
);
539 /* Set returned address to NULL */
540 *CapturedSidAndAttributes
= NULL
;
548 SeReleaseSidAndAttributesArray(
549 _In_ _Post_invalid_ PSID_AND_ATTRIBUTES CapturedSidAndAttributes
,
550 _In_ KPROCESSOR_MODE AccessMode
,
551 _In_ BOOLEAN CaptureIfKernel
)
555 if ((CapturedSidAndAttributes
!= NULL
) &&
556 ((AccessMode
!= KernelMode
) || CaptureIfKernel
))
558 ExFreePoolWithTag(CapturedSidAndAttributes
, TAG_SID_AND_ATTRIBUTES
);