Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

capture.c File Reference

#include "sep.h"
#include <sertlp.h>

Go to the source code of this file.

Defines

#define LongAligned(ptr)   (LongAlignPtr(ptr) == (ptr))

Functions

NTSTATUS SeCaptureSecurityDescriptor (IN PSECURITY_DESCRIPTOR InputSecurityDescriptor, IN KPROCESSOR_MODE RequestorMode, IN POOL_TYPE PoolType, IN BOOLEAN ForceCapture, OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor)
VOID SeReleaseSecurityDescriptor (IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, IN KPROCESSOR_MODE RequestorMode, IN BOOLEAN ForceCapture)
NTSTATUS SepCopyProxyData (OUT PSECURITY_TOKEN_PROXY_DATA *DestProxyData, IN PSECURITY_TOKEN_PROXY_DATA SourceProxyData)
VOID SepFreeProxyData (IN PSECURITY_TOKEN_PROXY_DATA ProxyData)
NTSTATUS SepProbeAndCaptureQosData (IN PSECURITY_ADVANCED_QUALITY_OF_SERVICE CapturedSecurityQos)
VOID SeFreeCapturedSecurityQos (IN PVOID SecurityQos)
NTSTATUS SeCaptureSecurityQos (IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE RequestorMode, OUT PBOOLEAN SecurityQosPresent, OUT PSECURITY_ADVANCED_QUALITY_OF_SERVICE CapturedSecurityQos)
NTSTATUS SeCaptureSid (IN PSID InputSid, IN KPROCESSOR_MODE RequestorMode, IN PVOID CaptureBuffer OPTIONAL, IN ULONG CaptureBufferLength, IN POOL_TYPE PoolType, IN BOOLEAN ForceCapture, OUT PSID *CapturedSid)
VOID SeReleaseSid (IN PSID CapturedSid, IN KPROCESSOR_MODE RequestorMode, IN BOOLEAN ForceCapture)
NTSTATUS SeCaptureAcl (IN PACL InputAcl, IN KPROCESSOR_MODE RequestorMode, IN PVOID CaptureBuffer OPTIONAL, IN ULONG CaptureBufferLength, IN POOL_TYPE PoolType, IN BOOLEAN ForceCapture, OUT PACL *CapturedAcl, OUT PULONG AlignedAclSize)
VOID SeReleaseAcl (IN PACL CapturedAcl, IN KPROCESSOR_MODE RequestorMode, IN BOOLEAN ForceCapture)
NTSTATUS SeCaptureLuidAndAttributesArray (IN PLUID_AND_ATTRIBUTES InputArray, IN ULONG ArrayCount, IN KPROCESSOR_MODE RequestorMode, IN PVOID CaptureBuffer OPTIONAL, IN ULONG CaptureBufferLength, IN POOL_TYPE PoolType, IN BOOLEAN ForceCapture, OUT PLUID_AND_ATTRIBUTES *CapturedArray, OUT PULONG AlignedArraySize)
VOID SeReleaseLuidAndAttributesArray (IN PLUID_AND_ATTRIBUTES CapturedArray, IN KPROCESSOR_MODE RequestorMode, IN BOOLEAN ForceCapture)
NTSTATUS SeCaptureSidAndAttributesArray (IN PSID_AND_ATTRIBUTES InputArray, IN ULONG ArrayCount, IN KPROCESSOR_MODE RequestorMode, IN PVOID CaptureBuffer OPTIONAL, IN ULONG CaptureBufferLength, IN POOL_TYPE PoolType, IN BOOLEAN ForceCapture, OUT PSID_AND_ATTRIBUTES *CapturedArray, OUT PULONG AlignedArraySize)
VOID SeReleaseSidAndAttributesArray (IN PSID_AND_ATTRIBUTES CapturedArray, IN KPROCESSOR_MODE RequestorMode, IN BOOLEAN ForceCapture)
NTSTATUS SeComputeQuotaInformationSize (IN PSECURITY_DESCRIPTOR SecurityDescriptor, OUT PULONG Size)
BOOLEAN SeValidSecurityDescriptor (IN ULONG Length, IN PSECURITY_DESCRIPTOR SecurityDescriptor)


Define Documentation

#define LongAligned ptr   )     (LongAlignPtr(ptr) == (ptr))
 

Definition at line 49 of file se/capture.c.


Function Documentation

NTSTATUS SeCaptureAcl IN PACL  InputAcl,
IN KPROCESSOR_MODE  RequestorMode,
IN PVOID CaptureBuffer  OPTIONAL,
IN ULONG  CaptureBufferLength,
IN POOL_TYPE  PoolType,
IN BOOLEAN  ForceCapture,
OUT PACL *  CapturedAcl,
OUT PULONG  AlignedAclSize
 

Definition at line 1370 of file se/capture.c.

References ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), FALSE, KernelMode, NULL, PAGED_CODE, ProbeAndReadUshort, ProbeForRead, and SepCheckAcl().

Referenced by NtCreateToken(), and NtSetInformationToken().

01383 : 01384 01385 This routine probes and captures a copy of the specified ACL. 01386 The ACL is either captured into a provided buffer, or pool 01387 allocated to receive the ACL. 01388 01389 Any ACL captured will have its structure validated. 01390 01391 01392 if the requestor mode is not kernel mode then 01393 01394 probe and capture the input ACL 01395 01396 if the requstor mode is kernel mode then 01397 01398 if force capture is true then 01399 01400 do not probe the input ACL, but do capture it 01401 01402 else 01403 01404 return address of original, but don't copy 01405 01406 Arguments: 01407 01408 InputAcl - Supplies the ACL to capture. This parameter is assumed 01409 to have been provided by the mode specified in RequestorMode. 01410 01411 RequestorMode - Specifies the caller's access mode. 01412 01413 CaptureBuffer - Specifies a buffer into which the ACL is to be 01414 captured. If this parameter is not provided, pool will be allocated 01415 to hold the captured data. 01416 01417 CaptureBufferLength - Indicates the length, in bytes, of the capture 01418 buffer. 01419 01420 PoolType - Specifies which pool type to allocate to capture the 01421 ACL into. This parameter is ignored if CaptureBuffer is provided. 01422 01423 ForceCapture - Specifies whether the ACL should be captured even if 01424 requestor mode is kernel. 01425 01426 CapturedAcl - Supplies the address of a pointer to an ACL. 01427 The pointer will be set to point to the captured (or uncaptured) ACL. 01428 01429 AlignedAclSize - Supplies the address of a ULONG to receive the length 01430 of the ACL rounded up to the next longword boundary. 01431 01432 Return Value: 01433 01434 STATUS_SUCCESS indicates the capture was successful. 01435 01436 STATUS_BUFFER_TOO_SMALL - indicates the buffer provided to capture the ACL 01437 into wasn't large enough to hold the ACL. 01438 01439 Any access violations encountered will be returned. 01440 01441 --*/ 01442 01443 { 01444 01445 ULONG AclSize; 01446 01447 PAGED_CODE(); 01448 01449 // 01450 // check if the requestors mode is kernel mode and we are not 01451 // to force a capture. 01452 // 01453 01454 if ((RequestorMode == KernelMode) && (ForceCapture == FALSE)) { 01455 01456 // 01457 // We don't need to do any work and can simply 01458 // return a pointer to the input ACL 01459 // 01460 01461 (*CapturedAcl) = InputAcl; 01462 01463 return STATUS_SUCCESS; 01464 } 01465 01466 01467 // 01468 // Get the length needed to hold the ACL 01469 // 01470 01471 if (RequestorMode != KernelMode) { 01472 01473 try { 01474 01475 AclSize = ProbeAndReadUshort( &(InputAcl->AclSize) ); 01476 01477 ProbeForRead( InputAcl, 01478 AclSize, 01479 sizeof(ULONG) ); 01480 01481 } except(EXCEPTION_EXECUTE_HANDLER) { 01482 return GetExceptionCode(); 01483 } 01484 01485 } else { 01486 01487 AclSize = InputAcl->AclSize; 01488 01489 } 01490 01491 // 01492 // If the passed pointer is non-null, it has better at least 01493 // point to a well formed ACL 01494 // 01495 01496 if (AclSize < sizeof(ACL)) { 01497 return( STATUS_INVALID_ACL ); 01498 } 01499 01500 (*AlignedAclSize) = (ULONG)LongAlignSize( AclSize ); 01501 01502 01503 // 01504 // If a buffer was provided, compare lengths. 01505 // Otherwise, allocate a buffer. 01506 // 01507 01508 if (ARGUMENT_PRESENT(CaptureBuffer)) { 01509 01510 if (AclSize > CaptureBufferLength) { 01511 return STATUS_BUFFER_TOO_SMALL; 01512 } else { 01513 01514 (*CapturedAcl) = CaptureBuffer; 01515 } 01516 01517 } else { 01518 01519 (*CapturedAcl) = (PACL)ExAllocatePoolWithTag(PoolType, AclSize, 'cAeS'); 01520 01521 if ( *CapturedAcl == NULL ) { 01522 return( STATUS_INSUFFICIENT_RESOURCES ); 01523 } 01524 01525 } 01526 01527 // 01528 // Now copy the ACL and validate it 01529 // 01530 01531 try { 01532 01533 RtlMoveMemory( (*CapturedAcl), InputAcl, AclSize ); 01534 01535 } except(EXCEPTION_EXECUTE_HANDLER) { 01536 if (!ARGUMENT_PRESENT(CaptureBuffer)) { 01537 ExFreePool( (*CapturedAcl) ); 01538 } 01539 01540 *CapturedAcl = NULL; 01541 return GetExceptionCode(); 01542 } 01543 01544 if ( (!SepCheckAcl( (*CapturedAcl), AclSize )) ) { 01545 01546 if (!ARGUMENT_PRESENT(CaptureBuffer)) { 01547 ExFreePool( (*CapturedAcl) ); 01548 } 01549 01550 *CapturedAcl = NULL; 01551 return STATUS_INVALID_ACL; 01552 } 01553 01554 return STATUS_SUCCESS; 01555 01556 }

NTSTATUS SeCaptureLuidAndAttributesArray IN PLUID_AND_ATTRIBUTES  InputArray,
IN ULONG  ArrayCount,
IN KPROCESSOR_MODE  RequestorMode,
IN PVOID CaptureBuffer  OPTIONAL,
IN ULONG  CaptureBufferLength,
IN POOL_TYPE  PoolType,
IN BOOLEAN  ForceCapture,
OUT PLUID_AND_ATTRIBUTES *  CapturedArray,
OUT PULONG  AlignedArraySize
 

Definition at line 1608 of file se/capture.c.

References ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), FALSE, InputArray, KernelMode, NULL, PAGED_CODE, ProbeForRead, and SEP_MAX_PRIVILEGE_COUNT.

Referenced by NtAdjustPrivilegesToken(), NtCreateToken(), NtFilterToken(), NtPrivilegeCheck(), and PspCaptureTokenFilter().

