none
イベントビューアのセキュリティログにおいて、ログオン/ログオフ時に出力されているログオンIDと同じ値を取得できますか? RRS feed

  • 質問

  • セキュリティログにログオン/ログオフ時にイベントが出力されます。

    (MMCにより監査ポリシーを設定する必要があります。デフォルトではこのイベントは出力されません)

    そこにログオンIDというものが出力されています。

    これはユーザIDではなくて例えば以下の様な感じて出力されます。

    -------------------------------

    ログオンの成功:
      ユーザー名: Administrator
      ドメイン:  xxxxx

      ログオン ID:  (0x0,0x19954)
      ログオンの種類: 2
    -------------------------------

    上記の「(0x0,0x19954)」と同じ値をプログラムから取得する方法はありますでしょうか?

    プログラムでやろうとしていることは、

    独自にログファイル出力時に上記のログオンIDを出力し、ログオン/ログオフ時イベントと紐付けしておきたいというものです。

    補足としまして、ユーザ名等もログファイル出力してますが、更なる情報としてログオンIDが出力できればと思ってます。

     

    一応、ログオンIDについての参考URLを下記します。

    http://www.microsoft.com/japan/technet/prodtechnol/windows2000serv/maintain/monitor/logonoff.mspx

     

    開発環境と実行環境について

    ■開発環境

    ・VS2005.NET C++

    MFCアプリケーション

    (.net Framework使用しない)

    ■実行環境

    ・Windows2000Server

    ・Windows2003Server

    2007年11月20日 14:14

回答

  • 上記の「(0x0,0x19954)」と同じ値をプログラムから取得する方法はありますでしょうか?

    後者の「0x019954」は恐らくログオン時のセッションIDログオンセッションに関連付けされた

    IDを指していると思われます。簡単に調べるのであれば、wbemtest上からWin32_LogonSession

    クラスのインスタンスを列挙してみてください。

    wbemtest上では10進数表記になっているので、16進数に直せば目的の数値が出現すると

    思われます。

     

    前者の「0x0」に関しては不明です(0x0以外見たことないし・・・)。

    (追記) 単に、LUIDのHighPart?

     

    # Win32_Account.LocalAccountを指しているのカナ、と思ってますが資料が見当たらない

    # ので定かではありません。

     

    Win32_LoggedOnUserクラスのインスタンスを列挙して調べれば何かでるカモ

    しれません。

     

    WMI上で話しましたが、Win32APIでも同等の関数はあると思います。

    2007年11月21日 0:01
  • # 正しいかどうかわかりませんが、一応作ってみました。

     

    コード ブロック

    #include <Ntsecapi.h>
    #pragma comment(lib, "Secur32.lib")

     

    #ifndef STATUS_SUCCESS
    #define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
    #endif

     

     

    コード ブロック

     BOOL  bSucceed;
     NTSTATUS status;
     HANDLE  hToken;

     

     bSucceed = ::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &hToken);
     ATLASSERT(bSucceed);

     

     TOKEN_STATISTICS ts = {0x00, };
     DWORD    dwReturned;

     

     bSucceed = ::GetTokenInformation

         (hToken, TokenStatistics, &ts, sizeof(ts), &dwReturned);
     ATLASSERT( bSucceed && (dwReturned == sizeof(ts)) );

     

     LUID luid = ts.AuthenticationId;

     PSECURITY_LOGON_SESSION_DATA pslsd = NULL;

     

     status = ::LsaGetLogonSessionData(&luid, &pslsd);
     ATLASSERT(status == STATUS_SUCCESS);

     

     LSA_UNICODE_STRING&  szName = pslsd->UserName;

     if (pslsd->LogonType == Interactive)
     {
      ATLTRACE(
       _T("Local logged on user is %.*S (0x%X, 0x%X)\n"),
       szName.Length, szName.Buffer, luid.HighPart, luid.LowPart
      );
     }

     else

      { ATLASSERT(0); }

     

     ::LsaFreeReturnBuffer(pslsd);

     

     

    2007年11月21日 4:24
  • 見落としがあったので補足しておきます。

     

    ■実行環境

    ・Windows2000Server

    ・Windows2003Server

    WMIのWin32_LogonSessionですが、これはWindowsXP以降が有効であり、Windows2000は

    対象外でした。その為、Windows2000上では先に書いたコードの通り、カレントプロセスの

    トークンから取得するしかなさそうです。

     

    # Win32_LogonSessionが内部的にコールしているであろうLsaEnumerateLogonSessions()も

    # 同様にWindowsXP以降となっています。

     

    最も、Win32_LogonSessionクラス or LsaEnumerateLogonSessions()からログオンIDを探ろう

    とすると、どれが自分のIDか特定する作業が必要になりそうですが。

     

    2007年11月22日 5:50
  • # 過去の資料から引っ張り出しただけなので、怪しい部分がありますが。

     

    LogonIdは名前がそのものずばり「ログオンID」を指しているものと思いましたが、

    LogonIdとAuthenticationIdとは同じものということでしょうか?

    MSDNドキュメント自体にはAuhthenticationIdがLogonIdと等価であることは記載されていません。

     

    ただ、TOKEN_STATISTICS::AuthenticationIdメンバの解説と、LsaEnumerateLogonSessions()

    関数の解説を見る限りは、この2つが等価であると見て良いように思われます。

     

    ピアソン・エデュケーション「Windows NT/2000 ネイティブAPIリファレンス」より引用

    AuthenticationId: トークンが表すセッションに割り当てられたLUID。

    一つのログオンセッションを表している複数のトークンがあることがあります。

     

     

    この2値を等価として扱うかが不安であるならば、先に書いたようにLsaEnumerateLogonSessions()

    からログオンセッション識別子(=LogonId)の一覧を取得して、インタラクティブなLogonIdを特定

    する、という作業が必要かと思われます。

    (ターミナルサーバー環境で試してないので、その場合は更に処理が必要になるのかどうなのか

    わかりませんが・・・)

     

    2007年11月24日 9:10

