Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of mappen te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen om mappen te wijzigen.
Sommige bestandssystemen kunnen het nuttig vinden om bewerkingen uit te voeren namens de oorspronkelijke beller. Een netwerkbestandssysteem moet bijvoorbeeld mogelijk de beveiligingsgegevens van de beller vastleggen op het moment dat een bestand wordt geopend, zodat een volgende bewerking kan worden uitgevoerd met de juiste referenties. Ongetwijfeld zijn er talloze andere speciale gevallen waarbij dit type functie nuttig is, zowel binnen een bestandssysteem als in specifieke toepassingen.
De belangrijkste routines die nodig zijn voor imitatie zijn onder andere:
PsImpersonateClientSeImpersonateClientEx-initieert imitatie. Tenzij een specifieke thread wordt aangegeven, wordt de imitatie uitgevoerd in de huidige threadcontext.
PsRevertToSelf:-beëindigt imitatie binnen de huidige threadcontext.
PsReferencePrimaryToken- bevat een verwijzing op het primaire (proces)-token voor het opgegeven proces. Deze functie kan worden gebruikt om het token vast te leggen voor elk proces op het systeem.
PsDereferencePrimaryToken brengt een verwijzing uit op een eerder verwezen primair token.
SeCreateClientSecurityFromSubjectContext:-retourneert een clientbeveiligingscontext die nuttig is voor imitatie vanuit een onderwerpcontext (bijvoorbeeld aan de FSD tijdens de IRP_MJ_CREATE verwerking).
SeCreateClientSecurity maakt een clientbeveiligingscontext op basis van de beveiligingsreferenties van een bestaande thread op het systeem.
ImpersonateSecurityContext:-imiteert de beveiligingscontext binnen ksecdd.sys, de kernelbeveiligingsservice.
RevertSecurityContext beëindigt de impersonatie binnen ksecdd.sys, de Kernel Security Service.
Imitatie is eenvoudig te implementeren. In het volgende codevoorbeeld ziet u een eenvoudige imitatie:
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;
}
Er zijn talloze varianten van deze imitatiecode beschikbaar voor ontwikkelaars van bestandssystemen, maar dit biedt een eenvoudige illustratie van de techniek.