01622 : 01623 01624 This routine probes and captures a copy of the specified 01625 LUID_AND_ATTRIBUTES array. 01626 01627 The array is either captured into a provided buffer, or pool 01628 allocated to receive the array. 01629 01630 01631 if the requestor mode is not kernel mode then 01632 01633 probe and capture the input array 01634 01635 if the requstor mode is kernel mode then 01636 01637 if force capture is true then 01638 01639 do not probe the input array, but do capture it 01640 01641 else 01642 01643 return address of original, but don't copy 01644 01645 Arguments: 01646 01647 InputArray - Supplies the array to capture. This parameter is assumed 01648 to have been provided by the mode specified in RequestorMode. 01649 01650 ArrayCount - Indicates the number of elements in the array to capture. 01651 01652 RequestorMode - Specifies the caller's access mode. 01653 01654 CaptureBuffer - Specifies a buffer into which the array is to be 01655 captured. If this parameter is not provided, pool will be allocated 01656 to hold the captured data. 01657 01658 CaptureBufferLength - Indicates the length, in bytes, of the capture 01659 buffer. 01660 01661 PoolType - Specifies which pool type to allocate to capture the 01662 array into. This parameter is ignored if CaptureBuffer is provided. 01663 01664 ForceCapture - Specifies whether the array should be captured even if 01665 requestor mode is kernel. 01666 01667 CapturedArray - Supplies the address of a pointer to an array. 01668 The pointer will be set to point to the captured (or uncaptured) array. 01669 01670 AlignedArraySize - Supplies the address of a ULONG to receive the length 01671 of the array rounded up to the next longword boundary. 01672 01673 Return Value: 01674 01675 STATUS_SUCCESS indicates the capture was successful. 01676 01677 STATUS_BUFFER_TOO_SMALL - indicates the buffer provided to capture the array 01678 into wasn't large enough to hold the array. 01679 01680 Any access violations encountered will be returned. 01681 01682 --*/ 01683 01684 { 01685 01686 ULONG ArraySize; 01687 01688 PAGED_CODE(); 01689 01690 // 01691 // Make sure the array isn't empty 01692 // 01693 01694 if (ArrayCount == 0) { 01695 (*CapturedArray) = NULL; 01696 (*AlignedArraySize) = 0; 01697 return STATUS_SUCCESS; 01698 } 01699 01700 // 01701 // If there are too many LUIDs, return failure 01702 // 01703 01704 if (ArrayCount > SEP_MAX_PRIVILEGE_COUNT) { 01705 return(STATUS_INVALID_PARAMETER); 01706 } 01707 01708 // 01709 // check if the requestors mode is kernel mode and we are not 01710 // to force a capture. 01711 // 01712 01713 if ((RequestorMode == KernelMode) && (ForceCapture == FALSE)) { 01714 01715 // 01716 // We don't need to do any work and can simply 01717 // return a pointer to the input array 01718 // 01719 01720 (*CapturedArray) = InputArray; 01721 01722 return STATUS_SUCCESS; 01723 } 01724 01725 01726 // 01727 // Get the length needed to hold the array 01728 // 01729 01730 ArraySize = ArrayCount * (ULONG)sizeof(LUID_AND_ATTRIBUTES); 01731 (*AlignedArraySize) = (ULONG)LongAlignSize( ArraySize ); 01732 01733 if (RequestorMode != KernelMode) { 01734 01735 try { 01736 01737 01738 ProbeForRead( InputArray, 01739 ArraySize, 01740 sizeof(ULONG) ); 01741 01742 } except(EXCEPTION_EXECUTE_HANDLER) { 01743 return GetExceptionCode(); 01744 } 01745 01746 } 01747 01748 01749 01750 // 01751 // If a buffer was provided, compare lengths. 01752 // Otherwise, allocate a buffer. 01753 // 01754 01755 if (ARGUMENT_PRESENT(CaptureBuffer)) { 01756 01757 if (ArraySize > CaptureBufferLength) { 01758 return STATUS_BUFFER_TOO_SMALL; 01759 } else { 01760 01761 (*CapturedArray) = CaptureBuffer; 01762 } 01763 01764 } else { 01765 01766 (*CapturedArray) = 01767 (PLUID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PoolType, ArraySize, 'uLeS'); 01768 01769 if ( *CapturedArray == NULL ) { 01770 return( STATUS_INSUFFICIENT_RESOURCES ); 01771 } 01772 01773 } 01774 01775 // 01776 // Now copy the array 01777 // 01778 01779 try { 01780 01781 RtlMoveMemory( (*CapturedArray), InputArray, ArraySize ); 01782 01783 } except(EXCEPTION_EXECUTE_HANDLER) { 01784 if (!ARGUMENT_PRESENT(CaptureBuffer)) { 01785 ExFreePool( (*CapturedArray) ); 01786 } 01787 01788 return GetExceptionCode(); 01789 } 01790 01791 return STATUS_SUCCESS; 01792 01793 }

NTSTATUS SeCaptureSecurityDescriptor IN PSECURITY_DESCRIPTOR  InputSecurityDescriptor,
IN KPROCESSOR_MODE  RequestorMode,
IN POOL_TYPE  PoolType,
IN BOOLEAN  ForceCapture,
OUT PSECURITY_DESCRIPTOR *  OutputSecurityDescriptor
 

Definition at line 53 of file se/capture.c.

References ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExRaiseDatatypeMisalignment(), FALSE, KernelMode, NULL, PAGED_CODE, ProbeAndReadUchar, ProbeAndReadUshort, ProbeForRead, RtlLengthRequiredSid(), RtlValidSid(), SepCheckAcl(), Size, and USHORT.

Referenced by IopGetRegistrySecurityWithFallback(), IopSetSecurityObjectFromRegistry(), NtLoadKey2(), NtOpenObjectAuditAlarm(), NtSetSecurityObject(), NtUserCreateWindowStation(), ObpCaptureObjectCreateInformation(), SeAccessCheckByType(), SepAccessCheckAndAuditAlarm(), and TestCaptureSecurityDescriptor().

