CreateProcessAsUser関数を使うために、LogonUser関数を実行したのですが
以下のエラーになりました。

// A required privilege is not held by the client.
#define ERROR_PRIVILEGE_NOT_HELD 1314L

環境は
・Windows2000 Pro
・VC++ 6.0
です。

そのマシンにはオートログオンの設定がしてあり、オートログオンした
ユーザとパスワードを LogonUser関数に指定したのですがNGでした。
EXEはエクスプローラからダブルクリックして実行しました。

<オートログオン>
ユーザ:ABC
パスワード:123

例えば上記のような設定で、以下のコードのようにしました。

HANDLE hToken;
BOOL  bRet;
DWORD dwLastError;

bRet = LogonUser( "ABC",
         ".",
         "123",
         LOGON32_LOGON_INTERACTIVE,
         LOGON32_PROVIDER_DEFAULT,
         &hToken);

if (bRet == 0) {
dwLastError = GetLastError();
}

LogonUser関数は 0 が返り、詳細エラーは 0x522(1314) でした。
権限がない、というようなエラーですが、ログオンしたユーザと
取得しようとしたユーザが同じなのにエラーとなります。
何がいけないのでしょうか。

全然間違った考えことを言ってたら、ごめんなさい。。。
ここら辺の関数を使うのが初めてで、MSDN を何回も読んだのですが
理解できませんでした。
識者の方、アドバイスなどをお願いします。

A 回答 (3件)

こんにちは。

itohhといいます。

その後、解決したのでしょうか?
「回答に対する補足」が投稿されたのを今まで知りませんでした。

SE_TCB_NAME特権は、そもそもユーザのポリシーに付加されていないと
いけないのだと思います。

わたしが前に行ったときも特定のユーザIDに特権を付加した記憶があります。
もしかしたら、正当な解決方法ではないのかもしれませんが。

付加の方法は、
「コントロールパネル」「管理ツール」「ローカルセキュリティポリシー」を使用します。
この中の「ローカルポリシー」「ユーザ権利の割り当て」で
「オペレーティングシステムの一部として機能」に該当ユーザを設定します。

>マシンにログオンしているユーザ/パスワードと LogonUser関数に渡す
>パラメータは同じなのです
同一ならば、EnablePrivilege関数を呼ぶ必要もありません。
    • good
    • 0
この回答へのお礼

お礼が遅くなり、ほんとに申し訳ありませんでした。
今回は別手段にて回避させました。
セキュリティ関連については、今後勉強していきたいと思います。
ありがとうございました。

お礼日時:2002/04/05 18:09

こんにちは。

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

この回答への補足

早速の回答ありがとうございました。
大変勉強になりました。
教えていただいた通りに実行したところ、
・OpenProcessToken
・LookupPrivilegeValue
・AdjustTokenPrivileges
の関数は正常終了しました。
LookupPrivilegeValue関数の第2パラメータには SE_TCB_NAME
を指定しました。
しかし、LogonUser関数はエラーとなってしまいました。
エラーは同じく、ERROR_PRIVILEGE_NOT_HELD (1314) でした。

マシンにログオンしているユーザ/パスワードと LogonUser関数に渡す
パラメータは同じなのですが、、、
MSDN には SE_TCB_NAME 特権がないとこのエラーになると書いてありますが
他にも要因があるのでしょうか。

お手数かけますが、心当たりあればアドバイスお願いします。

補足日時:2002/02/15 14:10
    • good
    • 0
この回答へのお礼

すみません、補足に追加があるため「お礼」で投稿します。
AdjustTokenPrivileges関数は正常終了していましたが、
GetLastError関数で確認したところ、詳細コードは以下でした。

// Not all privileges referenced are assigned to the caller.
#define ERROR_NOT_ALL_ASSIGNED 1300L

このため SE_TCB_NAME 特権が有効にならず、LogonUser関数も
エラーになったと思われます。

お礼日時:2002/02/15 15:22

こんにちは。

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 です。
何か環境が古いのでしょうか。

補足日時:2002/02/15 10:53
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qコンピューター名の文字数制限

コンピューター名の文字数制限
ネットで検索すると15文字以下、14文字以下、
12文字以下、15文字以下でなるべく少ない文字数など、
さまざまです。
どれが正解なのでしょうか?
また、少なければ少ないほど良いのでしょうか?

Aベストアンサー

OSが記載されていませんが、Windowsということならば以下のサイトが参考になると思います。
http://technet.microsoft.com/ja-jp/library/cc757496(WS.10).aspx

Windowsであれば、
最大63バイト(全角文字も有効であるため単位はバイト)
推奨は15文字

NetBIOS名の制限がありますので、一般的には英数およびハイフンで、15文字以下ということになるかと思います。

Qコマンドプロンプトで別ユーザで実行するとき記述

Windows2000コマンドプロンプトで管理者権限でソフトを起動させようと考え
RUNAS /USER:administrator "実行ファイル名"
とバッチファイルに記述したのですが実行時にユーザーのパスワードを聞かれてしまいます。

何かユーザ名を聞かれなくする方法があれば教えてください。

Aベストアンサー

http://www.vector.co.jp/soft/winnt/util/se364267.html
こちらをどうぞ

参考URL:http://www.vector.co.jp/soft/winnt/util/se364267.html

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

Q「SSL状態のクリア」ボタンを押すと何が起こるのでしょうか?

インターネットオプションのコンテンツタブのところにある「SSL状態のクリア」ボタンを押すと何が起こるのでしょうか?

Aベストアンサー

ちょっと難しいかも知れないが

SSL通信と証明書
http://alk.dip.jp/apache2-default/sv170.html
http://alk.dip.jp/apache2-default/sv290.html

SSL証明書のクリア
http://support.microsoft.com/kb/290345/ja

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

QUACの権限昇格の確認ダイアログについて

環境:Windows7+VS2012(VC++)

WindowsXPの時代に、INIファイルをコピーするプログラムを作成したのですが、それをWindows7へ移植したのですが、インストールフォルダを ProgramFiles にすると、UACの権限昇格の確認ダイアログが表示されてしまいます。

これを表示させないようにすることは可能なのでしょうか?

Aベストアンサー

定型処理をUACダイアログを表示させずに行うことは可能です。

1.タスクスケジューラーに、その定型作業を登録します。
2.このとき、「最上位の特権で実行する」をチェックします。これでUACを回避できます。
3.実行したいときは、「schtasks /run /tn タスク名」を実行します。

タスク登録の詳細手順:
1.コントロールパネル→システムとセキュリティ→管理ツール→タスクスケジューラ
2.右側ペインで、「タスクの作成」をクリック
3.全般タブで、名前を適当に付け、「最上位の特権で実行する」をチェック
4.操作タブで、「新規」をクリック
5.操作を「プログラムの開始」のままで、プログラム欄と、必要があれば引数欄を入力。開始欄には必要があれば、プログラム起動時のカレントフォルダを指定。引数が複雑だったり、複数ステップだったりならバッチファイルにしておくのがいいでしょう。
6.あとはOK


人気Q&Aランキング