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

privileg.c File Reference

#include "tokenp.h"

Go to the source code of this file.

Functions

BOOLEAN SepPrivilegeCheck (IN PTOKEN Token, IN OUT PLUID_AND_ATTRIBUTES RequiredPrivileges, IN ULONG RequiredPrivilegeCount, IN ULONG PrivilegeSetControl, IN KPROCESSOR_MODE PreviousMode)
BOOLEAN SePrivilegeCheck (IN OUT PPRIVILEGE_SET RequiredPrivileges, IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN KPROCESSOR_MODE AccessMode)
NTSTATUS NtPrivilegeCheck (IN HANDLE ClientToken, IN OUT PPRIVILEGE_SET RequiredPrivileges, OUT PBOOLEAN Result)
BOOLEAN SeSinglePrivilegeCheck (LUID PrivilegeValue, KPROCESSOR_MODE PreviousMode)
BOOLEAN SeCheckPrivilegedObject (LUID PrivilegeValue, HANDLE ObjectHandle, ACCESS_MASK DesiredAccess, KPROCESSOR_MODE PreviousMode)


Function Documentation

NTSTATUS NtPrivilegeCheck IN HANDLE  ClientToken,
IN OUT PPRIVILEGE_SET  RequiredPrivileges,
OUT PBOOLEAN  Result
 

Definition at line 231 of file privileg.c.

References ANYSIZE_ARRAY, ClientToken, EXCEPTION_EXECUTE_HANDLER, IsValidElementCount, KPROCESSOR_MODE, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, PagedPool, ProbeForWrite(), ProbeForWriteBoolean, PTOKEN, SeCaptureLuidAndAttributesArray(), SepPrivilegeCheck(), SepTokenObjectType, SeReleaseLuidAndAttributesArray(), Status, Token, TRUE, and UserMode.

Referenced by IsPrivileged(), RtlNewSecurityGrantedAccess(), RtlpNewSecurityObject(), and RtlpValidOwnerSubjectContext().