00063 : 00064 00065 This routine probes and captures a copy of the security descriptor based 00066 upon the following tests. 00067 00068 if the requestor mode is not kernel mode then 00069 00070 probe and capture the input descriptor 00071 (the captured descriptor is self-relative) 00072 00073 if the requstor mode is kernel mode then 00074 00075 if force capture is true then 00076 00077 do not probe the input descriptor, but do capture it. 00078 (the captured descriptor is self-relative) 00079 00080 else 00081 00082 do nothing 00083 (the input descriptor is expected to be self-relative) 00084 00085 Arguments: 00086 00087 InputSecurityDescriptor - Supplies the security descriptor to capture. 00088 This parameter is assumed to have been provided by the mode specified 00089 in RequestorMode. 00090 00091 RequestorMode - Specifies the caller's access mode. 00092 00093 PoolType - Specifies which pool type to allocate the captured 00094 descriptor from 00095 00096 ForceCapture - Specifies whether the input descriptor should always be 00097 captured 00098 00099 OutputSecurityDescriptor - Supplies the address of a pointer to the 00100 output security descriptor. The captured descriptor will be 00101 self-relative format. 00102 00103 Return Value: 00104 00105 STATUS_SUCCESS if the operation is successful. 00106 00107 STATUS_INVALID_SID - An SID within the security descriptor is not 00108 a valid SID. 00109 00110 STATUS_INVALID_ACL - An ACL within the security descriptor is not 00111 a valid ACL. 00112 00113 STATUS_UNKNOWN_REVISION - The revision level of the security descriptor 00114 is not one known to this revision of the capture routine. 00115 --*/ 00116 00117 { 00118 SECURITY_DESCRIPTOR Captured; 00119 SECURITY_DESCRIPTOR_RELATIVE *PIOutputSecurityDescriptor; 00120 PCHAR DescriptorOffset; 00121 00122 ULONG SaclSize; 00123 ULONG NewSaclSize; 00124 00125 ULONG DaclSize; 00126 ULONG NewDaclSize; 00127 00128 ULONG OwnerSubAuthorityCount; 00129 ULONG OwnerSize; 00130 ULONG NewOwnerSize; 00131 00132 ULONG GroupSubAuthorityCount; 00133 ULONG GroupSize; 00134 ULONG NewGroupSize; 00135 00136 ULONG Size; 00137 00138 PAGED_CODE(); 00139 00140 // 00141 // if the security descriptor is null then there is really nothing to 00142 // capture 00143 // 00144 00145 if (InputSecurityDescriptor == NULL) { 00146 00147 (*OutputSecurityDescriptor) = NULL; 00148 00149 return STATUS_SUCCESS; 00150 00151 } 00152 00153 // 00154 // check if the requestors mode is kernel mode and we are not 00155 // to force a capture 00156 // 00157 00158 if ((RequestorMode == KernelMode) && (ForceCapture == FALSE)) { 00159 00160 // 00161 // Yes it is so we don't need to do any work and can simply 00162 // return a pointer to the input descriptor 00163 // 00164 00165 (*OutputSecurityDescriptor) = InputSecurityDescriptor; 00166 00167 return STATUS_SUCCESS; 00168 00169 } 00170 00171 00172 // 00173 // We need to probe and capture the descriptor. 00174 // To do this we need to probe the main security descriptor record 00175 // first. 00176 // 00177 00178 if (RequestorMode != KernelMode) { 00179 00180 // 00181 // Capture of UserMode SecurityDescriptor. 00182 // 00183 00184 try { 00185 00186 // 00187 // Probe the main record of the input SecurityDescriptor 00188 // 00189 00190 ProbeForRead( InputSecurityDescriptor, 00191 sizeof(SECURITY_DESCRIPTOR_RELATIVE), 00192 sizeof(ULONG) ); 00193 00194 // 00195 // Capture the SecurityDescriptor main record. 00196 // 00197 00198 RtlCopyMemory( (&Captured), 00199 InputSecurityDescriptor, 00200 sizeof(SECURITY_DESCRIPTOR_RELATIVE) ); 00201 00202 // 00203 // Verify the alignment is correct for absolute case. This is 00204 // only needed when pointer are 64 bits. 00205 // 00206 00207 if (!(Captured.Control & SE_SELF_RELATIVE)) { 00208 00209 if ((ULONG_PTR) InputSecurityDescriptor & (sizeof(ULONG_PTR) - 1)) { 00210 ExRaiseDatatypeMisalignment(); 00211 } 00212 } 00213 00214 00215 } except(EXCEPTION_EXECUTE_HANDLER) { 00216 return GetExceptionCode(); 00217 } 00218 00219 } else { 00220 00221 // 00222 // Force capture of kernel mode SecurityDescriptor. 00223 // 00224 // Capture the SecurityDescriptor main record. 00225 // It doesn't need probing because requestor mode is kernel. 00226 // 00227 00228 RtlCopyMemory( (&Captured), 00229 InputSecurityDescriptor, 00230 sizeof(SECURITY_DESCRIPTOR_RELATIVE) ); 00231 00232 } 00233 00234 // 00235 // Make sure it is a revision we recognize 00236 // 00237 00238 if (Captured.Revision != SECURITY_DESCRIPTOR_REVISION) { 00239 return STATUS_UNKNOWN_REVISION; 00240 } 00241 00242 00243 // 00244 // In case the input security descriptor is self-relative, change the 00245 // captured main record to appear as an absolute form so we can use 00246 // common code for both cases below. 00247 // 00248 // Note that the fields of Captured are left pointing to user 00249 // space addresses. Treat them carefully. 00250 // 00251 00252 try { 00253 00254 Captured.Owner = RtlpOwnerAddrSecurityDescriptor( 00255 (SECURITY_DESCRIPTOR *)InputSecurityDescriptor 00256 ); 00257 Captured.Group = RtlpGroupAddrSecurityDescriptor( 00258 (SECURITY_DESCRIPTOR *)InputSecurityDescriptor 00259 ); 00260 Captured.Sacl = RtlpSaclAddrSecurityDescriptor ( 00261 (SECURITY_DESCRIPTOR *)InputSecurityDescriptor 00262 ); 00263 Captured.Dacl = RtlpDaclAddrSecurityDescriptor ( 00264 (SECURITY_DESCRIPTOR *)InputSecurityDescriptor 00265 ); 00266 Captured.Control &= ~SE_SELF_RELATIVE; 00267 00268 } except(EXCEPTION_EXECUTE_HANDLER) { 00269 return GetExceptionCode(); 00270 } 00271 00272 00273 00274 // 00275 // Indicate the size we are going to need to allocate for the captured 00276 // acls 00277 // 00278 00279 SaclSize = 0; 00280 DaclSize = 0; 00281 00282 NewSaclSize = 0; 00283 NewDaclSize = 0; 00284 NewGroupSize = 0; 00285 NewOwnerSize = 0; 00286 00287 // 00288 // Probe (if necessary) and capture each of the components of a 00289 // SECURITY_DESCRIPTOR. 00290 // 00291 00292 // 00293 // System ACL first 00294 // 00295 00296 if ((Captured.Control & SE_SACL_PRESENT) && 00297 (Captured.Sacl != NULL) ) { 00298 00299 if (RequestorMode != KernelMode) { 00300 00301 try { 00302 SaclSize = ProbeAndReadUshort( &(Captured.Sacl->AclSize) ); 00303 ProbeForRead( Captured.Sacl, 00304 SaclSize, 00305 sizeof(ULONG) ); 00306 } except(EXCEPTION_EXECUTE_HANDLER) { 00307 return GetExceptionCode(); 00308 } 00309 00310 } else { 00311 00312 SaclSize = Captured.Sacl->AclSize; 00313 00314 } 00315 00316 NewSaclSize = (ULONG)LongAlignSize( SaclSize ); 00317 00318 } else { 00319 // 00320 // Force the SACL to null if the bit is off 00321 // 00322 Captured.Sacl = NULL; 00323 } 00324 00325 // 00326 // Discretionary ACL 00327 // 00328 00329 if ((Captured.Control & SE_DACL_PRESENT) && 00330 (Captured.Dacl != NULL) ) { 00331 00332 if (RequestorMode != KernelMode) { 00333 00334 try { 00335 DaclSize = ProbeAndReadUshort( &(Captured.Dacl->AclSize) ); 00336 ProbeForRead( Captured.Dacl, 00337 DaclSize, 00338 sizeof(ULONG) ); 00339 } except(EXCEPTION_EXECUTE_HANDLER) { 00340 return GetExceptionCode(); 00341 } 00342 00343 } else { 00344 00345 DaclSize = Captured.Dacl->AclSize; 00346 00347 } 00348 00349 NewDaclSize = (ULONG)LongAlignSize( DaclSize ); 00350 00351 } else { 00352 // 00353 // Force the DACL to null if it is not present 00354 // 00355 Captured.Dacl = NULL; 00356 } 00357 00358 // 00359 // Owner SID 00360 // 00361 00362 if (Captured.Owner != NULL) { 00363 00364 if (RequestorMode != KernelMode) { 00365 00366 try { 00367 OwnerSubAuthorityCount = 00368 ProbeAndReadUchar( &(((SID *)(Captured.Owner))->SubAuthorityCount) ); 00369 OwnerSize = RtlLengthRequiredSid( OwnerSubAuthorityCount ); 00370 ProbeForRead( Captured.Owner, 00371 OwnerSize, 00372 sizeof(ULONG) ); 00373 } except(EXCEPTION_EXECUTE_HANDLER) { 00374 return GetExceptionCode(); 00375 } 00376 00377 } else { 00378 00379 OwnerSubAuthorityCount = ((SID *)(Captured.Owner))->SubAuthorityCount; 00380 OwnerSize = RtlLengthRequiredSid( OwnerSubAuthorityCount ); 00381 00382 } 00383 00384 NewOwnerSize = (ULONG)LongAlignSize( OwnerSize ); 00385 00386 } 00387 00388 // 00389 // Group SID 00390 // 00391 00392 if (Captured.Group != NULL) { 00393 00394 if (RequestorMode != KernelMode) { 00395 00396 try { 00397 GroupSubAuthorityCount = 00398 ProbeAndReadUchar( &(((SID *)(Captured.Group))->SubAuthorityCount) ); 00399 GroupSize = RtlLengthRequiredSid( GroupSubAuthorityCount ); 00400 ProbeForRead( Captured.Group, 00401 GroupSize, 00402 sizeof(ULONG) ); 00403 } except(EXCEPTION_EXECUTE_HANDLER) { 00404 return GetExceptionCode(); 00405 } 00406 00407 } else { 00408 00409 GroupSubAuthorityCount = ((SID *)(Captured.Group))->SubAuthorityCount; 00410 GroupSize = RtlLengthRequiredSid( GroupSubAuthorityCount ); 00411 00412 } 00413 00414 NewGroupSize = (ULONG)LongAlignSize( GroupSize ); 00415 00416 } 00417 00418 00419 00420 // 00421 // Now allocate enough pool to hold the descriptor 00422 // 00423 00424 Size = sizeof(SECURITY_DESCRIPTOR_RELATIVE) + 00425 NewSaclSize + 00426 NewDaclSize + 00427 NewOwnerSize + 00428 NewGroupSize; 00429 00430 (PIOutputSecurityDescriptor) = (SECURITY_DESCRIPTOR_RELATIVE *)ExAllocatePoolWithTag( PoolType, 00431 Size, 00432 'cSeS' ); 00433 00434 if ( PIOutputSecurityDescriptor == NULL ) { 00435 return( STATUS_INSUFFICIENT_RESOURCES ); 00436 } 00437 00438 (*OutputSecurityDescriptor) = (PSECURITY_DESCRIPTOR)PIOutputSecurityDescriptor; 00439 DescriptorOffset = (PCHAR)(PIOutputSecurityDescriptor); 00440 00441 00442 // 00443 // Copy the main security descriptor record over 00444 // 00445 00446 RtlCopyMemory( DescriptorOffset, 00447 &Captured, 00448 sizeof(SECURITY_DESCRIPTOR_RELATIVE) ); 00449 DescriptorOffset += sizeof(SECURITY_DESCRIPTOR_RELATIVE); 00450 00451 // 00452 // Indicate the output descriptor is self-relative 00453 // 00454 00455 PIOutputSecurityDescriptor->Control |= SE_SELF_RELATIVE; 00456 00457 // 00458 // If there is a System Acl, copy it over and set 00459 // the output descriptor's offset to point to the newly captured copy. 00460 // 00461 00462 if ((Captured.Control & SE_SACL_PRESENT) && (Captured.Sacl != NULL)) { 00463 00464 00465 try { 00466 RtlCopyMemory( DescriptorOffset, 00467 Captured.Sacl, 00468 SaclSize ); 00469 00470 00471 } except(EXCEPTION_EXECUTE_HANDLER) { 00472 ExFreePool( PIOutputSecurityDescriptor ); 00473 return GetExceptionCode(); 00474 } 00475 00476 if ((RequestorMode != KernelMode) && 00477 (!SepCheckAcl( (PACL) DescriptorOffset, SaclSize )) ) { 00478 00479 ExFreePool( PIOutputSecurityDescriptor ); 00480 return STATUS_INVALID_ACL; 00481 } 00482 00483 // 00484 // Change pointer to offset 00485 // 00486 00487 PIOutputSecurityDescriptor->Sacl = 00488 RtlPointerToOffset( PIOutputSecurityDescriptor, 00489 DescriptorOffset, 00490 ); 00491 00492 ((PACL) DescriptorOffset)->AclSize = (USHORT) NewSaclSize; 00493 DescriptorOffset += NewSaclSize; 00494 } else { 00495 PIOutputSecurityDescriptor->Sacl = 0; 00496 } 00497 00498 // 00499 // If there is a Discretionary Acl, copy it over and set 00500 // the output descriptor's offset to point to the newly captured copy. 00501 // 00502 00503 if ((Captured.Control & SE_DACL_PRESENT) && (Captured.Dacl != NULL)) { 00504 00505 00506 try { 00507 RtlCopyMemory( DescriptorOffset, 00508 Captured.Dacl, 00509 DaclSize ); 00510 } except(EXCEPTION_EXECUTE_HANDLER) { 00511 ExFreePool( PIOutputSecurityDescriptor ); 00512 return GetExceptionCode(); 00513 } 00514 00515 if ((RequestorMode != KernelMode) && 00516 (!SepCheckAcl( (PACL) DescriptorOffset, DaclSize )) ) { 00517 00518 ExFreePool( PIOutputSecurityDescriptor ); 00519 return STATUS_INVALID_ACL; 00520 } 00521 00522 // 00523 // Change pointer to offset 00524 // 00525 00526 PIOutputSecurityDescriptor->Dacl = 00527 RtlPointerToOffset( 00528 PIOutputSecurityDescriptor, 00529 DescriptorOffset 00530 ); 00531 00532 ((PACL) DescriptorOffset)->AclSize = (USHORT) NewDaclSize; 00533 DescriptorOffset += NewDaclSize; 00534 } else { 00535 PIOutputSecurityDescriptor->Dacl = 0; 00536 } 00537 00538 // 00539 // If there is an Owner SID, copy it over and set 00540 // the output descriptor's offset to point to the newly captured copy. 00541 // 00542 00543 if (Captured.Owner != NULL) { 00544 00545 00546 try { 00547 RtlCopyMemory( DescriptorOffset, 00548 Captured.Owner, 00549 OwnerSize ); 00550 ((SID *) (DescriptorOffset))->SubAuthorityCount = (UCHAR) OwnerSubAuthorityCount; 00551 00552 } except(EXCEPTION_EXECUTE_HANDLER) { 00553 ExFreePool( PIOutputSecurityDescriptor ); 00554 return GetExceptionCode(); 00555 } 00556 00557 if ((RequestorMode != KernelMode) && 00558 (!RtlValidSid( (PSID) DescriptorOffset )) ) { 00559 00560 ExFreePool( PIOutputSecurityDescriptor ); 00561 return STATUS_INVALID_SID; 00562 } 00563 00564 // 00565 // Change pointer to offset 00566 // 00567 00568 PIOutputSecurityDescriptor->Owner = 00569 RtlPointerToOffset( 00570 PIOutputSecurityDescriptor, 00571 DescriptorOffset 00572 ); 00573 00574 DescriptorOffset += NewOwnerSize; 00575 00576 } else { 00577 PIOutputSecurityDescriptor->Owner = 0; 00578 } 00579 00580 // 00581 // If there is a group SID, copy it over and set 00582 // the output descriptor's offset to point to the newly captured copy. 00583 // 00584 00585 if (Captured.Group != NULL) { 00586 00587 00588 try { 00589 RtlCopyMemory( DescriptorOffset, 00590 Captured.Group, 00591 GroupSize ); 00592 00593 ((SID *) DescriptorOffset)->SubAuthorityCount = (UCHAR) GroupSubAuthorityCount; 00594 } except(EXCEPTION_EXECUTE_HANDLER) { 00595 ExFreePool( PIOutputSecurityDescriptor ); 00596 return GetExceptionCode(); 00597 } 00598 00599 if ((RequestorMode != KernelMode) && 00600 (!RtlValidSid( (PSID) DescriptorOffset )) ) { 00601 00602 ExFreePool( PIOutputSecurityDescriptor ); 00603 return STATUS_INVALID_SID; 00604 } 00605 00606 // 00607 // Change pointer to offset 00608 // 00609 00610 PIOutputSecurityDescriptor->Group = 00611 RtlPointerToOffset( 00612 PIOutputSecurityDescriptor, 00613 DescriptorOffset 00614 ); 00615 00616 DescriptorOffset += NewGroupSize; 00617 } else { 00618 PIOutputSecurityDescriptor->Group = 0; 00619 } 00620 00621 // 00622 // And return to our caller 00623 // 00624 00625 return STATUS_SUCCESS; 00626 00627 }

