Muistiinpano
Tämän sivun käyttö edellyttää valtuutusta. Voit yrittää kirjautua sisään tai vaihtaa hakemistoa.
Tämän sivun käyttö edellyttää valtuutusta. Voit yrittää vaihtaa hakemistoa.
Some file systems might find it useful to perform operations on behalf of the original caller. For example, a network file system might need to capture the caller's security information at the time a file is opened so that a subsequent operation can be performed using the appropriate credentials. No doubt there are numerous other special cases where this type of feature is useful, both within a file system as well as in specific applications.
The key routines needed for impersonation include:
PsImpersonateClient SeImpersonateClientEx--initiates impersonation. Unless a specific thread is indicated, the impersonation is done in the current thread context.
PsRevertToSelf--terminates impersonation within the current thread context.
PsReferencePrimaryToken--holds a reference on the primary (process) token for the specified process. This function may be used to capture the token for any process on the system.
PsDereferencePrimaryToken--releases a reference on a previously referenced primary token.
SeCreateClientSecurityFromSubjectContext--returns a client security context useful for impersonation from a subject context (provided to the FSD during the IRP_MJ_CREATE handling, for example).
SeCreateClientSecurity--creates a client security context based upon the security credentials of an existing thread on the system.
ImpersonateSecurityContext--impersonates security context within ksecdd.sys, the kernel security service.
RevertSecurityContext--terminates impersonation within ksecdd.sys, the kernel security service.
Impersonation is straight-forward to implement. The following code example demonstrates basic impersonation:
NTSTATUS PerformSpecialTask(IN PFSD_CONTEXT Context)
{
BOOLEAN CopyOnOpen;
BOOLEAN EffectiveOnly;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
NTSTATUS Status;
PACCESS_TOKEN oldToken;
//
// We need to perform a task in the system process context
//
if (NULL == Context->SystemProcess) {
return STATUS_NO_TOKEN;
}
//
// Save the existing token, if any (otherwise NULL)
//
oldToken = PsReferenceImpersonationToken(PsGetCurrentThread(),
&CopyOnOpen,
&EffectiveOnly,
&ImpersonationLevel);
Status = PsImpersonateClient( PsGetCurrentThread(),
Context->SystemProcess,
TRUE,
TRUE,
SecurityImpersonation);
if (!NT_SUCCESS(Status)) {
if (oldToken)
PsDereferenceImpersonationToken(oldToken);
return Status;
}
//
// Perform task - whatever it is
//
//
// Restore to previous impersonation level
//
if (oldToken) {
Status = PsImpersonateClient(PsGetCurrentThread(),
oldToken,
CopyOnOpen,
EffectiveOnly,
ImpersonationLevel);
if (!NT_SUCCESS(Status)) {
//
// This is bad - we can't restore, we can't leave it this way
//
PsRevertToSelf();
}
PsDereferenceImpersonationToken(oldToken);
} else {
PsRevertToSelf();
}
return Status;
}
There are numerous variants of this impersonation code that are available to file systems developers, but this provides a basic illustration of the technique.