00239 : 00240 00241 This routine tests the caller's client's security context to see if it 00242 contains the specified privileges. 00243 00244 This API requires the caller have SeTcbPrivilege privilege. The test 00245 for this privilege is always against the primary token of the calling 00246 process, not the impersonation token of the thread. 00247 00248 00249 Arguments: 00250 00251 ClientToken - A handle to a token object representing a client 00252 attempting access. This handle must be obtained from a 00253 communication session layer, such as from an LPC Port or Local 00254 Named Pipe, to prevent possible security policy violations. 00255 00256 RequiredPrivileges - Points to a set of privileges. The client's 00257 security context is to be checked to see which of the specified 00258 privileges are present. The results will be indicated in the 00259 attributes associated with each privilege. Note that 00260 flags in this parameter indicate whether all the privileges listed 00261 are needed, or any of the privileges. 00262 00263 Result - Receives a boolean flag indicating whether the client has all 00264 the specified privileges or not. A value of TRUE indicates the 00265 client has all the specified privileges. Otherwise a value of 00266 FALSE is returned. 00267 00268 00269 00270 Return Value: 00271 00272 STATUS_SUCCESS - Indicates the call completed successfully. 00273 00274 STATUS_PRIVILEGE_NOT_HELD - Indicates the caller does not have 00275 sufficient privilege to use this privileged system service. 00276 00277 --*/ 00278 00279 00280 00281 { 00282 BOOLEAN BStatus; 00283 KPROCESSOR_MODE PreviousMode; 00284 NTSTATUS Status; 00285 PLUID_AND_ATTRIBUTES CapturedPrivileges = NULL; 00286 PTOKEN Token; 00287 ULONG CapturedPrivilegeCount; 00288 ULONG CapturedPrivilegesLength; 00289 ULONG ParameterLength; 00290 ULONG PrivilegeSetControl; 00291 00292 PAGED_CODE(); 00293 00294 PreviousMode = KeGetPreviousMode(); 00295 00296 Status = ObReferenceObjectByHandle( 00297 ClientToken, // Handle 00298 TOKEN_QUERY, // DesiredAccess 00299 SepTokenObjectType, // ObjectType 00300 PreviousMode, // AccessMode 00301 (PVOID *)&Token, // Object 00302 NULL // GrantedAccess 00303 ); 00304 00305 if ( !NT_SUCCESS(Status) ) { 00306 return Status; 00307 00308 } 00309 00310 // 00311 // If the passed token is an impersonation token, make sure 00312 // it is at SecurityIdentification or above. 00313 // 00314 00315 if (Token->TokenType == TokenImpersonation) { 00316 00317 if (Token->ImpersonationLevel < SecurityIdentification) { 00318 00319 ObDereferenceObject( (PVOID)Token ); 00320 00321 return( STATUS_BAD_IMPERSONATION_LEVEL ); 00322 00323 } 00324 } 00325 00326 try { 00327 00328 // 00329 // Capture passed Privilege Set 00330 // 00331 00332 ProbeForWrite( 00333 RequiredPrivileges, 00334 sizeof(PRIVILEGE_SET), 00335 sizeof(ULONG) 00336 ); 00337 00338 CapturedPrivilegeCount = RequiredPrivileges->PrivilegeCount; 00339 00340 if (!IsValidElementCount(CapturedPrivilegeCount, LUID_AND_ATTRIBUTES)) { 00341 Status = STATUS_INVALID_PARAMETER; 00342 leave; 00343 } 00344 ParameterLength = (ULONG)sizeof(PRIVILEGE_SET) + 00345 ((CapturedPrivilegeCount - ANYSIZE_ARRAY) * 00346 (ULONG)sizeof(LUID_AND_ATTRIBUTES) ); 00347 00348 ProbeForWrite( 00349 RequiredPrivileges, 00350 ParameterLength, 00351 sizeof(ULONG) 00352 ); 00353 00354 00355 ProbeForWriteBoolean(Result); 00356 00357 PrivilegeSetControl = RequiredPrivileges->Control; 00358 00359 00360 } except(EXCEPTION_EXECUTE_HANDLER) { 00361 Status = GetExceptionCode(); 00362 } 00363 00364 if (!NT_SUCCESS(Status)) { 00365 ObDereferenceObject( (PVOID)Token ); 00366 return Status; 00367 00368 } 00369 00370 Status = SeCaptureLuidAndAttributesArray( 00371 (RequiredPrivileges->Privilege), 00372 CapturedPrivilegeCount, 00373 UserMode, 00374 NULL, 0, 00375 PagedPool, 00376 TRUE, 00377 &CapturedPrivileges, 00378 &CapturedPrivilegesLength 00379 ); 00380 00381 if (!NT_SUCCESS(Status)) { 00382 00383 ObDereferenceObject( (PVOID)Token ); 00384 return Status; 00385 } 00386 00387 BStatus = SepPrivilegeCheck( 00388 Token, // Token, 00389 CapturedPrivileges, // RequiredPrivileges, 00390 CapturedPrivilegeCount, // RequiredPrivilegeCount, 00391 PrivilegeSetControl, // PrivilegeSetControl 00392 PreviousMode // PreviousMode 00393 ); 00394 00395 ObDereferenceObject( Token ); 00396 00397 00398 try { 00399 00400 // 00401 // copy the modified privileges buffer back to user 00402 // 00403 00404 RtlMoveMemory( 00405 RequiredPrivileges->Privilege, 00406 CapturedPrivileges, 00407 CapturedPrivilegesLength 00408 ); 00409 00410 *Result = BStatus; 00411 00412 } except (EXCEPTION_EXECUTE_HANDLER) { 00413 00414 SeReleaseLuidAndAttributesArray( 00415 CapturedPrivileges, 00416 PreviousMode, 00417 TRUE 00418 ); 00419 00420 return(GetExceptionCode()); 00421 00422 } 00423 00424 SeReleaseLuidAndAttributesArray( 00425 CapturedPrivileges, 00426 PreviousMode, 00427 TRUE 00428 ); 00429 00430 return( STATUS_SUCCESS ); 00431 }

