模擬
某些檔案系統可能會發現代表原始呼叫端執行作業會很有用。 例如,網路檔案系統可能需要在開啟檔案時擷取呼叫端的安全性資訊,以便使用適當的認證來執行後續作業。 不確定還有其他許多特殊案例,這類功能在檔案系統內以及特定應用程式中都很有用。
模擬所需的主要常式包括:
PsImpersonateClientSeImpersonateClientEx--起始模擬。 除非指出特定執行緒,否則模擬會在目前的執行緒內容中完成。
PsRevertToSelf--終止目前線程內容內的模擬。
PsReferencePrimaryToken--保留指定進程之主要 (進程) 權杖的參考。 此函式可用來擷取系統上任何進程的權杖。
PsDereferencePrimaryToken---releases 先前參考的主要權杖上的參考。
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;
}
此模擬程式碼有許多變體可供檔案系統開發人員使用,但提供技術的基本圖例。