Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensd.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: ntoskrnl/se/sd.c 00005 * PURPOSE: Security manager 00006 * 00007 * PROGRAMMERS: David Welch <welch@cwcom.net> 00008 */ 00009 00010 /* INCLUDES *******************************************************************/ 00011 00012 #include <ntoskrnl.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 #if defined (ALLOC_PRAGMA) 00017 #pragma alloc_text(INIT, SepInitSDs) 00018 #endif 00019 00020 /* GLOBALS ********************************************************************/ 00021 00022 PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL; 00023 PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd = NULL; 00024 PSECURITY_DESCRIPTOR SePublicOpenSd = NULL; 00025 PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd = NULL; 00026 PSECURITY_DESCRIPTOR SeSystemDefaultSd = NULL; 00027 PSECURITY_DESCRIPTOR SeUnrestrictedSd = NULL; 00028 00029 /* PRIVATE FUNCTIONS **********************************************************/ 00030 00031 PSID 00032 FORCEINLINE 00033 SepGetGroupFromDescriptor(PVOID _Descriptor) 00034 { 00035 PISECURITY_DESCRIPTOR Descriptor = (PISECURITY_DESCRIPTOR)_Descriptor; 00036 PISECURITY_DESCRIPTOR_RELATIVE SdRel; 00037 00038 if (Descriptor->Control & SE_SELF_RELATIVE) 00039 { 00040 SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)Descriptor; 00041 if (!SdRel->Group) return NULL; 00042 return (PSID)((ULONG_PTR)Descriptor + SdRel->Group); 00043 } 00044 else 00045 { 00046 return Descriptor->Group; 00047 } 00048 } 00049 00050 PSID 00051 FORCEINLINE 00052 SepGetOwnerFromDescriptor(PVOID _Descriptor) 00053 { 00054 PISECURITY_DESCRIPTOR Descriptor = (PISECURITY_DESCRIPTOR)_Descriptor; 00055 PISECURITY_DESCRIPTOR_RELATIVE SdRel; 00056 00057 if (Descriptor->Control & SE_SELF_RELATIVE) 00058 { 00059 SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)Descriptor; 00060 if (!SdRel->Owner) return NULL; 00061 return (PSID)((ULONG_PTR)Descriptor + SdRel->Owner); 00062 } 00063 else 00064 { 00065 return Descriptor->Owner; 00066 } 00067 } 00068 00069 PACL 00070 FORCEINLINE 00071 SepGetDaclFromDescriptor(PVOID _Descriptor) 00072 { 00073 PISECURITY_DESCRIPTOR Descriptor = (PISECURITY_DESCRIPTOR)_Descriptor; 00074 PISECURITY_DESCRIPTOR_RELATIVE SdRel; 00075 00076 if (Descriptor->Control & SE_SELF_RELATIVE) 00077 { 00078 SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)Descriptor; 00079 if (!SdRel->Dacl) return NULL; 00080 return (PACL)((ULONG_PTR)Descriptor + SdRel->Dacl); 00081 } 00082 else 00083 { 00084 return Descriptor->Dacl; 00085 } 00086 } 00087 00088 PACL 00089 FORCEINLINE 00090 SepGetSaclFromDescriptor(PVOID _Descriptor) 00091 { 00092 PISECURITY_DESCRIPTOR Descriptor = (PISECURITY_DESCRIPTOR)_Descriptor; 00093 PISECURITY_DESCRIPTOR_RELATIVE SdRel; 00094 00095 if (Descriptor->Control & SE_SELF_RELATIVE) 00096 { 00097 SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)Descriptor; 00098 if (!SdRel->Sacl) return NULL; 00099 return (PACL)((ULONG_PTR)Descriptor + SdRel->Sacl); 00100 } 00101 else 00102 { 00103 return Descriptor->Sacl; 00104 } 00105 } 00106 00107 BOOLEAN 00108 INIT_FUNCTION 00109 NTAPI 00110 SepInitSDs(VOID) 00111 { 00112 /* Create PublicDefaultSd */ 00113 SePublicDefaultSd = ExAllocatePoolWithTag(PagedPool, 00114 sizeof(SECURITY_DESCRIPTOR), TAG_SD); 00115 if (SePublicDefaultSd == NULL) 00116 return FALSE; 00117 00118 RtlCreateSecurityDescriptor(SePublicDefaultSd, 00119 SECURITY_DESCRIPTOR_REVISION); 00120 RtlSetDaclSecurityDescriptor(SePublicDefaultSd, 00121 TRUE, 00122 SePublicDefaultDacl, 00123 FALSE); 00124 00125 /* Create PublicDefaultUnrestrictedSd */ 00126 SePublicDefaultUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, 00127 sizeof(SECURITY_DESCRIPTOR), TAG_SD); 00128 if (SePublicDefaultUnrestrictedSd == NULL) 00129 return FALSE; 00130 00131 RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd, 00132 SECURITY_DESCRIPTOR_REVISION); 00133 RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd, 00134 TRUE, 00135 SePublicDefaultUnrestrictedDacl, 00136 FALSE); 00137 00138 /* Create PublicOpenSd */ 00139 SePublicOpenSd = ExAllocatePoolWithTag(PagedPool, 00140 sizeof(SECURITY_DESCRIPTOR), TAG_SD); 00141 if (SePublicOpenSd == NULL) 00142 return FALSE; 00143 00144 RtlCreateSecurityDescriptor(SePublicOpenSd, 00145 SECURITY_DESCRIPTOR_REVISION); 00146 RtlSetDaclSecurityDescriptor(SePublicOpenSd, 00147 TRUE, 00148 SePublicOpenDacl, 00149 FALSE); 00150 00151 /* Create PublicOpenUnrestrictedSd */ 00152 SePublicOpenUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, 00153 sizeof(SECURITY_DESCRIPTOR), TAG_SD); 00154 if (SePublicOpenUnrestrictedSd == NULL) 00155 return FALSE; 00156 00157 RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd, 00158 SECURITY_DESCRIPTOR_REVISION); 00159 RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd, 00160 TRUE, 00161 SePublicOpenUnrestrictedDacl, 00162 FALSE); 00163 00164 /* Create SystemDefaultSd */ 00165 SeSystemDefaultSd = ExAllocatePoolWithTag(PagedPool, 00166 sizeof(SECURITY_DESCRIPTOR), TAG_SD); 00167 if (SeSystemDefaultSd == NULL) 00168 return FALSE; 00169 00170 RtlCreateSecurityDescriptor(SeSystemDefaultSd, 00171 SECURITY_DESCRIPTOR_REVISION); 00172 RtlSetDaclSecurityDescriptor(SeSystemDefaultSd, 00173 TRUE, 00174 SeSystemDefaultDacl, 00175 FALSE); 00176 00177 /* Create UnrestrictedSd */ 00178 SeUnrestrictedSd = ExAllocatePoolWithTag(PagedPool, 00179 sizeof(SECURITY_DESCRIPTOR), TAG_SD); 00180 if (SeUnrestrictedSd == NULL) 00181 return FALSE; 00182 00183 RtlCreateSecurityDescriptor(SeUnrestrictedSd, 00184 SECURITY_DESCRIPTOR_REVISION); 00185 RtlSetDaclSecurityDescriptor(SeUnrestrictedSd, 00186 TRUE, 00187 SeUnrestrictedDacl, 00188 FALSE); 00189 00190 return TRUE; 00191 } 00192 00193 NTSTATUS 00194 NTAPI 00195 SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation, 00196 PISECURITY_DESCRIPTOR SecurityDescriptor, 00197 PULONG BufferLength) 00198 { 00199 ULONG Current; 00200 ULONG SidSize; 00201 ULONG SdSize; 00202 NTSTATUS Status; 00203 PISECURITY_DESCRIPTOR_RELATIVE SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; 00204 00205 DPRINT("SeSetWorldSecurityDescriptor() called\n"); 00206 00207 if (SecurityInformation == 0) 00208 { 00209 return STATUS_ACCESS_DENIED; 00210 } 00211 00212 /* calculate the minimum size of the buffer */ 00213 SidSize = RtlLengthSid(SeWorldSid); 00214 SdSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE); 00215 if (SecurityInformation & OWNER_SECURITY_INFORMATION) 00216 SdSize += SidSize; 00217 if (SecurityInformation & GROUP_SECURITY_INFORMATION) 00218 SdSize += SidSize; 00219 if (SecurityInformation & DACL_SECURITY_INFORMATION) 00220 { 00221 SdSize += sizeof(ACL) + sizeof(ACE) + SidSize; 00222 } 00223 00224 if (*BufferLength < SdSize) 00225 { 00226 *BufferLength = SdSize; 00227 return STATUS_BUFFER_TOO_SMALL; 00228 } 00229 00230 *BufferLength = SdSize; 00231 00232 Status = RtlCreateSecurityDescriptorRelative(SdRel, 00233 SECURITY_DESCRIPTOR_REVISION); 00234 if (!NT_SUCCESS(Status)) 00235 { 00236 return Status; 00237 } 00238 00239 Current = sizeof(SECURITY_DESCRIPTOR_RELATIVE); 00240 00241 if (SecurityInformation & OWNER_SECURITY_INFORMATION) 00242 { 00243 RtlCopyMemory((PUCHAR)SdRel + Current, SeWorldSid, SidSize); 00244 SdRel->Owner = Current; 00245 Current += SidSize; 00246 } 00247 00248 if (SecurityInformation & GROUP_SECURITY_INFORMATION) 00249 { 00250 RtlCopyMemory((PUCHAR)SdRel + Current, SeWorldSid, SidSize); 00251 SdRel->Group = Current; 00252 Current += SidSize; 00253 } 00254 00255 if (SecurityInformation & DACL_SECURITY_INFORMATION) 00256 { 00257 PACL Dacl = (PACL)((PUCHAR)SdRel + Current); 00258 SdRel->Control |= SE_DACL_PRESENT; 00259 00260 Status = RtlCreateAcl(Dacl, 00261 sizeof(ACL) + sizeof(ACE) + SidSize, 00262 ACL_REVISION); 00263 if (!NT_SUCCESS(Status)) 00264 return Status; 00265 00266 Status = RtlAddAccessAllowedAce(Dacl, 00267 ACL_REVISION, 00268 GENERIC_ALL, 00269 SeWorldSid); 00270 if (!NT_SUCCESS(Status)) 00271 return Status; 00272 00273 SdRel->Dacl = Current; 00274 } 00275 00276 if (SecurityInformation & SACL_SECURITY_INFORMATION) 00277 { 00278 /* FIXME - SdRel->Control |= SE_SACL_PRESENT; */ 00279 } 00280 00281 return STATUS_SUCCESS; 00282 } 00283 00284 00285 NTSTATUS 00286 NTAPI 00287 SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 00288 IN KPROCESSOR_MODE AccessMode, 00289 IN POOL_TYPE PoolType, 00290 IN BOOLEAN CaptureIfKernel, 00291 OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService, 00292 OUT PBOOLEAN Present) 00293 { 00294 PSECURITY_QUALITY_OF_SERVICE CapturedQos; 00295 NTSTATUS Status = STATUS_SUCCESS; 00296 00297 PAGED_CODE(); 00298 00299 ASSERT(CapturedSecurityQualityOfService); 00300 ASSERT(Present); 00301 00302 if (ObjectAttributes != NULL) 00303 { 00304 if (AccessMode != KernelMode) 00305 { 00306 SECURITY_QUALITY_OF_SERVICE SafeQos; 00307 00308 _SEH2_TRY 00309 { 00310 ProbeForRead(ObjectAttributes, 00311 sizeof(OBJECT_ATTRIBUTES), 00312 sizeof(ULONG)); 00313 if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) 00314 { 00315 if (ObjectAttributes->SecurityQualityOfService != NULL) 00316 { 00317 ProbeForRead(ObjectAttributes->SecurityQualityOfService, 00318 sizeof(SECURITY_QUALITY_OF_SERVICE), 00319 sizeof(ULONG)); 00320 00321 if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == 00322 sizeof(SECURITY_QUALITY_OF_SERVICE)) 00323 { 00324 /* 00325 * Don't allocate memory here because ExAllocate should bugcheck 00326 * the system if it's buggy, SEH would catch that! So make a local 00327 * copy of the qos structure. 00328 */ 00329 RtlCopyMemory(&SafeQos, 00330 ObjectAttributes->SecurityQualityOfService, 00331 sizeof(SECURITY_QUALITY_OF_SERVICE)); 00332 *Present = TRUE; 00333 } 00334 else 00335 { 00336 Status = STATUS_INVALID_PARAMETER; 00337 } 00338 } 00339 else 00340 { 00341 *CapturedSecurityQualityOfService = NULL; 00342 *Present = FALSE; 00343 } 00344 } 00345 else 00346 { 00347 Status = STATUS_INVALID_PARAMETER; 00348 } 00349 } 00350 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00351 { 00352 Status = _SEH2_GetExceptionCode(); 00353 } 00354 _SEH2_END; 00355 00356 if (NT_SUCCESS(Status)) 00357 { 00358 if (*Present) 00359 { 00360 CapturedQos = ExAllocatePool(PoolType, 00361 sizeof(SECURITY_QUALITY_OF_SERVICE)); 00362 if (CapturedQos != NULL) 00363 { 00364 RtlCopyMemory(CapturedQos, 00365 &SafeQos, 00366 sizeof(SECURITY_QUALITY_OF_SERVICE)); 00367 *CapturedSecurityQualityOfService = CapturedQos; 00368 } 00369 else 00370 { 00371 Status = STATUS_INSUFFICIENT_RESOURCES; 00372 } 00373 } 00374 else 00375 { 00376 *CapturedSecurityQualityOfService = NULL; 00377 } 00378 } 00379 } 00380 else 00381 { 00382 if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES)) 00383 { 00384 if (CaptureIfKernel) 00385 { 00386 if (ObjectAttributes->SecurityQualityOfService != NULL) 00387 { 00388 if (((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length == 00389 sizeof(SECURITY_QUALITY_OF_SERVICE)) 00390 { 00391 CapturedQos = ExAllocatePool(PoolType, 00392 sizeof(SECURITY_QUALITY_OF_SERVICE)); 00393 if (CapturedQos != NULL) 00394 { 00395 RtlCopyMemory(CapturedQos, 00396 ObjectAttributes->SecurityQualityOfService, 00397 sizeof(SECURITY_QUALITY_OF_SERVICE)); 00398 *CapturedSecurityQualityOfService = CapturedQos; 00399 *Present = TRUE; 00400 } 00401 else 00402 { 00403 Status = STATUS_INSUFFICIENT_RESOURCES; 00404 } 00405 } 00406 else 00407 { 00408 Status = STATUS_INVALID_PARAMETER; 00409 } 00410 } 00411 else 00412 { 00413 *CapturedSecurityQualityOfService = NULL; 00414 *Present = FALSE; 00415 } 00416 } 00417 else 00418 { 00419 *CapturedSecurityQualityOfService = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService; 00420 *Present = (ObjectAttributes->SecurityQualityOfService != NULL); 00421 } 00422 } 00423 else 00424 { 00425 Status = STATUS_INVALID_PARAMETER; 00426 } 00427 } 00428 } 00429 else 00430 { 00431 *CapturedSecurityQualityOfService = NULL; 00432 *Present = FALSE; 00433 } 00434 00435 return Status; 00436 } 00437 00438 00439 VOID 00440 NTAPI 00441 SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL, 00442 IN KPROCESSOR_MODE AccessMode, 00443 IN BOOLEAN CaptureIfKernel) 00444 { 00445 PAGED_CODE(); 00446 00447 if (CapturedSecurityQualityOfService != NULL && 00448 (AccessMode != KernelMode || CaptureIfKernel)) 00449 { 00450 ExFreePool(CapturedSecurityQualityOfService); 00451 } 00452 } 00453 00454 /* PUBLIC FUNCTIONS ***********************************************************/ 00455 00456 static 00457 ULONG 00458 DetermineSIDSize( 00459 PISID Sid, 00460 PULONG OutSAC, 00461 KPROCESSOR_MODE ProcessorMode) 00462 { 00463 ULONG Size; 00464 00465 if (!Sid) 00466 { 00467 *OutSAC = 0; 00468 return 0; 00469 } 00470 00471 if (ProcessorMode != KernelMode) 00472 { 00473 /* Securely access the buffers! */ 00474 *OutSAC = ProbeForReadUchar(&Sid->SubAuthorityCount); 00475 Size = RtlLengthRequiredSid(*OutSAC); 00476 ProbeForRead(Sid, Size, sizeof(ULONG)); 00477 } 00478 else 00479 { 00480 *OutSAC = Sid->SubAuthorityCount; 00481 Size = RtlLengthRequiredSid(*OutSAC); 00482 } 00483 00484 return Size; 00485 } 00486 00487 static 00488 ULONG 00489 DetermineACLSize( 00490 PACL Acl, 00491 KPROCESSOR_MODE ProcessorMode) 00492 { 00493 ULONG Size; 00494 00495 if (!Acl) return 0; 00496 00497 if (ProcessorMode == KernelMode) return Acl->AclSize; 00498 00499 /* Probe the buffers! */ 00500 Size = ProbeForReadUshort(&Acl->AclSize); 00501 ProbeForRead(Acl, Size, sizeof(ULONG)); 00502 00503 return Size; 00504 } 00505 00506 NTSTATUS 00507 NTAPI 00508 SeCaptureSecurityDescriptor( 00509 IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, 00510 IN KPROCESSOR_MODE CurrentMode, 00511 IN POOL_TYPE PoolType, 00512 IN BOOLEAN CaptureIfKernel, 00513 OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor) 00514 { 00515 PISECURITY_DESCRIPTOR OriginalDescriptor = _OriginalSecurityDescriptor; 00516 SECURITY_DESCRIPTOR DescriptorCopy; 00517 PISECURITY_DESCRIPTOR_RELATIVE NewDescriptor; 00518 ULONG OwnerSAC = 0, GroupSAC = 0; 00519 ULONG OwnerSize = 0, GroupSize = 0; 00520 ULONG SaclSize = 0, DaclSize = 0; 00521 ULONG DescriptorSize = 0; 00522 ULONG Offset; 00523 00524 if (!OriginalDescriptor) 00525 { 00526 /* Nothing to do... */ 00527 *CapturedSecurityDescriptor = NULL; 00528 return STATUS_SUCCESS; 00529 } 00530 00531 /* Quick path */ 00532 if (CurrentMode == KernelMode && !CaptureIfKernel) 00533 { 00534 /* Check descriptor version */ 00535 if (OriginalDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) 00536 { 00537 return STATUS_UNKNOWN_REVISION; 00538 } 00539 00540 *CapturedSecurityDescriptor = _OriginalSecurityDescriptor; 00541 return STATUS_SUCCESS; 00542 } 00543 00544 _SEH2_TRY 00545 { 00546 if (CurrentMode != KernelMode) 00547 { 00548 ProbeForRead(OriginalDescriptor, 00549 sizeof(SECURITY_DESCRIPTOR_RELATIVE), 00550 sizeof(ULONG)); 00551 } 00552 00553 /* Check the descriptor version */ 00554 if (OriginalDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) 00555 { 00556 _SEH2_YIELD(return STATUS_UNKNOWN_REVISION); 00557 } 00558 00559 if (CurrentMode != KernelMode) 00560 { 00561 /* Get the size of the descriptor */ 00562 DescriptorSize = (OriginalDescriptor->Control & SE_SELF_RELATIVE) ? 00563 sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR); 00564 00565 /* Probe the entire security descriptor structure. The SIDs 00566 * and ACLs will be probed and copied later though */ 00567 ProbeForRead(OriginalDescriptor, DescriptorSize, sizeof(ULONG)); 00568 } 00569 00570 /* Now capture all fields and convert to an absolute descriptor */ 00571 DescriptorCopy.Revision = OriginalDescriptor->Revision; 00572 DescriptorCopy.Sbz1 = OriginalDescriptor->Sbz1; 00573 DescriptorCopy.Control = OriginalDescriptor->Control & ~SE_SELF_RELATIVE; 00574 DescriptorCopy.Owner = SepGetOwnerFromDescriptor(OriginalDescriptor); 00575 DescriptorCopy.Group = SepGetGroupFromDescriptor(OriginalDescriptor); 00576 DescriptorCopy.Sacl = SepGetSaclFromDescriptor(OriginalDescriptor); 00577 DescriptorCopy.Dacl = SepGetDaclFromDescriptor(OriginalDescriptor); 00578 DescriptorSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE); 00579 00580 /* Determine owner and group sizes */ 00581 OwnerSize = DetermineSIDSize(DescriptorCopy.Owner, &OwnerSAC, CurrentMode); 00582 DescriptorSize += ROUND_UP(OwnerSize, sizeof(ULONG)); 00583 GroupSize = DetermineSIDSize(DescriptorCopy.Group, &GroupSAC, CurrentMode); 00584 DescriptorSize += ROUND_UP(GroupSize, sizeof(ULONG)); 00585 00586 /* Determine the size of the ACLs */ 00587 if (DescriptorCopy.Control & SE_SACL_PRESENT) 00588 { 00589 /* Get the size and probe if user mode */ 00590 SaclSize = DetermineACLSize(DescriptorCopy.Sacl, CurrentMode); 00591 DescriptorSize += ROUND_UP(SaclSize, sizeof(ULONG)); 00592 } 00593 00594 if (DescriptorCopy.Control & SE_DACL_PRESENT) 00595 { 00596 /* Get the size and probe if user mode */ 00597 DaclSize = DetermineACLSize(DescriptorCopy.Dacl, CurrentMode); 00598 DescriptorSize += ROUND_UP(DaclSize, sizeof(ULONG)); 00599 } 00600 } 00601 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00602 { 00603 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 00604 } 00605 _SEH2_END 00606 00607 /* 00608 * Allocate enough memory to store a complete copy of a self-relative 00609 * security descriptor 00610 */ 00611 NewDescriptor = ExAllocatePoolWithTag(PoolType, 00612 DescriptorSize, 00613 TAG_SD); 00614 if (!NewDescriptor) return STATUS_INSUFFICIENT_RESOURCES; 00615 00616 RtlZeroMemory(NewDescriptor, DescriptorSize); 00617 NewDescriptor->Revision = DescriptorCopy.Revision; 00618 NewDescriptor->Sbz1 = DescriptorCopy.Sbz1; 00619 NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE; 00620 00621 _SEH2_TRY 00622 { 00623 /* 00624 * Setup the offsets and copy the SIDs and ACLs to the new 00625 * self-relative security descriptor. Probing the pointers is not 00626 * neccessary anymore as we did that when collecting the sizes! 00627 * Make sure to validate the SIDs and ACLs *again* as they could have 00628 * been modified in the meanwhile! 00629 */ 00630 Offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE); 00631 00632 if (DescriptorCopy.Owner) 00633 { 00634 if (!RtlValidSid(DescriptorCopy.Owner)) RtlRaiseStatus(STATUS_INVALID_SID); 00635 NewDescriptor->Owner = Offset; 00636 RtlCopyMemory((PUCHAR)NewDescriptor + Offset, 00637 DescriptorCopy.Owner, 00638 OwnerSize); 00639 Offset += ROUND_UP(OwnerSize, sizeof(ULONG)); 00640 } 00641 00642 if (DescriptorCopy.Group) 00643 { 00644 if (!RtlValidSid(DescriptorCopy.Group)) RtlRaiseStatus(STATUS_INVALID_SID); 00645 NewDescriptor->Group = Offset; 00646 RtlCopyMemory((PUCHAR)NewDescriptor + Offset, 00647 DescriptorCopy.Group, 00648 GroupSize); 00649 Offset += ROUND_UP(GroupSize, sizeof(ULONG)); 00650 } 00651 00652 if (DescriptorCopy.Sacl) 00653 { 00654 if (!RtlValidAcl(DescriptorCopy.Sacl)) RtlRaiseStatus(STATUS_INVALID_ACL); 00655 NewDescriptor->Sacl = Offset; 00656 RtlCopyMemory((PUCHAR)NewDescriptor + Offset, 00657 DescriptorCopy.Sacl, 00658 SaclSize); 00659 Offset += ROUND_UP(SaclSize, sizeof(ULONG)); 00660 } 00661 00662 if (DescriptorCopy.Dacl) 00663 { 00664 if (!RtlValidAcl(DescriptorCopy.Dacl)) RtlRaiseStatus(STATUS_INVALID_ACL); 00665 NewDescriptor->Dacl = Offset; 00666 RtlCopyMemory((PUCHAR)NewDescriptor + Offset, 00667 DescriptorCopy.Dacl, 00668 DaclSize); 00669 Offset += ROUND_UP(DaclSize, sizeof(ULONG)); 00670 } 00671 00672 /* Make sure the size was correct */ 00673 ASSERT(Offset == DescriptorSize); 00674 } 00675 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00676 { 00677 /* We failed to copy the data to the new descriptor */ 00678 ExFreePoolWithTag(NewDescriptor, TAG_SD); 00679 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 00680 } 00681 _SEH2_END; 00682 00683 /* 00684 * We're finally done! 00685 * Copy the pointer to the captured descriptor to to the caller. 00686 */ 00687 *CapturedSecurityDescriptor = NewDescriptor; 00688 return STATUS_SUCCESS; 00689 } 00690 00691 /* 00692 * @implemented 00693 */ 00694 NTSTATUS NTAPI 00695 SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation, 00696 IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, 00697 IN OUT PULONG Length, 00698 IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL) 00699 { 00700 PISECURITY_DESCRIPTOR ObjectSd; 00701 PISECURITY_DESCRIPTOR_RELATIVE RelSD; 00702 PSID Owner = NULL; 00703 PSID Group = NULL; 00704 PACL Dacl = NULL; 00705 PACL Sacl = NULL; 00706 ULONG OwnerLength = 0; 00707 ULONG GroupLength = 0; 00708 ULONG DaclLength = 0; 00709 ULONG SaclLength = 0; 00710 ULONG Control = 0; 00711 ULONG_PTR Current; 00712 ULONG SdLength; 00713 00714 RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; 00715 00716 if (*ObjectsSecurityDescriptor == NULL) 00717 { 00718 if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE)) 00719 { 00720 *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE); 00721 return STATUS_BUFFER_TOO_SMALL; 00722 } 00723 00724 *Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE); 00725 RtlCreateSecurityDescriptorRelative(RelSD, 00726 SECURITY_DESCRIPTOR_REVISION); 00727 return STATUS_SUCCESS; 00728 } 00729 00730 ObjectSd = *ObjectsSecurityDescriptor; 00731 00732 /* Calculate the required security descriptor length */ 00733 Control = SE_SELF_RELATIVE; 00734 if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) && 00735 (ObjectSd->Owner != NULL)) 00736 { 00737 Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd); 00738 OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); 00739 Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED); 00740 } 00741 00742 if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) && 00743 (ObjectSd->Group != NULL)) 00744 { 00745 Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd); 00746 GroupLength = ROUND_UP(RtlLengthSid(Group), 4); 00747 Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED); 00748 } 00749 00750 if ((*SecurityInformation & DACL_SECURITY_INFORMATION) && 00751 (ObjectSd->Control & SE_DACL_PRESENT)) 00752 { 00753 if (ObjectSd->Dacl != NULL) 00754 { 00755 Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd); 00756 DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4); 00757 } 00758 00759 Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT)); 00760 } 00761 00762 if ((*SecurityInformation & SACL_SECURITY_INFORMATION) && 00763 (ObjectSd->Control & SE_SACL_PRESENT)) 00764 { 00765 if (ObjectSd->Sacl != NULL) 00766 { 00767 Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd); 00768 SaclLength = ROUND_UP(Sacl->AclSize, 4); 00769 } 00770 00771 Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT)); 00772 } 00773 00774 SdLength = OwnerLength + GroupLength + DaclLength + 00775 SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE); 00776 if (*Length < SdLength) 00777 { 00778 *Length = SdLength; 00779 return STATUS_BUFFER_TOO_SMALL; 00780 } 00781 00782 /* Build the new security descrtiptor */ 00783 RtlCreateSecurityDescriptorRelative(RelSD, 00784 SECURITY_DESCRIPTOR_REVISION); 00785 RelSD->Control = (USHORT)Control; 00786 00787 Current = (ULONG_PTR)(RelSD + 1); 00788 00789 if (OwnerLength != 0) 00790 { 00791 RtlCopyMemory((PVOID)Current, 00792 Owner, 00793 OwnerLength); 00794 RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); 00795 Current += OwnerLength; 00796 } 00797 00798 if (GroupLength != 0) 00799 { 00800 RtlCopyMemory((PVOID)Current, 00801 Group, 00802 GroupLength); 00803 RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); 00804 Current += GroupLength; 00805 } 00806 00807 if (DaclLength != 0) 00808 { 00809 RtlCopyMemory((PVOID)Current, 00810 Dacl, 00811 DaclLength); 00812 RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); 00813 Current += DaclLength; 00814 } 00815 00816 if (SaclLength != 0) 00817 { 00818 RtlCopyMemory((PVOID)Current, 00819 Sacl, 00820 SaclLength); 00821 RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor); 00822 Current += SaclLength; 00823 } 00824 00825 *Length = SdLength; 00826 00827 return STATUS_SUCCESS; 00828 } 00829 00830 /* 00831 * @implemented 00832 */ 00833 NTSTATUS 00834 NTAPI 00835 SeReleaseSecurityDescriptor(IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, 00836 IN KPROCESSOR_MODE CurrentMode, 00837 IN BOOLEAN CaptureIfKernelMode) 00838 { 00839 PAGED_CODE(); 00840 00841 /* 00842 * WARNING! You need to call this function with the same value for CurrentMode 00843 * and CaptureIfKernelMode that you previously passed to 00844 * SeCaptureSecurityDescriptor() in order to avoid memory leaks! 00845 */ 00846 if (CapturedSecurityDescriptor != NULL && 00847 (CurrentMode != KernelMode || 00848 (CurrentMode == KernelMode && CaptureIfKernelMode))) 00849 { 00850 /* Only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */ 00851 ExFreePoolWithTag(CapturedSecurityDescriptor, TAG_SD); 00852 } 00853 00854 return STATUS_SUCCESS; 00855 } 00856 00857 /* 00858 * @implemented 00859 */ 00860 NTSTATUS NTAPI 00861 SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL, 00862 IN PSECURITY_INFORMATION _SecurityInformation, 00863 IN PSECURITY_DESCRIPTOR _SecurityDescriptor, 00864 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, 00865 IN POOL_TYPE PoolType, 00866 IN PGENERIC_MAPPING GenericMapping) 00867 { 00868 PISECURITY_DESCRIPTOR_RELATIVE ObjectSd; 00869 PISECURITY_DESCRIPTOR_RELATIVE NewSd; 00870 PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor; 00871 PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; 00872 PSID Owner = 0; 00873 PSID Group = 0; 00874 PACL Dacl = 0; 00875 PACL Sacl = 0; 00876 ULONG OwnerLength = 0; 00877 ULONG GroupLength = 0; 00878 ULONG DaclLength = 0; 00879 ULONG SaclLength = 0; 00880 ULONG Control = 0; 00881 ULONG Current; 00882 SECURITY_INFORMATION SecurityInformation; 00883 00884 ObjectSd = *ObjectsSecurityDescriptor; 00885 ASSERT(ObjectSd->Control & SE_SELF_RELATIVE); 00886 00887 /* The object does not have a security descriptor. */ 00888 if (!ObjectSd) 00889 return STATUS_NO_SECURITY_ON_OBJECT; 00890 00891 SecurityInformation = *_SecurityInformation; 00892 00893 /* Get owner and owner size */ 00894 if (SecurityInformation & OWNER_SECURITY_INFORMATION) 00895 { 00896 if (SecurityDescriptor->Owner != NULL) 00897 { 00898 if (SecurityDescriptor->Control & SE_SELF_RELATIVE) 00899 Owner = (PSID)((ULONG_PTR)RelSD->Owner + 00900 (ULONG_PTR)SecurityDescriptor); 00901 else 00902 Owner = (PSID)SecurityDescriptor->Owner; 00903 OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); 00904 } 00905 00906 Control |= (SecurityDescriptor->Control & SE_OWNER_DEFAULTED); 00907 } 00908 else 00909 { 00910 if (ObjectSd->Owner) 00911 { 00912 Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd); 00913 OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); 00914 } 00915 00916 Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED); 00917 } 00918 00919 /* Get group and group size */ 00920 if (SecurityInformation & GROUP_SECURITY_INFORMATION) 00921 { 00922 if (SecurityDescriptor->Group != NULL) 00923 { 00924 if( SecurityDescriptor->Control & SE_SELF_RELATIVE ) 00925 Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group + 00926 (ULONG_PTR)SecurityDescriptor); 00927 else 00928 Group = (PSID)SecurityDescriptor->Group; 00929 GroupLength = ROUND_UP(RtlLengthSid(Group), 4); 00930 } 00931 00932 Control |= (SecurityDescriptor->Control & SE_GROUP_DEFAULTED); 00933 } 00934 else 00935 { 00936 if (ObjectSd->Group) 00937 { 00938 Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd); 00939 GroupLength = ROUND_UP(RtlLengthSid(Group), 4); 00940 } 00941 00942 Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED); 00943 } 00944 00945 /* Get DACL and DACL size */ 00946 if (SecurityInformation & DACL_SECURITY_INFORMATION) 00947 { 00948 if ((SecurityDescriptor->Control & SE_DACL_PRESENT) && 00949 (SecurityDescriptor->Dacl != NULL)) 00950 { 00951 if( SecurityDescriptor->Control & SE_SELF_RELATIVE ) 00952 Dacl = (PACL)((ULONG_PTR)SecurityDescriptor->Dacl + 00953 (ULONG_PTR)SecurityDescriptor); 00954 else 00955 Dacl = (PACL)SecurityDescriptor->Dacl; 00956 00957 DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4); 00958 } 00959 00960 Control |= (SecurityDescriptor->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT)); 00961 } 00962 else 00963 { 00964 if ((ObjectSd->Control & SE_DACL_PRESENT) && (ObjectSd->Dacl)) 00965 { 00966 Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd); 00967 DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4); 00968 } 00969 00970 Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT)); 00971 } 00972 00973 /* Get SACL and SACL size */ 00974 if (SecurityInformation & SACL_SECURITY_INFORMATION) 00975 { 00976 if ((SecurityDescriptor->Control & SE_SACL_PRESENT) && 00977 (SecurityDescriptor->Sacl != NULL)) 00978 { 00979 if( SecurityDescriptor->Control & SE_SELF_RELATIVE ) 00980 Sacl = (PACL)((ULONG_PTR)SecurityDescriptor->Sacl + 00981 (ULONG_PTR)SecurityDescriptor); 00982 else 00983 Sacl = (PACL)SecurityDescriptor->Sacl; 00984 SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4); 00985 } 00986 00987 Control |= (SecurityDescriptor->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT)); 00988 } 00989 else 00990 { 00991 if ((ObjectSd->Control & SE_SACL_PRESENT) && (ObjectSd->Sacl)) 00992 { 00993 Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd); 00994 SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4); 00995 } 00996 00997 Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT)); 00998 } 00999 01000 NewSd = ExAllocatePool(NonPagedPool, 01001 sizeof(SECURITY_DESCRIPTOR_RELATIVE) + OwnerLength + GroupLength + 01002 DaclLength + SaclLength); 01003 if (NewSd == NULL) 01004 { 01005 ObDereferenceObject(Object); 01006 return STATUS_INSUFFICIENT_RESOURCES; 01007 } 01008 01009 RtlCreateSecurityDescriptor(NewSd, 01010 SECURITY_DESCRIPTOR_REVISION1); 01011 01012 /* We always build a self-relative descriptor */ 01013 NewSd->Control = (USHORT)Control | SE_SELF_RELATIVE; 01014 01015 Current = sizeof(SECURITY_DESCRIPTOR); 01016 01017 if (OwnerLength != 0) 01018 { 01019 RtlCopyMemory((PUCHAR)NewSd + Current, Owner, OwnerLength); 01020 NewSd->Owner = Current; 01021 Current += OwnerLength; 01022 } 01023 01024 if (GroupLength != 0) 01025 { 01026 RtlCopyMemory((PUCHAR)NewSd + Current, Group, GroupLength); 01027 NewSd->Group = Current; 01028 Current += GroupLength; 01029 } 01030 01031 if (DaclLength != 0) 01032 { 01033 RtlCopyMemory((PUCHAR)NewSd + Current, Dacl, DaclLength); 01034 NewSd->Dacl = Current; 01035 Current += DaclLength; 01036 } 01037 01038 if (SaclLength != 0) 01039 { 01040 RtlCopyMemory((PUCHAR)NewSd + Current, Sacl, SaclLength); 01041 NewSd->Sacl = Current; 01042 Current += SaclLength; 01043 } 01044 01045 *ObjectsSecurityDescriptor = NewSd; 01046 return STATUS_SUCCESS; 01047 } 01048 01049 /* 01050 * @unimplemented 01051 */ 01052 NTSTATUS 01053 NTAPI 01054 SeSetSecurityDescriptorInfoEx(IN PVOID Object OPTIONAL, 01055 IN PSECURITY_INFORMATION SecurityInformation, 01056 IN PSECURITY_DESCRIPTOR ModificationDescriptor, 01057 IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, 01058 IN ULONG AutoInheritFlags, 01059 IN POOL_TYPE PoolType, 01060 IN PGENERIC_MAPPING GenericMapping) 01061 { 01062 PISECURITY_DESCRIPTOR ObjectSd = *ObjectsSecurityDescriptor; 01063 01064 /* The object does not have a security descriptor. */ 01065 if (!ObjectSd) 01066 return STATUS_NO_SECURITY_ON_OBJECT; 01067 01068 UNIMPLEMENTED; 01069 return STATUS_NOT_IMPLEMENTED; 01070 } 01071 01072 01073 /* 01074 * @implemented 01075 */ 01076 BOOLEAN NTAPI 01077 SeValidSecurityDescriptor(IN ULONG Length, 01078 IN PSECURITY_DESCRIPTOR _SecurityDescriptor) 01079 { 01080 ULONG SdLength; 01081 PISID Sid; 01082 PACL Acl; 01083 PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor = _SecurityDescriptor; 01084 01085 if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH) 01086 { 01087 DPRINT1("Invalid Security Descriptor revision\n"); 01088 return FALSE; 01089 } 01090 01091 if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1) 01092 { 01093 DPRINT1("Invalid Security Descriptor revision\n"); 01094 return FALSE; 01095 } 01096 01097 if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE)) 01098 { 01099 DPRINT1("No self-relative Security Descriptor\n"); 01100 return FALSE; 01101 } 01102 01103 SdLength = sizeof(SECURITY_DESCRIPTOR); 01104 01105 /* Check Owner SID */ 01106 if (SecurityDescriptor->Owner) 01107 { 01108 DPRINT1("No Owner SID\n"); 01109 return FALSE; 01110 } 01111 01112 if (SecurityDescriptor->Owner % sizeof(ULONG)) 01113 { 01114 DPRINT1("Invalid Owner SID alignment\n"); 01115 return FALSE; 01116 } 01117 01118 Sid = (PISID)((ULONG_PTR)SecurityDescriptor + SecurityDescriptor->Owner); 01119 if (Sid->Revision != SID_REVISION) 01120 { 01121 DPRINT1("Invalid Owner SID revision\n"); 01122 return FALSE; 01123 } 01124 01125 SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG)); 01126 if (Length < SdLength) 01127 { 01128 DPRINT1("Invalid Owner SID size\n"); 01129 return FALSE; 01130 } 01131 01132 /* Check Group SID */ 01133 if (SecurityDescriptor->Group) 01134 { 01135 if (SecurityDescriptor->Group % sizeof(ULONG)) 01136 { 01137 DPRINT1("Invalid Group SID alignment\n"); 01138 return FALSE; 01139 } 01140 01141 Sid = (PSID)((ULONG_PTR)SecurityDescriptor + SecurityDescriptor->Group); 01142 if (Sid->Revision != SID_REVISION) 01143 { 01144 DPRINT1("Invalid Group SID revision\n"); 01145 return FALSE; 01146 } 01147 01148 SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG)); 01149 if (Length < SdLength) 01150 { 01151 DPRINT1("Invalid Group SID size\n"); 01152 return FALSE; 01153 } 01154 } 01155 01156 /* Check DACL */ 01157 if (SecurityDescriptor->Dacl) 01158 { 01159 if (SecurityDescriptor->Dacl % sizeof(ULONG)) 01160 { 01161 DPRINT1("Invalid DACL alignment\n"); 01162 return FALSE; 01163 } 01164 01165 Acl = (PACL)((ULONG_PTR)SecurityDescriptor + SecurityDescriptor->Dacl); 01166 if ((Acl->AclRevision < MIN_ACL_REVISION) && 01167 (Acl->AclRevision > MAX_ACL_REVISION)) 01168 { 01169 DPRINT1("Invalid DACL revision\n"); 01170 return FALSE; 01171 } 01172 01173 SdLength += Acl->AclSize; 01174 if (Length < SdLength) 01175 { 01176 DPRINT1("Invalid DACL size\n"); 01177 return FALSE; 01178 } 01179 } 01180 01181 /* Check SACL */ 01182 if (SecurityDescriptor->Sacl) 01183 { 01184 if (SecurityDescriptor->Sacl % sizeof(ULONG)) 01185 { 01186 DPRINT1("Invalid SACL alignment\n"); 01187 return FALSE; 01188 } 01189 01190 Acl = (PACL)((ULONG_PTR)SecurityDescriptor + SecurityDescriptor->Sacl); 01191 if ((Acl->AclRevision < MIN_ACL_REVISION) || 01192 (Acl->AclRevision > MAX_ACL_REVISION)) 01193 { 01194 DPRINT1("Invalid SACL revision\n"); 01195 return FALSE; 01196 } 01197 01198 SdLength += Acl->AclSize; 01199 if (Length < SdLength) 01200 { 01201 DPRINT1("Invalid SACL size\n"); 01202 return FALSE; 01203 } 01204 } 01205 01206 return TRUE; 01207 } 01208 01209 /* 01210 * @implemented 01211 */ 01212 NTSTATUS NTAPI 01213 SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor) 01214 { 01215 PAGED_CODE(); 01216 01217 if (*SecurityDescriptor != NULL) 01218 { 01219 ExFreePoolWithTag(*SecurityDescriptor, TAG_SD); 01220 *SecurityDescriptor = NULL; 01221 } 01222 01223 return STATUS_SUCCESS; 01224 } 01225 01226 01227 01228 /* 01229 * @unimplemented 01230 */ 01231 NTSTATUS NTAPI 01232 SeAssignSecurityEx(IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, 01233 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL, 01234 OUT PSECURITY_DESCRIPTOR *NewDescriptor, 01235 IN GUID *ObjectType OPTIONAL, 01236 IN BOOLEAN IsDirectoryObject, 01237 IN ULONG AutoInheritFlags, 01238 IN PSECURITY_SUBJECT_CONTEXT SubjectContext, 01239 IN PGENERIC_MAPPING GenericMapping, 01240 IN POOL_TYPE PoolType) 01241 { 01242 UNIMPLEMENTED; 01243 return STATUS_NOT_IMPLEMENTED; 01244 } 01245 01246 /* 01247 * @implemented 01248 */ 01249 NTSTATUS NTAPI 01250 SeAssignSecurity(PSECURITY_DESCRIPTOR _ParentDescriptor OPTIONAL, 01251 PSECURITY_DESCRIPTOR _ExplicitDescriptor OPTIONAL, 01252 PSECURITY_DESCRIPTOR *NewDescriptor, 01253 BOOLEAN IsDirectoryObject, 01254 PSECURITY_SUBJECT_CONTEXT SubjectContext, 01255 PGENERIC_MAPPING GenericMapping, 01256 POOL_TYPE PoolType) 01257 { 01258 PISECURITY_DESCRIPTOR ParentDescriptor = _ParentDescriptor; 01259 PISECURITY_DESCRIPTOR ExplicitDescriptor = _ExplicitDescriptor; 01260 PISECURITY_DESCRIPTOR_RELATIVE Descriptor; 01261 PTOKEN Token; 01262 ULONG OwnerLength = 0; 01263 ULONG GroupLength = 0; 01264 ULONG DaclLength = 0; 01265 ULONG SaclLength = 0; 01266 ULONG Length = 0; 01267 ULONG Control = 0; 01268 ULONG Current; 01269 PSID Owner = NULL; 01270 PSID Group = NULL; 01271 PACL Dacl = NULL; 01272 PACL Sacl = NULL; 01273 01274 PAGED_CODE(); 01275 01276 /* Lock subject context */ 01277 SeLockSubjectContext(SubjectContext); 01278 01279 if (SubjectContext->ClientToken != NULL) 01280 { 01281 Token = SubjectContext->ClientToken; 01282 } 01283 else 01284 { 01285 Token = SubjectContext->PrimaryToken; 01286 } 01287 01288 /* Inherit the Owner SID */ 01289 if (ExplicitDescriptor != NULL) 01290 { 01291 DPRINT("Use explicit owner sid!\n"); 01292 Owner = SepGetOwnerFromDescriptor(ExplicitDescriptor); 01293 } 01294 01295 if (!Owner) 01296 { 01297 if (Token != NULL) 01298 { 01299 DPRINT("Use token owner sid!\n"); 01300 Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid; 01301 } 01302 else 01303 { 01304 DPRINT("Use default owner sid!\n"); 01305 Owner = SeLocalSystemSid; 01306 } 01307 01308 Control |= SE_OWNER_DEFAULTED; 01309 } 01310 01311 OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4); 01312 01313 /* Inherit the Group SID */ 01314 if (ExplicitDescriptor != NULL) 01315 { 01316 Group = SepGetGroupFromDescriptor(ExplicitDescriptor); 01317 } 01318 01319 if (!Group) 01320 { 01321 if (Token != NULL) 01322 { 01323 DPRINT("Use token group sid!\n"); 01324 Group = Token->PrimaryGroup; 01325 } 01326 else 01327 { 01328 DPRINT("Use default group sid!\n"); 01329 Group = SeLocalSystemSid; 01330 } 01331 01332 Control |= SE_GROUP_DEFAULTED; 01333 } 01334 01335 GroupLength = ROUND_UP(RtlLengthSid(Group), 4); 01336 01337 /* Inherit the DACL */ 01338 if (ExplicitDescriptor != NULL && 01339 (ExplicitDescriptor->Control & SE_DACL_PRESENT) && 01340 !(ExplicitDescriptor->Control & SE_DACL_DEFAULTED)) 01341 { 01342 DPRINT("Use explicit DACL!\n"); 01343 Dacl = SepGetDaclFromDescriptor(ExplicitDescriptor); 01344 Control |= SE_DACL_PRESENT; 01345 } 01346 else if (ParentDescriptor != NULL && 01347 (ParentDescriptor->Control & SE_DACL_PRESENT)) 01348 { 01349 DPRINT("Use parent DACL!\n"); 01350 /* FIXME: Inherit */ 01351 Dacl = SepGetDaclFromDescriptor(ParentDescriptor); 01352 Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); 01353 } 01354 else if (Token != NULL && Token->DefaultDacl != NULL) 01355 { 01356 DPRINT("Use token default DACL!\n"); 01357 /* FIXME: Inherit */ 01358 Dacl = Token->DefaultDacl; 01359 Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); 01360 } 01361 else 01362 { 01363 DPRINT("Use NULL DACL!\n"); 01364 Dacl = NULL; 01365 Control |= (SE_DACL_PRESENT | SE_DACL_DEFAULTED); 01366 } 01367 01368 DaclLength = (Dacl != NULL) ? ROUND_UP(Dacl->AclSize, 4) : 0; 01369 01370 /* Inherit the SACL */ 01371 if (ExplicitDescriptor != NULL && 01372 (ExplicitDescriptor->Control & SE_SACL_PRESENT) && 01373 !(ExplicitDescriptor->Control & SE_SACL_DEFAULTED)) 01374 { 01375 DPRINT("Use explicit SACL!\n"); 01376 Sacl = SepGetSaclFromDescriptor(ExplicitDescriptor); 01377 Control |= SE_SACL_PRESENT; 01378 } 01379 else if (ParentDescriptor != NULL && 01380 (ParentDescriptor->Control & SE_SACL_PRESENT)) 01381 { 01382 DPRINT("Use parent SACL!\n"); 01383 /* FIXME: Inherit */ 01384 Sacl = SepGetSaclFromDescriptor(ParentDescriptor); 01385 Control |= (SE_SACL_PRESENT | SE_SACL_DEFAULTED); 01386 } 01387 01388 SaclLength = (Sacl != NULL) ? ROUND_UP(Sacl->AclSize, 4) : 0; 01389 01390 /* Allocate and initialize the new security descriptor */ 01391 Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE) + 01392 OwnerLength + GroupLength + DaclLength + SaclLength; 01393 01394 DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n", 01395 sizeof(SECURITY_DESCRIPTOR), 01396 OwnerLength, 01397 GroupLength, 01398 DaclLength, 01399 SaclLength); 01400 01401 Descriptor = ExAllocatePoolWithTag(PagedPool, Length, TAG_SD); 01402 if (Descriptor == NULL) 01403 { 01404 DPRINT1("ExAlloctePool() failed\n"); 01405 /* FIXME: Unlock subject context */ 01406 return STATUS_INSUFFICIENT_RESOURCES; 01407 } 01408 01409 RtlZeroMemory(Descriptor, Length); 01410 RtlCreateSecurityDescriptor(Descriptor, SECURITY_DESCRIPTOR_REVISION); 01411 01412 Descriptor->Control = (USHORT)Control | SE_SELF_RELATIVE; 01413 01414 Current = sizeof(SECURITY_DESCRIPTOR_RELATIVE); 01415 01416 if (SaclLength != 0) 01417 { 01418 RtlCopyMemory((PUCHAR)Descriptor + Current, Sacl, SaclLength); 01419 Descriptor->Sacl = Current; 01420 Current += SaclLength; 01421 } 01422 01423 if (DaclLength != 0) 01424 { 01425 RtlCopyMemory((PUCHAR)Descriptor + Current, Dacl, DaclLength); 01426 Descriptor->Dacl = Current; 01427 Current += DaclLength; 01428 } 01429 01430 if (OwnerLength != 0) 01431 { 01432 RtlCopyMemory((PUCHAR)Descriptor + Current, Owner, OwnerLength); 01433 Descriptor->Owner = Current; 01434 Current += OwnerLength; 01435 DPRINT("Owner of %x at %x\n", Descriptor, Descriptor->Owner); 01436 } 01437 else 01438 { 01439 DPRINT("Owner of %x is zero length\n", Descriptor); 01440 } 01441 01442 if (GroupLength != 0) 01443 { 01444 RtlCopyMemory((PUCHAR)Descriptor + Current, Group, GroupLength); 01445 Descriptor->Group = Current; 01446 } 01447 01448 /* Unlock subject context */ 01449 SeUnlockSubjectContext(SubjectContext); 01450 01451 *NewDescriptor = Descriptor; 01452 01453 DPRINT("Descrptor %x\n", Descriptor); 01454 ASSERT(RtlLengthSecurityDescriptor(Descriptor)); 01455 01456 return STATUS_SUCCESS; 01457 } 01458 01459 /* EOF */ Generated on Sat May 26 2012 04:35:23 for ReactOS by
1.7.6.1
|