00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "sep.h"
00024
#include "sertlp.h"
00025
#include "tokenp.h"
00026
00027
#ifdef ALLOC_PRAGMA
00028
#pragma alloc_text(PAGE,NtSetInformationToken)
00029
#pragma alloc_text(PAGE,SepFreePrimaryGroup)
00030
#pragma alloc_text(PAGE,SepFreeDefaultDacl)
00031
#pragma alloc_text(PAGE,SepAppendPrimaryGroup)
00032
#pragma alloc_text(PAGE,SepAppendDefaultDacl)
00033
#endif
00034
00035
00036
NTSTATUS
00037 NtSetInformationToken (
00038 IN HANDLE TokenHandle,
00039 IN TOKEN_INFORMATION_CLASS TokenInformationClass,
00040 IN PVOID TokenInformation,
00041 IN ULONG TokenInformationLength
00042 )
00043
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
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 {
00126
00127
KPROCESSOR_MODE PreviousMode;
00128
NTSTATUS Status;
00129
00130
PTOKEN Token;
00131
00132 ULONG
Index;
00133 BOOLEAN Found;
00134 BOOLEAN TokenModified =
FALSE;
00135
00136 ULONG NewLength;
00137 ULONG
CurrentLength;
00138
00139 PSID CapturedOwner;
00140 PSID CapturedPrimaryGroup;
00141 PACL CapturedDefaultDacl;
00142 ACCESS_MASK DesiredAccess;
00143
00144
PAGED_CODE();
00145
00146
00147
00148
00149
00150 PreviousMode = KeGetPreviousMode();
00151
if (PreviousMode !=
KernelMode) {
00152
try {
00153
00154
00155
00156
00157
00158
00159
00160
00161
ProbeForRead(
00162 TokenInformation,
00163 TokenInformationLength,
00164
sizeof(ULONG)
00165 );
00166
00167 } except(
EXCEPTION_EXECUTE_HANDLER) {
00168
return GetExceptionCode();
00169 }
00170 }
00171
00172
00173
00174
00175
if ( (TokenInformationClass != TokenOwner) &&
00176 (TokenInformationClass != TokenPrimaryGroup) &&
00177 (TokenInformationClass != TokenSessionId) &&
00178 (TokenInformationClass != TokenDefaultDacl) ) {
00179
00180
return STATUS_INVALID_INFO_CLASS;
00181
00182 }
00183
00184
00185
00186
00187
00188
00189 DesiredAccess = TOKEN_ADJUST_DEFAULT;
00190
if (TokenInformationClass == TokenSessionId) {
00191 DesiredAccess |= TOKEN_ADJUST_SESSIONID;
00192 }
00193
00194
Status =
ObReferenceObjectByHandle(
00195 TokenHandle,
00196 DesiredAccess,
00197
SepTokenObjectType,
00198 PreviousMode,
00199 (PVOID *)&
Token,
00200
NULL
00201 );
00202
00203
if ( !
NT_SUCCESS(
Status) ) {
00204
return Status;
00205 }
00206
00207
00208
00209
00210
00211
00212
switch ( TokenInformationClass ) {
00213
00214
case TokenOwner:
00215
00216
00217
00218
00219
00220
00221
if (TokenInformationLength < (ULONG)
sizeof(TOKEN_OWNER)) {
00222
00223
ObDereferenceObject(
Token );
00224
return STATUS_INFO_LENGTH_MISMATCH;
00225 }
00226
00227
00228
00229
00230
try {
00231
00232
00233
00234
00235
00236 CapturedOwner = ((PTOKEN_OWNER)TokenInformation)->Owner;
00237
Status =
SeCaptureSid(
00238 CapturedOwner,
00239 PreviousMode,
00240
NULL, 0,
00241
PagedPool,
00242
TRUE,
00243 &CapturedOwner
00244 );
00245
00246 } except(
EXCEPTION_EXECUTE_HANDLER) {
00247
00248
ObDereferenceObject(
Token );
00249
return GetExceptionCode();
00250 }
00251
00252
if (!
NT_SUCCESS(
Status)) {
00253
ObDereferenceObject(
Token );
00254
return Status;
00255 }
00256
00257
00258
00259
00260
00261
SepAcquireTokenWriteLock(
Token );
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
Index = 0;
00272
while (
Index <
Token->UserAndGroupCount) {
00273
00274
try {
00275
00276 Found =
RtlEqualSid(
00277 CapturedOwner,
00278
Token->UserAndGroups[
Index].Sid
00279 );
00280
00281
if ( Found ) {
00282
00283
if (
SepIdAssignableAsOwner(
Token,
Index) ){
00284
00285
Token->DefaultOwnerIndex =
Index;
00286 TokenModified =
TRUE;
00287
Status = STATUS_SUCCESS;
00288
00289 }
else {
00290
00291
Status = STATUS_INVALID_OWNER;
00292
00293 }
00294
00295
SepReleaseTokenWriteLock(
Token, TokenModified );
00296
ObDereferenceObject(
Token );
00297
SeReleaseSid( CapturedOwner, PreviousMode,
TRUE);
00298
return Status;
00299
00300 }
00301
00302 } except(
EXCEPTION_EXECUTE_HANDLER) {
00303
00304
SepReleaseTokenWriteLock(
Token, TokenModified );
00305
ObDereferenceObject(
Token );
00306
SeReleaseSid( CapturedOwner, PreviousMode,
TRUE);
00307
return GetExceptionCode();
00308
00309 }
00310
00311
Index += 1;
00312
00313 }
00314
00315
SepReleaseTokenWriteLock(
Token, TokenModified );
00316
ObDereferenceObject(
Token );
00317
SeReleaseSid( CapturedOwner, PreviousMode,
TRUE);
00318
return STATUS_INVALID_OWNER;
00319
00320
case TokenPrimaryGroup:
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
if (TokenInformationLength < (ULONG)
sizeof(TOKEN_PRIMARY_GROUP)) {
00335
00336
ObDereferenceObject(
Token );
00337
return STATUS_INFO_LENGTH_MISMATCH;
00338 }
00339
00340
00341
00342
00343
00344
try {
00345
00346 CapturedPrimaryGroup =
00347 ((PTOKEN_PRIMARY_GROUP)TokenInformation)->PrimaryGroup;
00348
00349
Status =
SeCaptureSid(
00350 CapturedPrimaryGroup,
00351 PreviousMode,
00352
NULL, 0,
00353
PagedPool,
00354
TRUE,
00355 &CapturedPrimaryGroup
00356 );
00357
00358 } except(
EXCEPTION_EXECUTE_HANDLER) {
00359
00360
ObDereferenceObject(
Token );
00361
return GetExceptionCode();
00362 }
00363
00364
if (!
NT_SUCCESS(
Status)) {
00365
ObDereferenceObject(
Token );
00366
return Status;
00367 }
00368
00369
if (!
SepIdAssignableAsGroup(
Token, CapturedPrimaryGroup )) {
00370
ObDereferenceObject(
Token );
00371
SeReleaseSid( CapturedPrimaryGroup, PreviousMode,
TRUE);
00372
return STATUS_INVALID_PRIMARY_GROUP;
00373 }
00374
00375
00376
00377
00378
00379
SepAcquireTokenWriteLock(
Token );
00380
00381
00382
00383
00384
00385
00386 NewLength =
SeLengthSid( CapturedPrimaryGroup );
00387
CurrentLength =
SeLengthSid(
Token->PrimaryGroup );
00388
00389
if (NewLength > (
CurrentLength +
Token->DynamicAvailable) ) {
00390
00391
SepReleaseTokenWriteLock(
Token, TokenModified );
00392
ObDereferenceObject(
Token );
00393
SeReleaseSid( CapturedPrimaryGroup, PreviousMode,
TRUE);
00394
return STATUS_ALLOTTED_SPACE_EXCEEDED;
00395 }
00396
00397
00398
00399
00400
00401
SepFreePrimaryGroup(
Token );
00402
00403
00404
00405
00406
00407
SepAppendPrimaryGroup(
Token, CapturedPrimaryGroup );
00408
00409 TokenModified =
TRUE;
00410
00411
00412
00413
00414
00415
SepReleaseTokenWriteLock(
Token, TokenModified );
00416
ObDereferenceObject(
Token );
00417
SeReleaseSid( CapturedPrimaryGroup, PreviousMode,
TRUE);
00418
return STATUS_SUCCESS;
00419
00420
00421
case TokenDefaultDacl:
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
if (TokenInformationLength < (ULONG)
sizeof(TOKEN_DEFAULT_DACL)) {
00436
00437
ObDereferenceObject(
Token );
00438
return STATUS_INFO_LENGTH_MISMATCH;
00439 }
00440
00441
00442
00443
00444
00445
try {
00446
00447 CapturedDefaultDacl =
00448 ((PTOKEN_DEFAULT_DACL)TokenInformation)->DefaultDacl;
00449
00450
if (ARGUMENT_PRESENT(CapturedDefaultDacl)) {
00451
Status =
SeCaptureAcl(
00452 CapturedDefaultDacl,
00453 PreviousMode,
00454
NULL, 0,
00455
PagedPool,
00456
TRUE,
00457 &CapturedDefaultDacl,
00458 &NewLength
00459 );
00460
00461 }
else {
00462 NewLength = 0;
00463
Status = STATUS_SUCCESS;
00464 }
00465
00466 } except(
EXCEPTION_EXECUTE_HANDLER) {
00467
00468
ObDereferenceObject(
Token );
00469
return GetExceptionCode();
00470 }
00471
00472
if (!
NT_SUCCESS(
Status)) {
00473
ObDereferenceObject(
Token );
00474
return Status;
00475 }
00476
00477
00478
00479
00480
00481
SepAcquireTokenWriteLock(
Token );
00482
00483
00484
00485
00486
00487
00488
if (ARGUMENT_PRESENT(
Token->DefaultDacl)) {
00489
CurrentLength =
Token->DefaultDacl->AclSize;
00490 }
else {
00491
CurrentLength = 0;
00492 }
00493
00494
if (NewLength > (
CurrentLength +
Token->DynamicAvailable) ) {
00495
00496
SepReleaseTokenWriteLock(
Token, TokenModified );
00497
ObDereferenceObject(
Token );
00498
if (ARGUMENT_PRESENT(CapturedDefaultDacl)) {
00499
SeReleaseAcl( CapturedDefaultDacl, PreviousMode,
TRUE);
00500 }
00501
return STATUS_ALLOTTED_SPACE_EXCEEDED;
00502 }
00503
00504
00505
00506
00507
00508
SepFreeDefaultDacl(
Token );
00509
00510
00511
00512
00513
00514
if (ARGUMENT_PRESENT(CapturedDefaultDacl)) {
00515
SepAppendDefaultDacl(
Token, CapturedDefaultDacl );
00516 }
00517
00518 TokenModified =
TRUE;
00519
00520
00521
00522
00523
00524
SepReleaseTokenWriteLock(
Token, TokenModified );
00525
ObDereferenceObject(
Token );
00526
if (ARGUMENT_PRESENT(CapturedDefaultDacl)) {
00527
SeReleaseAcl( CapturedDefaultDacl, PreviousMode,
TRUE);
00528 }
00529
return STATUS_SUCCESS;
00530
00531
case TokenSessionId:
00532 {
00533 ULONG SessionId;
00534
00535
if ( TokenInformationLength !=
sizeof(ULONG) ) {
00536
ObDereferenceObject(
Token );
00537
return( STATUS_INFO_LENGTH_MISMATCH );
00538 }
00539
00540
try {
00541
00542 SessionId = *(PULONG)TokenInformation;
00543
00544 } except(
EXCEPTION_EXECUTE_HANDLER) {
00545
ObDereferenceObject(
Token );
00546
return GetExceptionCode();
00547 }
00548
00549
00550
00551
00552
if ( !
SeSinglePrivilegeCheck(
SeTcbPrivilege,PreviousMode) ) {
00553
ObDereferenceObject(
Token );
00554
return( STATUS_PRIVILEGE_NOT_HELD );
00555 }
00556
00557
00558
00559
00560
SeSetSessionIdToken( (PACCESS_TOKEN)
Token,
00561 SessionId );
00562
00563
ObDereferenceObject(
Token );
00564
return( STATUS_SUCCESS );
00565 }
00566
00567 }
00568
00569
ASSERT(
TRUE ==
FALSE );
00570
return( STATUS_INVALID_PARAMETER );
00571
00572 }
00573
00574
00575
VOID
00576 SepFreePrimaryGroup(
00577 IN PTOKEN Token
00578 )
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600 {
00601
PAGED_CODE();
00602
00603
00604
00605
00606
00607
Token->DynamicAvailable +=
SeLengthSid(
Token->PrimaryGroup );
00608
00609
00610
00611
00612
00613
00614
00615
if (ARGUMENT_PRESENT(
Token->DefaultDacl)) {
00616
if (
Token->DynamicPart != (PULONG)(
Token->DefaultDacl)) {
00617
00618 RtlMoveMemory(
00619 (PVOID)(
Token->DynamicPart),
00620 (PVOID)(
Token->DefaultDacl),
00621
Token->DefaultDacl->AclSize
00622 );
00623
00624
Token->DefaultDacl = (PACL)(
Token->DynamicPart);
00625
00626 }
00627 }
00628
00629
return;
00630
00631 }
00632
00633
00634
VOID
00635 SepFreeDefaultDacl(
00636 IN PTOKEN Token
00637 )
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 {
00660 ULONG PrimaryGroupSize;
00661
00662
PAGED_CODE();
00663
00664
00665
00666
00667
00668
if (ARGUMENT_PRESENT(
Token->DefaultDacl)) {
00669
00670
Token->DynamicAvailable +=
Token->DefaultDacl->AclSize;
00671
Token->DefaultDacl =
NULL;
00672
00673 }
00674
00675
00676
00677
00678
00679
00680
if (
Token->DynamicPart != (PULONG)(
Token->PrimaryGroup)) {
00681
00682 PrimaryGroupSize =
SeLengthSid(
Token->PrimaryGroup );
00683
00684 RtlMoveMemory(
00685 (PVOID)(
Token->DynamicPart),
00686 (PVOID)(
Token->PrimaryGroup),
00687 PrimaryGroupSize
00688 );
00689
00690
Token->PrimaryGroup = (PSID)(
Token->DynamicPart);
00691 }
00692
00693
return;
00694 }
00695
00696
VOID
00697 SepAppendPrimaryGroup(
00698 IN PTOKEN Token,
00699 IN PSID PSid
00700 )
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726 {
00727 ULONG_PTR NextFree;
00728 ULONG SidSize;
00729
00730
PAGED_CODE();
00731
00732
00733
00734
00735
00736
00737
00738
if (ARGUMENT_PRESENT(
Token->DefaultDacl)) {
00739
00740
00741
00742
00743 NextFree = (ULONG_PTR)(
Token->DynamicPart) +
Token->DefaultDacl->AclSize;
00744
00745 }
else {
00746
00747 NextFree = (ULONG_PTR)(
Token->DynamicPart);
00748
00749 }
00750
00751
00752
00753
00754
00755
00756 SidSize =
SeLengthSid( PSid );
00757
00758 RtlCopyMemory(
00759 (PVOID)NextFree,
00760 (PVOID)PSid,
00761 SidSize
00762 );
00763
00764
Token->PrimaryGroup = (PSID)NextFree;
00765
00766
00767
00768
00769
00770
ASSERT( SidSize <= (Token->DynamicAvailable) );
00771
Token->DynamicAvailable -= SidSize;
00772
00773
return;
00774
00775 }
00776
00777
VOID
00778 SepAppendDefaultDacl(
00779 IN PTOKEN Token,
00780 IN PACL PAcl
00781 )
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807 {
00808 ULONG_PTR NextFree;
00809 ULONG AclSize;
00810
00811
PAGED_CODE();
00812
00813
00814
00815
00816
00817
00818
00819
ASSERT(ARGUMENT_PRESENT(
Token->PrimaryGroup));
00820
00821 NextFree = (ULONG_PTR)(
Token->DynamicPart) +
SeLengthSid(
Token->PrimaryGroup);
00822
00823
00824
00825
00826
00827 AclSize = (ULONG)(PAcl->AclSize);
00828
00829
00830 RtlCopyMemory(
00831 (PVOID)NextFree,
00832 (PVOID)PAcl,
00833 AclSize
00834 );
00835
00836
Token->DefaultDacl = (PACL)NextFree;
00837
00838
00839
00840
00841
00842
ASSERT( AclSize <= (Token->DynamicAvailable) );
00843
Token->DynamicAvailable -= AclSize;
00844
00845
return;
00846
00847 }
00848
00849
00850
NTSTATUS
00851 SeSetSessionIdToken(
00852 PACCESS_TOKEN Token,
00853 ULONG SessionId
00854 )
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875 {
00876
00877
00878
00879
00880
00881
00882
SepAcquireTokenWriteLock(
Token );
00883
00884 ((
PTOKEN)
Token)->SessionId = SessionId;
00885
00886
SepReleaseTokenWriteLock(
Token,
TRUE );
00887
00888
return( STATUS_SUCCESS );
00889 }