NTSTATUS SeCaptureSecurityQos IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN KPROCESSOR_MODE  RequestorMode,
OUT PBOOLEAN  SecurityQosPresent,
OUT PSECURITY_ADVANCED_QUALITY_OF_SERVICE  CapturedSecurityQos
 

Definition at line 953 of file se/capture.c.

References EXCEPTION_EXECUTE_HANDLER, ExFreePool(), FALSE, KernelMode, NT_SUCCESS, NTSTATUS(), NULL, ObjectAttributes, PAGED_CODE, ProbeForRead, SepFreeProxyData(), SepProbeAndCaptureQosData(), Status, and TRUE.

Referenced by NtCreateToken(), and NtDuplicateToken().

00961 : 00962 00963 This routine probes and captures a copy of any security quality 00964 of service parameters that might have been provided via the 00965 ObjectAttributes argument. 00966 00967 Arguments: 00968 00969 ObjectAttributes - The object attributes from which the QOS 00970 information is to be retrieved. 00971 00972 RequestorMode - Indicates the processor mode by which the access 00973 is being requested. 00974 00975 SecurityQosPresent - Receives a boolean value indicating whether 00976 or not the optional security QOS information was available 00977 and copied. 00978 00979 CapturedSecurityQos - Receives the security QOS information if available. 00980 00981 Return Value: 00982 00983 STATUS_SUCCESS indicates no exceptions were encountered. 00984 00985 Any access violations encountered will be returned. 00986 00987 --*/ 00988 00989 { 00990 00991 PSECURITY_QUALITY_OF_SERVICE LocalSecurityQos; 00992 ULONG LocalQosLength; 00993 PSECURITY_ADVANCED_QUALITY_OF_SERVICE LocalAdvancedSecurityQos; 00994 NTSTATUS Status; 00995 BOOLEAN CapturedQos; 00996 00997 PAGED_CODE(); 00998 00999 CapturedQos = FALSE; 01000 // 01001 // Set default return 01002 // 01003 01004 (*SecurityQosPresent) = FALSE; 01005 01006 // 01007 // check if the requestors mode is kernel mode 01008 // 01009 01010 if (RequestorMode != KernelMode) { 01011 try { 01012 01013 if ( ARGUMENT_PRESENT(ObjectAttributes) ) { 01014 01015 ProbeForRead( ObjectAttributes, 01016 sizeof(OBJECT_ATTRIBUTES), 01017 sizeof(ULONG) 01018 ); 01019 01020 LocalSecurityQos = 01021 (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService; 01022 01023 if ( ARGUMENT_PRESENT(LocalSecurityQos) ) { 01024 01025 ProbeForRead( 01026 LocalSecurityQos, 01027 sizeof(SECURITY_QUALITY_OF_SERVICE), 01028 sizeof(ULONG) 01029 ); 01030 01031 LocalQosLength = LocalSecurityQos->Length; 01032 01033 // 01034 // Check the length and see if this is a QOS or Advanced QOS 01035 // structure. 01036 // 01037 01038 if (LocalQosLength == sizeof( SECURITY_QUALITY_OF_SERVICE )) { 01039 01040 // 01041 // It's a downlevel QOS, copy what's there and leave. 01042 // 01043 01044 (*SecurityQosPresent) = TRUE; 01045 RtlMoveMemory( CapturedSecurityQos, LocalSecurityQos, sizeof( SECURITY_QUALITY_OF_SERVICE )); 01046 CapturedSecurityQos->ProxyData = NULL; 01047 CapturedSecurityQos->AuditData = NULL; 01048 CapturedSecurityQos->Length = LocalQosLength; 01049 01050 } else { 01051 01052 if (LocalQosLength == sizeof( SECURITY_ADVANCED_QUALITY_OF_SERVICE )) { 01053 01054 LocalAdvancedSecurityQos = 01055 (PSECURITY_ADVANCED_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService; 01056 01057 ProbeForRead( 01058 LocalAdvancedSecurityQos, 01059 sizeof(SECURITY_ADVANCED_QUALITY_OF_SERVICE), 01060 sizeof(ULONG) 01061 ); 01062 01063 (*SecurityQosPresent) = TRUE; 01064 *CapturedSecurityQos = *LocalAdvancedSecurityQos; 01065 CapturedSecurityQos->Length = LocalQosLength; 01066 01067 // 01068 // Capture the proxy and audit data, if necessary. 01069 // 01070 01071 if ( ARGUMENT_PRESENT(CapturedSecurityQos->ProxyData) || ARGUMENT_PRESENT( CapturedSecurityQos->AuditData ) ) { 01072 01073 CapturedQos = TRUE; 01074 Status = SepProbeAndCaptureQosData( CapturedSecurityQos ); 01075 01076 if (!NT_SUCCESS( Status )) { 01077 01078 return( Status ); 01079 } 01080 } 01081 01082 } else { 01083 01084 return( STATUS_INVALID_PARAMETER ); 01085 } 01086 } 01087 01088 } // end_if 01089 01090 01091 } // end_if 01092 01093 } except(EXCEPTION_EXECUTE_HANDLER) { 01094 01095 01096 // 01097 // If we captured any proxy data, we need to free it now. 01098 // 01099 01100 if ( CapturedQos ) { 01101 01102 SepFreeProxyData( CapturedSecurityQos->ProxyData ); 01103 01104 if ( CapturedSecurityQos->AuditData != NULL ) { 01105 ExFreePool( CapturedSecurityQos->AuditData ); 01106 } 01107 } 01108 01109 return GetExceptionCode(); 01110 } // end_try 01111 01112 01113 } else { 01114 01115 if ( ARGUMENT_PRESENT(ObjectAttributes) ) { 01116 if ( ARGUMENT_PRESENT(ObjectAttributes->SecurityQualityOfService) ) { 01117 (*SecurityQosPresent) = TRUE; 01118 01119 if (((PSECURITY_QUALITY_OF_SERVICE)(ObjectAttributes->SecurityQualityOfService))->Length == sizeof( SECURITY_QUALITY_OF_SERVICE )) { 01120 01121 RtlMoveMemory( CapturedSecurityQos, ObjectAttributes->SecurityQualityOfService, sizeof( SECURITY_QUALITY_OF_SERVICE )); 01122 CapturedSecurityQos->ProxyData = NULL; 01123 CapturedSecurityQos->AuditData = NULL; 01124 01125 } else { 01126 01127 (*CapturedSecurityQos) = 01128 (*(SECURITY_ADVANCED_QUALITY_OF_SERVICE *)(ObjectAttributes->SecurityQualityOfService)); 01129 } 01130 01131 01132 } // end_if 01133 } // end_if 01134 01135 } // end_if 01136 01137 return STATUS_SUCCESS; 01138 }

NTSTATUS SeCaptureSid IN PSID  InputSid,
IN KPROCESSOR_MODE  RequestorMode,
IN PVOID CaptureBuffer  OPTIONAL,
IN ULONG  CaptureBufferLength,
IN POOL_TYPE  PoolType,
IN BOOLEAN  ForceCapture,
OUT PSID *  CapturedSid
 

Definition at line 1141 of file se/capture.c.

References ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), FALSE, KernelMode, NULL, PAGED_CODE, ProbeAndReadUchar, ProbeForRead, RtlLengthRequiredSid(), and RtlValidSid().

Referenced by NtCreateToken(), NtSecureConnectPort(), NtSetInformationToken(), SeAccessCheckByType(), and SepAccessCheckAndAuditAlarm().

