1. ホーム
  2. windows-services

[解決済み] 管理者以外のユーザーアカウントでWindowsサービスを開始/停止する

2022-07-04 14:31:23

質問

BST という名前の WindowsService を持っています。そして、管理者でないユーザー UserA に、この特定のサービスを開始/停止する権限を与える必要があります。私のサービスは、Windows Server 2003 から Windows 7 まで、さまざまな Windows OS 上で実行されます。

どうすればよいでしょうか。

私はググって、[sc sdset]コマンドを使用してパーミッションを与えることについていくつかのものを見つけましたが、私はパラメータについて正確に理解していません。私はグループのためにパーミッションを設定したいのではなく、特定のユーザー(この場合はUserA)に対してのみ設定したいのです。

どのように解決するのですか?

以下に、非管理者ユーザー アカウントからの Windows サービスの開始/停止について私が学んだことすべてをまとめましたので、どなたか知っておく必要があればご覧ください。

主に、Windows サービスを開始/停止する方法は 2 つあります。 1. Windowsユーザーアカウントでログオンし、サービスに直接アクセスする。 2. ネットワークサービスアカウントを使用してIISからサービスにアクセスする。

サービスの開始/停止を行うコマンドラインコマンド。

C:/> net start <SERVICE_NAME>
C:/> net stop <SERVICE_NAME>

サービスの起動・停止を行うC#コードです。

ServiceController service = new ServiceController(SERVICE_NAME);

//Start the service
if (service.Status == ServiceControllerStatus.Stopped)
{
      service.Start();
      service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(10.0));
}

//Stop the service
if (service.Status == ServiceControllerStatus.Running)
{
      service.Stop();
      service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(10.0));
}

注1: IISからアクセスする場合は、Visual Studio C# ASP.NET Web Applicationを作成し、その中にコードを記述してください。WebServiceをIIS Root Folder (C:\inetpubwwwroot Filter)にデプロイすれば、OKです。 http:/// というURLでアクセスします。

1. 直接アクセスの方法

コマンドを実行する、またはコードを実行する Windows ユーザー アカウントが管理者以外のアカウントである場合、その特定のユーザー アカウントに Windows サービスを開始および停止する能力を持つように、特権を設定する必要があります。これはそれを行う方法です。 サービスを開始/停止したい非管理者アカウントを持つコンピュータで、管理者アカウントにログインします。 コマンドプロンプトを開き、以下のコマンドを実行します。

C:/>sc sdshow <SERVICE_NAME>

これを出力すると、次のようになります。

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

このコンピュータ上の各ユーザー / グループが持っている、.NET Framework に関するすべての権限を一覧表示します。

A description of one part of above command is as follows:

    D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)

It has the default owner, default group, and it has the Security descriptor control flags (A;;CCLCSWRPWPDTLOCRRC;;;SY):

ace_type - "A": ACCESS_ALLOWED_ACE_TYPE,
ace_flags - n/a,
rights - CCLCSWRPWPDTLOCRRC,  please refer to the Access Rights and Access Masks and Directory Services Access Rights
CC: ADS_RIGHT_DS_CREATE_CHILD - Create a child DS object.
LC: ADS_RIGHT_ACTRL_DS_LIST - Enumerate a DS object.
SW: ADS_RIGHT_DS_SELF - Access allowed only after validated rights checks supported by the object are performed. This flag can be used alone to perform all validated rights checks of the object or it can be combined with an identifier of a specific validated right to perform only that check.
RP: ADS_RIGHT_DS_READ_PROP - Read the properties of a DS object.
WP: ADS_RIGHT_DS_WRITE_PROP - Write properties for a DS object.
DT: ADS_RIGHT_DS_DELETE_TREE - Delete a tree of DS objects.
LO: ADS_RIGHT_DS_LIST_OBJECT - List a tree of DS objects.
CR: ADS_RIGHT_DS_CONTROL_ACCESS - Access allowed only after extended rights checks supported by the object are performed. This flag can be used alone to perform all extended rights checks on the object or it can be combined with an identifier of a specific extended right to perform only that check.
RC: READ_CONTROL - The right to read the information in the object's security descriptor, not including the information in the system access control list (SACL). (This is a Standard Access Right, please read more http://msdn.microsoft.com/en-us/library/aa379607(VS.85).aspx)
object_guid - n/a,
inherit_object_guid - n/a,
account_sid - "SY": Local system. The corresponding RID is SECURITY_LOCAL_SYSTEM_RID.

