サービス間での通信を行うには?

解決


柚子  2009-04-08 00:26:35  No: 69935

先日サービスについて質問致しましたが
また問題が発生しましたので質問させて頂きます。

サービス起動後に、そのサービス間で通信を行うプログラムを作成しておりますが
サービスでファイルマッピング作成を行っても、通信側でマップを開くと
ERROR_ACCESS_DENIEDが発生します

DLLにマップ処理全てを纏めて、サービスからDLLをロードして試しても
同様のエラーが発生します。

サービスがSystem権限で動いている為にこのような事になっているのは分かってはいますが
どうすればうまく通信が出来るでしょうか?

サービスから連携プログラムを起動させ
共にSystem権限にするしか無いのでしょうか?

どうぞよろしく御願いします。


オショウ  2009-04-08 01:15:58  No: 69936

C言語でサービス作っておられるならば、近道は無い
ので、サービスの偽装に関しては、ちゃんと勉強して
みては?

一般的?な偽装方法
http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/46c3ded6-b576-4b83-a06e-36db22ec0562/

ここにAPIでの手順を書いてくれていました。

この方は、プロセスの起動ですが・・・先の質問と同様ですネ
で、偽装は同じ方法なので・・・流用してみて下さい。

因みに、サービス間と言う表現は、サービス同士のように思わ
れますが、デスクトップのアプリとWidnowsサービス間ですよ
ね?

以上。参考まで


オショウ  2009-04-08 01:35:47  No: 69937

サービス作りの勉強に使った書籍
※  もうかなり昔なので、入手不能だと思われますが

Win32システムサービスプログラミング  \5,631.-
プレティスホール社 ISBN4-88735-030-9

WindowsNT ServiceProgramming  \4,800.-
ソフトバンクパブリッシング社 ISBN4-7973-0948-2

Windowsサービス開発テクニック  \2,300.-
CQ出版社 ISBN4-7898-1873-3

●  この中で一番よくタメになったのは・・・
    WindowsNT ServiceProgramming でした。

    Win2000以降Windowsサービス関連の書籍は少なく
    なったように思いますが、提供される開発環境内
    で簡単に作れるようになったので、少なくなった
    のでは・・・と思ってます。

    最近の書籍では残念ながら見知ったものはありま
    せん。

参考まで


オショウ  2009-04-08 01:39:36  No: 69938

追伸・・・もう1冊

Win32システムサービスプログラミング改訂版  \7,800.-
ピアソンエデュケーション社 ISBN4-89471-371-3

こちらは先のものから出版社が相違しますが、Win2000と
セキュリティ関係やActiveDirectory部分の記事が追加さ
れ、改訂版として出版されたものです。
1.5倍ほど厚みが増えてます・・・

以上。


柚子  2009-04-08 18:41:29  No: 69939

おしょうさん、レス有難うございます

サービスとデーモンの開発経験があり
デーモン側でのActiveDirectoryからログオン、ユーザ偽装等はやった事があります

今回はサービス自身がユーザを偽装するという事でしょうか?
サービスはSystem権限で常に動いている事を望んでいますが
やはり権限の差があるため、相互通信は難しいでしょうか?

質問ばかりで申し訳ありません。よろしく御願いします。


aetos  2009-04-08 19:28:08  No: 69940

いくつか質問。

1:OSは何ですか?
2:サービスと、サービスでないアプリ間で、ファイルマッピングを共有したい、ということでOK?
3:サービス側での CreateFileMapping には成功しているが、アプリの方で OpenFileMapping で ERROR_ACCESS_DENIED ということ?
4:それぞれの関数の引数は具体的にどうなってます?


柚子  2009-04-08 23:44:26  No: 69941

aetosさん、レス有難うございます

1: XP Pro SP2で現在開発しています
2: はい、その通りです。
3: はい、その通りです。
4: サービス側   ->CreateFileMapping( (HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, 10000, "HOGEHOGE" );
   連携アプリ側 ->OpenFileMapping( NULL, FALSE, "HOGEHOGE" );

としています。

通常のアプリ同士で試した所うまく動作しているのは確認しています。


aetos  2009-04-09 02:00:23  No: 69942

CreateFileMapping の第2引数が NULL ですね。
この引数は、「よくわからないのでとりあえず NULL」にしがちで、今回のようなケースでもなければ大抵それで問題にならないのですが、今回はどうもそれが原因みたいです。
あと、OpenFileMapping の第1引数が NULL なのはおかしいですね。ここはポインタじゃありませんから。

CreateFileMapping の第2引数は SECURITY_INFORMATION 構造体へのポインタです。
この構造体の lpSecurityDescriptor が、セキュリティ記述子へのポインタになります。
セキュリティ記述子は、このオブジェクトに対して、誰がどんなアクセスをしようとした時に許可するか・拒否するか等の情報が格納されます。

第2引数が NULL ですと、デフォルトのセキュリティ記述子が使われます。
デフォルトのセキュリティ記述子は、そのオブジェクトの作成者と LocalSystem にのみアクセスを許可します。
http://support.microsoft.com/kb/318825/ja

従って、そのオブジェクトの作成者でも LocalSystem でもない一般ユーザーアカウントで実行されているアプリからは、Open に失敗する、というのが原因だと思われます。

ちょっと面倒くさいですが、連携アプリを実行するユーザに対してアクセスを許可するようなセキュリティ記述子を作って、第2引数に渡してやる必要があるでしょう。

1. ACL を作る
2. ACL に、連携アプリを実行するユーザにアクセスを許可するような ACE を追加する
3. セキュリティ記述子を作る
4. セキュリティ記述子に ACL を追加する
5. 作ったセキュリティ記述子を入れた SECURITY_INFORMATION 構造体を使って CreateFileMapping する

という流れになります。
詳しくは、このへん
http://eternalwindows.jp/security/accesscontrol/accesscontrol00.html
を参照してください。


柚子  2009-04-09 04:30:20  No: 69943

詳細に書いて頂き有難うございます。
OpenFileMappingの第一引数はFILE_MAP_ALL_ACCESSでした; 申し訳ありません

aetosさんが仰るとおり、CreateFileMappingの第二引数は良く分からずNULLにしていました。
aetosさんがご教授して頂けました流れに沿ってまたコーディングを行ってみます。

レスを下さった方々本当に有難うございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加