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

質問
-
セキュリティログにログオン/ログオフ時にイベントが出力されます。
(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
回答
-
上記の「(0x0,0x19954)」と同じ値をプログラムから取得する方法はありますでしょうか?
後者の「0x019954」は
恐らくログオン時のセッションIDログオンセッションに関連付けされたIDを指していると思われます。簡単に調べるのであれば、wbemtest上からWin32_LogonSession
クラスのインスタンスを列挙してみてください。
wbemtest上では10進数表記になっているので、16進数に直せば目的の数値が出現すると
思われます。
前者の「0x0」に関しては不明です(0x0以外見たことないし・・・)。
(追記) 単に、LUIDのHighPart?
#
Win32_Account.LocalAccountを指しているのカナ、と思ってますが資料が見当たらない#
ので定かではありません。Win32_LoggedOnUserクラスのインスタンスを列挙して調べれば何かでるカモ
しれません。
WMI上で話しましたが、Win32APIでも同等の関数はあると思います。
-
# 正しいかどうかわかりませんが、一応作ってみました。
コード ブロック#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);
-
見落としがあったので補足しておきます。
■実行環境
・Windows2000Server
・Windows2003Server
WMIのWin32_LogonSessionですが、これはWindowsXP以降が有効であり、Windows2000は
対象外でした。その為、Windows2000上では先に書いたコードの通り、カレントプロセスの
トークンから取得するしかなさそうです。
# Win32_LogonSessionが内部的にコールしているであろうLsaEnumerateLogonSessions()も
# 同様にWindowsXP以降となっています。
最も、Win32_LogonSessionクラス or LsaEnumerateLogonSessions()からログオンIDを探ろう
とすると、どれが自分のIDか特定する作業が必要になりそうですが。
-
# 過去の資料から引っ張り出しただけなので、怪しい部分がありますが。
LogonIdは名前がそのものずばり「ログオンID」を指しているものと思いましたが、
LogonIdとAuthenticationIdとは同じものということでしょうか?
MSDNドキュメント自体にはAuhthenticationIdがLogonIdと等価であることは記載されていません。
ただ、TOKEN_STATISTICS::AuthenticationIdメンバの解説と、LsaEnumerateLogonSessions()
関数の解説を見る限りは、この2つが等価であると見て良いように思われます。
ピアソン・エデュケーション「Windows NT/2000 ネイティブAPIリファレンス」より引用
AuthenticationId: トークンが表すセッションに割り当てられたLUID。
一つのログオンセッションを表している複数のトークンがあることがあります。
この2値を等価として扱うかが不安であるならば、先に書いたようにLsaEnumerateLogonSessions()
からログオンセッション識別子(=LogonId)の一覧を取得して、インタラクティブなLogonIdを特定
する、という作業が必要かと思われます。
(ターミナルサーバー環境で試してないので、その場合は更に処理が必要になるのかどうなのか
わかりませんが・・・)
すべての返信
-
上記の「(0x0,0x19954)」と同じ値をプログラムから取得する方法はありますでしょうか?
後者の「0x019954」は
恐らくログオン時のセッションIDログオンセッションに関連付けされたIDを指していると思われます。簡単に調べるのであれば、wbemtest上からWin32_LogonSession
クラスのインスタンスを列挙してみてください。
wbemtest上では10進数表記になっているので、16進数に直せば目的の数値が出現すると
思われます。
前者の「0x0」に関しては不明です(0x0以外見たことないし・・・)。
(追記) 単に、LUIDのHighPart?
#
Win32_Account.LocalAccountを指しているのカナ、と思ってますが資料が見当たらない#
ので定かではありません。Win32_LoggedOnUserクラスのインスタンスを列挙して調べれば何かでるカモ
しれません。
WMI上で話しましたが、Win32APIでも同等の関数はあると思います。
-
# 正しいかどうかわかりませんが、一応作ってみました。
コード ブロック#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);
-
見落としがあったので補足しておきます。
■実行環境
・Windows2000Server
・Windows2003Server
WMIのWin32_LogonSessionですが、これはWindowsXP以降が有効であり、Windows2000は
対象外でした。その為、Windows2000上では先に書いたコードの通り、カレントプロセスの
トークンから取得するしかなさそうです。
# Win32_LogonSessionが内部的にコールしているであろうLsaEnumerateLogonSessions()も
# 同様にWindowsXP以降となっています。
最も、Win32_LogonSessionクラス or LsaEnumerateLogonSessions()からログオンIDを探ろう
とすると、どれが自分のIDか特定する作業が必要になりそうですが。
-
作っていただいたサンプルソースを試してみました。
イベントビューア上のログオンIDと同じものが取得できました。
ところでサンプルソースではGetTokenInformationで取得したTOKEN_STATISTICS構造体メンバのAuthenticationIdを出力されてますが、
後続するLsaGetLogonSessionDataで取得したSECURITY_LOGON_SESSION_DATA構造体メンバにLogonIdというものがあります。
このLogonIdも出力してみるとAuthenticationIdと同じ値でした。
LogonIdは名前がそのものずばり「ログオンID」を指しているものと思いましたが、
LogonIdとAuthenticationIdとは同じものということでしょうか?
-
# 過去の資料から引っ張り出しただけなので、怪しい部分がありますが。
LogonIdは名前がそのものずばり「ログオンID」を指しているものと思いましたが、
LogonIdとAuthenticationIdとは同じものということでしょうか?
MSDNドキュメント自体にはAuhthenticationIdがLogonIdと等価であることは記載されていません。
ただ、TOKEN_STATISTICS::AuthenticationIdメンバの解説と、LsaEnumerateLogonSessions()
関数の解説を見る限りは、この2つが等価であると見て良いように思われます。
ピアソン・エデュケーション「Windows NT/2000 ネイティブAPIリファレンス」より引用
AuthenticationId: トークンが表すセッションに割り当てられたLUID。
一つのログオンセッションを表している複数のトークンがあることがあります。
この2値を等価として扱うかが不安であるならば、先に書いたようにLsaEnumerateLogonSessions()
からログオンセッション識別子(=LogonId)の一覧を取得して、インタラクティブなLogonIdを特定
する、という作業が必要かと思われます。
(ターミナルサーバー環境で試してないので、その場合は更に処理が必要になるのかどうなのか
わかりませんが・・・)
-
色々ありがとうございました。
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