ここで必要なことは、Windowsサービスを開始/停止するための適切なパーミッションを、必要なグループまたはユーザーに設定することです。この場合、現在の非管理ユーザーがサービスを開始/停止できるようにする必要があるので、そのユーザーに権限を設定するつもりです。これを行うには、その特定のWindowsユーザーアカウントのSIDが必要です。これを取得するには、レジストリ (スタート > regedit) を開き、次のレジストリ キーを探します。

LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList

その下には、このコンピュータの各ユーザーアカウントごとに別々の鍵があり、鍵の名前は各アカウントの SID になっています。SIDは通常、S-1-5-21-2103278432-2794320136-1883075150-1000という形式です。各Keyをクリックすると、右側のペインに各Keyの値のリストが表示されます。ProfileImagePath"を見つけると、その値からSIDが所属するユーザー名を見つけることができます。例えば、アカウントのユーザー名がSACHの場合、"ProfileImagePath" の値は "C:\UsersSach" のようなものになります。なので、パーミッションを設定したいユーザーアカウントのSIDをメモしておいてください。

注2: ここでは、キーとその値のリストを取得するために使用できる簡単なC#のコードサンプルです。

//LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList RegistryKey
RegistryKey profileList = Registry.LocalMachine.OpenSubKey(keyName);

//Get a list of SID corresponding to each account on the computer
string[] sidList = profileList.GetSubKeyNames();

foreach (string sid in sidList)
{
    //Based on above names, get 'Registry Keys' corresponding to each SID
    RegistryKey profile = Registry.LocalMachine.OpenSubKey(Path.Combine(keyName, sid));

    //SID
    string strSID = sid;
    //UserName which is represented by above SID    
    string strUserName = (string)profile.GetValue("ProfileImagePath");
}

さて、パーミッションを設定したいユーザーアカウントのSIDがわかったところで、本題に入りましょう。ユーザーアカウントのSIDを S-1-5-21-2103278432-2794320136-1883075150-1000 . sc sdshow ]コマンドの出力をテキストエディタにコピーしてください。このように表示されます。

D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)

ここで (a;;cclcswrpwpdtlocrrc;;;sy) とします。 の部分をコピーし、貼り付けます。 の直前に S:(AU;...です。 の部分を変更します。そして、その部分を次のように変更します。 (A;;RPWPCR;;;S-1-5-21-2103278432-2794320136-1883075150-1000)

次に scsdset を追加し、上記の部分を引用符で囲みます。最終的には以下のようなコマンドになるはずです。

sc sdset <SERVICE_NAME> "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPCR;;;S-1-5-21-2103278432-2794320136-1883075150-1000)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"

さて、これをコマンドプロンプトで実行すると、成功すれば以下のような出力が得られるはずです。

[SC] SetServiceObjectSecurity SUCCESS

これでもう大丈夫です! 非Adminユーザーアカウントに、サービスをStart/Stopする権限が付与されました! このユーザーアカウントでログインし、サービスの開始/停止を実行してみてください。

2. IISメソッドによるアクセス

この場合、ログオンしている Windows ユーザー アカウントではなく、IIS ユーザー "Network Services" に権限を付与する必要があります。手順は同じで、コマンドのパラメーターが変更されるだけです。許可を "Network Services" に設定するので、SID を文字列 "NS" に置き換え、最後の sdset コマンドを使用します。最終的なコマンドは、次のようになります。

sc sdset <SERVICE_NAME> "D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;RPWPCR;;;NS)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)"

Adminユーザーアカウントからコマンドプロンプトで実行すると、ほら! これで、どのユーザーアカウントからでも(Adminアカウントかどうかにかかわらず)WebMethodを使ってサービスを開始/停止できるようになりました。その方法については、注1を参照してください。