00047 :
00048
00049 Modify information in a specified token.
00050
00051 Arguments:
00052
00053 TokenHandle - Provides a handle to
the token to operate on.
00054
00055 TokenInformationClass - The token information
class being set.
00056
00057 TokenInformation - The buffer containing
the new values for
the
00058 specified class of information. The buffer must be aligned
00059 on at least a longword boundary. The actual structures
00060 provided are dependent upon
the information class specified,
00061 as defined in
the TokenInformationClass parameter
00062 description.
00063
00064 TokenInformation Format By Information Class:
00065
00066 TokenUser => This value
is not a valid value for this API.
00067 The User
ID may not be replaced.
00068
00069 TokenGroups => This value
is not a valid value for this
00070 API. The
Group IDs may not be replaced. However, groups
00071 may be enabled and disabled using
NtAdjustGroupsToken().
00072
00073 TokenPrivileges => This value
is not a valid value for
00074 this API. Privilege information may not be replaced.
00075 However, privileges may be explicitly enabled and disabled
00076 using
the NtAdjustPrivilegesToken API.
00077
00078 TokenOwner => TOKEN_OWNER data structure.
00079 TOKEN_ADJUST_DEFAULT access
is needed to replace this
00080 information in a token. The owner values that may be
00081 specified are restricted to
the user and group IDs with an
00082 attribute indicating they may be assigned as
the owner of
00083 objects.
00084
00085 TokenPrimaryGroup => TOKEN_PRIMARY_GROUP data structure.
00086 TOKEN_ADJUST_DEFAULT access
is needed to replace this
00087 information in a token. The primary group values that may
00088 be specified are restricted to be one of
the group IDs
00089 already in
the token.
00090
00091 TokenDefaultDacl => TOKEN_DEFAULT_DACL data structure.
00092 TOKEN_ADJUST_DEFAULT access
is needed to replace this
00093 information in a token. The ACL provided as a new default
00094 discretionary ACL
is not validated for structural
00095 correctness or consistency.
00096
00097 TokenSource => This value
is not a valid value for this
00098 API. The source name and context handle may not be
00099 replaced.
00100
00101 TokenStatistics => This value
is not a valid value for this
00102 API. The statistics of a token are read-
only.
00103
00104 TokenInformationLength - Indicates
the length, in bytes, of
the
00105 TokenInformation buffer. This
is only the length of
the primary
00106 buffer. All extensions of
the primary buffer are self describing.
00107
00108 Return Value:
00109
00110 STATUS_SUCCESS - The operation was successful.
00111
00112 STATUS_INVALID_OWNER - The
ID specified to be an owner (or
00113 default owner)
is not one
the caller may assign as
the owner
00114 of an object.
00115
00116 STATUS_INVALID_INFO_CLASS - The specified information class
is
00117 not one that may be specified in this API.
00118
00119 STATUS_ALLOTTED_SPACE_EXCEEDED - The space allotted for storage
00120 of
the default discretionary access
control and
the primary
00121 group
ID is not large enough to accept
the new value of one
00122 of these fields.
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 }