某些檔案系統可能會認為,為原始呼叫端執行作業是很有用的。 例如,網路檔案系統可能需要在開啟檔案時擷取呼叫端的安全性資訊,以便使用適當的認證來執行後續作業。 毫無疑問,在許多其他特殊情況下,這種類型的功能在檔案系統內以及特定應用程式中都很有用。
模擬所需的關鍵例程包括:
PsImpersonateClientSeImpersonateClientEx--起始模擬。 除非指定特定執行緒,否則模擬會在目前執行緒的上下文中進行。
PsRevertToSelf--終止目前執行緒內容內的擬似身份。
PsReferencePrimaryToken-- 保留指定程序的主要(程序)權杖的參考。 此函式可用來取得系統上任何程序的權杖(Token)。
PsDereferencePrimaryToken--釋放對先前引用的主要權杖的引用。
SeCreateClientSecurityFromSubjectContext--傳回一個用於模擬的有用用戶端安全性內容,從主旨內容中獲取(例如,在 IRP_MJ_CREATE 處理期間提供給 FSD)。
SeCreateClientSecurity--根據系統上現有執行緒的安全性認證來建立用戶端安全性內容。
ImpersonateSecurityContext--模擬核心安全服務 ksecdd.sys內的安全內容。
RevertSecurityContext--終止核心安全性服務 ksecdd.sys內的模擬。
模擬很容易實現。 下列程式碼範例示範基本模擬:
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;
}
檔案系統開發人員可以使用此模擬程式碼的許多變體,但這提供了該技術的基本說明。