01152 : 01153 01154 This routine probes and captures a copy of the specified SID. 01155 The SID is either captured into a provided buffer, or pool 01156 allocated to receive the SID. 01157 01158 01159 if the requestor mode is not kernel mode then 01160 01161 probe and capture the input SID 01162 01163 if the requstor mode is kernel mode then 01164 01165 if force capture is true then 01166 01167 do not probe the input SID, but do capture it 01168 01169 else 01170 01171 return address of original, but don't copy 01172 01173 Arguments: 01174 01175 InputSid - Supplies the SID to capture. This parameter is assumed 01176 to have been provided by the mode specified in RequestorMode. 01177 01178 RequestorMode - Specifies the caller's access mode. 01179 01180 CaptureBuffer - Specifies a buffer into which the SID is to be 01181 captured. If this parameter is not provided, pool will be allocated 01182 to hold the captured data. 01183 01184 CaptureBufferLength - Indicates the length, in bytes, of the capture 01185 buffer. 01186 01187 PoolType - Specifies which pool type to allocate to capture the 01188 SID into. This parameter is ignored if CaptureBuffer is provided. 01189 01190 ForceCapture - Specifies whether the SID should be captured even if 01191 requestor mode is kernel. 01192 01193 CapturedSid - Supplies the address of a pointer to an SID. 01194 The pointer will be set to point to the captured (or uncaptured) SID. 01195 01196 AlignedSidSize - Supplies the address of a ULONG to receive the length 01197 of the SID rounded up to the next longword boundary. 01198 01199 Return Value: 01200 01201 STATUS_SUCCESS indicates the capture was successful. 01202 01203 STATUS_BUFFER_TOO_SMALL - indicates the buffer provided to capture the SID 01204 into wasn't large enough to hold the SID. 01205 01206 Any access violations encountered will be returned. 01207 01208 --*/ 01209 01210 { 01211 01212 01213 01214 ULONG GetSidSubAuthorityCount; 01215 ULONG SidSize; 01216 01217 PAGED_CODE(); 01218 01219 // 01220 // check if the requestors mode is kernel mode and we are not 01221 // to force a capture. 01222 // 01223 01224 if ((RequestorMode == KernelMode) && (ForceCapture == FALSE)) { 01225 01226 // 01227 // We don't need to do any work and can simply 01228 // return a pointer to the input SID 01229 // 01230 01231 (*CapturedSid) = InputSid; 01232 01233 return STATUS_SUCCESS; 01234 } 01235 01236 01237 // 01238 // Get the length needed to hold the SID 01239 // 01240 01241 if (RequestorMode != KernelMode) { 01242 01243 try { 01244 GetSidSubAuthorityCount = 01245 ProbeAndReadUchar( &(((SID *)(InputSid))->SubAuthorityCount) ); 01246 SidSize = RtlLengthRequiredSid( GetSidSubAuthorityCount ); 01247 ProbeForRead( InputSid, 01248 SidSize, 01249 sizeof(ULONG) ); 01250 } except(EXCEPTION_EXECUTE_HANDLER) { 01251 return GetExceptionCode(); 01252 } 01253 01254 } else { 01255 01256 GetSidSubAuthorityCount = ((SID *)(InputSid))->SubAuthorityCount; 01257 SidSize = RtlLengthRequiredSid( GetSidSubAuthorityCount ); 01258 01259 } 01260 01261 01262 // 01263 // If a buffer was provided, compare lengths. 01264 // Otherwise, allocate a buffer. 01265 // 01266 01267 if (ARGUMENT_PRESENT(CaptureBuffer)) { 01268 01269 if (SidSize > CaptureBufferLength) { 01270 return STATUS_BUFFER_TOO_SMALL; 01271 } else { 01272 01273 (*CapturedSid) = CaptureBuffer; 01274 } 01275 01276 } else { 01277 01278 (*CapturedSid) = (PSID)ExAllocatePoolWithTag(PoolType, SidSize, 'iSeS'); 01279 01280 if ( *CapturedSid == NULL ) { 01281 return( STATUS_INSUFFICIENT_RESOURCES ); 01282 } 01283 01284 } 01285 01286 // 01287 // Now copy the SID and validate it 01288 // 01289 01290 try { 01291 01292 RtlMoveMemory( (*CapturedSid), InputSid, SidSize ); 01293 ((SID *)(*CapturedSid))->SubAuthorityCount = (UCHAR) GetSidSubAuthorityCount; 01294 01295 } except(EXCEPTION_EXECUTE_HANDLER) { 01296 if (!ARGUMENT_PRESENT(CaptureBuffer)) { 01297 ExFreePool( (*CapturedSid) ); 01298 *CapturedSid = NULL; 01299 } 01300 01301 return GetExceptionCode(); 01302 } 01303 01304 if ((!RtlValidSid( (*CapturedSid) )) ) { 01305 01306 if (!ARGUMENT_PRESENT(CaptureBuffer)) { 01307 ExFreePool( (*CapturedSid) ); 01308 *CapturedSid = NULL; 01309 } 01310 01311 return STATUS_INVALID_SID; 01312 } 01313 01314 return STATUS_SUCCESS; 01315 01316 }

NTSTATUS SeCaptureSidAndAttributesArray IN PSID_AND_ATTRIBUTES  InputArray,
IN ULONG  ArrayCount,
IN KPROCESSOR_MODE  RequestorMode,
IN PVOID CaptureBuffer  OPTIONAL,
IN ULONG  CaptureBufferLength,
IN POOL_TYPE  PoolType,
IN BOOLEAN  ForceCapture,
OUT PSID_AND_ATTRIBUTES *  CapturedArray,
OUT PULONG  AlignedArraySize
 

Definition at line 1850 of file se/capture.c.

References ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), FALSE, InputArray, KernelMode, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, ProbeAndReadUchar, ProbeForRead, RtlLengthRequiredSid(), RtlLengthSid(), RtlValidSid(), and SEP_MAX_GROUP_COUNT.

Referenced by NtAdjustGroupsToken(), NtCreateToken(), NtFilterToken(), and PspCaptureTokenFilter().

01864 : 01865 01866 This routine probes and captures a copy of the specified 01867 SID_AND_ATTRIBUTES array, along with the SID values pointed 01868 to. 01869 01870 The array is either captured into a provided buffer, or pool 01871 allocated to receive the array. 01872 01873 The format of the captured information is an array of SID_AND_ATTRIBUTES 01874 data structures followed by the SID values. THIS MAY NOT BE THE CASE 01875 FOR KERNEL MODE UNLESS A FORCE CAPTURE IS SPECIFIED. 01876 01877 01878 if the requestor mode is not kernel mode then 01879 01880 probe and capture the input array 01881 01882 if the requstor mode is kernel mode then 01883 01884 if force capture is true then 01885 01886 do not probe the input array, but do capture it 01887 01888 else 01889 01890 return address of original, but don't copy 01891 01892 Arguments: 01893 01894 InputArray - Supplies the array to capture. This parameter is assumed 01895 to have been provided by the mode specified in RequestorMode. 01896 01897 ArrayCount - Indicates the number of elements in the array to capture. 01898 01899 RequestorMode - Specifies the caller's access mode. 01900 01901 CaptureBuffer - Specifies a buffer into which the array is to be 01902 captured. If this parameter is not provided, pool will be allocated 01903 to hold the captured data. 01904 01905 CaptureBufferLength - Indicates the length, in bytes, of the capture 01906 buffer. 01907 01908 PoolType - Specifies which pool type to allocate to capture the 01909 array into. This parameter is ignored if CaptureBuffer is provided. 01910 01911 ForceCapture - Specifies whether the array should be captured even if 01912 requestor mode is kernel. 01913 01914 CapturedArray - Supplies the address of a pointer to an array. 01915 The pointer will be set to point to the captured (or uncaptured) array. 01916 01917 AlignedArraySize - Supplies the address of a ULONG to receive the length 01918 of the array rounded up to the next longword boundary. 01919 01920 Return Value: 01921 01922 STATUS_SUCCESS indicates the capture was successful. 01923 01924 STATUS_BUFFER_TOO_SMALL - indicates the buffer provided to capture the array 01925 into wasn't large enough to hold the array. 01926 01927 Any access violations encountered will be returned. 01928 01929 --*/ 01930 01931 { 01932 01933 typedef struct _TEMP_ARRAY_ELEMENT { 01934 PISID Sid; 01935 ULONG SidLength; 01936 } TEMP_ARRAY_ELEMENT; 01937 01938 01939 TEMP_ARRAY_ELEMENT *TempArray; 01940 01941 NTSTATUS CompletionStatus = STATUS_SUCCESS; 01942 01943 ULONG ArraySize; 01944 ULONG AlignedLengthRequired; 01945 01946 ULONG NextIndex; 01947 01948 PSID_AND_ATTRIBUTES NextElement; 01949 PVOID NextBufferLocation; 01950 01951 ULONG GetSidSubAuthorityCount; 01952 ULONG SidSize; 01953 ULONG AlignedSidSize; 01954 01955 PAGED_CODE(); 01956 01957 // 01958 // Make sure the array isn't empty 01959 // 01960 01961 if (ArrayCount == 0) { 01962 (*CapturedArray) = NULL; 01963 (*AlignedArraySize) = 0; 01964 return STATUS_SUCCESS; 01965 } 01966 01967 // 01968 // Check there aren't too many SIDs 01969 // 01970 01971 if (ArrayCount > SEP_MAX_GROUP_COUNT) { 01972 return(STATUS_INVALID_PARAMETER); 01973 } 01974 // 01975 // check if the requestor's mode is kernel mode and we are not 01976 // to force a capture. 01977 // 01978 01979 if ((RequestorMode == KernelMode) && (ForceCapture == FALSE)) { 01980 01981 // 01982 // We don't need to do any work and can simply 01983 // return a pointer to the input array 01984 // 01985 01986 (*CapturedArray) = InputArray; 01987 01988 return STATUS_SUCCESS; 01989 } 01990 01991 01992 // 01993 // ---------- For RequestorMode == UserMode ---------------------- 01994 // 01995 // the algorithm for capturing an SID_AND_ATTRIBUTES array is somewhat 01996 // convoluted to avoid problems that could occur if the data is 01997 // being changed while being captured. 01998 // 01999 // The algorithm uses two loops. 02000 // 02001 // Allocate a temporary buffer to house the fixed length data. 02002 // 02003 // 1st loop: 02004 // For each SID: 02005 // Capture the Pointers to the SID and the length of the SID. 02006 // 02007 // Allocate a buffer large enough to hold all of the data. 02008 // 02009 // 2nd loop: 02010 // For each SID: 02011 // Capture the Attributes. 02012 // Capture the SID. 02013 // Set the pointer to the SID. 02014 // 02015 // Deallocate temporary buffer. 02016 // 02017 // ------------ For RequestorMode == KernelMode -------------------- 02018 // 02019 // There is no need to capture the length and address of the SIDs 02020 // in the first loop (since the kernel can be trusted not to change 02021 // them while they are being copied.) So for kernel mode, the first 02022 // loop just adds up the length needed. Kernel mode, thus, avoids 02023 // having to allocate a temporary buffer. 02024 // 02025 02026 // 02027 // Get the length needed to hold the array elements. 02028 // 02029 02030 ArraySize = ArrayCount * (ULONG)sizeof(SID_AND_ATTRIBUTES); 02031 AlignedLengthRequired = (ULONG)LongAlignSize( ArraySize ); 02032 02033 if (RequestorMode != KernelMode) { 02034 02035 // 02036 // Allocate a temporary array to capture the array elements into 02037 // 02038 02039 TempArray = 02040 (TEMP_ARRAY_ELEMENT *)ExAllocatePoolWithTag(PoolType, AlignedLengthRequired, 'aTeS'); 02041 02042 if ( TempArray == NULL ) { 02043 return( STATUS_INSUFFICIENT_RESOURCES ); 02044 } 02045 02046 02047 try { 02048 02049 // 02050 // Make sure we can read each SID_AND_ATTRIBUTE 02051 // 02052 02053 ProbeForRead( InputArray, 02054 ArraySize, 02055 sizeof(ULONG) ); 02056 02057 // 02058 // Probe and capture the length and address of each SID 02059 // 02060 02061 NextIndex = 0; 02062 while (NextIndex < ArrayCount) { 02063 PSID TempSid; 02064 02065 TempSid = InputArray[NextIndex].Sid; 02066 GetSidSubAuthorityCount = 02067 ProbeAndReadUchar( &((PISID)TempSid)->SubAuthorityCount); 02068 02069 if (GetSidSubAuthorityCount > SID_MAX_SUB_AUTHORITIES) { 02070 CompletionStatus = STATUS_INVALID_SID; 02071 break; 02072 } 02073 02074 TempArray[NextIndex].Sid = ((PISID)(TempSid)); 02075 TempArray[NextIndex].SidLength = 02076 RtlLengthRequiredSid( GetSidSubAuthorityCount ); 02077 02078 ProbeForRead( TempArray[NextIndex].Sid, 02079 TempArray[NextIndex].SidLength, 02080 sizeof(ULONG) ); 02081 02082 AlignedLengthRequired += 02083 (ULONG)LongAlignSize( TempArray[NextIndex].SidLength ); 02084 02085 NextIndex += 1; 02086 02087 } //end while 02088 02089 } except(EXCEPTION_EXECUTE_HANDLER) { 02090 02091 ExFreePool( TempArray ); 02092 return GetExceptionCode(); 02093 } 02094 02095 if (!NT_SUCCESS(CompletionStatus)) { 02096 ExFreePool( TempArray ); 02097 return(CompletionStatus); 02098 } 02099 02100 } else { 02101 02102 // 02103 // No need to capture anything. 02104 // But, we do need to add up the lengths of the SIDs 02105 // so we can allocate a buffer (or check the size of one provided). 02106 // 02107 02108 NextIndex = 0; 02109 02110 while (NextIndex < ArrayCount) { 02111 02112 GetSidSubAuthorityCount = 02113 ((PISID)(InputArray[NextIndex].Sid))->SubAuthorityCount; 02114 02115 AlignedLengthRequired += 02116 (ULONG)LongAlignSize(RtlLengthRequiredSid(GetSidSubAuthorityCount)); 02117 02118 NextIndex += 1; 02119 02120 } //end while 02121 02122 } 02123 02124 02125 // 02126 // Now we know how much memory we need. 02127 // Return this value in the output parameter. 02128 // 02129 02130 (*AlignedArraySize) = AlignedLengthRequired; 02131 02132 // 02133 // If a buffer was provided, make sure it is long enough. 02134 // Otherwise, allocate a buffer. 02135 // 02136 02137 if (ARGUMENT_PRESENT(CaptureBuffer)) { 02138 02139 if (AlignedLengthRequired > CaptureBufferLength) { 02140 02141 if (RequestorMode != KernelMode) { 02142 ExFreePool( TempArray ); 02143 } 02144 02145 return STATUS_BUFFER_TOO_SMALL; 02146 02147 } else { 02148 02149 (*CapturedArray) = CaptureBuffer; 02150 } 02151 02152 } else { 02153 02154 (*CapturedArray) = 02155 (PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PoolType, AlignedLengthRequired, 'aSeS'); 02156 02157 if ( *CapturedArray == NULL ) { 02158 if (RequestorMode != KernelMode) { 02159 ExFreePool( TempArray ); 02160 } 02161 return( STATUS_INSUFFICIENT_RESOURCES ); 02162 } 02163 } 02164 02165 02166 // 02167 // Now copy everything. 02168 // This is done by copying all the SID_AND_ATTRIBUTES and then 02169 // copying each individual SID. 02170 // 02171 // All SIDs have already been probed for READ access. We just 02172 // need to copy them. 02173 // 02174 // 02175 02176 if (RequestorMode != KernelMode) { 02177 try { 02178 02179 // 02180 // Copy the SID_AND_ATTRIBUTES array elements 02181 // This really only sets the attributes, since we 02182 // over-write the SID pointer field later on. 02183 // 02184 02185 NextBufferLocation = (*CapturedArray); 02186 RtlMoveMemory( NextBufferLocation, InputArray, ArraySize ); 02187 NextBufferLocation = (PVOID)((ULONG_PTR)NextBufferLocation + 02188 (ULONG)LongAlignSize(ArraySize) ); 02189 02190 // 02191 // Now go through and copy each referenced SID. 02192 // Validate each SID as it is copied. 02193 // 02194 02195 NextIndex = 0; 02196 NextElement = (*CapturedArray); 02197 while ( (NextIndex < ArrayCount) && 02198 (CompletionStatus == STATUS_SUCCESS) ) { 02199 02200 02201 RtlMoveMemory( NextBufferLocation, 02202 TempArray[NextIndex].Sid, 02203 TempArray[NextIndex].SidLength ); 02204 02205 02206 NextElement[NextIndex].Sid = (PSID)NextBufferLocation; 02207 NextBufferLocation = 02208 (PVOID)((ULONG_PTR)NextBufferLocation + 02209 (ULONG)LongAlignSize(TempArray[NextIndex].SidLength)); 02210 02211 // 02212 // Verify the sid is valid and its length didn't change 02213 // 02214 02215 if (!RtlValidSid(NextElement[NextIndex].Sid) ) { 02216 CompletionStatus = STATUS_INVALID_SID; 02217 } else if (RtlLengthSid(NextElement[NextIndex].Sid) != TempArray[NextIndex].SidLength) { 02218 CompletionStatus = STATUS_INVALID_SID; 02219 } 02220 02221 02222 NextIndex += 1; 02223 02224 } //end while 02225 02226 02227 } except(EXCEPTION_EXECUTE_HANDLER) { 02228 02229 if (!ARGUMENT_PRESENT(CaptureBuffer)) { 02230 ExFreePool( (*CapturedArray) ); 02231 } 02232 02233 ExFreePool( TempArray ); 02234 02235 return GetExceptionCode(); 02236 } 02237 } else { 02238 02239 // 02240 // Requestor mode is kernel mode - 02241 // don't need protection, probing, and validating 02242 // 02243 02244 // 02245 // Copy the SID_AND_ATTRIBUTES array elements 02246 // This really only sets the attributes, since we 02247 // over-write the SID pointer field later on. 02248 // 02249 02250 NextBufferLocation = (*CapturedArray); 02251 RtlMoveMemory( NextBufferLocation, InputArray, ArraySize ); 02252 NextBufferLocation = (PVOID)( (ULONG_PTR)NextBufferLocation + 02253 (ULONG)LongAlignSize(ArraySize)); 02254 02255 // 02256 // Now go through and copy each referenced SID 02257 // 02258 02259 NextIndex = 0; 02260 NextElement = (*CapturedArray); 02261 while (NextIndex < ArrayCount) { 02262 02263 GetSidSubAuthorityCount = 02264 ((PISID)(NextElement[NextIndex].Sid))->SubAuthorityCount; 02265 02266 RtlMoveMemory( 02267 NextBufferLocation, 02268 NextElement[NextIndex].Sid, 02269 RtlLengthRequiredSid(GetSidSubAuthorityCount) ); 02270 SidSize = RtlLengthRequiredSid( GetSidSubAuthorityCount ); 02271 AlignedSidSize = (ULONG)LongAlignSize(SidSize); 02272 02273 NextElement[NextIndex].Sid = (PSID)NextBufferLocation; 02274 02275 NextIndex += 1; 02276 NextBufferLocation = (PVOID)((ULONG_PTR)NextBufferLocation + 02277 AlignedSidSize); 02278 02279 } //end while 02280 02281 } 02282 02283 if (RequestorMode != KernelMode) { 02284 ExFreePool( TempArray ); 02285 } 02286 02287 if (!ARGUMENT_PRESENT(CaptureBuffer) && !NT_SUCCESS(CompletionStatus)) { 02288 ExFreePool( (*CapturedArray) ); 02289 *CapturedArray = NULL ; 02290 } 02291 02292 return CompletionStatus; 02293 }

