test: tokenqry.c Source File

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

# tokenqry.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1989  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     Tokenqry.c
    00008
    00009 Abstract:
    00010
    00011     This module implements the QUERY function for the executive
    00012     token object.
    00013
    00014 Author:
    00015
    00016     Jim Kelly (JimK) 15-June-1990
    00017
    00018
    00019 Revision History:
    00020
    00021 --*/
    00022
    00023 #include "sep.h"
    00024 #include "tokenp.h"
    00025
    00026 #ifdef ALLOC_PRAGMA
    00027 #pragma alloc_text(PAGE,NtQueryInformationToken)
    00028 #pragma alloc_text(PAGE,SeQueryAuthenticationIdToken)
    00029 #pragma alloc_text(PAGE,SeQueryInformationToken)
    00030 #endif
    00031
    00032
    00033 NTSTATUS
    00034 NtQueryInformationToken (
    00035     IN HANDLE TokenHandle,
    00036     IN TOKEN_INFORMATION_CLASS TokenInformationClass,
    00037     OUT PVOID TokenInformation,
    00038     IN ULONG TokenInformationLength,
    00039     OUT PULONG ReturnLength
    00040     )
    00041
    00042 /*++
    00043
    00044
    00045 Routine Description:
    00046
    00047     Retrieve information about a specified token.
    00048
    00049 Arguments:
    00050
    00051     TokenHandle - Provides a handle to the token to operate on.
    00052
    00053     TokenInformationClass - The token information class about which
    00054         to retrieve information.
    00055
    00056     TokenInformation - The buffer to receive the requested class of
    00057         information.  The buffer must be aligned on at least a
    00058         longword boundary.  The actual structures returned are
    00059         dependent upon the information class requested, as defined in
    00060         the TokenInformationClass parameter description.
    00061
    00062         TokenInformation Format By Information Class:
    00063
    00064            TokenUser => TOKEN_USER data structure.  TOKEN_QUERY
    00065            access is needed to retrieve this information about a
    00066            token.
    00067
    00068            TokenGroups => TOKEN_GROUPS data structure.  TOKEN_QUERY
    00069            access is needed to retrieve this information about a
    00070            token.
    00071
    00072            TokenPrivileges => TOKEN_PRIVILEGES data structure.
    00073            TOKEN_QUERY access is needed to retrieve this information
    00074            about a token.
    00075
    00076            TokenOwner => TOKEN_OWNER data structure.  TOKEN_QUERY
    00077            access is needed to retrieve this information about a
    00078            token.
    00079
    00080            TokenPrimaryGroup => TOKEN_PRIMARY_GROUP data structure.
    00081            TOKEN_QUERY access is needed to retrieve this information
    00082            about a token.
    00083
    00084            TokenDefaultDacl => TOKEN_DEFAULT_DACL data structure.
    00085            TOKEN_QUERY access is needed to retrieve this information
    00086            about a token.
    00087
    00088            TokenSource => TOKEN_SOURCE data structure.
    00089            TOKEN_QUERY_SOURCE access is needed to retrieve this
    00090            information about a token.
    00091
    00092            TokenType => TOKEN_TYPE data structure.
    00093            TOKEN_QUERY access is needed to retrieve this information
    00094            about a token.
    00095
    00096            TokenStatistics => TOKEN_STATISTICS data structure.
    00097            TOKEN_QUERY access is needed to retrieve this
    00098            information about a token.
    00099
    00100            TokenGroups => TOKEN_GROUPS data structure.  TOKEN_QUERY
    00101            access is needed to retrieve this information about a
    00102            token.
    00103
    00104     TokenInformationLength - Indicates the length, in bytes, of the
    00105         TokenInformation buffer.
    00106
    00107     ReturnLength - This OUT parameter receives the actual length of
    00108         the requested information.  If this value is larger than that
    00109         provided by the TokenInformationLength parameter, then the
    00110         buffer provided to receive the requested information is not
    00111         large enough to hold that data and no data is returned.
    00112
    00113         If the queried class is TokenDefaultDacl and there is no
    00114         default Dacl established for the token, then the return
    00115         length will be returned as zero, and no data will be returned.
    00116
    00117 Return Value:
    00118
    00119     STATUS_SUCCESS - Indicates the operation was successful.
    00120
    00121     STATUS_BUFFER_TOO_SMALL - if the requested information did not
    00122         fit in the provided output buffer.  In this case, the
    00123         ReturnLength OUT parameter contains the number of bytes
    00124         actually needed to store the requested information.
    00125
    00126 --*/
    00127 {
    00128
    00129     KPROCESSOR_MODE PreviousMode;
    00130     NTSTATUS Status;
    00131
    00132     PTOKEN Token;
    00133
    00134     ULONG RequiredLength;
    00135     ULONG Index;
    00136
    00137     PTOKEN_TYPE LocalType;
    00138     PTOKEN_USER LocalUser;
    00139     PTOKEN_GROUPS LocalGroups;
    00140     PTOKEN_PRIVILEGES LocalPrivileges;
    00141     PTOKEN_OWNER LocalOwner;
    00142     PTOKEN_PRIMARY_GROUP LocalPrimaryGroup;
    00143     PTOKEN_DEFAULT_DACL LocalDefaultDacl;
    00144     PTOKEN_SOURCE LocalSource;
    00145     PSECURITY_IMPERSONATION_LEVEL LocalImpersonationLevel;
    00146     PTOKEN_STATISTICS LocalStatistics;
    00147
    00148     PSID PSid;
    00149     PACL PAcl;
    00150
    00151     PVOID Ignore;
    00152     ULONG SessionId;
    00153
    00154     PAGED_CODE();
    00155
    00156     //
    00157     // Get previous processor mode and probe output argument if necessary.
    00158     //
    00159
    00160     PreviousMode = KeGetPreviousMode();
    00161     if (PreviousMode != KernelMode) {
    00162         try {
    00163
    00164             ProbeForWrite(
    00165                 TokenInformation,
    00166                 TokenInformationLength,
    00167                 sizeof(ULONG)
    00168                 );
    00169
    00170             ProbeForWriteUlong(ReturnLength);
    00171
    00172         } except(EXCEPTION_EXECUTE_HANDLER) {
    00173             return GetExceptionCode();
    00174         }
    00175     }
    00176
    00177     //
    00178     // Case on information class.
    00179     //
    00180
    00181     switch ( TokenInformationClass ) {
    00182
    00183     case TokenUser:
    00184
    00185         LocalUser = (PTOKEN_USER)TokenInformation;
    00186
    00187         Status = ObReferenceObjectByHandle(
    00188                  TokenHandle,           // Handle
    00189                  TOKEN_QUERY,           // DesiredAccess
    00190                  SepTokenObjectType,    // ObjectType
    00191                  PreviousMode,          // AccessMode
    00192                  (PVOID *)&Token,       // Object
    00193                  NULL                   // GrantedAccess
    00194                  );
    00195
    00196         if ( !NT_SUCCESS(Status) ) {
    00197             return Status;
    00198         }
    00199
    00200         //
    00201         //  Gain exclusive access to the token.
    00202         //
    00203
    00204         SepAcquireTokenReadLock( Token );
    00205
    00206
    00207
    00208         //
    00209         // Return the length required now in case not enough buffer
    00210         // was provided by the caller and we have to return an error.
    00211         //
    00212
    00213         RequiredLength = SeLengthSid( Token->UserAndGroups[0].Sid) +
    00214                          (ULONG)sizeof( TOKEN_USER );
    00215
    00216         try {
    00217
    00218             *ReturnLength = RequiredLength;
    00219
    00220         } except(EXCEPTION_EXECUTE_HANDLER) {
    00221
    00222             SepReleaseTokenReadLock( Token );
    00223             ObDereferenceObject( Token );
    00224             return GetExceptionCode();
    00225         }
    00226
    00227         if ( TokenInformationLength < RequiredLength ) {
    00228
    00229             SepReleaseTokenReadLock( Token );
    00230             ObDereferenceObject( Token );
    00231             return STATUS_BUFFER_TOO_SMALL;
    00232
    00233         }
    00234
    00235         //
    00236         // Return the user SID
    00237         //
    00238
    00239         try {
    00240
    00241             //
    00242             //  Put SID immediately following TOKEN_USER data structure
    00243             //
    00244             PSid = (PSID)( (ULONG_PTR)LocalUser + (ULONG)sizeof(TOKEN_USER) );
    00245
    00246             RtlCopySidAndAttributesArray(
    00247                 1,
    00248                 Token->UserAndGroups,
    00249                 RequiredLength,
    00250                 &(LocalUser->User),
    00251                 PSid,
    00252                 ((PSID *)&Ignore),
    00253                 ((PULONG)&Ignore)
    00254                 );
    00255
    00256         } except(EXCEPTION_EXECUTE_HANDLER) {
    00257
    00258             SepReleaseTokenReadLock( Token );
    00259             ObDereferenceObject( Token );
    00260             return GetExceptionCode();
    00261         }
    00262
    00263
    00264         SepReleaseTokenReadLock( Token );
    00265         ObDereferenceObject( Token );
    00266         return STATUS_SUCCESS;
    00267
    00268     case TokenGroups:
    00269
    00270         LocalGroups = (PTOKEN_GROUPS)TokenInformation;
    00271
    00272         Status = ObReferenceObjectByHandle(
    00273                  TokenHandle,           // Handle
    00274                  TOKEN_QUERY,           // DesiredAccess
    00275                  SepTokenObjectType,    // ObjectType
    00276                  PreviousMode,          // AccessMode
    00277                  (PVOID *)&Token,       // Object
    00278                  NULL                   // GrantedAccess
    00279                  );
    00280
    00281         if ( !NT_SUCCESS(Status) ) {
    00282             return Status;
    00283         }
    00284
    00285         //
    00286         //  Gain exclusive access to the token.
    00287         //
    00288
    00289         SepAcquireTokenReadLock( Token );
    00290
    00291         //
    00292         // Figure out how much space is needed to return the group SIDs.
    00293         // That's the size of TOKEN_GROUPS (without any array entries)
    00294         // plus the size of an SID_AND_ATTRIBUTES times the number of groups.
    00295         // The number of groups is Token->UserAndGroups-1 (since the count
    00296         // includes the user ID).  Then the lengths of each individual group
    00297         // must be added.
    00298         //
    00299
    00300         RequiredLength = (ULONG)sizeof(TOKEN_GROUPS) +
    00301                          ((Token->UserAndGroupCount - ANYSIZE_ARRAY - 1) *
    00302                          ((ULONG)sizeof(SID_AND_ATTRIBUTES)) );
    00303
    00304         Index = 1;
    00305         while (Index < Token->UserAndGroupCount) {
    00306
    00307             RequiredLength += SeLengthSid( Token->UserAndGroups[Index].Sid );
    00308
    00309             Index += 1;
    00310
    00311         } // endwhile
    00312
    00313         //
    00314         // Return the length required now in case not enough buffer
    00315         // was provided by the caller and we have to return an error.
    00316         //
    00317
    00318         try {
    00319
    00320             *ReturnLength = RequiredLength;
    00321
    00322         } except(EXCEPTION_EXECUTE_HANDLER) {
    00323
    00324             SepReleaseTokenReadLock( Token );
    00325             ObDereferenceObject( Token );
    00326             return GetExceptionCode();
    00327         }
    00328
    00329         if ( TokenInformationLength < RequiredLength ) {
    00330
    00331             SepReleaseTokenReadLock( Token );
    00332             ObDereferenceObject( Token );
    00333             return STATUS_BUFFER_TOO_SMALL;
    00334
    00335         }
    00336
    00337         //
    00338         // Now copy the groups.
    00339         //
    00340
    00341         try {
    00342
    00343             LocalGroups->GroupCount = Token->UserAndGroupCount - 1;
    00344
    00345             PSid = (PSID)( (ULONG_PTR)LocalGroups +
    00346                            (ULONG)sizeof(TOKEN_GROUPS) +
    00347                            (   (Token->UserAndGroupCount - ANYSIZE_ARRAY - 1) *
    00348                                (ULONG)sizeof(SID_AND_ATTRIBUTES) )
    00349                          );
    00350
    00351             RtlCopySidAndAttributesArray(
    00352                 (ULONG)(Token->UserAndGroupCount - 1),
    00353                 &(Token->UserAndGroups[1]),
    00354                 RequiredLength,
    00355                 LocalGroups->Groups,
    00356                 PSid,
    00357                 ((PSID *)&Ignore),
    00358                 ((PULONG)&Ignore)
    00359                 );
    00360
    00361         } except(EXCEPTION_EXECUTE_HANDLER) {
    00362
    00363             SepReleaseTokenReadLock( Token );
    00364             ObDereferenceObject( Token );
    00365             return GetExceptionCode();
    00366         }
    00367
    00368
    00369         SepReleaseTokenReadLock( Token );
    00370         ObDereferenceObject( Token );
    00371         return STATUS_SUCCESS;
    00372
    00373     case TokenRestrictedSids:
    00374
    00375         LocalGroups = (PTOKEN_GROUPS)TokenInformation;
    00376
    00377         Status = ObReferenceObjectByHandle(
    00378                  TokenHandle,           // Handle
    00379                  TOKEN_QUERY,           // DesiredAccess
    00380                  SepTokenObjectType,    // ObjectType
    00381                  PreviousMode,          // AccessMode
    00382                  (PVOID *)&Token,       // Object
    00383                  NULL                   // GrantedAccess
    00384                  );
    00385
    00386         if ( !NT_SUCCESS(Status) ) {
    00387             return Status;
    00388         }
    00389
    00390         //
    00391         //  Gain exclusive access to the token.
    00392         //
    00393
    00394         SepAcquireTokenReadLock( Token );
    00395
    00396         //
    00397         // Figure out how much space is needed to return the group SIDs.
    00398         // That's the size of TOKEN_GROUPS (without any array entries)
    00399         // plus the size of an SID_AND_ATTRIBUTES times the number of groups.
    00400         // The number of groups is Token->UserAndGroups-1 (since the count
    00401         // includes the user ID).  Then the lengths of each individual group
    00402         // must be added.
    00403         //
    00404
    00405         RequiredLength = (ULONG)sizeof(TOKEN_GROUPS) +
    00406                          ((Token->RestrictedSidCount) *
    00407                          ((ULONG)sizeof(SID_AND_ATTRIBUTES)) -
    00408                          ANYSIZE_ARRAY * sizeof(SID_AND_ATTRIBUTES) );
    00409
    00410         Index = 0;
    00411         while (Index < Token->RestrictedSidCount) {
    00412
    00413             RequiredLength += SeLengthSid( Token->RestrictedSids[Index].Sid );
    00414
    00415             Index += 1;
    00416
    00417         } // endwhile
    00418
    00419         //
    00420         // Return the length required now in case not enough buffer
    00421         // was provided by the caller and we have to return an error.
    00422         //
    00423
    00424         try {
    00425
    00426             *ReturnLength = RequiredLength;
    00427
    00428         } except(EXCEPTION_EXECUTE_HANDLER) {
    00429
    00430             SepReleaseTokenReadLock( Token );
    00431             ObDereferenceObject( Token );
    00432             return GetExceptionCode();
    00433         }
    00434
    00435         if ( TokenInformationLength < RequiredLength ) {
    00436
    00437             SepReleaseTokenReadLock( Token );
    00438             ObDereferenceObject( Token );
    00439             return STATUS_BUFFER_TOO_SMALL;
    00440
    00441         }
    00442
    00443         //
    00444         // Now copy the groups.
    00445         //
    00446
    00447         try {
    00448
    00449             LocalGroups->GroupCount = Token->RestrictedSidCount;
    00450
    00451             PSid = (PSID)( (ULONG_PTR)LocalGroups +
    00452                            (ULONG)sizeof(TOKEN_GROUPS) +
    00453                            (   (Token->RestrictedSidCount ) *
    00454                                (ULONG)sizeof(SID_AND_ATTRIBUTES) -
    00455                                ANYSIZE_ARRAY * sizeof(SID_AND_ATTRIBUTES) )
    00456                          );
    00457
    00458             RtlCopySidAndAttributesArray(
    00459                 (ULONG)(Token->RestrictedSidCount),
    00460                 Token->RestrictedSids,
    00461                 RequiredLength,
    00462                 LocalGroups->Groups,
    00463                 PSid,
    00464                 ((PSID *)&Ignore),
    00465                 ((PULONG)&Ignore)
    00466                 );
    00467
    00468         } except(EXCEPTION_EXECUTE_HANDLER) {
    00469
    00470             SepReleaseTokenReadLock( Token );
    00471             ObDereferenceObject( Token );
    00472             return GetExceptionCode();
    00473         }
    00474
    00475
    00476         SepReleaseTokenReadLock( Token );
    00477         ObDereferenceObject( Token );
    00478         return STATUS_SUCCESS;
    00479
    00480     case TokenPrivileges:
    00481
    00482         LocalPrivileges = (PTOKEN_PRIVILEGES)TokenInformation;
    00483
    00484         Status = ObReferenceObjectByHandle(
    00485                  TokenHandle,           // Handle
    00486                  TOKEN_QUERY,           // DesiredAccess
    00487                  SepTokenObjectType,    // ObjectType
    00488                  PreviousMode,          // AccessMode
    00489                  (PVOID *)&Token,       // Object
    00490                  NULL                   // GrantedAccess
    00491                  );
    00492
    00493         if ( !NT_SUCCESS(Status) ) {
    00494             return Status;
    00495         }
    00496
    00497         //
    00498         //  Gain exclusive access to the token to prevent changes
    00499         //  from occuring to the privileges.
    00500         //
    00501
    00502         SepAcquireTokenReadLock( Token );
    00503
    00504
    00505         //
    00506         // Return the length required now in case not enough buffer
    00507         // was provided by the caller and we have to return an error.
    00508         //
    00509
    00510         RequiredLength = (ULONG)sizeof(TOKEN_PRIVILEGES) +
    00511                          ((Token->PrivilegeCount - ANYSIZE_ARRAY) *
    00512                          ((ULONG)sizeof(LUID_AND_ATTRIBUTES)) );
    00513
    00514
    00515         try {
    00516
    00517             *ReturnLength = RequiredLength;
    00518
    00519         } except(EXCEPTION_EXECUTE_HANDLER) {
    00520
    00521             SepReleaseTokenReadLock( Token );
    00522             ObDereferenceObject( Token );
    00523             return GetExceptionCode();
    00524         }
    00525
    00526         if ( TokenInformationLength < RequiredLength ) {
    00527
    00528             SepReleaseTokenReadLock( Token );
    00529             ObDereferenceObject( Token );
    00530             return STATUS_BUFFER_TOO_SMALL;
    00531
    00532         }
    00533
    00534         //
    00535         // Return the token privileges.
    00536         //
    00537
    00538         try {
    00539
    00540             LocalPrivileges->PrivilegeCount = Token->PrivilegeCount;
    00541
    00542             RtlCopyLuidAndAttributesArray(
    00543                 Token->PrivilegeCount,
    00544                 Token->Privileges,
    00545                 LocalPrivileges->Privileges
    00546                 );
    00547
    00548         } except(EXCEPTION_EXECUTE_HANDLER) {
    00549
    00550             SepReleaseTokenReadLock( Token );
    00551             ObDereferenceObject( Token );
    00552             return GetExceptionCode();
    00553         }
    00554
    00555
    00556         SepReleaseTokenReadLock( Token );
    00557         ObDereferenceObject( Token );
    00558         return STATUS_SUCCESS;
    00559
    00560     case TokenOwner:
    00561
    00562         LocalOwner = (PTOKEN_OWNER)TokenInformation;
    00563
    00564         Status = ObReferenceObjectByHandle(
    00565                  TokenHandle,           // Handle
    00566                  TOKEN_QUERY,           // DesiredAccess
    00567                  SepTokenObjectType,    // ObjectType
    00568                  PreviousMode,          // AccessMode
    00569                  (PVOID *)&Token,       // Object
    00570                  NULL                   // GrantedAccess
    00571                  );
    00572
    00573         if ( !NT_SUCCESS(Status) ) {
    00574             return Status;
    00575         }
    00576
    00577         //
    00578         //  Gain exclusive access to the token to prevent changes
    00579         //  from occuring to the owner.
    00580         //
    00581
    00582         SepAcquireTokenReadLock( Token );
    00583
    00584         //
    00585         // Return the length required now in case not enough buffer
    00586         // was provided by the caller and we have to return an error.
    00587         //
    00588
    00589         PSid = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
    00590         RequiredLength = (ULONG)sizeof(TOKEN_OWNER) +
    00591                          SeLengthSid( PSid );
    00592
    00593         try {
    00594
    00595             *ReturnLength = RequiredLength;
    00596
    00597         } except(EXCEPTION_EXECUTE_HANDLER) {
    00598
    00599             SepReleaseTokenReadLock( Token );
    00600             ObDereferenceObject( Token );
    00601             return GetExceptionCode();
    00602         }
    00603
    00604         if ( TokenInformationLength < RequiredLength ) {
    00605
    00606             SepReleaseTokenReadLock( Token );
    00607             ObDereferenceObject( Token );
    00608             return STATUS_BUFFER_TOO_SMALL;
    00609
    00610         }
    00611
    00612         //
    00613         // Return the owner SID
    00614         //
    00615
    00616         PSid = (PSID)((ULONG_PTR)LocalOwner +
    00617                       (ULONG)sizeof(TOKEN_OWNER));
    00618
    00619         try {
    00620
    00621             LocalOwner->Owner = PSid;
    00622
    00623             Status = RtlCopySid(
    00624                          (RequiredLength - (ULONG)sizeof(TOKEN_OWNER)),
    00625                          PSid,
    00626                          Token->UserAndGroups[Token->DefaultOwnerIndex].Sid
    00627                          );
    00628
    00629             ASSERT( NT_SUCCESS(Status) );
    00630
    00631         } except(EXCEPTION_EXECUTE_HANDLER) {
    00632
    00633             SepReleaseTokenReadLock( Token );
    00634             ObDereferenceObject( Token );
    00635             return GetExceptionCode();
    00636         }
    00637
    00638
    00639         SepReleaseTokenReadLock( Token );
    00640         ObDereferenceObject( Token );
    00641         return STATUS_SUCCESS;
    00642
    00643     case TokenPrimaryGroup:
    00644
    00645         LocalPrimaryGroup = (PTOKEN_PRIMARY_GROUP)TokenInformation;
    00646
    00647         Status = ObReferenceObjectByHandle(
    00648                  TokenHandle,           // Handle
    00649                  TOKEN_QUERY,           // DesiredAccess
    00650                  SepTokenObjectType,    // ObjectType
    00651                  PreviousMode,          // AccessMode
    00652                  (PVOID *)&Token,       // Object
    00653                  NULL                   // GrantedAccess
    00654                  );
    00655
    00656         if ( !NT_SUCCESS(Status) ) {
    00657             return Status;
    00658         }
    00659
    00660         //
    00661         //  Gain exclusive access to the token to prevent changes
    00662         //  from occuring to the owner.
    00663         //
    00664
    00665         SepAcquireTokenReadLock( Token );
    00666
    00667         //
    00668         // Return the length required now in case not enough buffer
    00669         // was provided by the caller and we have to return an error.
    00670         //
    00671
    00672         RequiredLength = (ULONG)sizeof(TOKEN_PRIMARY_GROUP) +
    00673                          SeLengthSid( Token->PrimaryGroup );
    00674
    00675         try {
    00676
    00677             *ReturnLength = RequiredLength;
    00678
    00679         } except(EXCEPTION_EXECUTE_HANDLER) {
    00680
    00681             SepReleaseTokenReadLock( Token );
    00682             ObDereferenceObject( Token );
    00683             return GetExceptionCode();
    00684         }
    00685
    00686         if ( TokenInformationLength < RequiredLength ) {
    00687
    00688             SepReleaseTokenReadLock( Token );
    00689             ObDereferenceObject( Token );
    00690             return STATUS_BUFFER_TOO_SMALL;
    00691
    00692         }
    00693
    00694         //
    00695         // Return the primary group SID
    00696         //
    00697
    00698         PSid = (PSID)((ULONG_PTR)LocalPrimaryGroup +
    00699                       (ULONG)sizeof(TOKEN_PRIMARY_GROUP));
    00700
    00701         try {
    00702
    00703             LocalPrimaryGroup->PrimaryGroup = PSid;
    00704
    00705             Status = RtlCopySid( (RequiredLength - (ULONG)sizeof(TOKEN_PRIMARY_GROUP)),
    00706                                  PSid,
    00707                                  Token->PrimaryGroup
    00708                                  );
    00709
    00710             ASSERT( NT_SUCCESS(Status) );
    00711
    00712         } except(EXCEPTION_EXECUTE_HANDLER) {
    00713
    00714             SepReleaseTokenReadLock( Token );
    00715             ObDereferenceObject( Token );
    00716             return GetExceptionCode();
    00717         }
    00718
    00719
    00720         SepReleaseTokenReadLock( Token );
    00721         ObDereferenceObject( Token );
    00722         return STATUS_SUCCESS;
    00723
    00724     case TokenDefaultDacl:
    00725
    00726         LocalDefaultDacl = (PTOKEN_DEFAULT_DACL)TokenInformation;
    00727
    00728         Status = ObReferenceObjectByHandle(
    00729                  TokenHandle,           // Handle
    00730                  TOKEN_QUERY,           // DesiredAccess
    00731                  SepTokenObjectType,    // ObjectType
    00732                  PreviousMode,          // AccessMode
    00733                  (PVOID *)&Token,       // Object
    00734                  NULL                   // GrantedAccess
    00735                  );
    00736
    00737         if ( !NT_SUCCESS(Status) ) {
    00738             return Status;
    00739         }
    00740
    00741         //
    00742         //  Gain exclusive access to the token to prevent changes
    00743         //  from occuring to the owner.
    00744         //
    00745
    00746         SepAcquireTokenReadLock( Token );
    00747
    00748
    00749         //
    00750         // Return the length required now in case not enough buffer
    00751         // was provided by the caller and we have to return an error.
    00752         //
    00753
    00754         RequiredLength = (ULONG)sizeof(TOKEN_DEFAULT_DACL);
    00755
    00756         if (ARGUMENT_PRESENT(Token->DefaultDacl)) {
    00757
    00758             RequiredLength += Token->DefaultDacl->AclSize;
    00759
    00760         }
    00761
    00762         try {
    00763
    00764             *ReturnLength = RequiredLength;
    00765
    00766         } except(EXCEPTION_EXECUTE_HANDLER) {
    00767
    00768             SepReleaseTokenReadLock( Token );
    00769             ObDereferenceObject( Token );
    00770             return GetExceptionCode();
    00771         }
    00772
    00773         if ( TokenInformationLength < RequiredLength ) {
    00774
    00775             SepReleaseTokenReadLock( Token );
    00776             ObDereferenceObject( Token );
    00777             return STATUS_BUFFER_TOO_SMALL;
    00778
    00779         }
    00780
    00781         //
    00782         // Return the default Dacl
    00783         //
    00784
    00785         PAcl = (PACL)((ULONG_PTR)LocalDefaultDacl +
    00786                       (ULONG)sizeof(TOKEN_DEFAULT_DACL));
    00787
    00788         try {
    00789
    00790             if (ARGUMENT_PRESENT(Token->DefaultDacl)) {
    00791
    00792                 LocalDefaultDacl->DefaultDacl = PAcl;
    00793
    00794                 RtlCopyMemory( (PVOID)PAcl,
    00795                                (PVOID)Token->DefaultDacl,
    00796                                Token->DefaultDacl->AclSize
    00797                                );
    00798             } else {
    00799
    00800                 LocalDefaultDacl->DefaultDacl = NULL;
    00801
    00802             }
    00803
    00804         } except(EXCEPTION_EXECUTE_HANDLER) {
    00805
    00806             SepReleaseTokenReadLock( Token );
    00807             ObDereferenceObject( Token );
    00808             return GetExceptionCode();
    00809         }
    00810
    00811
    00812         SepReleaseTokenReadLock( Token );
    00813         ObDereferenceObject( Token );
    00814         return STATUS_SUCCESS;
    00815
    00816
    00817
    00818     case TokenSource:
    00819
    00820         LocalSource = (PTOKEN_SOURCE)TokenInformation;
    00821
    00822         Status = ObReferenceObjectByHandle(
    00823                  TokenHandle,           // Handle
    00824                  TOKEN_QUERY_SOURCE,    // DesiredAccess
    00825                  SepTokenObjectType,    // ObjectType
    00826                  PreviousMode,          // AccessMode
    00827                  (PVOID *)&Token,       // Object
    00828                  NULL                   // GrantedAccess
    00829                  );
    00830
    00831         if ( !NT_SUCCESS(Status) ) {
    00832             return Status;
    00833         }
    00834
    00835         //
    00836         // The type of a token can not be changed, so
    00837         // exclusive access to the token is not necessary.
    00838         //
    00839
    00840         //
    00841         // Return the length required now in case not enough buffer
    00842         // was provided by the caller and we have to return an error.
    00843         //
    00844
    00845         RequiredLength = (ULONG) sizeof(TOKEN_SOURCE);
    00846
    00847         try {
    00848
    00849             *ReturnLength = RequiredLength;
    00850
    00851         } except(EXCEPTION_EXECUTE_HANDLER) {
    00852
    00853             ObDereferenceObject( Token );
    00854             return GetExceptionCode();
    00855         }
    00856
    00857         if ( TokenInformationLength < RequiredLength ) {
    00858
    00859             ObDereferenceObject( Token );
    00860             return STATUS_BUFFER_TOO_SMALL;
    00861
    00862         }
    00863
    00864
    00865         //
    00866         // Return the token source
    00867         //
    00868
    00869         try {
    00870
    00871             (*LocalSource) = Token->TokenSource;
    00872
    00873         } except(EXCEPTION_EXECUTE_HANDLER) {
    00874
    00875             ObDereferenceObject( Token );
    00876             return GetExceptionCode();
    00877         }
    00878
    00879
    00880         ObDereferenceObject( Token );
    00881         return STATUS_SUCCESS;
    00882
    00883     case TokenType:
    00884
    00885         LocalType = (PTOKEN_TYPE)TokenInformation;
    00886
    00887         Status = ObReferenceObjectByHandle(
    00888                  TokenHandle,           // Handle
    00889                  TOKEN_QUERY,           // DesiredAccess
    00890                  SepTokenObjectType,    // ObjectType
    00891                  PreviousMode,          // AccessMode
    00892                  (PVOID *)&Token,       // Object
    00893                  NULL                   // GrantedAccess
    00894                  );
    00895
    00896         if ( !NT_SUCCESS(Status) ) {
    00897             return Status;
    00898         }
    00899
    00900         //
    00901         // The type of a token can not be changed, so
    00902         // exclusive access to the token is not necessary.
    00903         //
    00904
    00905         //
    00906         // Return the length required now in case not enough buffer
    00907         // was provided by the caller and we have to return an error.
    00908         //
    00909
    00910         RequiredLength = (ULONG) sizeof(TOKEN_TYPE);
    00911
    00912         try {
    00913
    00914             *ReturnLength = RequiredLength;
    00915
    00916         } except(EXCEPTION_EXECUTE_HANDLER) {
    00917
    00918             ObDereferenceObject( Token );
    00919             return GetExceptionCode();
    00920         }
    00921
    00922         if ( TokenInformationLength < RequiredLength ) {
    00923
    00924             ObDereferenceObject( Token );
    00925             return STATUS_BUFFER_TOO_SMALL;
    00926
    00927         }
    00928
    00929
    00930         //
    00931         // Return the token type
    00932         //
    00933
    00934         try {
    00935
    00936             (*LocalType) = Token->TokenType;
    00937
    00938         } except(EXCEPTION_EXECUTE_HANDLER) {
    00939
    00940             ObDereferenceObject( Token );
    00941             return GetExceptionCode();
    00942         }
    00943
    00944
    00945         ObDereferenceObject( Token );
    00946         return STATUS_SUCCESS;
    00947
    00948
    00949     case TokenImpersonationLevel:
    00950
    00951         LocalImpersonationLevel = (PSECURITY_IMPERSONATION_LEVEL)TokenInformation;
    00952
    00953         Status = ObReferenceObjectByHandle(
    00954                  TokenHandle,           // Handle
    00955                  TOKEN_QUERY,           // DesiredAccess
    00956                  SepTokenObjectType,    // ObjectType
    00957                  PreviousMode,          // AccessMode
    00958                  (PVOID *)&Token,       // Object
    00959                  NULL                   // GrantedAccess
    00960                  );
    00961
    00962         if ( !NT_SUCCESS(Status) ) {
    00963             return Status;
    00964         }
    00965
    00966         //
    00967         // The impersonation level of a token can not be changed, so
    00968         // exclusive access to the token is not necessary.
    00969         //
    00970
    00971         //
    00972         //  Make sure the token is an appropriate type to be retrieving
    00973         //  the impersonation level from.
    00974         //
    00975
    00976         if (Token->TokenType != TokenImpersonation) {
    00977
    00978             ObDereferenceObject( Token );
    00979             return STATUS_INVALID_INFO_CLASS;
    00980
    00981         }
    00982
    00983         //
    00984         // Return the length required now in case not enough buffer
    00985         // was provided by the caller and we have to return an error.
    00986         //
    00987
    00988         RequiredLength = (ULONG) sizeof(SECURITY_IMPERSONATION_LEVEL);
    00989
    00990         try {
    00991
    00992             *ReturnLength = RequiredLength;
    00993
    00994         } except(EXCEPTION_EXECUTE_HANDLER) {
    00995
    00996             ObDereferenceObject( Token );
    00997             return GetExceptionCode();
    00998         }
    00999
    01000         if ( TokenInformationLength < RequiredLength ) {
    01001
    01002             ObDereferenceObject( Token );
    01003             return STATUS_BUFFER_TOO_SMALL;
    01004
    01005         }
    01006
    01007
    01008         //
    01009         // Return the impersonation level
    01010         //
    01011
    01012         try {
    01013
    01014             (*LocalImpersonationLevel) = Token->ImpersonationLevel;
    01015
    01016         } except(EXCEPTION_EXECUTE_HANDLER) {
    01017
    01018             ObDereferenceObject( Token );
    01019             return GetExceptionCode();
    01020         }
    01021
    01022
    01023         ObDereferenceObject( Token );
    01024         return STATUS_SUCCESS;
    01025
    01026
    01027     case TokenStatistics:
    01028
    01029         LocalStatistics = (PTOKEN_STATISTICS)TokenInformation;
    01030
    01031         Status = ObReferenceObjectByHandle(
    01032                  TokenHandle,           // Handle
    01033                  TOKEN_QUERY,           // DesiredAccess
    01034                  SepTokenObjectType,    // ObjectType
    01035                  PreviousMode,          // AccessMode
    01036                  (PVOID *)&Token,       // Object
    01037                  NULL                   // GrantedAccess
    01038                  );
    01039
    01040         if ( !NT_SUCCESS(Status) ) {
    01041             return Status;
    01042         }
    01043
    01044         //
    01045         //  Gain exclusive access to the token.
    01046         //
    01047
    01048         SepAcquireTokenReadLock( Token );
    01049
    01050
    01051
    01052         //
    01053         // Return the length required now in case not enough buffer
    01054         // was provided by the caller and we have to return an error.
    01055         //
    01056
    01057         RequiredLength = (ULONG)sizeof( TOKEN_STATISTICS );
    01058
    01059         try {
    01060
    01061             *ReturnLength = RequiredLength;
    01062
    01063         } except(EXCEPTION_EXECUTE_HANDLER) {
    01064
    01065             SepReleaseTokenReadLock( Token );
    01066             ObDereferenceObject( Token );
    01067             return GetExceptionCode();
    01068         }
    01069
    01070         if ( TokenInformationLength < RequiredLength ) {
    01071
    01072             SepReleaseTokenReadLock( Token );
    01073             ObDereferenceObject( Token );
    01074             return STATUS_BUFFER_TOO_SMALL;
    01075
    01076         }
    01077
    01078         //
    01079         // Return the statistics
    01080         //
    01081
    01082         try {
    01083
    01084             LocalStatistics->TokenId            = Token->TokenId;
    01085             LocalStatistics->AuthenticationId   = Token->AuthenticationId;
    01086             LocalStatistics->ExpirationTime     = Token->ExpirationTime;
    01087             LocalStatistics->TokenType          = Token->TokenType;
    01088             LocalStatistics->ImpersonationLevel = Token->ImpersonationLevel;
    01089             LocalStatistics->DynamicCharged     = Token->DynamicCharged;
    01090             LocalStatistics->DynamicAvailable   = Token->DynamicAvailable;
    01091             LocalStatistics->GroupCount         = Token->UserAndGroupCount-1;
    01092             LocalStatistics->PrivilegeCount     = Token->PrivilegeCount;
    01093             LocalStatistics->ModifiedId         = Token->ModifiedId;
    01094
    01095         } except(EXCEPTION_EXECUTE_HANDLER) {
    01096
    01097             SepReleaseTokenReadLock( Token );
    01098             ObDereferenceObject( Token );
    01099             return GetExceptionCode();
    01100         }
    01101
    01102
    01103         SepReleaseTokenReadLock( Token );
    01104         ObDereferenceObject( Token );
    01105         return STATUS_SUCCESS;
    01106
    01107     case TokenSessionId:
    01108
    01109         if ( TokenInformationLength != sizeof(ULONG) )
    01110             return( STATUS_INFO_LENGTH_MISMATCH );
    01111
    01112         Status = ObReferenceObjectByHandle(
    01113                  TokenHandle,           // Handle
    01114                  TOKEN_QUERY,           // DesiredAccess
    01115                  SepTokenObjectType,    // ObjectType
    01116                  PreviousMode,          // AccessMode
    01117                  (PVOID *)&Token,       // Object
    01118                  NULL                   // GrantedAccess
    01119                  );
    01120
    01121         if ( !NT_SUCCESS(Status) ) {
    01122             return Status;
    01123         }
    01124
    01125         //
    01126         // Get SessionId for the token
    01127         //
    01128         SeQuerySessionIdToken( (PACCESS_TOKEN)Token,
    01129                                &SessionId);
    01130
    01131         try {
    01132
    01133             *(PULONG)TokenInformation = SessionId;
    01134             *ReturnLength = sizeof(ULONG);
    01135
    01136         } except(EXCEPTION_EXECUTE_HANDLER) {
    01137             ObDereferenceObject( Token );
    01138             return GetExceptionCode();
    01139         }
    01140
    01141         ObDereferenceObject( Token );
    01142         return( STATUS_SUCCESS );
    01143
    01144     default:
    01145
    01146         return STATUS_INVALID_INFO_CLASS;
    01147     }
    01148 }
    01149
    01150
    01151 NTSTATUS
    01152 SeQueryAuthenticationIdToken(
    01153     IN PACCESS_TOKEN Token,
    01154     OUT PLUID AuthenticationId
    01155     )
    01156
    01157 /*++
    01158
    01159
    01160 Routine Description:
    01161
    01162     Retrieve authentication ID out of the token.
    01163
    01164 Arguments:
    01165
    01166     Token - Referenced pointer to a token.
    01167
    01168     AutenticationId - Receives the token's authentication ID.
    01169
    01170 Return Value:
    01171
    01172     STATUS_SUCCESS - Indicates the operation was successful.
    01173
    01174     This is the only expected status.
    01175
    01176 --*/
    01177 {
    01178     PAGED_CODE();
    01179
    01180     SepAcquireTokenReadLock( ((PTOKEN)Token) );
    01181     (*AuthenticationId) = ((PTOKEN)Token)->AuthenticationId;
    01182     SepReleaseTokenReadLock( ((PTOKEN)Token) );
    01183     return(STATUS_SUCCESS);
    01184 }
    01185
    01186
    01187
    01188 NTSTATUS
    01189 SeQueryInformationToken (
    01190     IN PACCESS_TOKEN AccessToken,
    01191     IN TOKEN_INFORMATION_CLASS TokenInformationClass,
    01192     OUT PVOID *TokenInformation
    01193     )
    01194
    01195 /*++
    01196
    01197
    01198 Routine Description:
    01199
    01200     Retrieve information about a specified token.
    01201
    01202 Arguments:
    01203
    01204     TokenHandle - Provides a handle to the token to operate on.
    01205
    01206     TokenInformationClass - The token information class about which
    01207         to retrieve information.
    01208
    01209     TokenInformation - Receives a pointer to the requested information.
    01210         The actual structures returned are dependent upon the information
    01211         class requested, as defined in the TokenInformationClass parameter
    01212         description.
    01213
    01214         TokenInformation Format By Information Class:
    01215
    01216            TokenUser => TOKEN_USER data structure.  TOKEN_QUERY
    01217            access is needed to retrieve this information about a
    01218            token.
    01219
    01220            TokenGroups => TOKEN_GROUPS data structure.  TOKEN_QUERY
    01221            access is needed to retrieve this information about a
    01222            token.
    01223
    01224            TokenPrivileges => TOKEN_PRIVILEGES data structure.
    01225            TOKEN_QUERY access is needed to retrieve this information
    01226            about a token.
    01227
    01228            TokenOwner => TOKEN_OWNER data structure.  TOKEN_QUERY
    01229            access is needed to retrieve this information about a
    01230            token.
    01231
    01232            TokenPrimaryGroup => TOKEN_PRIMARY_GROUP data structure.
    01233            TOKEN_QUERY access is needed to retrieve this information
    01234            about a token.
    01235
    01236            TokenDefaultDacl => TOKEN_DEFAULT_DACL data structure.
    01237            TOKEN_QUERY access is needed to retrieve this information
    01238            about a token.
    01239
    01240            TokenSource => TOKEN_SOURCE data structure.
    01241            TOKEN_QUERY_SOURCE access is needed to retrieve this
    01242            information about a token.
    01243
    01244            TokenType => TOKEN_TYPE data structure.
    01245            TOKEN_QUERY access is needed to retrieve this information
    01246            about a token.
    01247
    01248            TokenStatistics => TOKEN_STATISTICS data structure.
    01249            TOKEN_QUERY access is needed to retrieve this
    01250            information about a token.
    01251
    01252 Return Value:
    01253
    01254     STATUS_SUCCESS - Indicates the operation was successful.
    01255
    01256 --*/
    01257 {
    01258
    01259     NTSTATUS Status;
    01260
    01261     ULONG RequiredLength;
    01262     ULONG Index;
    01263
    01264     PSID PSid;
    01265     PACL PAcl;
    01266
    01267     PVOID Ignore;
    01268     PTOKEN Token = (PTOKEN)AccessToken;
    01269
    01270     PAGED_CODE();
    01271
    01272     //
    01273     // Case on information class.
    01274     //
    01275
    01276     switch ( TokenInformationClass ) {
    01277
    01278         case TokenUser:
    01279             {
    01280                 PTOKEN_USER LocalUser;
    01281
    01282                 //
    01283                 //  Gain exclusive access to the token.
    01284                 //
    01285
    01286                 SepAcquireTokenReadLock( Token );
    01287
    01288                 //
    01289                 // Return the length required now in case not enough buffer
    01290                 // was provided by the caller and we have to return an error.
    01291                 //
    01292
    01293                 RequiredLength = SeLengthSid( Token->UserAndGroups[0].Sid) +
    01294                                  (ULONG)sizeof( TOKEN_USER );
    01295
    01296                 LocalUser = ExAllocatePool( PagedPool, RequiredLength );
    01297
    01298                 if (LocalUser == NULL) {
    01299                     SepReleaseTokenReadLock( Token );
    01300                     return( STATUS_INSUFFICIENT_RESOURCES );
    01301                 }
    01302
    01303                 //
    01304                 // Return the user SID
    01305                 //
    01306                 //  Put SID immediately following TOKEN_USER data structure
    01307                 //
    01308
    01309                 PSid = (PSID)( (ULONG_PTR)LocalUser + (ULONG)sizeof(TOKEN_USER) );
    01310
    01311                 RtlCopySidAndAttributesArray(
    01312                     1,
    01313                     Token->UserAndGroups,
    01314                     RequiredLength,
    01315                     &(LocalUser->User),
    01316                     PSid,
    01317                     ((PSID *)&Ignore),
    01318                     ((PULONG)&Ignore)
    01319                     );
    01320
    01321                 SepReleaseTokenReadLock( Token );
    01322                 *TokenInformation = LocalUser;
    01323                 return STATUS_SUCCESS;
    01324             }
    01325
    01326
    01327         case TokenGroups:
    01328             {
    01329                 PTOKEN_GROUPS LocalGroups;
    01330
    01331                 //
    01332                 //  Gain exclusive access to the token.
    01333                 //
    01334
    01335                 SepAcquireTokenReadLock( Token );
    01336
    01337                 //
    01338                 // Figure out how much space is needed to return the group SIDs.
    01339                 // That's the size of TOKEN_GROUPS (without any array entries)
    01340                 // plus the size of an SID_AND_ATTRIBUTES times the number of groups.
    01341                 // The number of groups is Token->UserAndGroups-1 (since the count
    01342                 // includes the user ID).  Then the lengths of each individual group
    01343                 // must be added.
    01344                 //
    01345
    01346                 RequiredLength = (ULONG)sizeof(TOKEN_GROUPS) +
    01347                                  ((Token->UserAndGroupCount - ANYSIZE_ARRAY - 1) *
    01348                                  ((ULONG)sizeof(SID_AND_ATTRIBUTES)) );
    01349
    01350                 Index = 1;
    01351                 while (Index < Token->UserAndGroupCount) {
    01352
    01353                     RequiredLength += SeLengthSid( Token->UserAndGroups[Index].Sid );
    01354
    01355                     Index += 1;
    01356
    01357                 } // endwhile
    01358
    01359                 LocalGroups = ExAllocatePool( PagedPool, RequiredLength );
    01360
    01361                 if (LocalGroups == NULL) {
    01362                     SepReleaseTokenReadLock( Token );
    01363                     return( STATUS_INSUFFICIENT_RESOURCES );
    01364                 }
    01365
    01366                 //
    01367                 // Now copy the groups.
    01368                 //
    01369
    01370                 LocalGroups->GroupCount = Token->UserAndGroupCount - 1;
    01371
    01372                 PSid = (PSID)( (ULONG_PTR)LocalGroups +
    01373                                (ULONG)sizeof(TOKEN_GROUPS) +
    01374                                (   (Token->UserAndGroupCount - ANYSIZE_ARRAY - 1) *
    01375                                    (ULONG)sizeof(SID_AND_ATTRIBUTES) )
    01376                              );
    01377
    01378                 RtlCopySidAndAttributesArray(
    01379                     (ULONG)(Token->UserAndGroupCount - 1),
    01380                     &(Token->UserAndGroups[1]),
    01381                     RequiredLength,
    01382                     LocalGroups->Groups,
    01383                     PSid,
    01384                     ((PSID *)&Ignore),
    01385                     ((PULONG)&Ignore)
    01386                     );
    01387
    01388                 SepReleaseTokenReadLock( Token );
    01389                 *TokenInformation = LocalGroups;
    01390                 return STATUS_SUCCESS;
    01391             }
    01392
    01393
    01394         case TokenPrivileges:
    01395             {
    01396                 PTOKEN_PRIVILEGES LocalPrivileges;
    01397
    01398                 //
    01399                 //  Gain exclusive access to the token to prevent changes
    01400                 //  from occuring to the privileges.
    01401                 //
    01402
    01403                 SepAcquireTokenReadLock( Token );
    01404
    01405                 //
    01406                 // Return the length required now in case not enough buffer
    01407                 // was provided by the caller and we have to return an error.
    01408                 //
    01409
    01410                 RequiredLength = (ULONG)sizeof(TOKEN_PRIVILEGES) +
    01411                                  ((Token->PrivilegeCount - ANYSIZE_ARRAY) *
    01412                                  ((ULONG)sizeof(LUID_AND_ATTRIBUTES)) );
    01413
    01414                 LocalPrivileges = ExAllocatePool( PagedPool, RequiredLength );
    01415
    01416                 if (LocalPrivileges == NULL) {
    01417                     SepReleaseTokenReadLock( Token );
    01418                     return( STATUS_INSUFFICIENT_RESOURCES );
    01419                 }
    01420
    01421                 //
    01422                 // Return the token privileges.
    01423                 //
    01424
    01425                 LocalPrivileges->PrivilegeCount = Token->PrivilegeCount;
    01426
    01427                 RtlCopyLuidAndAttributesArray(
    01428                     Token->PrivilegeCount,
    01429                     Token->Privileges,
    01430                     LocalPrivileges->Privileges
    01431                     );
    01432
    01433                 SepReleaseTokenReadLock( Token );
    01434                 *TokenInformation = LocalPrivileges;
    01435                 return STATUS_SUCCESS;
    01436             }
    01437
    01438
    01439         case TokenOwner:
    01440             {
    01441                 PTOKEN_OWNER LocalOwner;
    01442
    01443                 //
    01444                 //  Gain exclusive access to the token to prevent changes
    01445                 //  from occuring to the owner.
    01446                 //
    01447
    01448                 SepAcquireTokenReadLock( Token );
    01449
    01450                 //
    01451                 // Return the length required now in case not enough buffer
    01452                 // was provided by the caller and we have to return an error.
    01453                 //
    01454
    01455                 PSid = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid;
    01456                 RequiredLength = (ULONG)sizeof(TOKEN_OWNER) +
    01457                                  SeLengthSid( PSid );
    01458
    01459                 LocalOwner = ExAllocatePool( PagedPool, RequiredLength );
    01460
    01461                 if (LocalOwner == NULL) {
    01462                     SepReleaseTokenReadLock( Token );
    01463                     return( STATUS_INSUFFICIENT_RESOURCES );
    01464                 }
    01465
    01466                 //
    01467                 // Return the owner SID
    01468                 //
    01469
    01470                 PSid = (PSID)((ULONG_PTR)LocalOwner +
    01471                               (ULONG)sizeof(TOKEN_OWNER));
    01472
    01473                 LocalOwner->Owner = PSid;
    01474
    01475                 Status = RtlCopySid(
    01476                              (RequiredLength - (ULONG)sizeof(TOKEN_OWNER)),
    01477                              PSid,
    01478                              Token->UserAndGroups[Token->DefaultOwnerIndex].Sid
    01479                              );
    01480
    01481                 ASSERT( NT_SUCCESS(Status) );
    01482
    01483                 SepReleaseTokenReadLock( Token );
    01484                 *TokenInformation = LocalOwner;
    01485                 return STATUS_SUCCESS;
    01486             }
    01487
    01488
    01489         case TokenPrimaryGroup:
    01490             {
    01491                 PTOKEN_PRIMARY_GROUP LocalPrimaryGroup;
    01492
    01493                 //
    01494                 //  Gain exclusive access to the token to prevent changes
    01495                 //  from occuring to the owner.
    01496                 //
    01497
    01498                 SepAcquireTokenReadLock( Token );
    01499
    01500                 //
    01501                 // Return the length required now in case not enough buffer
    01502                 // was provided by the caller and we have to return an error.
    01503                 //
    01504
    01505                 RequiredLength = (ULONG)sizeof(TOKEN_PRIMARY_GROUP) +
    01506                                  SeLengthSid( Token->PrimaryGroup );
    01507
    01508                 LocalPrimaryGroup = ExAllocatePool( PagedPool, RequiredLength );
    01509
    01510                 if (LocalPrimaryGroup == NULL) {
    01511                     SepReleaseTokenReadLock( Token );
    01512                     return( STATUS_INSUFFICIENT_RESOURCES );
    01513                 }
    01514
    01515                 //
    01516                 // Return the primary group SID
    01517                 //
    01518
    01519                 PSid = (PSID)((ULONG_PTR)LocalPrimaryGroup +
    01520                               (ULONG)sizeof(TOKEN_PRIMARY_GROUP));
    01521
    01522                 LocalPrimaryGroup->PrimaryGroup = PSid;
    01523
    01524                 Status = RtlCopySid( (RequiredLength - (ULONG)sizeof(TOKEN_PRIMARY_GROUP)),
    01525                                      PSid,
    01526                                      Token->PrimaryGroup
    01527                                      );
    01528
    01529                 ASSERT( NT_SUCCESS(Status) );
    01530
    01531                 SepReleaseTokenReadLock( Token );
    01532                 *TokenInformation = LocalPrimaryGroup;
    01533                 return STATUS_SUCCESS;
    01534             }
    01535
    01536
    01537         case TokenDefaultDacl:
    01538             {
    01539                 PTOKEN_DEFAULT_DACL LocalDefaultDacl;
    01540
    01541                 //
    01542                 //  Gain exclusive access to the token to prevent changes
    01543                 //  from occuring to the owner.
    01544                 //
    01545
    01546                 SepAcquireTokenReadLock( Token );
    01547
    01548                 //
    01549                 // Return the length required now in case not enough buffer
    01550                 // was provided by the caller and we have to return an error.
    01551                 //
    01552
    01553                 RequiredLength = (ULONG)sizeof(TOKEN_DEFAULT_DACL);
    01554
    01555                 if (ARGUMENT_PRESENT(Token->DefaultDacl)) {
    01556
    01557                     RequiredLength += Token->DefaultDacl->AclSize;
    01558                 }
    01559
    01560                 LocalDefaultDacl = ExAllocatePool( PagedPool, RequiredLength );
    01561
    01562                 if (LocalDefaultDacl == NULL) {
    01563                     SepReleaseTokenReadLock( Token );
    01564                     return( STATUS_INSUFFICIENT_RESOURCES );
    01565                 }
    01566
    01567                 //
    01568                 // Return the default Dacl
    01569                 //
    01570
    01571                 PAcl = (PACL)((ULONG_PTR)LocalDefaultDacl +
    01572                               (ULONG)sizeof(TOKEN_DEFAULT_DACL));
    01573
    01574                 if (ARGUMENT_PRESENT(Token->DefaultDacl)) {
    01575
    01576                     LocalDefaultDacl->DefaultDacl = PAcl;
    01577
    01578                     RtlCopyMemory( (PVOID)PAcl,
    01579                                    (PVOID)Token->DefaultDacl,
    01580                                    Token->DefaultDacl->AclSize
    01581                                    );
    01582                 } else {
    01583
    01584                     LocalDefaultDacl->DefaultDacl = NULL;
    01585                 }
    01586
    01587                 SepReleaseTokenReadLock( Token );
    01588                 *TokenInformation = LocalDefaultDacl;
    01589                 return STATUS_SUCCESS;
    01590             }
    01591
    01592
    01593         case TokenSource:
    01594             {
    01595                 PTOKEN_SOURCE LocalSource;
    01596
    01597                 //
    01598                 // The type of a token can not be changed, so
    01599                 // exclusive access to the token is not necessary.
    01600                 //
    01601
    01602                 //
    01603                 // Return the length required now in case not enough buffer
    01604                 // was provided by the caller and we have to return an error.
    01605                 //
    01606
    01607                 RequiredLength = (ULONG) sizeof(TOKEN_SOURCE);
    01608
    01609                 LocalSource = ExAllocatePool( PagedPool, RequiredLength );
    01610
    01611                 if (LocalSource == NULL) {
    01612                     return( STATUS_INSUFFICIENT_RESOURCES );
    01613                 }
    01614
    01615                 //
    01616                 // Return the token source
    01617                 //
    01618
    01619                 (*LocalSource) = Token->TokenSource;
    01620                 *TokenInformation = LocalSource;
    01621
    01622                 return STATUS_SUCCESS;
    01623             }
    01624
    01625
    01626         case TokenType:
    01627             {
    01628                 PTOKEN_TYPE LocalType;
    01629
    01630                 //
    01631                 // The type of a token can not be changed, so
    01632                 // exclusive access to the token is not necessary.
    01633                 //
    01634
    01635                 //
    01636                 // Return the length required now in case not enough buffer
    01637                 // was provided by the caller and we have to return an error.
    01638                 //
    01639
    01640                 RequiredLength = (ULONG) sizeof(TOKEN_TYPE);
    01641
    01642                 LocalType = ExAllocatePool( PagedPool, RequiredLength );
    01643
    01644                 if (LocalType == NULL) {
    01645                     return( STATUS_INSUFFICIENT_RESOURCES );
    01646                 }
    01647
    01648                 //
    01649                 // Return the token type
    01650                 //
    01651
    01652                 (*LocalType) = Token->TokenType;
    01653                 *TokenInformation = LocalType;
    01654                 return STATUS_SUCCESS;
    01655             }
    01656
    01657
    01658         case TokenImpersonationLevel:
    01659             {
    01660                 PSECURITY_IMPERSONATION_LEVEL LocalImpersonationLevel;
    01661
    01662                 //
    01663                 // The impersonation level of a token can not be changed, so
    01664                 // exclusive access to the token is not necessary.
    01665                 //
    01666
    01667                 //
    01668                 //  Make sure the token is an appropriate type to be retrieving
    01669                 //  the impersonation level from.
    01670                 //
    01671
    01672                 if (Token->TokenType != TokenImpersonation) {
    01673
    01674                     return STATUS_INVALID_INFO_CLASS;
    01675                 }
    01676
    01677                 //
    01678                 // Return the length required now in case not enough buffer
    01679                 // was provided by the caller and we have to return an error.
    01680                 //
    01681
    01682                 RequiredLength = (ULONG) sizeof(SECURITY_IMPERSONATION_LEVEL);
    01683
    01684                 LocalImpersonationLevel = ExAllocatePool( PagedPool, RequiredLength );
    01685
    01686                 if (LocalImpersonationLevel == NULL) {
    01687                     return( STATUS_INSUFFICIENT_RESOURCES );
    01688                 }
    01689
    01690                 //
    01691                 // Return the impersonation level
    01692                 //
    01693
    01694                 (*LocalImpersonationLevel) = Token->ImpersonationLevel;
    01695                 *TokenInformation = LocalImpersonationLevel;
    01696                 return STATUS_SUCCESS;
    01697             }
    01698
    01699
    01700         case TokenStatistics:
    01701             {
    01702                 PTOKEN_STATISTICS LocalStatistics;
    01703
    01704                 //
    01705                 //  Gain exclusive access to the token.
    01706                 //
    01707
    01708                 SepAcquireTokenReadLock( Token );
    01709
    01710                 //
    01711                 // Return the length required now in case not enough buffer
    01712                 // was provided by the caller and we have to return an error.
    01713                 //
    01714
    01715                 RequiredLength = (ULONG)sizeof( TOKEN_STATISTICS );
    01716
    01717                 LocalStatistics = ExAllocatePool( PagedPool, RequiredLength );
    01718
    01719                 if (LocalStatistics == NULL) {
    01720                     SepReleaseTokenReadLock( Token );
    01721                     return( STATUS_INSUFFICIENT_RESOURCES );
    01722                 }
    01723
    01724                 //
    01725                 // Return the statistics
    01726                 //
    01727
    01728                 LocalStatistics->TokenId            = Token->TokenId;
    01729                 LocalStatistics->AuthenticationId   = Token->AuthenticationId;
    01730                 LocalStatistics->ExpirationTime     = Token->ExpirationTime;
    01731                 LocalStatistics->TokenType          = Token->TokenType;
    01732                 LocalStatistics->ImpersonationLevel = Token->ImpersonationLevel;
    01733                 LocalStatistics->DynamicCharged     = Token->DynamicCharged;
    01734                 LocalStatistics->DynamicAvailable   = Token->DynamicAvailable;
    01735                 LocalStatistics->GroupCount         = Token->UserAndGroupCount-1;
    01736                 LocalStatistics->PrivilegeCount     = Token->PrivilegeCount;
    01737                 LocalStatistics->ModifiedId         = Token->ModifiedId;
    01738
    01739                 SepReleaseTokenReadLock( Token );
    01740                 *TokenInformation = LocalStatistics;
    01741                 return STATUS_SUCCESS;
    01742             }
    01743
    01744     case TokenSessionId:
    01745
    01746         /*
    01747          * Get SessionId for the token
    01748          */
    01749         SeQuerySessionIdToken( (PACCESS_TOKEN)Token,
    01750                              (PULONG)TokenInformation );
    01751
    01752         return( STATUS_SUCCESS );
    01753
    01754     default:
    01755
    01756         return STATUS_INVALID_INFO_CLASS;
    01757     }
    01758 }
    01759
    01760
    01761
    01762 NTSTATUS
    01763 SeQuerySessionIdToken(
    01764     PACCESS_TOKEN Token,
    01765     PULONG SessionId
    01766     )
    01767
    01768 /*++
    01769
    01770
    01771 Routine Description:
    01772
    01773     Gets the SessionId from the specified token object.
    01774
    01775 Arguments:
    01776
    01777     Token (input)
    01778       Opaque kernel ACCESS_TOKEN pointer
    01779     SessionId (output)
    01780       pointer to location to return SessionId
    01781
    01782 Return Value:
    01783
    01784     STATUS_SUCCESS - no error
    01785
    01786 --*/
    01787 {
    01788
    01789     /*
    01790      * Get the SessionId.
    01791      */
    01792     SepAcquireTokenReadLock( ((PTOKEN)Token) );
    01793     (*SessionId) = ((PTOKEN)Token)->SessionId;
    01794     SepReleaseTokenReadLock( ((PTOKEN)Token) );
    01795     return( STATUS_SUCCESS );
    01796 }
    01797
    01798