BOOLEAN SeCheckPrivilegedObject LUID  PrivilegeValue,
HANDLE  ObjectHandle,
ACCESS_MASK  DesiredAccess,
KPROCESSOR_MODE  PreviousMode
 

Definition at line 504 of file privileg.c.

References KernelMode, PAGED_CODE, SeCaptureSubjectContext(), SePrivilegeCheck(), SePrivilegeObjectAuditAlarm(), and SeReleaseSubjectContext().

Referenced by NtSetInformationJobObject(), NtSetInformationProcess(), NtSetInformationThread(), and PspSetPrimaryToken().

00513 : 00514 00515 This function will check for the passed privilege value in the 00516 current context, and generate audits as appropriate. 00517 00518 Arguments: 00519 00520 PrivilegeValue - The value of the privilege being checked. 00521 00522 Object - Specifies a pointer to the object being accessed. 00523 00524 ObjectHandle - Specifies the object handle being used. 00525 00526 DesiredAccess - The desired access mask, if any 00527 00528 PreviousMode - The previous processor mode 00529 00530 00531 Return Value: 00532 00533 TRUE - The current subject has the desired privilege. 00534 00535 FALSE - The current subject does not have the desired privilege. 00536 --*/ 00537 00538 { 00539 BOOLEAN AccessGranted; 00540 PRIVILEGE_SET RequiredPrivileges; 00541 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; 00542 00543 PAGED_CODE(); 00544 00545 // 00546 // Make sure the caller has the privilege to make this 00547 // call. 00548 // 00549 00550 RequiredPrivileges.PrivilegeCount = 1; 00551 RequiredPrivileges.Control = PRIVILEGE_SET_ALL_NECESSARY; 00552 RequiredPrivileges.Privilege[0].Luid = PrivilegeValue; 00553 RequiredPrivileges.Privilege[0].Attributes = 0; 00554 00555 SeCaptureSubjectContext( &SubjectSecurityContext ); 00556 00557 AccessGranted = SePrivilegeCheck( 00558 &RequiredPrivileges, 00559 &SubjectSecurityContext, 00560 PreviousMode 00561 ); 00562 00563 if ( PreviousMode != KernelMode ) { 00564 00565 SePrivilegeObjectAuditAlarm( 00566 ObjectHandle, 00567 &SubjectSecurityContext, 00568 DesiredAccess, 00569 &RequiredPrivileges, 00570 AccessGranted, 00571 PreviousMode 00572 ); 00573 00574 } 00575 00576 00577 SeReleaseSubjectContext( &SubjectSecurityContext ); 00578 00579 return( AccessGranted ); 00580 00581 } }

BOOLEAN SepPrivilegeCheck IN PTOKEN  Token,
IN OUT PLUID_AND_ATTRIBUTES  RequiredPrivileges,
IN ULONG  RequiredPrivilegeCount,
IN ULONG  PrivilegeSetControl,
IN KPROCESSOR_MODE  PreviousMode
 

Definition at line 38 of file privileg.c.

References FALSE, KernelMode, PAGED_CODE, RtlEqualLuid(), SepAcquireTokenReadLock, SepReleaseTokenReadLock, Token, and TRUE.

Referenced by NtPrivilegeCheck(), SeCheckAuditPrivilege(), SePrivilegeCheck(), and SepSinglePrivilegeCheck().

00047 : 00048 00049 Worker routine for SePrivilegeCheck 00050 00051 Arguments: 00052 00053 Token - The user's effective token. 00054 00055 RequiredPrivileges - A privilege set describing the required 00056 privileges. The UsedForAccess bits will be set in any privilege 00057 that is actually used (usually all of them). 00058 00059 RequiredPrivilegeCount - How many privileges are in the 00060 RequiredPrivileges set. 00061 00062 PrivilegeSetControl - Describes how many privileges are required. 00063 00064 PreviousMode - The previous processor mode. 00065 00066 Return Value: 00067 00068 Returns TRUE if requested privileges are granted, FALSE otherwise. 00069 00070 --*/ 00071 00072 { 00073 PLUID_AND_ATTRIBUTES CurrentRequiredPrivilege; 00074 PLUID_AND_ATTRIBUTES CurrentTokenPrivilege; 00075 00076 BOOLEAN RequiredAll; 00077 00078 ULONG TokenPrivilegeCount; 00079 ULONG MatchCount = 0; 00080 00081 ULONG i; 00082 ULONG j; 00083 00084 PAGED_CODE(); 00085 00086 // 00087 // Take care of kernel callers first 00088 // 00089 00090 if (PreviousMode == KernelMode) { 00091 00092 return(TRUE); 00093 00094 } 00095 00096 SepAcquireTokenReadLock( Token ); 00097 00098 TokenPrivilegeCount = Token->PrivilegeCount; 00099 00100 // 00101 // Save whether we require ALL of them or ANY 00102 // 00103 00104 RequiredAll = (BOOLEAN)(PrivilegeSetControl & PRIVILEGE_SET_ALL_NECESSARY); 00105 00106 for ( i = 0 , CurrentRequiredPrivilege = RequiredPrivileges ; 00107 i < RequiredPrivilegeCount ; 00108 i++, CurrentRequiredPrivilege++ ) { 00109 00110 for ( j = 0, CurrentTokenPrivilege = Token->Privileges; 00111 j < TokenPrivilegeCount ; 00112 j++, CurrentTokenPrivilege++ ) { 00113 00114 if ((CurrentTokenPrivilege->Attributes & SE_PRIVILEGE_ENABLED) && 00115 (RtlEqualLuid(&CurrentTokenPrivilege->Luid, 00116 &CurrentRequiredPrivilege->Luid)) 00117 ) { 00118 00119 CurrentRequiredPrivilege->Attributes |= 00120 SE_PRIVILEGE_USED_FOR_ACCESS; 00121 MatchCount++; 00122 break; // start looking for next one 00123 } 00124 00125 } 00126 00127 } 00128 00129 SepReleaseTokenReadLock( Token ); 00130 00131 // 00132 // If we wanted ANY and didn't get any, return failure. 00133 // 00134 00135 if (!RequiredAll && (MatchCount == 0)) { 00136 00137 return (FALSE); 00138 00139 } 00140 00141 // 00142 // If we wanted ALL and didn't get all, return failure. 00143 // 00144 00145 if (RequiredAll && (MatchCount != RequiredPrivilegeCount)) { 00146 00147 return(FALSE); 00148 } 00149 00150 return(TRUE); 00151 00152 }

BOOLEAN SePrivilegeCheck IN OUT PPRIVILEGE_SET  RequiredPrivileges,
IN PSECURITY_SUBJECT_CONTEXT  SubjectSecurityContext,
IN KPROCESSOR_MODE  AccessMode
 

Definition at line 158 of file privileg.c.

References EffectiveToken, FALSE, NULL, PAGED_CODE, SepPrivilegeCheck(), and Status.

Referenced by IopCheckBackupRestorePrivilege(), IsPrivileged(), ObpIncrementHandleCount(), RtlpNewSecurityObject(), SeCheckPrivilegedObject(), and SeSinglePrivilegeCheck().

00165 : 00166 00167 This routine checks to see if the token contains the specified 00168 privileges. 00169 00170 Arguments: 00171 00172 RequiredPrivileges - Points to a set of privileges. The subject's 00173 security context is to be checked to see which of the specified 00174 privileges are present. The results will be indicated in the 00175 attributes associated with each privilege. Note that 00176 flags in this parameter indicate whether all the privileges listed 00177 are needed, or any of the privileges. 00178 00179 SubjectSecurityContext - A pointer to the subject's captured security 00180 context. 00181 00182 AccessMode - Indicates the access mode to use for access check. One of 00183 UserMode or KernelMode. If the mode is kernel, then all privileges 00184 will be marked as being possessed by the subject, and successful 00185 completion status is returned. 00186 00187 00188 Return Value: 00189 00190 BOOLEAN - TRUE if all specified privileges are held by the subject, 00191 otherwise FALSE. 00192 00193 00194 --*/ 00195 00196 { 00197 BOOLEAN Status; 00198 00199 PAGED_CODE(); 00200 00201 // 00202 // If we're impersonating a client, we have to be at impersonation level 00203 // of SecurityImpersonation or above. 00204 // 00205 00206 if ( (SubjectSecurityContext->ClientToken != NULL) && 00207 (SubjectSecurityContext->ImpersonationLevel < SecurityImpersonation) 00208 ) { 00209 00210 return(FALSE); 00211 } 00212 00213 // 00214 // SepPrivilegeCheck locks the passed token for read access 00215 // 00216 00217 Status = SepPrivilegeCheck( 00218 EffectiveToken( SubjectSecurityContext ), 00219 RequiredPrivileges->Privilege, 00220 RequiredPrivileges->PrivilegeCount, 00221 RequiredPrivileges->Control, 00222 AccessMode 00223 ); 00224 00225 return(Status); 00226 }

BOOLEAN SeSinglePrivilegeCheck LUID  PrivilegeValue,
KPROCESSOR_MODE  PreviousMode
 

Definition at line 436 of file privileg.c.

References KernelMode, NULL, PAGED_CODE, SeCaptureSubjectContext(), SECURITY_SUBJECT_CONTEXT, SePrivilegeCheck(), SePrivilegedServiceAuditAlarm(), and SeReleaseSubjectContext().

Referenced by CmpDoOpen(), CmpRefreshHive(), ExpRaiseHardError(), NtAllocateUserPhysicalPages(), NtCreatePagingFile(), NtCreateProfile(), NtLoadDriver(), NtLoadKey2(), NtLockVirtualMemory(), NtOpenProcess(), NtOpenThread(), NtQuerySystemEnvironmentValue(), NtQuerySystemInformation(), NtReplaceKey(), NtRestoreKey(), NtSaveKey(), NtSaveMergedKeys(), NtSetDefaultHardErrorPort(), NtSetInformationProcess(), NtSetInformationToken(), NtSetSystemEnvironmentValue(), NtSetSystemInformation(), NtSystemDebugControl(), NtUnloadDriver(), NtUnloadKey(), NtUnlockVirtualMemory(), ObCreateObject(), PspSetQuotaLimits(), SepCreateToken(), SepValidOwnerSubjectContext(), and UdfInvalidateVolumes().

00443 : 00444 00445 This function will check for the passed privilege value in the 00446 current context. 00447 00448 Arguments: 00449 00450 PrivilegeValue - The value of the privilege being checked. 00451 00452 00453 Return Value: 00454 00455 TRUE - The current subject has the desired privilege. 00456 00457 FALSE - The current subject does not have the desired privilege. 00458 --*/ 00459 00460 { 00461 BOOLEAN AccessGranted; 00462 PRIVILEGE_SET RequiredPrivileges; 00463 SECURITY_SUBJECT_CONTEXT SubjectSecurityContext; 00464 00465 PAGED_CODE(); 00466 00467 // 00468 // Make sure the caller has the privilege to make this 00469 // call. 00470 // 00471 00472 RequiredPrivileges.PrivilegeCount = 1; 00473 RequiredPrivileges.Control = PRIVILEGE_SET_ALL_NECESSARY; 00474 RequiredPrivileges.Privilege[0].Luid = PrivilegeValue; 00475 RequiredPrivileges.Privilege[0].Attributes = 0; 00476 00477 SeCaptureSubjectContext( &SubjectSecurityContext ); 00478 00479 AccessGranted = SePrivilegeCheck( 00480 &RequiredPrivileges, 00481 &SubjectSecurityContext, 00482 PreviousMode 00483 ); 00484 00485 if ( PreviousMode != KernelMode ) { 00486 00487 SePrivilegedServiceAuditAlarm ( 00488 NULL, // BUGWARNING need service name 00489 &SubjectSecurityContext, 00490 &RequiredPrivileges, 00491 AccessGranted 00492 ); 00493 } 00494 00495 00496 SeReleaseSubjectContext( &SubjectSecurityContext ); 00497 00498 return( AccessGranted ); 00499 00500 }


Generated on Sat May 15 19:45:18 2004 for test by doxygen 1.3.7