Démarrer / Arrêter un service Windows à partir d'un compte d'utilisateur non administrateur

121

J'ai un WindowsService nommé, disons, BST. Et je dois donner à un utilisateur non administrateur, UserA, les autorisations pour démarrer / arrêter ce service particulier. Mon service fonctionne sur une variété de systèmes d'exploitation Windows, à partir de Windows Server 2003 à Windows 7.

Comment puis-je faire ceci?

J'ai cherché sur Google et trouvé des informations sur l'octroi d'autorisations à l'aide de la commande [sc sdset], mais je ne suis pas exactement sûr des paramètres. Je ne veux pas définir les autorisations pour un groupe, mais UNIQUEMENT à un utilisateur particulier, UserA dans ce cas.

Sach
la source

Réponses:

141

Ci-dessous, j'ai rassemblé tout ce que j'ai appris sur le démarrage / l'arrêt d'un service Windows à partir d'un compte d'utilisateur non administrateur, si quelqu'un a besoin de savoir.

Principalement, il existe deux façons de démarrer / arrêter un service Windows. 1. Accéder directement au service via le compte utilisateur Windows de connexion. 2. Accéder au service via IIS à l'aide d'un compte de service réseau.

Commande de ligne de commande pour démarrer / arrêter les services:

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

Code C # pour démarrer / arrêter les services:

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

Remarque 1: lors de l'accès au service via IIS, créez une application Web Visual Studio C # ASP.NET et placez-y le code. Déployez le WebService dans le dossier racine IIS (C: \ inetpub \ wwwroot \) et vous êtes prêt à partir. Accédez-y par l'url http: ///.

1. Méthode d'accès direct

Si le compte d'utilisateur Windows à partir duquel vous donnez la commande ou exécutez le code est un compte non administrateur, vous devez définir les privilèges sur ce compte d'utilisateur particulier afin qu'il puisse démarrer et arrêter les services Windows. Voici comment vous procédez. Connectez-vous à un compte administrateur sur l'ordinateur qui possède le compte non administrateur à partir duquel vous souhaitez démarrer / arrêter le service. Ouvrez l'invite de commande et donnez la commande suivante:

C:/>sc sdshow <SERVICE_NAME>

La sortie de ceci sera quelque chose comme ceci:

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

Il répertorie toutes les autorisations de chaque utilisateur / groupe sur cet ordinateur.

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.

Maintenant, ce que nous devons faire est de définir les autorisations appropriées pour démarrer / arrêter les services Windows pour les groupes ou les utilisateurs que nous voulons. Dans ce cas, nous avons besoin que l'utilisateur non administrateur actuel puisse démarrer / arrêter le service, nous allons donc définir les autorisations pour cet utilisateur. Pour ce faire, nous avons besoin du SID de ce compte utilisateur Windows particulier. Pour l'obtenir, ouvrez le registre (Démarrer> regedit) et recherchez la clé de registre suivante.

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

En dessous, il existe une clé distincte pour chaque compte d'utilisateur de cet ordinateur et le nom de la clé est le SID de chaque compte. Les SID sont généralement au format S-1-5-21-2103278432-2794320136-1883075150-1000. Cliquez sur chaque clé, et vous verrez sur le volet à droite une liste de valeurs pour chaque clé. Recherchez «ProfileImagePath» et par sa valeur, vous pouvez trouver le nom d'utilisateur auquel appartient le SID. Par exemple, si le nom d'utilisateur du compte est SACH, la valeur de "ProfileImagePath" sera quelque chose comme "C: \ Users \ Sach". Notez donc le SID du compte d'utilisateur sur lequel vous souhaitez définir les autorisations.

Note 2: Voici un exemple de code C # simple qui peut être utilisé pour obtenir une liste desdites clés et de leurs valeurs.

//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");
}

Maintenant que nous avons le SID du compte d'utilisateur sur lequel nous voulons définir les autorisations, allons-y. Supposons que le SID du compte utilisateur soit S-1-5-21-2103278432-2794320136-1883075150-1000 . Copiez la sortie de la commande [sc sdshow] dans un éditeur de texte. Il ressemblera à ceci:

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

