1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: ntoskrnl/se/sid.c 5 * PURPOSE: Security manager 6 * 7 * PROGRAMMERS: David Welch <welch@cwcom.net> 8 */ 9 10 /* INCLUDES *******************************************************************/ 11 12 #include <ntoskrnl.h> 13 #define NDEBUG 14 #include <debug.h> 15 16 #define TAG_SID_AND_ATTRIBUTES 'aSeS' 17 18 #if defined (ALLOC_PRAGMA) 19 #pragma alloc_text(INIT, SepInitSecurityIDs) 20 #endif 21 22 /* GLOBALS ********************************************************************/ 23 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}; 29 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; 58 PSID SeLocalServiceSid = NULL; 59 PSID SeNetworkServiceSid = NULL; 60 61 /* FUNCTIONS ******************************************************************/ 62 63 VOID 64 NTAPI 65 FreeInitializedSids(VOID) 66 { 67 if (SeNullSid) ExFreePoolWithTag(SeNullSid, TAG_SID); 68 if (SeWorldSid) ExFreePoolWithTag(SeWorldSid, TAG_SID); 69 if (SeLocalSid) ExFreePoolWithTag(SeLocalSid, TAG_SID); 70 if (SeCreatorOwnerSid) ExFreePoolWithTag(SeCreatorOwnerSid, TAG_SID); 71 if (SeCreatorGroupSid) ExFreePoolWithTag(SeCreatorGroupSid, TAG_SID); 72 if (SeCreatorOwnerServerSid) ExFreePoolWithTag(SeCreatorOwnerServerSid, TAG_SID); 73 if (SeCreatorGroupServerSid) ExFreePoolWithTag(SeCreatorGroupServerSid, TAG_SID); 74 if (SeNtAuthoritySid) ExFreePoolWithTag(SeNtAuthoritySid, TAG_SID); 75 if (SeDialupSid) ExFreePoolWithTag(SeDialupSid, TAG_SID); 76 if (SeNetworkSid) ExFreePoolWithTag(SeNetworkSid, TAG_SID); 77 if (SeBatchSid) ExFreePoolWithTag(SeBatchSid, TAG_SID); 78 if (SeInteractiveSid) ExFreePoolWithTag(SeInteractiveSid, TAG_SID); 79 if (SeServiceSid) ExFreePoolWithTag(SeServiceSid, TAG_SID); 80 if (SePrincipalSelfSid) ExFreePoolWithTag(SePrincipalSelfSid, TAG_SID); 81 if (SeLocalSystemSid) ExFreePoolWithTag(SeLocalSystemSid, TAG_SID); 82 if (SeAuthenticatedUserSid) ExFreePoolWithTag(SeAuthenticatedUserSid, TAG_SID); 83 if (SeRestrictedCodeSid) ExFreePoolWithTag(SeRestrictedCodeSid, TAG_SID); 84 if (SeAliasAdminsSid) ExFreePoolWithTag(SeAliasAdminsSid, TAG_SID); 85 if (SeAliasUsersSid) ExFreePoolWithTag(SeAliasUsersSid, TAG_SID); 86 if (SeAliasGuestsSid) ExFreePoolWithTag(SeAliasGuestsSid, TAG_SID); 87 if (SeAliasPowerUsersSid) ExFreePoolWithTag(SeAliasPowerUsersSid, TAG_SID); 88 if (SeAliasAccountOpsSid) ExFreePoolWithTag(SeAliasAccountOpsSid, TAG_SID); 89 if (SeAliasSystemOpsSid) ExFreePoolWithTag(SeAliasSystemOpsSid, TAG_SID); 90 if (SeAliasPrintOpsSid) ExFreePoolWithTag(SeAliasPrintOpsSid, TAG_SID); 91 if (SeAliasBackupOpsSid) ExFreePoolWithTag(SeAliasBackupOpsSid, TAG_SID); 92 if (SeAuthenticatedUsersSid) ExFreePoolWithTag(SeAuthenticatedUsersSid, TAG_SID); 93 if (SeRestrictedSid) ExFreePoolWithTag(SeRestrictedSid, TAG_SID); 94 if (SeAnonymousLogonSid) ExFreePoolWithTag(SeAnonymousLogonSid, TAG_SID); 95 } 96 97 INIT_FUNCTION 98 BOOLEAN 99 NTAPI 100 SepInitSecurityIDs(VOID) 101 { 102 ULONG SidLength0; 103 ULONG SidLength1; 104 ULONG SidLength2; 105 PULONG SubAuthority; 106 107 SidLength0 = RtlLengthRequiredSid(0); 108 SidLength1 = RtlLengthRequiredSid(1); 109 SidLength2 = RtlLengthRequiredSid(2); 110 111 /* create NullSid */ 112 SeNullSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 113 SeWorldSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 114 SeLocalSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 115 SeCreatorOwnerSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 116 SeCreatorGroupSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 117 SeCreatorOwnerServerSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 118 SeCreatorGroupServerSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 119 SeNtAuthoritySid = ExAllocatePoolWithTag(PagedPool, SidLength0, TAG_SID); 120 SeDialupSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 121 SeNetworkSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 122 SeBatchSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 123 SeInteractiveSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 124 SeServiceSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 125 SePrincipalSelfSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 126 SeLocalSystemSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 127 SeAuthenticatedUserSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 128 SeRestrictedCodeSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 129 SeAliasAdminsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); 130 SeAliasUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); 131 SeAliasGuestsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); 132 SeAliasPowerUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); 133 SeAliasAccountOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); 134 SeAliasSystemOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); 135 SeAliasPrintOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); 136 SeAliasBackupOpsSid = ExAllocatePoolWithTag(PagedPool, SidLength2, TAG_SID); 137 SeAuthenticatedUsersSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 138 SeRestrictedSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 139 SeAnonymousLogonSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 140 SeLocalServiceSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 141 SeNetworkServiceSid = ExAllocatePoolWithTag(PagedPool, SidLength1, TAG_SID); 142 143 if (SeNullSid == NULL || SeWorldSid == NULL || 144 SeLocalSid == NULL || SeCreatorOwnerSid == NULL || 145 SeCreatorGroupSid == NULL || SeCreatorOwnerServerSid == NULL || 146 SeCreatorGroupServerSid == NULL || SeNtAuthoritySid == NULL || 147 SeDialupSid == NULL || SeNetworkSid == NULL || SeBatchSid == NULL || 148 SeInteractiveSid == NULL || SeServiceSid == NULL || 149 SePrincipalSelfSid == NULL || SeLocalSystemSid == NULL || 150 SeAuthenticatedUserSid == NULL || SeRestrictedCodeSid == NULL || 151 SeAliasAdminsSid == NULL || SeAliasUsersSid == NULL || 152 SeAliasGuestsSid == NULL || SeAliasPowerUsersSid == NULL || 153 SeAliasAccountOpsSid == NULL || SeAliasSystemOpsSid == NULL || 154 SeAliasPrintOpsSid == NULL || SeAliasBackupOpsSid == NULL || 155 SeAuthenticatedUsersSid == NULL || SeRestrictedSid == NULL || 156 SeAnonymousLogonSid == NULL || SeLocalServiceSid == NULL || 157 SeNetworkServiceSid == NULL) 158 { 159 FreeInitializedSids(); 160 return FALSE; 161 } 162 163 RtlInitializeSid(SeNullSid, &SeNullSidAuthority, 1); 164 RtlInitializeSid(SeWorldSid, &SeWorldSidAuthority, 1); 165 RtlInitializeSid(SeLocalSid, &SeLocalSidAuthority, 1); 166 RtlInitializeSid(SeCreatorOwnerSid, &SeCreatorSidAuthority, 1); 167 RtlInitializeSid(SeCreatorGroupSid, &SeCreatorSidAuthority, 1); 168 RtlInitializeSid(SeCreatorOwnerServerSid, &SeCreatorSidAuthority, 1); 169 RtlInitializeSid(SeCreatorGroupServerSid, &SeCreatorSidAuthority, 1); 170 RtlInitializeSid(SeNtAuthoritySid, &SeNtSidAuthority, 0); 171 RtlInitializeSid(SeDialupSid, &SeNtSidAuthority, 1); 172 RtlInitializeSid(SeNetworkSid, &SeNtSidAuthority, 1); 173 RtlInitializeSid(SeBatchSid, &SeNtSidAuthority, 1); 174 RtlInitializeSid(SeInteractiveSid, &SeNtSidAuthority, 1); 175 RtlInitializeSid(SeServiceSid, &SeNtSidAuthority, 1); 176 RtlInitializeSid(SePrincipalSelfSid, &SeNtSidAuthority, 1); 177 RtlInitializeSid(SeLocalSystemSid, &SeNtSidAuthority, 1); 178 RtlInitializeSid(SeAuthenticatedUserSid, &SeNtSidAuthority, 1); 179 RtlInitializeSid(SeRestrictedCodeSid, &SeNtSidAuthority, 1); 180 RtlInitializeSid(SeAliasAdminsSid, &SeNtSidAuthority, 2); 181 RtlInitializeSid(SeAliasUsersSid, &SeNtSidAuthority, 2); 182 RtlInitializeSid(SeAliasGuestsSid, &SeNtSidAuthority, 2); 183 RtlInitializeSid(SeAliasPowerUsersSid, &SeNtSidAuthority, 2); 184 RtlInitializeSid(SeAliasAccountOpsSid, &SeNtSidAuthority, 2); 185 RtlInitializeSid(SeAliasSystemOpsSid, &SeNtSidAuthority, 2); 186 RtlInitializeSid(SeAliasPrintOpsSid, &SeNtSidAuthority, 2); 187 RtlInitializeSid(SeAliasBackupOpsSid, &SeNtSidAuthority, 2); 188 RtlInitializeSid(SeAuthenticatedUsersSid, &SeNtSidAuthority, 1); 189 RtlInitializeSid(SeRestrictedSid, &SeNtSidAuthority, 1); 190 RtlInitializeSid(SeAnonymousLogonSid, &SeNtSidAuthority, 1); 191 RtlInitializeSid(SeLocalServiceSid, &SeNtSidAuthority, 1); 192 RtlInitializeSid(SeNetworkServiceSid, &SeNtSidAuthority, 1); 193 194 SubAuthority = RtlSubAuthoritySid(SeNullSid, 0); 195 *SubAuthority = SECURITY_NULL_RID; 196 SubAuthority = RtlSubAuthoritySid(SeWorldSid, 0); 197 *SubAuthority = SECURITY_WORLD_RID; 198 SubAuthority = RtlSubAuthoritySid(SeLocalSid, 0); 199 *SubAuthority = SECURITY_LOCAL_RID; 200 SubAuthority = RtlSubAuthoritySid(SeCreatorOwnerSid, 0); 201 *SubAuthority = SECURITY_CREATOR_OWNER_RID; 202 SubAuthority = RtlSubAuthoritySid(SeCreatorGroupSid, 0); 203 *SubAuthority = SECURITY_CREATOR_GROUP_RID; 204 SubAuthority = RtlSubAuthoritySid(SeCreatorOwnerServerSid, 0); 205 *SubAuthority = SECURITY_CREATOR_OWNER_SERVER_RID; 206 SubAuthority = RtlSubAuthoritySid(SeCreatorGroupServerSid, 0); 207 *SubAuthority = SECURITY_CREATOR_GROUP_SERVER_RID; 208 SubAuthority = RtlSubAuthoritySid(SeDialupSid, 0); 209 *SubAuthority = SECURITY_DIALUP_RID; 210 SubAuthority = RtlSubAuthoritySid(SeNetworkSid, 0); 211 *SubAuthority = SECURITY_NETWORK_RID; 212 SubAuthority = RtlSubAuthoritySid(SeBatchSid, 0); 213 *SubAuthority = SECURITY_BATCH_RID; 214 SubAuthority = RtlSubAuthoritySid(SeInteractiveSid, 0); 215 *SubAuthority = SECURITY_INTERACTIVE_RID; 216 SubAuthority = RtlSubAuthoritySid(SeServiceSid, 0); 217 *SubAuthority = SECURITY_SERVICE_RID; 218 SubAuthority = RtlSubAuthoritySid(SePrincipalSelfSid, 0); 219 *SubAuthority = SECURITY_PRINCIPAL_SELF_RID; 220 SubAuthority = RtlSubAuthoritySid(SeLocalSystemSid, 0); 221 *SubAuthority = SECURITY_LOCAL_SYSTEM_RID; 222 SubAuthority = RtlSubAuthoritySid(SeAuthenticatedUserSid, 0); 223 *SubAuthority = SECURITY_AUTHENTICATED_USER_RID; 224 SubAuthority = RtlSubAuthoritySid(SeRestrictedCodeSid, 0); 225 *SubAuthority = SECURITY_RESTRICTED_CODE_RID; 226 SubAuthority = RtlSubAuthoritySid(SeAliasAdminsSid, 0); 227 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; 228 SubAuthority = RtlSubAuthoritySid(SeAliasAdminsSid, 1); 229 *SubAuthority = DOMAIN_ALIAS_RID_ADMINS; 230 SubAuthority = RtlSubAuthoritySid(SeAliasUsersSid, 0); 231 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; 232 SubAuthority = RtlSubAuthoritySid(SeAliasUsersSid, 1); 233 *SubAuthority = DOMAIN_ALIAS_RID_USERS; 234 SubAuthority = RtlSubAuthoritySid(SeAliasGuestsSid, 0); 235 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; 236 SubAuthority = RtlSubAuthoritySid(SeAliasGuestsSid, 1); 237 *SubAuthority = DOMAIN_ALIAS_RID_GUESTS; 238 SubAuthority = RtlSubAuthoritySid(SeAliasPowerUsersSid, 0); 239 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; 240 SubAuthority = RtlSubAuthoritySid(SeAliasPowerUsersSid, 1); 241 *SubAuthority = DOMAIN_ALIAS_RID_POWER_USERS; 242 SubAuthority = RtlSubAuthoritySid(SeAliasAccountOpsSid, 0); 243 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; 244 SubAuthority = RtlSubAuthoritySid(SeAliasAccountOpsSid, 1); 245 *SubAuthority = DOMAIN_ALIAS_RID_ACCOUNT_OPS; 246 SubAuthority = RtlSubAuthoritySid(SeAliasSystemOpsSid, 0); 247 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; 248 SubAuthority = RtlSubAuthoritySid(SeAliasSystemOpsSid, 1); 249 *SubAuthority = DOMAIN_ALIAS_RID_SYSTEM_OPS; 250 SubAuthority = RtlSubAuthoritySid(SeAliasPrintOpsSid, 0); 251 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; 252 SubAuthority = RtlSubAuthoritySid(SeAliasPrintOpsSid, 1); 253 *SubAuthority = DOMAIN_ALIAS_RID_PRINT_OPS; 254 SubAuthority = RtlSubAuthoritySid(SeAliasBackupOpsSid, 0); 255 *SubAuthority = SECURITY_BUILTIN_DOMAIN_RID; 256 SubAuthority = RtlSubAuthoritySid(SeAliasBackupOpsSid, 1); 257 *SubAuthority = DOMAIN_ALIAS_RID_BACKUP_OPS; 258 SubAuthority = RtlSubAuthoritySid(SeAuthenticatedUsersSid, 0); 259 *SubAuthority = SECURITY_AUTHENTICATED_USER_RID; 260 SubAuthority = RtlSubAuthoritySid(SeRestrictedSid, 0); 261 *SubAuthority = SECURITY_RESTRICTED_CODE_RID; 262 SubAuthority = RtlSubAuthoritySid(SeAnonymousLogonSid, 0); 263 *SubAuthority = SECURITY_ANONYMOUS_LOGON_RID; 264 SubAuthority = RtlSubAuthoritySid(SeLocalServiceSid, 0); 265 *SubAuthority = SECURITY_LOCAL_SERVICE_RID; 266 SubAuthority = RtlSubAuthoritySid(SeNetworkServiceSid, 0); 267 *SubAuthority = SECURITY_NETWORK_SERVICE_RID; 268 269 return TRUE; 270 } 271 272 NTSTATUS 273 NTAPI 274 SepCaptureSid(IN PSID InputSid, 275 IN KPROCESSOR_MODE AccessMode, 276 IN POOL_TYPE PoolType, 277 IN BOOLEAN CaptureIfKernel, 278 OUT PSID *CapturedSid) 279 { 280 ULONG SidSize = 0; 281 PISID NewSid, Sid = (PISID)InputSid; 282 283 PAGED_CODE(); 284 285 if (AccessMode != KernelMode) 286 { 287 _SEH2_TRY 288 { 289 ProbeForRead(Sid, FIELD_OFFSET(SID, SubAuthority), sizeof(UCHAR)); 290 SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount); 291 ProbeForRead(Sid, SidSize, sizeof(UCHAR)); 292 } 293 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 294 { 295 /* Return the exception code */ 296 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 297 } 298 _SEH2_END; 299 300 /* Allocate a SID and copy it */ 301 NewSid = ExAllocatePoolWithTag(PoolType, SidSize, TAG_SID); 302 if (!NewSid) 303 return STATUS_INSUFFICIENT_RESOURCES; 304 305 _SEH2_TRY 306 { 307 RtlCopyMemory(NewSid, Sid, SidSize); 308 309 *CapturedSid = NewSid; 310 } 311 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 312 { 313 /* Free the SID and return the exception code */ 314 ExFreePoolWithTag(NewSid, TAG_SID); 315 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 316 } 317 _SEH2_END; 318 } 319 else if (!CaptureIfKernel) 320 { 321 *CapturedSid = InputSid; 322 } 323 else 324 { 325 SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount); 326 327 /* Allocate a SID and copy it */ 328 NewSid = ExAllocatePoolWithTag(PoolType, SidSize, TAG_SID); 329 if (NewSid == NULL) 330 return STATUS_INSUFFICIENT_RESOURCES; 331 332 RtlCopyMemory(NewSid, Sid, SidSize); 333 334 *CapturedSid = NewSid; 335 } 336 337 return STATUS_SUCCESS; 338 } 339 340 VOID 341 NTAPI 342 SepReleaseSid(IN PSID CapturedSid, 343 IN KPROCESSOR_MODE AccessMode, 344 IN BOOLEAN CaptureIfKernel) 345 { 346 PAGED_CODE(); 347 348 if (CapturedSid != NULL && 349 (AccessMode != KernelMode || 350 (AccessMode == KernelMode && CaptureIfKernel))) 351 { 352 ExFreePoolWithTag(CapturedSid, TAG_SID); 353 } 354 } 355 356 NTSTATUS 357 NTAPI 358 SeCaptureSidAndAttributesArray( 359 _In_ PSID_AND_ATTRIBUTES SrcSidAndAttributes, 360 _In_ ULONG AttributeCount, 361 _In_ KPROCESSOR_MODE PreviousMode, 362 _In_opt_ PVOID AllocatedMem, 363 _In_ ULONG AllocatedLength, 364 _In_ POOL_TYPE PoolType, 365 _In_ BOOLEAN CaptureIfKernel, 366 _Out_ PSID_AND_ATTRIBUTES *CapturedSidAndAttributes, 367 _Out_ PULONG ResultLength) 368 { 369 ULONG ArraySize, RequiredLength, SidLength, i; 370 PSID_AND_ATTRIBUTES SidAndAttributes; 371 PUCHAR CurrentDest; 372 PISID Sid; 373 NTSTATUS Status; 374 PAGED_CODE(); 375 376 *CapturedSidAndAttributes = NULL; 377 *ResultLength = 0; 378 379 if (AttributeCount == 0) 380 { 381 return STATUS_SUCCESS; 382 } 383 384 if (AttributeCount > 0x1000) 385 { 386 return STATUS_INVALID_PARAMETER; 387 } 388 389 if ((PreviousMode == KernelMode) && !CaptureIfKernel) 390 { 391 *CapturedSidAndAttributes = SrcSidAndAttributes; 392 return STATUS_SUCCESS; 393 } 394 395 ArraySize = AttributeCount * sizeof(SID_AND_ATTRIBUTES); 396 RequiredLength = ALIGN_UP_BY(ArraySize, sizeof(ULONG)); 397 398 /* Check for user mode data */ 399 if (PreviousMode != KernelMode) 400 { 401 _SEH2_TRY 402 { 403 /* First probe the whole array */ 404 ProbeForRead(SrcSidAndAttributes, ArraySize, sizeof(ULONG)); 405 406 /* Loop the array elements */ 407 for (i = 0; i < AttributeCount; i++) 408 { 409 /* Get the SID and probe the minimal structure */ 410 Sid = SrcSidAndAttributes[i].Sid; 411 ProbeForRead(Sid, sizeof(*Sid), sizeof(ULONG)); 412 413 /* Verify that the SID is valid */ 414 if (((Sid->Revision & 0xF) != SID_REVISION) || 415 (Sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES)) 416 { 417 _SEH2_YIELD(return STATUS_INVALID_SID); 418 } 419 420 /* Calculate the SID length and probe the full SID */ 421 SidLength = RtlLengthRequiredSid(Sid->SubAuthorityCount); 422 ProbeForRead(Sid, SidLength, sizeof(ULONG)); 423 424 /* Add the aligned length to the required length */ 425 RequiredLength += ALIGN_UP_BY(SidLength, sizeof(ULONG)); 426 } 427 } 428 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 429 { 430 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 431 } 432 _SEH2_END; 433 } 434 else 435 { 436 /* Loop the array elements */ 437 for (i = 0; i < AttributeCount; i++) 438 { 439 /* Get the SID and it's length */ 440 Sid = SrcSidAndAttributes[i].Sid; 441 SidLength = RtlLengthRequiredSid(Sid->SubAuthorityCount); 442 443 /* Add the aligned length to the required length */ 444 RequiredLength += ALIGN_UP_BY(SidLength, sizeof(ULONG)); 445 } 446 } 447 448 /* Assume success */ 449 Status = STATUS_SUCCESS; 450 *ResultLength = RequiredLength; 451 452 /* Check if we have no buffer */ 453 if (AllocatedMem == NULL) 454 { 455 /* Allocate a new buffer */ 456 SidAndAttributes = ExAllocatePoolWithTag(PoolType, 457 RequiredLength, 458 TAG_SID_AND_ATTRIBUTES); 459 if (SidAndAttributes == NULL) 460 { 461 return STATUS_INSUFFICIENT_RESOURCES; 462 } 463 } 464 /* Otherwise check if the buffer is large enough */ 465 else if (AllocatedLength >= RequiredLength) 466 { 467 /* Buffer is large enough, use it */ 468 SidAndAttributes = AllocatedMem; 469 } 470 else 471 { 472 /* Buffer is too small, fail */ 473 return STATUS_BUFFER_TOO_SMALL; 474 } 475 476 *CapturedSidAndAttributes = SidAndAttributes; 477 478 /* Check again for user mode */ 479 if (PreviousMode != KernelMode) 480 { 481 _SEH2_TRY 482 { 483 /* The rest of the data starts after the array */ 484 CurrentDest = (PUCHAR)SidAndAttributes; 485 CurrentDest += ALIGN_UP_BY(ArraySize, sizeof(ULONG)); 486 487 /* Loop the array elements */ 488 for (i = 0; i < AttributeCount; i++) 489 { 490 /* Get the SID and it's length */ 491 Sid = SrcSidAndAttributes[i].Sid; 492 SidLength = RtlLengthRequiredSid(Sid->SubAuthorityCount); 493 494 /* Copy attributes */ 495 SidAndAttributes[i].Attributes = SrcSidAndAttributes[i].Attributes; 496 497 /* Copy the SID to the current destination address */ 498 SidAndAttributes[i].Sid = (PSID)CurrentDest; 499 RtlCopyMemory(CurrentDest, SrcSidAndAttributes[i].Sid, SidLength); 500 501 /* Sanity checks */ 502 ASSERT(RtlLengthSid(SidAndAttributes[i].Sid) == SidLength); 503 ASSERT(RtlValidSid(SidAndAttributes[i].Sid)); 504 505 /* Update the current destination address */ 506 CurrentDest += ALIGN_UP_BY(SidLength, sizeof(ULONG)); 507 } 508 } 509 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 510 { 511 Status = _SEH2_GetExceptionCode(); 512 } 513 _SEH2_END; 514 } 515 else 516 { 517 /* The rest of the data starts after the array */ 518 CurrentDest = (PUCHAR)SidAndAttributes; 519 CurrentDest += ALIGN_UP_BY(ArraySize, sizeof(ULONG)); 520 521 /* Loop the array elements */ 522 for (i = 0; i < AttributeCount; i++) 523 { 524 /* Get the SID and it's length */ 525 Sid = SrcSidAndAttributes[i].Sid; 526 SidLength = RtlLengthRequiredSid(Sid->SubAuthorityCount); 527 528 /* Copy attributes */ 529 SidAndAttributes[i].Attributes = SrcSidAndAttributes[i].Attributes; 530 531 /* Copy the SID to the current destination address */ 532 SidAndAttributes[i].Sid = (PSID)CurrentDest; 533 RtlCopyMemory(CurrentDest, SrcSidAndAttributes[i].Sid, SidLength); 534 535 /* Update the current destination address */ 536 CurrentDest += ALIGN_UP_BY(SidLength, sizeof(ULONG)); 537 } 538 } 539 540 /* Check for failure */ 541 if (!NT_SUCCESS(Status)) 542 { 543 /* Check if we allocated a new array */ 544 if (SidAndAttributes != AllocatedMem) 545 { 546 /* Free the array */ 547 ExFreePoolWithTag(SidAndAttributes, TAG_SID_AND_ATTRIBUTES); 548 } 549 550 /* Set returned address to NULL */ 551 *CapturedSidAndAttributes = NULL ; 552 } 553 554 return Status; 555 } 556 557 VOID 558 NTAPI 559 SeReleaseSidAndAttributesArray( 560 _In_ _Post_invalid_ PSID_AND_ATTRIBUTES CapturedSidAndAttributes, 561 _In_ KPROCESSOR_MODE AccessMode, 562 _In_ BOOLEAN CaptureIfKernel) 563 { 564 PAGED_CODE(); 565 566 if ((CapturedSidAndAttributes != NULL) && 567 ((AccessMode != KernelMode) || CaptureIfKernel)) 568 { 569 ExFreePoolWithTag(CapturedSidAndAttributes, TAG_SID_AND_ATTRIBUTES); 570 } 571 } 572 573 574 /* EOF */ 575