セキュリティ ID

Windows は、セキュリティ エンティティを相互に区別するための決定的な値としてセキュリティ識別子を使用します。 たとえば、システム上の個々のユーザーに対して作成された新しいアカウントごとに、一意のセキュリティ識別子が割り当てられます。 ファイル システムでは、この SID のみが使用されます。

次の図は、セキュリティ識別子の構造を示しています。

セキュリティ識別子の構造を示す図。

Windows システムは、一意の SID に加えて、一連の既知の識別子を定義します。 たとえば、ローカルの Administrator は、よく知られた SID です。

Windows には、カーネル環境内で SID とユーザー名を変換するためのカーネル内メカニズムが用意されています。 これらの関数呼び出しは、ユーザー モード ヘルパー サービスを使用してこれらの関数を実装する ksecdd ドライバーから使用できます。 したがって、ファイル システム内での使用は、ユーザー モード サービスとの通信に関する通常の規則に従う必要があります。 これらの呼び出しは、ページング ファイル I/O 中には使用できません。

これらの関数の一部を次に示します。

  • SecMakeSPN は、特定のセキュリティ サービス プロバイダーと通信するときに使用できるサービス プロバイダー名の文字列を作成します。

  • SecMakeSPNEx は、Windows XP で導入された SecMakeSPN の拡張バージョンです。

  • SecMakeSPNEx2 は、Windows Vista および Windows Server 2008 以降で使用できる SecMakeSPNEx の拡張バージョンです。

  • SecLookupAccountSid は、指定された SID のアカウント名を返します。

  • SecLookupAccountName は、指定されたアカウント名の SID を取得します。

  • SecLookupWellKnownSid は、指定された既知の SID 型の正しい SID を返します。 この機能は、Windows Server 2003 以降で使用できます。

さらに、カーネル ドライバーは、次の標準ランタイム ライブラリ ルーチンを使用して SID を作成できます。

  • RtlInitializeSid は、新しい SID のバッファーを初期化します。

  • RtlLengthSid は、指定されたバッファー内に格納されている SID のサイズを決定します。

  • RtlValidSid は、指定された SID バッファーが有効な書式設定されたバッファーであるかどうかを判断します。

RtlLengthSidRtlValidSid は、SID の 8 バイト固定ヘッダーが存在することを前提としています。 そのため、ドライバーは、これらの関数を呼び出す前に、SID ヘッダーのこの最小長をチェックする必要があります。

他にもいくつかの RTL 関数がありますが、このリストは SID を構築するときに必要な主な関数です。

次のコード例は、「ローカル システム」エンティティの SID を作成する方法を示しています。 Windows Server 2003で導入された simpler SecLookupWellKnownSid 関数も使用できます。

{
    //
    // temporary stack-based storage for an SID
    //
    UCHAR sidBuffer[128];
    PISID localSid = (PISID) sidBuffer;
    SID_IDENTIFIER_AUTHORITY localSidAuthority = 
        SECURITY_NT_AUTHORITY;

    //
    // build the local system SID
    //
    RtlZeroMemory(sidBuffer, sizeof(sidBuffer));
 
    localSid->Revision = SID_REVISION;
    localSid->SubAuthorityCount = 1;
    localSid->IdentifierAuthority = localSidAuthority;
    localSid->SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
 
    //
    // make sure it is valid
    //
    if (!RtlValidSid(localSid)) {
        DbgPrint("no dice - SID is invalid\n");
        return(1);
    }
}

次のコード例は、"ローカル システム" エンティティの SecLookupWellKnownSid 関数を使用して SID を作成する方法を示しています。

{
    UCHAR sidBuffer[128];
    PISID localSid = (PISID) sidBuffer;
    SIZE_T sidSize;
    status = SecLookupWellKnownSid(WinLocalSid,
                                   &localSid,
                                   sizeof(sidBuffer),
                                   &sidSize);

    if (!NT_SUCCESS(status)) {
      //
      // error handling
      //
    }
  }

どちらの方法も有効ですが、後者のコードをお勧めします。 これらのコード例では、SID を格納するためにローカル バッファーを使用します。 これらのバッファーは、現在の呼び出しコンテキストの外部では使用できません。 SID バッファーを永続的にする必要がある場合は、バッファーをプール メモリから割り当てる必要があります。