NTSTATUS SeComputeQuotaInformationSize IN PSECURITY_DESCRIPTOR  SecurityDescriptor,
OUT PULONG  Size
 

Definition at line 2350 of file se/capture.c.

References Dacl, Group, NULL, PAGED_CODE, SeLengthSid, and Size.

Referenced by ObpCaptureObjectCreateInformation().

02357 : 02358 02359 This routine computes the size of the Group and DACL for the 02360 passed security descriptor. 02361 02362 This quantity will later be used in calculating the amount 02363 of quota to charge for this object. 02364 02365 Arguments: 02366 02367 SecurityDescriptor - Supplies a pointer to the security descriptor 02368 to be examined. 02369 02370 Size - Returns the size in bytes of the sum of the Group and Dacl 02371 fields of the security descriptor. 02372 02373 Return Value: 02374 02375 STATUS_SUCCESS - The operation was successful. 02376 02377 STATUS_INVALID_REVISION - The passed security descriptor was of 02378 an unknown revision. 02379 02380 --*/ 02381 02382 { 02383 PISECURITY_DESCRIPTOR ISecurityDescriptor; 02384 02385 PSID Group; 02386 PACL Dacl; 02387 02388 PAGED_CODE(); 02389 02390 ISecurityDescriptor = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 02391 *Size = 0; 02392 02393 if (ISecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) { 02394 return( STATUS_UNKNOWN_REVISION ); 02395 } 02396 02397 Group = RtlpGroupAddrSecurityDescriptor( ISecurityDescriptor ); 02398 02399 Dacl = RtlpDaclAddrSecurityDescriptor( ISecurityDescriptor ); 02400 02401 if (Group != NULL) { 02402 *Size += (ULONG)LongAlignSize(SeLengthSid( Group )); 02403 } 02404 02405 if (Dacl != NULL) { 02406 *Size += (ULONG)LongAlignSize(Dacl->AclSize); 02407 } 02408 02409 return( STATUS_SUCCESS ); 02410 }

VOID SeFreeCapturedSecurityQos IN PVOID  SecurityQos  ) 
 

Definition at line 910 of file se/capture.c.

References ExFreePool(), NULL, PAGED_CODE, SecurityQos, and SepFreeProxyData().

Referenced by NtCreateToken(), and NtDuplicateToken().

00916 : 00917 00918 This routine frees the data associated with a captured SecurityQos 00919 structure. It does not free the body of the structure, just whatever 00920 its internal fields point to. 00921 00922 Arguments: 00923 00924 SecurityQos - Points to a captured security QOS structure. 00925 00926 Return Value: 00927 00928 None. 00929 00930 --*/ 00931 00932 { 00933 PSECURITY_ADVANCED_QUALITY_OF_SERVICE IAdvancedSecurityQos; 00934 00935 PAGED_CODE(); 00936 00937 IAdvancedSecurityQos = (PSECURITY_ADVANCED_QUALITY_OF_SERVICE)SecurityQos; 00938 00939 if (IAdvancedSecurityQos->Length == sizeof( SECURITY_ADVANCED_QUALITY_OF_SERVICE )) { 00940 00941 if (IAdvancedSecurityQos->AuditData != NULL) { 00942 ExFreePool( IAdvancedSecurityQos->AuditData ); 00943 } 00944 00945 SepFreeProxyData( IAdvancedSecurityQos->ProxyData ); 00946 } 00947 00948 return; 00949 }

NTSTATUS SepCopyProxyData OUT PSECURITY_TOKEN_PROXY_DATA *  DestProxyData,
IN PSECURITY_TOKEN_PROXY_DATA  SourceProxyData
 

Definition at line 681 of file se/capture.c.

References ExAllocatePoolWithTag, ExFreePool(), NULL, PAGED_CODE, PagedPool, and RtlCopyUnicodeString().

Referenced by SepCreateToken(), SepDuplicateToken(), SepFilterToken(), and SepProbeAndCaptureQosData().