すべての返信

  • 上記の「(0x0,0x19954)」と同じ値をプログラムから取得する方法はありますでしょうか?

    後者の「0x019954」は恐らくログオン時のセッションIDログオンセッションに関連付けされた

    IDを指していると思われます。簡単に調べるのであれば、wbemtest上からWin32_LogonSession

    クラスのインスタンスを列挙してみてください。

    wbemtest上では10進数表記になっているので、16進数に直せば目的の数値が出現すると

    思われます。

     

    前者の「0x0」に関しては不明です(0x0以外見たことないし・・・)。

    (追記) 単に、LUIDのHighPart?

     

    # Win32_Account.LocalAccountを指しているのカナ、と思ってますが資料が見当たらない

    # ので定かではありません。

     

    Win32_LoggedOnUserクラスのインスタンスを列挙して調べれば何かでるカモ

    しれません。

     

    WMI上で話しましたが、Win32APIでも同等の関数はあると思います。

    2007年11月21日 0:01
  • # 正しいかどうかわかりませんが、一応作ってみました。

     

    コード ブロック

    #include <Ntsecapi.h>
    #pragma comment(lib, "Secur32.lib")

     

    #ifndef STATUS_SUCCESS
    #define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
    #endif

     

     

    コード ブロック

     BOOL  bSucceed;
     NTSTATUS status;
     HANDLE  hToken;

     

     bSucceed = ::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &hToken);
     ATLASSERT(bSucceed);

     

     TOKEN_STATISTICS ts = {0x00, };
     DWORD    dwReturned;

     

     bSucceed = ::GetTokenInformation

         (hToken, TokenStatistics, &ts, sizeof(ts), &dwReturned);
     ATLASSERT( bSucceed && (dwReturned == sizeof(ts)) );

     

     LUID luid = ts.AuthenticationId;

     PSECURITY_LOGON_SESSION_DATA pslsd = NULL;

     

     status = ::LsaGetLogonSessionData(&luid, &pslsd);
     ATLASSERT(status == STATUS_SUCCESS);

     

     LSA_UNICODE_STRING&  szName = pslsd->UserName;

     if (pslsd->LogonType == Interactive)
     {
      ATLTRACE(
       _T("Local logged on user is %.*S (0x%X, 0x%X)\n"),
       szName.Length, szName.Buffer, luid.HighPart, luid.LowPart
      );
     }

     else

      { ATLASSERT(0); }

     

     ::LsaFreeReturnBuffer(pslsd);

     

     

    2007年11月21日 4:24
  • 早速のお返事ありがとうございました。

    wbemtestというもの存在を知らなかったので、まずは使い方等をネットで調べて・・・というお勉強から始めたいと思います。

     

    それからサンプルソースまで作っていただきありがとうございました。

    試してみます。

    今まで全く糸口が見えなかったので、すごく助かります。

    2007年11月21日 12:06
  • 見落としがあったので補足しておきます。

     

    ■実行環境

    ・Windows2000Server

    ・Windows2003Server

    WMIのWin32_LogonSessionですが、これはWindowsXP以降が有効であり、Windows2000は

    対象外でした。その為、Windows2000上では先に書いたコードの通り、カレントプロセスの

    トークンから取得するしかなさそうです。

     

    # Win32_LogonSessionが内部的にコールしているであろうLsaEnumerateLogonSessions()も

    # 同様にWindowsXP以降となっています。

     

    最も、Win32_LogonSessionクラス or LsaEnumerateLogonSessions()からログオンIDを探ろう

    とすると、どれが自分のIDか特定する作業が必要になりそうですが。

     

    2007年11月22日 5:50
  • 作っていただいたサンプルソースを試してみました。

    イベントビューア上のログオンIDと同じものが取得できました。

     

    ところでサンプルソースではGetTokenInformationで取得したTOKEN_STATISTICS構造体メンバのAuthenticationIdを出力されてますが、

    後続するLsaGetLogonSessionDataで取得したSECURITY_LOGON_SESSION_DATA構造体メンバにLogonIdというものがあります。

    このLogonIdも出力してみるとAuthenticationIdと同じ値でした。

     

    LogonIdは名前がそのものずばり「ログオンID」を指しているものと思いましたが、

    LogonIdとAuthenticationIdとは同じものということでしょうか?

     

    2007年11月22日 13:51
  • # 過去の資料から引っ張り出しただけなので、怪しい部分がありますが。

     

    LogonIdは名前がそのものずばり「ログオンID」を指しているものと思いましたが、

    LogonIdとAuthenticationIdとは同じものということでしょうか?

    MSDNドキュメント自体にはAuhthenticationIdがLogonIdと等価であることは記載されていません。

     

    ただ、TOKEN_STATISTICS::AuthenticationIdメンバの解説と、LsaEnumerateLogonSessions()

    関数の解説を見る限りは、この2つが等価であると見て良いように思われます。

     

    ピアソン・エデュケーション「Windows NT/2000 ネイティブAPIリファレンス」より引用

    AuthenticationId: トークンが表すセッションに割り当てられたLUID。

    一つのログオンセッションを表している複数のトークンがあることがあります。

     

     

    この2値を等価として扱うかが不安であるならば、先に書いたようにLsaEnumerateLogonSessions()

    からログオンセッション識別子(=LogonId)の一覧を取得して、インタラクティブなLogonIdを特定

    する、という作業が必要かと思われます。

    (ターミナルサーバー環境で試してないので、その場合は更に処理が必要になるのかどうなのか

    わかりませんが・・・)

     

    2007年11月24日 9:10
  • 色々ありがとうございました。

     

    TOKEN_STATISTICS::AuthenticationIdメンバの解説をMSDNで見ました。

    http://msdn2.microsoft.com/en-us/library/aa379632.aspx

     

    書いていることは

     

    AuthenticationId: トークンが表すセッションに割り当てられたLUID。
    一つのログオンセッションを表している複数のトークンがあることがあります。

     

    と同じだと思います(英語ですけど。。。)

     

    気になるのは

    「一つのログオンセッションを表している複数のトークンがあることがあります。」

    ということですが、これがどういう状態で起こるのか分かりませんが。。。

    もし、そういう状態があったとして

    「複数のトークン」は、それぞれTOKEN_STATISTICS::TokenIdが異なる値をとるんでしょう。

    けれども、それらが「一つのログオンセッションを表している」のですから

    TOKEN_STATISTICS::AuthenticationId

    は同一なんだと思います。

    このケースでもAuthenticationIdがログオンIDと異なる理由はないと思われました。

     

    プログラムのテストの過程で、

    AuthenticationIdがログオンIDでない場合に遭遇しないかどうか注視しておきたいと思います。

    (その場合は、LsaGetLogonSessionDataがエラーになると思うので。。。)

     

    それから

    LsaEnumerateLogonSessions()

    にて列挙する方法ですが、

    例えば、ターミナルサーバにて同じユーザで複数ログオンした場合、

    ログオンセッションを特定する方法が思いつきませんでした。

    この場合、

    SECURITY_LOGON_SESSION_DATA 構造体メンバ

    のログオンID以外(ユーザIDとかSIDとか。。。)は全部同じになりそうなので。。。

    http://msdn2.microsoft.com/en-us/library/aa380128.aspx

     

     

     

     

    2007年11月27日 14:23