Maintenant, copiez la partie (A ;; CCLCSWRPWPDTLOCRRC ;;; SY) du texte ci-dessus et collez-la juste avant la partie S: (AU; ... du texte. Puis changez cette partie pour qu'elle ressemble à ceci: (A ;; RPWPCR ;;; S-1-5-21-2103278432-2794320136-1883075150-1000)

Ensuite, ajoutez sc sdset au début et entourez la partie ci-dessus de guillemets. Votre commande finale devrait ressembler à ceci:

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)"

Maintenant, exécutez ceci dans votre invite de commande, et il devrait donner la sortie comme suit en cas de succès:

[SC] SetServiceObjectSecurity SUCCESS

Maintenant, nous sommes prêts à partir! Votre compte utilisateur non administrateur a reçu les autorisations pour démarrer / arrêter votre service! Essayez de vous connecter au compte d'utilisateur et de démarrer / arrêter le service et cela devrait vous permettre de le faire.

2. Accès via la méthode IIS

Dans ce cas, nous devons accorder l'autorisation à l'utilisateur IIS "Services réseau" au lieu du compte d'utilisateur Windows de connexion. La procédure est la même, seuls les paramètres de la commande seront modifiés. Puisque nous avons défini l'autorisation sur "Services réseau", remplacez SID par la chaîne "NS" dans la commande sdset finale que nous avons utilisée précédemment. La commande finale devrait ressembler à ceci:

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)"

