00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
#include "tokenp.h"
00026
00027
00028
#ifdef ALLOC_PRAGMA
00029
#pragma alloc_text(PAGE,NtPrivilegeCheck)
00030
#pragma alloc_text(PAGE,SeCheckPrivilegedObject)
00031
#pragma alloc_text(PAGE,SepPrivilegeCheck)
00032
#pragma alloc_text(PAGE,SePrivilegeCheck)
00033
#pragma alloc_text(PAGE,SeSinglePrivilegeCheck)
00034
#endif
00035
00036
00037 BOOLEAN
00038 SepPrivilegeCheck(
00039 IN PTOKEN Token,
00040 IN OUT PLUID_AND_ATTRIBUTES RequiredPrivileges,
00041 IN ULONG RequiredPrivilegeCount,
00042 IN ULONG PrivilegeSetControl,
00043 IN KPROCESSOR_MODE PreviousMode
00044 )
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
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
00088
00089
00090
if (PreviousMode ==
KernelMode) {
00091
00092
return(
TRUE);
00093
00094 }
00095
00096
SepAcquireTokenReadLock(
Token );
00097
00098 TokenPrivilegeCount =
Token->PrivilegeCount;
00099
00100
00101
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;
00123 }
00124
00125 }
00126
00127 }
00128
00129
SepReleaseTokenReadLock(
Token );
00130
00131
00132
00133
00134
00135
if (!RequiredAll && (MatchCount == 0)) {
00136
00137
return (
FALSE);
00138
00139 }
00140
00141
00142
00143
00144
00145
if (RequiredAll && (MatchCount != RequiredPrivilegeCount)) {
00146
00147
return(
FALSE);
00148 }
00149
00150
return(
TRUE);
00151
00152 }
00153
00154
00155
00156
00157 BOOLEAN
00158 SePrivilegeCheck(
00159 IN OUT PPRIVILEGE_SET RequiredPrivileges,
00160 IN
PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
00161 IN KPROCESSOR_MODE AccessMode
00162 )
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 {
00197 BOOLEAN
Status;
00198
00199
PAGED_CODE();
00200
00201
00202
00203
00204
00205
00206
if ( (SubjectSecurityContext->ClientToken !=
NULL) &&
00207 (SubjectSecurityContext->ImpersonationLevel < SecurityImpersonation)
00208 ) {
00209
00210
return(
FALSE);
00211 }
00212
00213
00214
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 }
00227
00228
00229
00230
NTSTATUS
00231 NtPrivilegeCheck(
00232 IN HANDLE ClientToken,
00233 IN OUT PPRIVILEGE_SET RequiredPrivileges,
00234 OUT PBOOLEAN Result
00235 )
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
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,
00298 TOKEN_QUERY,
00299
SepTokenObjectType,
00300 PreviousMode,
00301 (PVOID *)&
Token,
00302
NULL
00303 );
00304
00305
if ( !
NT_SUCCESS(
Status) ) {
00306
return Status;
00307
00308 }
00309
00310
00311
00312
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
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,
00389 CapturedPrivileges,
00390 CapturedPrivilegeCount,
00391 PrivilegeSetControl,
00392 PreviousMode
00393 );
00394
00395
ObDereferenceObject(
Token );
00396
00397
00398
try {
00399
00400
00401
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 }
00432
00433
00434
00435 BOOLEAN
00436 SeSinglePrivilegeCheck(
00437 LUID PrivilegeValue,
00438 KPROCESSOR_MODE PreviousMode
00439 )
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 {
00461 BOOLEAN AccessGranted;
00462 PRIVILEGE_SET RequiredPrivileges;
00463
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
00464
00465
PAGED_CODE();
00466
00467
00468
00469
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,
00489 &SubjectSecurityContext,
00490 &RequiredPrivileges,
00491 AccessGranted
00492 );
00493 }
00494
00495
00496
SeReleaseSubjectContext( &SubjectSecurityContext );
00497
00498
return( AccessGranted );
00499
00500 }
00501
00502
00503 BOOLEAN
00504 SeCheckPrivilegedObject(
00505 LUID PrivilegeValue,
00506 HANDLE ObjectHandle,
00507 ACCESS_MASK DesiredAccess,
00508 KPROCESSOR_MODE PreviousMode
00509 )
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 {
00539 BOOLEAN AccessGranted;
00540 PRIVILEGE_SET RequiredPrivileges;
00541
SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
00542
00543
PAGED_CODE();
00544
00545
00546
00547
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 }