共用方式為


模擬

某些檔案系統可能會發現代表原始呼叫端執行作業會很有用。 例如,網路檔案系統可能需要在開啟檔案時擷取呼叫端的安全性資訊,以便使用適當的認證來執行後續作業。 不確定還有其他許多特殊案例,這類功能在檔案系統內以及特定應用程式中都很有用。

模擬所需的主要常式包括:

  • 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;
}

此模擬程式碼有許多變體可供檔案系統開發人員使用,但提供技術的基本圖例。