ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

access.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS kernel
00004  * FILE:            ntoskrnl/se/access.c
00005  * PURPOSE:         Access state functions
00006  *
00007  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net) - 
00008  *                               Based on patch by Javier M. Mellid
00009  */
00010 
00011 /* INCLUDES *******************************************************************/
00012 
00013 #include <ntoskrnl.h>
00014 #define NDEBUG
00015 #include <debug.h>
00016 
00017 /* GLOBALS ********************************************************************/
00018 
00019 ERESOURCE SepSubjectContextLock;
00020 
00021 /* FUNCTIONS ******************************************************************/
00022 
00023 /*
00024  * @implemented
00025  */
00026 VOID
00027 NTAPI
00028 SeCaptureSubjectContextEx(IN PETHREAD Thread,
00029                           IN PEPROCESS Process,
00030                           OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
00031 {
00032     BOOLEAN CopyOnOpen, EffectiveOnly;
00033 
00034     PAGED_CODE();
00035 
00036     /* Save the unique ID */
00037     SubjectContext->ProcessAuditId = Process->UniqueProcessId;
00038 
00039     /* Check if we have a thread */
00040     if (!Thread)
00041     {
00042         /* We don't, so no token */
00043         SubjectContext->ClientToken = NULL;
00044     }
00045     else
00046     {
00047         /* Get the impersonation token */
00048         SubjectContext->ClientToken = PsReferenceImpersonationToken(Thread,
00049                                                                     &CopyOnOpen,
00050                                                                     &EffectiveOnly,
00051                                                                     &SubjectContext->ImpersonationLevel);
00052     }
00053 
00054     /* Get the primary token */
00055     SubjectContext->PrimaryToken = PsReferencePrimaryToken(Process);
00056 }
00057 
00058 /*
00059  * @implemented
00060  */
00061 VOID
00062 NTAPI
00063 SeCaptureSubjectContext(OUT PSECURITY_SUBJECT_CONTEXT SubjectContext)
00064 {
00065     /* Call the extended API */
00066     SeCaptureSubjectContextEx(PsGetCurrentThread(),
00067                               PsGetCurrentProcess(),
00068                               SubjectContext);
00069 }
00070 
00071 /*
00072  * @implemented
00073  */
00074 VOID
00075 NTAPI
00076 SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
00077 {
00078     PAGED_CODE();
00079 
00080     KeEnterCriticalRegion();
00081     ExAcquireResourceExclusiveLite(&SepSubjectContextLock, TRUE);
00082 }
00083 
00084 /*
00085  * @implemented
00086  */
00087 VOID
00088 NTAPI
00089 SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
00090 {
00091     PAGED_CODE();
00092 
00093     ExReleaseResourceLite(&SepSubjectContextLock);
00094     KeLeaveCriticalRegion();
00095 }
00096 
00097 /*
00098  * @implemented
00099  */
00100 VOID
00101 NTAPI
00102 SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
00103 {
00104     PAGED_CODE();
00105 
00106     if (SubjectContext->PrimaryToken != NULL)
00107     {
00108         ObFastDereferenceObject(&PsGetCurrentProcess()->Token, SubjectContext->PrimaryToken);
00109     }
00110 
00111     if (SubjectContext->ClientToken != NULL)
00112     {
00113         ObDereferenceObject(SubjectContext->ClientToken);
00114     }
00115 }
00116 
00117 /*
00118  * @implemented
00119  */
00120 NTSTATUS
00121 NTAPI
00122 SeCreateAccessStateEx(IN PETHREAD Thread,
00123                       IN PEPROCESS Process,
00124                       IN OUT PACCESS_STATE AccessState,
00125                       IN PAUX_ACCESS_DATA AuxData,
00126                       IN ACCESS_MASK Access,
00127                       IN PGENERIC_MAPPING GenericMapping)
00128 {
00129     ACCESS_MASK AccessMask = Access;
00130     PTOKEN Token;
00131 
00132     PAGED_CODE();
00133 
00134     /* Map the Generic Acess to Specific Access if we have a Mapping */
00135     if ((Access & GENERIC_ACCESS) && (GenericMapping))
00136     {
00137         RtlMapGenericMask(&AccessMask, GenericMapping);
00138     }
00139 
00140     /* Initialize the Access State */
00141     RtlZeroMemory(AccessState, sizeof(ACCESS_STATE));
00142 
00143     /* Capture the Subject Context */
00144     SeCaptureSubjectContextEx(Thread,
00145                               Process,
00146                               &AccessState->SubjectSecurityContext);
00147 
00148     /* Set Access State Data */
00149     AccessState->AuxData = AuxData;
00150     AccessState->RemainingDesiredAccess  = AccessMask;
00151     AccessState->OriginalDesiredAccess = AccessMask;
00152     ExpAllocateLocallyUniqueId(&AccessState->OperationID);
00153 
00154     /* Get the Token to use */
00155     Token = AccessState->SubjectSecurityContext.ClientToken ?
00156             (PTOKEN)&AccessState->SubjectSecurityContext.ClientToken :
00157             (PTOKEN)&AccessState->SubjectSecurityContext.PrimaryToken;
00158 
00159     /* Check for Travers Privilege */
00160     if (Token->TokenFlags & TOKEN_HAS_TRAVERSE_PRIVILEGE)
00161     {
00162         /* Preserve the Traverse Privilege */
00163         AccessState->Flags = TOKEN_HAS_TRAVERSE_PRIVILEGE;
00164     }
00165 
00166     /* Set the Auxiliary Data */
00167     AuxData->PrivilegeSet = (PPRIVILEGE_SET)((ULONG_PTR)AccessState +
00168                                              FIELD_OFFSET(ACCESS_STATE,
00169                                                           Privileges));
00170     if (GenericMapping) AuxData->GenericMapping = *GenericMapping;
00171 
00172     /* Return Sucess */
00173     return STATUS_SUCCESS;
00174 }
00175 
00176 /*
00177  * @implemented
00178  */
00179 NTSTATUS
00180 NTAPI
00181 SeCreateAccessState(IN OUT PACCESS_STATE AccessState,
00182                     IN PAUX_ACCESS_DATA AuxData,
00183                     IN ACCESS_MASK Access,
00184                     IN PGENERIC_MAPPING GenericMapping)
00185 {
00186     PAGED_CODE();
00187 
00188     /* Call the extended API */
00189     return SeCreateAccessStateEx(PsGetCurrentThread(),
00190                                  PsGetCurrentProcess(),
00191                                  AccessState,
00192                                  AuxData,
00193                                  Access,
00194                                  GenericMapping);
00195 }
00196 
00197 /*
00198  * @implemented
00199  */
00200 VOID
00201 NTAPI
00202 SeDeleteAccessState(IN PACCESS_STATE AccessState)
00203 {
00204     PAUX_ACCESS_DATA AuxData;
00205 
00206     PAGED_CODE();
00207 
00208     /* Get the Auxiliary Data */
00209     AuxData = AccessState->AuxData;
00210 
00211     /* Deallocate Privileges */
00212     if (AccessState->PrivilegesAllocated) ExFreePool(AuxData->PrivilegeSet);
00213 
00214     /* Deallocate Name and Type Name */
00215     if (AccessState->ObjectName.Buffer)
00216     {
00217         ExFreePool(AccessState->ObjectName.Buffer);
00218     }
00219 
00220     if (AccessState->ObjectTypeName.Buffer)
00221     {
00222         ExFreePool(AccessState->ObjectTypeName.Buffer);
00223     }
00224 
00225     /* Release the Subject Context */
00226     SeReleaseSubjectContext(&AccessState->SubjectSecurityContext);
00227 }
00228 
00229 /*
00230  * @implemented
00231  */
00232 VOID
00233 NTAPI
00234 SeSetAccessStateGenericMapping(IN PACCESS_STATE AccessState,
00235                                IN PGENERIC_MAPPING GenericMapping)
00236 {
00237     PAGED_CODE();
00238 
00239     /* Set the Generic Mapping */
00240     ((PAUX_ACCESS_DATA)AccessState->AuxData)->GenericMapping = *GenericMapping;
00241 }
00242 
00243 /*
00244  * @implemented
00245  */
00246 NTSTATUS
00247 NTAPI
00248 SeCreateClientSecurity(IN PETHREAD Thread,
00249                        IN PSECURITY_QUALITY_OF_SERVICE Qos,
00250                        IN BOOLEAN RemoteClient,
00251                        OUT PSECURITY_CLIENT_CONTEXT ClientContext)
00252 {
00253     TOKEN_TYPE TokenType;
00254     BOOLEAN ThreadEffectiveOnly;
00255     SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
00256     PACCESS_TOKEN Token;
00257     NTSTATUS Status;
00258     PACCESS_TOKEN NewToken;
00259 
00260     PAGED_CODE();
00261 
00262     Token = PsReferenceEffectiveToken(Thread,
00263                                       &TokenType,
00264                                       &ThreadEffectiveOnly,
00265                                       &ImpersonationLevel);
00266     if (TokenType != TokenImpersonation)
00267     {
00268         ClientContext->DirectAccessEffectiveOnly = Qos->EffectiveOnly;
00269     }
00270     else
00271     {
00272         if (Qos->ImpersonationLevel > ImpersonationLevel)
00273         {
00274             if (Token) ObDereferenceObject(Token);
00275             return STATUS_BAD_IMPERSONATION_LEVEL;
00276         }
00277 
00278         if ((ImpersonationLevel == SecurityAnonymous) ||
00279             (ImpersonationLevel == SecurityIdentification) ||
00280             ((RemoteClient) && (ImpersonationLevel != SecurityDelegation)))
00281         {
00282             if (Token) ObDereferenceObject(Token);
00283             return STATUS_BAD_IMPERSONATION_LEVEL;
00284         }
00285 
00286         ClientContext->DirectAccessEffectiveOnly = ((ThreadEffectiveOnly) ||
00287                                                     (Qos->EffectiveOnly)) ? TRUE : FALSE;
00288     }
00289 
00290     if (Qos->ContextTrackingMode == SECURITY_STATIC_TRACKING)
00291     {
00292         ClientContext->DirectlyAccessClientToken = FALSE;
00293         Status = SeCopyClientToken(Token, ImpersonationLevel, 0, &NewToken);
00294         if (!NT_SUCCESS(Status)) return Status;
00295     }
00296     else
00297     {
00298         ClientContext->DirectlyAccessClientToken = TRUE;
00299         if (RemoteClient != FALSE)
00300         {
00301 #if 0
00302             SeGetTokenControlInformation(Token,
00303                                          &ClientContext->ClientTokenControl);
00304 #endif
00305         }
00306 
00307         NewToken = Token;
00308     }
00309 
00310     ClientContext->SecurityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
00311     ClientContext->SecurityQos.ImpersonationLevel = Qos->ImpersonationLevel;
00312     ClientContext->SecurityQos.ContextTrackingMode = Qos->ContextTrackingMode;
00313     ClientContext->SecurityQos.EffectiveOnly = Qos->EffectiveOnly;
00314     ClientContext->ServerIsRemote = RemoteClient;
00315     ClientContext->ClientToken = NewToken;
00316     return STATUS_SUCCESS;
00317 }
00318 
00319 /*
00320  * @unimplemented
00321  */
00322 NTSTATUS
00323 NTAPI
00324 SeCreateClientSecurityFromSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext,
00325                                          IN PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos,
00326                                          IN BOOLEAN ServerIsRemote,
00327                                          OUT PSECURITY_CLIENT_CONTEXT ClientContext)
00328 {
00329     UNIMPLEMENTED;
00330     return STATUS_NOT_IMPLEMENTED;
00331 }
00332 
00333 /*
00334  * @implemented
00335  */
00336 NTSTATUS
00337 NTAPI
00338 SeImpersonateClientEx(IN PSECURITY_CLIENT_CONTEXT ClientContext,
00339                       IN PETHREAD ServerThread OPTIONAL)
00340 {
00341     BOOLEAN EffectiveOnly;
00342 
00343     PAGED_CODE();
00344 
00345     if (ClientContext->DirectlyAccessClientToken == FALSE)
00346     {
00347         EffectiveOnly = ClientContext->SecurityQos.EffectiveOnly;
00348     }
00349     else
00350     {
00351         EffectiveOnly = ClientContext->DirectAccessEffectiveOnly;
00352     }
00353 
00354     if (ServerThread == NULL)
00355     {
00356         ServerThread = PsGetCurrentThread();
00357     }
00358 
00359     return PsImpersonateClient(ServerThread,
00360                                ClientContext->ClientToken,
00361                                TRUE,
00362                                EffectiveOnly,
00363                                ClientContext->SecurityQos.ImpersonationLevel);
00364 }
00365 
00366 /*
00367  * @implemented
00368  */
00369 VOID
00370 NTAPI
00371 SeImpersonateClient(IN PSECURITY_CLIENT_CONTEXT ClientContext,
00372                     IN PETHREAD ServerThread OPTIONAL)
00373 {
00374     PAGED_CODE();
00375 
00376     SeImpersonateClientEx(ClientContext,
00377                           ServerThread);
00378 }
00379 
00380 /* EOF */

Generated on Sun May 27 2012 04:20:50 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.