- ベストアンサー
LogonUser関数でERROR_PRIVILEGE_NOT_HELDエラーが発生しました
- LogonUser関数を実行する際に、CreateProcessAsUser関数を使用するために必要な特権がクライアントによって保持されていないため、ERROR_PRIVILEGE_NOT_HELDエラーが発生しました。
- オートログオンが設定されているWindows 2000 Pro環境で、LogonUser関数を呼び出す際にオートログオンしたユーザとパスワードを指定しましたが、エラーが発生しました。
- LogonUser関数の戻り値が0であり、詳細エラーコードは0x522 (1314) です。同じユーザでログオンしているにもかかわらず、特権がないというエラーが発生しています。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。itohhといいます。 その後、解決したのでしょうか? 「回答に対する補足」が投稿されたのを今まで知りませんでした。 SE_TCB_NAME特権は、そもそもユーザのポリシーに付加されていないと いけないのだと思います。 わたしが前に行ったときも特定のユーザIDに特権を付加した記憶があります。 もしかしたら、正当な解決方法ではないのかもしれませんが。 付加の方法は、 「コントロールパネル」「管理ツール」「ローカルセキュリティポリシー」を使用します。 この中の「ローカルポリシー」「ユーザ権利の割り当て」で 「オペレーティングシステムの一部として機能」に該当ユーザを設定します。 >マシンにログオンしているユーザ/パスワードと LogonUser関数に渡す >パラメータは同じなのです 同一ならば、EnablePrivilege関数を呼ぶ必要もありません。
その他の回答 (2)
- itohh
- ベストアンサー率45% (210/459)
こんにちは。itohhといいます。 >EnablePrivilege関数についてMSDNを見たのですが、載っていませんでした。 すみません、わたしが自作した関数でした。 失念していました。 改めて解説します。 MSDNライブラリの解説に >LogonUser 関数を呼び出すプロセスは、SE_TCB_NAME 特権を備えていなければなりません。 とあるように特権を動的にプログラム内から設定しなければいけません。 処理の流れとしては、以下のとおりです。 1.アクセストークンのオープン 2.Privilegeの名前に対するLUIDを取得 3.特権の設定(Enable/Disable) 4.アクセストークンのクローズ EnablePrivilege関数のサンプルを載せておきます。 (インデントするために行の先頭に全角スペースを挿入しています) この関数で一時的にSE_TCB_NAME 特権を有効にするように使ってください。 (クラスのメンバ関数としても良いと思います) BOOL EnablePrivilege(LPCTSTR pszPrivName, BOOL bEnable) { HANDLE hToken; TOKEN_PRIVILEGES tp; LUID luid; BOOL bResult = FALSE; // アクセストークンのオープン if (!::OpenProcessToken( ::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)){ return FALSE; } // Privilegeの名前に対するLUIDを取得 if (::LookupPrivilegeValue(NULL, pszPrivName, &luid)){ tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; // (Enable/Disable)に応じてアトリビュートを設定する。 if( bEnable ){ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; } else { tp.Privileges[0].Attributes = 0; } // 特権のEnable/Disableを設定 if (::AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), 0, 0) ){ bResult = TRUE; } } // アクセストークンをクローズする。 ::CloseHandle(hToken); return bResult; }
お礼
すみません、補足に追加があるため「お礼」で投稿します。 AdjustTokenPrivileges関数は正常終了していましたが、 GetLastError関数で確認したところ、詳細コードは以下でした。 // Not all privileges referenced are assigned to the caller. #define ERROR_NOT_ALL_ASSIGNED 1300L このため SE_TCB_NAME 特権が有効にならず、LogonUser関数も エラーになったと思われます。
補足
早速の回答ありがとうございました。 大変勉強になりました。 教えていただいた通りに実行したところ、 ・OpenProcessToken ・LookupPrivilegeValue ・AdjustTokenPrivileges の関数は正常終了しました。 LookupPrivilegeValue関数の第2パラメータには SE_TCB_NAME を指定しました。 しかし、LogonUser関数はエラーとなってしまいました。 エラーは同じく、ERROR_PRIVILEGE_NOT_HELD (1314) でした。 マシンにログオンしているユーザ/パスワードと LogonUser関数に渡す パラメータは同じなのですが、、、 MSDN には SE_TCB_NAME 特権がないとこのエラーになると書いてありますが 他にも要因があるのでしょうか。 お手数かけますが、心当たりあればアドバイスお願いします。
- itohh
- ベストアンサー率45% (210/459)
こんにちは。itohhといいます。 特権 SE_TCB_NAMEを有効にしてからLogonUser関数を実行してみてください。 // 特権 SE_TCB_NAME を有効にする。 if (!::EnablePrivilege(SE_TCB_NAME, TRUE)){ return FALSE; } bRet = LogonUser( "ABC", ".", "123", LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken); if (bRet == 0) { dwLastError = GetLastError(); } // 特権 SE_TCB_NAME を無効にする。 ::EnablePrivilege(SE_TCB_NAME, FALSE);
補足
回答ありがとうございました。 ちょっと教えていただきたいことがあります。 EnablePrivilege関数についてMSDNを見たのですが、載っていませんでした。 (2001年110月版です) また、実際にコンパイルしてみてもエラーとなりました。 使用しているのは VC++ 6.0 です。 何か環境が古いのでしょうか。
お礼
お礼が遅くなり、ほんとに申し訳ありませんでした。 今回は別手段にて回避させました。 セキュリティ関連については、今後勉強していきたいと思います。 ありがとうございました。