Exécutez-le dans l'invite de commande à partir d'un compte d'utilisateur Admin, et le tour est joué! Vous avez la permission de démarrer / arrêter le service à partir de n'importe quel compte utilisateur (qu'il s'agisse d'un compte administrateur ou non) à l'aide d'une méthode Web. Reportez-vous à la note 1 pour savoir comment procéder.

Sach
la source
11
REMARQUE: ** Vous DEVEZ copier les résultats de la commande shshow exécutée dans votre propre machine, puis les éditer selon ce que j'ai spécifié. ** NE copiez PAS simplement le code à partir d'ici et exécutez-le sur votre ordinateur tel quel.
Sach
5
J'ai essayé cette approche manuelle et cela a fonctionné à merveille. Mais si vous êtes comme moi et que vous devez le faire sur plus de 20 ordinateurs, vous voudrez un programme ou un script pour le faire. Vous pouvez utiliser les appels d'API Windows QueryServiceObjectSecurity et SetServiceObjectSecurity . MSDN a un exemple
Drew Chapin
1
Bravo! A travaillé comme un charme.
Horst Gutmann
2
pour ne pas enlever les efforts et les soins qui ont été apportés à cette réponse, je pense que certaines des autres réponses offrent une solution plus simple et plus directe. À moins que je ne manque un avantage de cela?
Spike0xff
1
Si vous faites cela par programme et que vous souhaitez fractionner la sortie, sc sdshowvous pouvez utiliser cette expression régulière pour fractionner les composants: (?:\D:)?\(.+?\)puis insérer la nouvelle partie avec le SID comme avant-dernier.
PhonicUK
115

J'utilise l' utilitaire SubInACL pour cela. Par exemple, si je voulais donner au travail utilisateur sur l'ordinateur VMX001 la possibilité de démarrer et d'arrêter le service de publication World Wide Web (également connu sous le nom de w3svc), j'émettrais la commande suivante en tant qu'administrateur:

subinacl.exe /service w3svc /grant=VMX001\job=PTO

Les autorisations que vous pouvez accorder sont définies comme suit (liste tirée d' ici ):

F : Full Control
R : Generic Read
W : Generic Write
X : Generic eXecute
L : Read controL
Q : Query Service Configuration
S : Query Service Status
E : Enumerate Dependent Services
C : Service Change Configuration
T : Start Service
O : Stop Service
P : Pause/Continue Service
I : Interrogate Service 
U : Service User-Defined Control Commands

Ainsi, en spécifiant PTO, j'autorise l' utilisateur du travail à mettre en pause / continuer, démarrer et arrêter le service w3svc.

arcain
la source
18
C'est la meilleure réponse. Il utilise le bon outil pour le travail sans pirater le registre, traduire les SID ou dépendre d'un formatage ACL obscur. Fournit tout ce qui est nécessaire pour faire le travail rapidement et facilement avec suffisamment de détails pour l'extrapoler à n'importe quel scénario raisonnable.
pierce.jason
2
Dois-je redémarrer ou me déconnecter / me connecter lorsque j'utilise cela?
David dit réintégrer Monica le
2
@DavidGrinberg Je ne me souviens pas avoir jamais eu besoin de déconnecter puis de rallumer le compte concerné, ou d'avoir à redémarrer en utilisant uniquement subinacl comme décrit ici.
arcain
1
Peut confirmer que cela fonctionne sur le serveur 2012 en utilisant sc \\server start|stop|query servicenameun serveur distant. Aucun redémarrage \ déconnexion nécessaire
Stig Eide
Cela a fonctionné pour démarrer un service localement. Cependant , il est écrasé avec l' CouldNotAccessDependentServicesaide powershell à distance: Cannot access dependent services of '...'. L'ajout E : Enumerate Dependent Servicesdes droits ACL a corrigé cela.
Willem
42
  1. Connectez-vous en tant qu'administrateur.
  2. Téléchargement subinacl.exedepuis Microsoft:
    http://www.microsoft.com/en-us/download/details.aspx?id=23510
  3. Accordez des autorisations au compte d'utilisateur normal pour gérer les services BST.
    ( subinacl.exeest en C:\Program Files (x86)\Windows Resource Kits\Tools\).
  4. cd C:\Program Files (x86)\Windows Resource Kits\Tools\
    subinacl /SERVICE \\MachineName\bst /GRANT=domainname.com\username=F ou
    subinacl /SERVICE \\MachineName\bst /GRANT=username=F
  5. Déconnectez-vous et reconnectez-vous en tant qu'utilisateur. Ils devraient maintenant pouvoir lancer le service BST.
Venkat
la source
1
Cela semble beaucoup plus facile et meilleur que de manipuler manuellement les configurations.
gsk
1
La déconnexion est-elle requise?
David dit réintégrer Monica le
oups! Échec ... J'ai eu "Erreur OpenSCManager: Le serveur RPC n'est pas disponible. AVERTISSEMENT: / grant = mike = f: Aucun objet précédent ouvert". Le service que j'ai essayé était MySQL. Redémarrage: l'accès est refusé, comme toujours.
mike rodent
15

Il existe un ServiceSecurityEditor d' outil GUI gratuit

Ce qui vous permet de modifier les autorisations du service Windows. Je l'ai utilisé avec succès pour donner à un utilisateur non administrateur les droits de démarrer et d'arrêter un service.

J'avais utilisé "sc sdset" avant de connaître cet outil.

ServiceSecurityEditor a l'impression de tricher, c'est aussi simple que ça :)

FCW
la source
1
J'ai essayé ServiceSecurityEditor sur la base de cette recommandation et c'est excellent.
Guru Josh
11

Il est beaucoup plus facile d'accorder des autorisations de gestion à un service à l'aide de l'un de ces outils:

  • Stratégie de groupe
  • Modèle de sécurité
  • Outil de ligne de commande subinacl.exe.

Voici l' article MSKB avec des instructions pour Windows Server 2008 / Windows 7, mais les instructions sont les mêmes pour 2000 et 2003.

Ryan Fisher
la source
1

L'outil de ligne de commande subinacl.exe est probablement le seul viable et très facile à utiliser à partir de tout ce qui se trouve dans cet article. Vous ne pouvez pas utiliser un GPO avec des services non système et l'autre option est bien trop compliquée.

JustAGuy
la source
-2

Le service Windows s'exécute à l'aide d'un compte système local.Il peut démarrer automatiquement lorsque l'utilisateur se connecte au système ou il peut être démarré manuellement.Cependant, un service Windows dit que BST peut être exécuté à l'aide d'un compte utilisateur particulier sur la machine. comme suit: démarrez services.msc et accédez aux propriétés de votre service Windows, BST.De là, vous pouvez donner les paramètres de connexion de l'utilisateur requis.Le service s'exécute ensuite avec ce compte d'utilisateur et aucun autre utilisateur ne peut exécuter ce service.

Jack Sparrow
la source
1
Merci pour la réponse Jack. Cependant ce n'est pas ce que je veux faire. J'ai besoin de mon service BST pour fonctionner comme il le fait maintenant. Je n'ai besoin que d'un utilisateur qui n'est pas un administrateur pour pouvoir l'arrêter / le démarrer.
Sach