00688 : 00689 00690 This routine copies a token proxy data structure from one token to another. 00691 00692 Arguments: 00693 00694 DestProxyData - Receives a pointer to a new proxy data structure. 00695 00696 SourceProxyData - Supplies a pointer to an already existing proxy data structure. 00697 00698 Return Value: 00699 00700 STATUS_INSUFFICIENT_RESOURCES on failure. 00701 00702 --*/ 00703 00704 { 00705 00706 PAGED_CODE(); 00707 00708 *DestProxyData = ExAllocatePoolWithTag( PagedPool, sizeof( SECURITY_TOKEN_PROXY_DATA ), 'dPoT' ); 00709 00710 if (*DestProxyData == NULL) { 00711 return( STATUS_INSUFFICIENT_RESOURCES ); 00712 } 00713 00714 00715 00716 (*DestProxyData)->PathInfo.Buffer = ExAllocatePoolWithTag( PagedPool, SourceProxyData->PathInfo.Length, 'dPoT' ); 00717 00718 if ((*DestProxyData)->PathInfo.Buffer == NULL) { 00719 ExFreePool( *DestProxyData ); 00720 *DestProxyData = NULL; 00721 return( STATUS_INSUFFICIENT_RESOURCES ); 00722 } 00723 00724 (*DestProxyData)->Length = SourceProxyData->Length; 00725 (*DestProxyData)->ProxyClass = SourceProxyData->ProxyClass; 00726 (*DestProxyData)->PathInfo.MaximumLength = 00727 (*DestProxyData)->PathInfo.Length = SourceProxyData->PathInfo.Length; 00728 (*DestProxyData)->ContainerMask = SourceProxyData->ContainerMask; 00729 (*DestProxyData)->ObjectMask = SourceProxyData->ObjectMask; 00730 00731 RtlCopyUnicodeString( &(*DestProxyData)->PathInfo, &SourceProxyData->PathInfo ); 00732 00733 return( STATUS_SUCCESS ); 00734 }

VOID SepFreeProxyData IN PSECURITY_TOKEN_PROXY_DATA  ProxyData  ) 
 

Definition at line 737 of file se/capture.c.

References ExFreePool(), NULL, and PAGED_CODE.

Referenced by SeCaptureSecurityQos(), SeFreeCapturedSecurityQos(), SepDuplicateToken(), SepFilterToken(), SepProbeAndCaptureQosData(), and SepTokenDeleteMethod().

00743 : 00744 00745 This routine frees a SECURITY_TOKEN_PROXY_DATA structure and all sub structures. 00746 00747 Arguments: 00748 00749 ProxyData - Supplies a pointer to an existing proxy data structure. 00750 00751 Return Value: 00752 00753 None. 00754 00755 --*/ 00756 { 00757 PAGED_CODE(); 00758 00759 if (ProxyData != NULL) { 00760 00761 if (ProxyData->PathInfo.Buffer != NULL) { 00762 ExFreePool( ProxyData->PathInfo.Buffer ); 00763 } 00764 00765 ExFreePool( ProxyData ); 00766 } 00767 }

NTSTATUS SepProbeAndCaptureQosData IN PSECURITY_ADVANCED_QUALITY_OF_SERVICE  CapturedSecurityQos  ) 
 

Definition at line 773 of file se/capture.c.

References ExAllocatePool, ExFreePool(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PagedPool, ProbeForRead, SepCopyProxyData(), SepFreeProxyData(), and Status.

Referenced by SeCaptureSecurityQos().

00779 : 00780 00781 This routine probes and captures the imbedded structures in a 00782 Security Quality of Service structure. 00783 00784 This routine assumes that it is being called under an existing 00785 try-except clause. 00786 00787 Arguments: 00788 00789 CapturedSecurityQos - Points to the captured body of a QOS 00790 structure. The pointers in this structure are presumed 00791 not to be probed or captured at this point. 00792 00793 Return Value: 00794 00795 STATUS_SUCCESS indicates no exceptions were encountered. 00796 00797 Any access violations encountered will be returned. 00798 00799 --*/ 00800 { 00801 NTSTATUS Status; 00802 PSECURITY_TOKEN_PROXY_DATA CapturedProxyData; 00803 PSECURITY_TOKEN_AUDIT_DATA CapturedAuditData; 00804 SECURITY_TOKEN_PROXY_DATA StackProxyData; 00805 PAGED_CODE(); 00806 00807 CapturedProxyData = CapturedSecurityQos->ProxyData; 00808 CapturedSecurityQos->ProxyData = NULL; 00809 CapturedAuditData = CapturedSecurityQos->AuditData; 00810 CapturedSecurityQos->AuditData = NULL; 00811 00812 if (ARGUMENT_PRESENT( CapturedProxyData )) { 00813 00814 // 00815 // Make sure the body of the proxy data is ok to read. 00816 // 00817 00818 ProbeForRead( 00819 CapturedProxyData, 00820 sizeof(SECURITY_TOKEN_PROXY_DATA), 00821 sizeof(ULONG) 00822 ); 00823 00824 StackProxyData = *CapturedProxyData; 00825 00826 if (StackProxyData.Length != sizeof( SECURITY_TOKEN_PROXY_DATA )) { 00827 return( STATUS_INVALID_PARAMETER ); 00828 } 00829 00830 00831 // 00832 // Probe the passed pathinfo buffer 00833 // 00834 00835 ProbeForRead( 00836 StackProxyData.PathInfo.Buffer, 00837 StackProxyData.PathInfo.Length, 00838 sizeof( UCHAR ) 00839 ); 00840 00841 Status = SepCopyProxyData( &CapturedSecurityQos->ProxyData, &StackProxyData ); 00842 00843 if (!NT_SUCCESS(Status)) { 00844 00845 if (CapturedSecurityQos->ProxyData != NULL) { 00846 SepFreeProxyData( CapturedSecurityQos->ProxyData ); 00847 CapturedSecurityQos->ProxyData = NULL; 00848 } 00849 00850 return( Status ); 00851 } 00852 00853 } 00854 00855 if (ARGUMENT_PRESENT( CapturedAuditData )) { 00856 00857 PSECURITY_TOKEN_AUDIT_DATA LocalAuditData; 00858 00859 // 00860 // Probe the audit data structure and make sure it looks ok 00861 // 00862 00863 ProbeForRead( 00864 CapturedAuditData, 00865 sizeof( SECURITY_TOKEN_AUDIT_DATA ), 00866 sizeof( ULONG ) 00867 ); 00868 00869 00870 LocalAuditData = ExAllocatePool( PagedPool, sizeof( SECURITY_TOKEN_AUDIT_DATA )); 00871 00872 if (LocalAuditData == NULL) { 00873 00874 // 00875 // Cleanup any proxy data we may have allocated. 00876 // 00877 00878 SepFreeProxyData( CapturedSecurityQos->ProxyData ); 00879 CapturedSecurityQos->ProxyData = NULL; 00880 00881 return( STATUS_INSUFFICIENT_RESOURCES ); 00882 00883 } 00884 00885 // 00886 // Copy the data to the local buffer. Note: we do this in this 00887 // order so that if the final assignment fails the caller will 00888 // still be able to free the allocated pool. 00889 // 00890 00891 CapturedSecurityQos->AuditData = LocalAuditData; 00892 00893 *CapturedSecurityQos->AuditData = *CapturedAuditData; 00894 00895 if ( LocalAuditData->Length != sizeof( SECURITY_TOKEN_AUDIT_DATA ) ) { 00896 SepFreeProxyData( CapturedSecurityQos->ProxyData ); 00897 CapturedSecurityQos->ProxyData = NULL; 00898 ExFreePool(CapturedSecurityQos->AuditData); 00899 CapturedSecurityQos->AuditData = NULL; 00900 return( STATUS_INVALID_PARAMETER ); 00901 } 00902 } 00903 00904 return( STATUS_SUCCESS ); 00905 00906 }

VOID SeReleaseAcl IN PACL  CapturedAcl,
IN KPROCESSOR_MODE  RequestorMode,
IN BOOLEAN  ForceCapture
 

Definition at line 1560 of file se/capture.c.

References ExFreePool(), KernelMode, PAGED_CODE, TRUE, and UserMode.

Referenced by NtCreateToken(), and NtSetInformationToken().

01568 : 01569 01570 This routine releases a previously captured ACL. 01571 01572 This routine should NOT be called if the ACL was captured into a 01573 provided CaptureBuffer (see SeCaptureAcl). 01574 01575 Arguments: 01576 01577 CapturedAcl - Supplies the ACL to release. 01578 01579 RequestorMode - The processor mode specified when the ACL was captured. 01580 01581 ForceCapture - The ForceCapture value specified when the ACL was 01582 captured. 01583 01584 Return Value: 01585 01586 None. 01587 01588 --*/ 01589 01590 { 01591 // 01592 // We only have something to deallocate if the requestor was user 01593 // mode or kernel mode requesting ForceCapture. 01594 // 01595 01596 PAGED_CODE(); 01597 01598 if ( ((RequestorMode == KernelMode) && (ForceCapture == TRUE)) || 01599 (RequestorMode == UserMode ) ) { 01600 01601 ExFreePool(CapturedAcl); 01602 01603 } 01604 01605 }

VOID SeReleaseLuidAndAttributesArray IN PLUID_AND_ATTRIBUTES  CapturedArray,
IN KPROCESSOR_MODE  RequestorMode,
IN BOOLEAN  ForceCapture
 

Definition at line 1797 of file se/capture.c.

References ExFreePool(), KernelMode, NULL, PAGED_CODE, TRUE, and UserMode.

Referenced by NtAdjustPrivilegesToken(), NtCreateToken(), NtFilterToken(), and NtPrivilegeCheck().

01805 : 01806 01807 This routine releases a previously captured array of LUID_AND_ATTRIBUTES. 01808 01809 This routine should NOT be called if the array was captured into a 01810 provided CaptureBuffer (see SeCaptureLuidAndAttributesArray). 01811 01812 Arguments: 01813 01814 CapturedArray - Supplies the array to release. 01815 01816 RequestorMode - The processor mode specified when the array was captured. 01817 01818 ForceCapture - The ForceCapture value specified when the array was 01819 captured. 01820 01821 Return Value: 01822 01823 None. 01824 01825 --*/ 01826 01827 { 01828 // 01829 // We only have something to deallocate if the requestor was user 01830 // mode or kernel mode requesting ForceCapture. 01831 // 01832 01833 PAGED_CODE(); 01834 01835 if ( ((RequestorMode == KernelMode) && (ForceCapture == TRUE)) || 01836 (RequestorMode == UserMode )) { 01837 // 01838 // the capture routine returns success with a null pointer for zero elements. 01839 // 01840 if (CapturedArray != NULL) 01841 ExFreePool(CapturedArray); 01842 01843 } 01844 01845 return; 01846 01847 }

VOID SeReleaseSecurityDescriptor IN PSECURITY_DESCRIPTOR  CapturedSecurityDescriptor,
IN KPROCESSOR_MODE  RequestorMode,
IN BOOLEAN  ForceCapture
 

Definition at line 631 of file se/capture.c.

References ExFreePool(), KernelMode, PAGED_CODE, TRUE, and UserMode.

Referenced by IopSetSecurityObjectFromRegistry(), NtOpenObjectAuditAlarm(), NtSetSecurityObject(), NtUserCreateWindowStation(), ObInsertObject(), SeAccessCheckByType(), and SepAccessCheckAndAuditAlarm().

00639 : 00640 00641 This routine releases a previously captured security descriptor. 00642 Only 00643 00644 Arguments: 00645 00646 CapturedSecurityDescriptor - Supplies the security descriptor to release. 00647 00648 RequestorMode - The processor mode specified when the descriptor was 00649 captured. 00650 00651 ForceCapture - The ForceCapture value specified when the descriptor was 00652 captured. 00653 00654 Return Value: 00655 00656 None. 00657 00658 --*/ 00659 00660 { 00661 // 00662 // We only have something to deallocate if the requestor was user 00663 // mode or kernel mode requesting ForceCapture. 00664 // 00665 00666 PAGED_CODE(); 00667 00668 if ( ((RequestorMode == KernelMode) && (ForceCapture == TRUE)) || 00669 (RequestorMode == UserMode ) ) { 00670 if ( CapturedSecurityDescriptor ) { 00671 ExFreePool(CapturedSecurityDescriptor); 00672 } 00673 } 00674 00675 return; 00676 00677 }

VOID SeReleaseSid IN PSID  CapturedSid,
IN KPROCESSOR_MODE  RequestorMode,
IN BOOLEAN  ForceCapture
 

Definition at line 1320 of file se/capture.c.

References ExFreePool(), KernelMode, PAGED_CODE, TRUE, and UserMode.

Referenced by NtCreateToken(), NtSecureConnectPort(), NtSetInformationToken(), SeAccessCheckByType(), and SepAccessCheckAndAuditAlarm().

01328 : 01329 01330 This routine releases a previously captured SID. 01331 01332 This routine should NOT be called if the SID was captured into a 01333 provided CaptureBuffer (see SeCaptureSid). 01334 01335 Arguments: 01336 01337 CapturedSid - Supplies the SID to release. 01338 01339 RequestorMode - The processor mode specified when the SID was captured. 01340 01341 ForceCapture - The ForceCapture value specified when the SID was 01342 captured. 01343 01344 Return Value: 01345 01346 None. 01347 01348 --*/ 01349 01350 { 01351 // 01352 // We only have something to deallocate if the requestor was user 01353 // mode or kernel mode requesting ForceCapture. 01354 // 01355 01356 PAGED_CODE(); 01357 01358 if ( ((RequestorMode == KernelMode) && (ForceCapture == TRUE)) || 01359 (RequestorMode == UserMode ) ) { 01360 01361 ExFreePool(CapturedSid); 01362 01363 } 01364 01365 return; 01366 01367 }

VOID SeReleaseSidAndAttributesArray IN PSID_AND_ATTRIBUTES  CapturedArray,
IN KPROCESSOR_MODE  RequestorMode,
IN BOOLEAN  ForceCapture
 

Definition at line 2297 of file se/capture.c.

References ExFreePool(), KernelMode, PAGED_CODE, TRUE, and UserMode.

Referenced by NtAdjustGroupsToken(), NtCreateToken(), and NtFilterToken().

02305 : 02306 02307 This routine releases a previously captured array of SID_AND_ATTRIBUTES. 02308 02309 This routine should NOT be called if the array was captured into a 02310 provided CaptureBuffer (see SeCaptureSidAndAttributesArray). 02311 02312 Arguments: 02313 02314 CapturedArray - Supplies the array to release. 02315 02316 RequestorMode - The processor mode specified when the array was captured. 02317 02318 ForceCapture - The ForceCapture value specified when the array was 02319 captured. 02320 02321 Return Value: 02322 02323 None. 02324 02325 --*/ 02326 02327 { 02328 // 02329 // We only have something to deallocate if the requestor was user 02330 // mode or kernel mode requesting ForceCapture. 02331 // 02332 02333 PAGED_CODE(); 02334 02335 if ( ((RequestorMode == KernelMode) && (ForceCapture == TRUE)) || 02336 (RequestorMode == UserMode ) ) { 02337 02338 ExFreePool(CapturedArray); 02339 02340 } 02341 02342 return; 02343 02344 }

BOOLEAN SeValidSecurityDescriptor IN ULONG  Length,
IN PSECURITY_DESCRIPTOR  SecurityDescriptor
 

Definition at line 2414 of file se/capture.c.

References Dacl, FALSE, LongAligned, RtlValidAcl(), SeLengthSid, and TRUE.

Referenced by CmpValidateHiveSecurityDescriptors().

02421 : 02422 02423 Validates a security descriptor for structural correctness. The idea is to make 02424 sure that the security descriptor may be passed to other kernel callers, without 02425 fear that they're going to choke while manipulating it. 02426 02427 This routine does not enforce policy (e.g., ACL/ACE revision information). It is 02428 entirely possible for a security descriptor to be approved by this routine, only 02429 to be later found to be invalid by some later routine. 02430 02431 This routine is designed to be used by callers who have a security descriptor in 02432 kernel memory. Callers wishing to validate a security descriptor passed from user 02433 mode should call RtlValidSecurityDescriptor. 02434 02435 Arguments: 02436 02437 Length - Length in bytes of passed Security Descriptor. 02438 02439 SecurityDescriptor - Points to the Security Descriptor (in kernel memory) to be 02440 validatated. 02441 02442 Return Value: 02443 02444 TRUE - The passed security descriptor is correctly structured 02445 FALSE - The passed security descriptor is badly formed 02446 02447 --*/ 02448 02449 { 02450 PISECURITY_DESCRIPTOR_RELATIVE ISecurityDescriptor = 02451 (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; 02452 PISID OwnerSid; 02453 PISID GroupSid; 02454 PACE_HEADER Ace; 02455 PISID Sid; 02456 PISID Sid2; 02457 PACL Dacl; 02458 PACL Sacl; 02459 ULONG i; 02460 02461 if (Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE)) { 02462 return(FALSE); 02463 } 02464 02465 // 02466 // Check the revision information. 02467 // 02468 02469 if (ISecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) { 02470 return(FALSE); 02471 } 02472 02473 // 02474 // Make sure the passed SecurityDescriptor is in self-relative form 02475 // 02476 02477 if (!(ISecurityDescriptor->Control & SE_SELF_RELATIVE)) { 02478 return(FALSE); 02479 } 02480 02481 // 02482 // Check the owner. A valid SecurityDescriptor must have an owner. 02483 // It must also be long aligned. 02484 // 02485 02486 if ((ISecurityDescriptor->Owner == 0) || 02487 (!LongAligned((PVOID)(ULONG_PTR)(ULONG)ISecurityDescriptor->Owner)) || 02488 (ISecurityDescriptor->Owner > Length) || 02489 (Length - ISecurityDescriptor->Owner < sizeof(SID))) { 02490 02491 return(FALSE); 02492 } 02493 02494 // 02495 // It is safe to reference the owner's SubAuthorityCount, compute the 02496 // expected length of the SID 02497 // 02498 02499 OwnerSid = (PSID)RtlOffsetToPointer( ISecurityDescriptor, ISecurityDescriptor->Owner ); 02500 02501 if (OwnerSid->Revision != SID_REVISION) { 02502 return(FALSE); 02503 } 02504 02505 if (OwnerSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) { 02506 return(FALSE); 02507 } 02508 02509 if (Length - ISecurityDescriptor->Owner < (ULONG) SeLengthSid(OwnerSid)) { 02510 return(FALSE); 02511 } 02512 02513 // 02514 // The owner appears to be a structurally valid SID that lies within 02515 // the bounds of the security descriptor. Do the same for the Group 02516 // if there is one. 02517 // 02518 02519 if (ISecurityDescriptor->Group != 0) { 02520 02521 // 02522 // Check alignment 02523 // 02524 02525 if (!LongAligned( (PVOID)(ULONG_PTR)(ULONG)ISecurityDescriptor->Group)) { 02526 return(FALSE); 02527 } 02528 02529 if (ISecurityDescriptor->Group > Length) { 02530 return(FALSE); 02531 } 02532 02533 if (Length - ISecurityDescriptor->Group < sizeof (SID)) { 02534 return(FALSE); 02535 } 02536 02537 // 02538 // It is safe to reference the Group's SubAuthorityCount, compute the 02539 // expected length of the SID 02540 // 02541 02542 GroupSid = (PSID)RtlOffsetToPointer( ISecurityDescriptor, ISecurityDescriptor->Group ); 02543 02544 if (GroupSid->Revision != SID_REVISION) { 02545 return(FALSE); 02546 } 02547 02548 if (GroupSid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) { 02549 return(FALSE); 02550 } 02551 02552 if (Length - ISecurityDescriptor->Group < (ULONG) SeLengthSid(GroupSid)) { 02553 return(FALSE); 02554 } 02555 } 02556 02557 // 02558 // Validate the DACL. A structurally valid SecurityDescriptor may not necessarily 02559 // have a DACL. 02560 // 02561 02562 if (ISecurityDescriptor->Dacl != 0) { 02563 02564 // 02565 // Check alignment 02566 // 02567 02568 if (!LongAligned( (PVOID)(ULONG_PTR)(ULONG)ISecurityDescriptor->Dacl)) { 02569 return(FALSE); 02570 } 02571 02572 // 02573 // Make sure the DACL structure is within the bounds of the security descriptor. 02574 // 02575 02576 if ((ISecurityDescriptor->Dacl > Length) || 02577 (Length - ISecurityDescriptor->Dacl < sizeof(ACL))) { 02578 return(FALSE); 02579 } 02580 02581 Dacl = (PACL) RtlOffsetToPointer( ISecurityDescriptor, ISecurityDescriptor->Dacl ); 02582 02583 02584 // 02585 // Make sure the DACL length fits within the bounds of the security descriptor. 02586 // 02587 02588 if (Length - ISecurityDescriptor->Dacl < Dacl->AclSize) { 02589 return(FALSE); 02590 } 02591 02592 // 02593 // Make sure the ACL is structurally valid. 02594 // 02595 02596 if (!RtlValidAcl( Dacl )) { 02597 return(FALSE); 02598 } 02599 } 02600 02601 // 02602 // Validate the SACL. A structurally valid SecurityDescriptor may not 02603 // have a SACL. 02604 // 02605 02606 if (ISecurityDescriptor->Sacl != 0) { 02607 02608 // 02609 // Check alignment 02610 // 02611 02612 if (!LongAligned( (PVOID)(ULONG_PTR)(ULONG)ISecurityDescriptor->Sacl)) { 02613 return(FALSE); 02614 } 02615 02616 // 02617 // Make sure the SACL structure is within the bounds of the security descriptor. 02618 // 02619 02620 if ((ISecurityDescriptor->Sacl > Length) || 02621 (Length - ISecurityDescriptor->Sacl < sizeof(ACL))) { 02622 return(FALSE); 02623 } 02624 02625 // 02626 // Make sure the Sacl structure is within the bounds of the security descriptor. 02627 // 02628 02629 Sacl = (PACL)RtlOffsetToPointer( ISecurityDescriptor, ISecurityDescriptor->Sacl ); 02630 02631 02632 if (Length - ISecurityDescriptor->Sacl < Sacl->AclSize) { 02633 return(FALSE); 02634 } 02635 02636 // 02637 // Make sure the ACL is structurally valid. 02638 // 02639 02640 if (!RtlValidAcl( Sacl )) { 02641 return(FALSE); 02642 } 02643 } 02644 02645 return(TRUE); 02646 }


Generated on Sat May 15 19:43:02 2004 for test by doxygen 1.3.7