.Net 2.0 ServiceController.GetServices()
J'ai un site qui a de l'authentification windows activer sur elle. À partir d'une page dans le site web, les utilisateurs ont la possibilité de démarrer un service qui fait des trucs avec la base de données.
Il fonctionne très bien pour moi de démarrer le service parce que je suis un administrateur local sur le serveur. Mais j'ai juste eu un test d'utilisateurs et ils ne peuvent pas obtenir le démarrage du service.
Ma question est:
Personne ne sait de façon à obtenir une liste de services sur un ordinateur spécifié par le nom à l'aide d'un autre compte windows que celui auquel ils sont actuellement connecté avec?
Je ne veux vraiment pas à ajouter tous les utilisateurs qui ont besoin de démarrer le service dans un groupe windows et de les mettre tous à un admin sur mon serveur IIS.....
Voici le code que j'ai:
public static ServiceControllerStatus FindService()
{
ServiceControllerStatus status = ServiceControllerStatus.Stopped;
try
{
string machineName = ConfigurationManager.AppSettings["ServiceMachineName"];
ServiceController[] services = ServiceController.GetServices(machineName);
string serviceName = ConfigurationManager.AppSettings["ServiceName"].ToLower();
foreach (ServiceController service in services)
{
if (service.ServiceName.ToLower() == serviceName)
{
status = service.Status;
break;
}
}
}
catch(Exception ex)
{
status = ServiceControllerStatus.Stopped;
SaveError(ex, "Utilities - FindService()");
}
return status;
}
Mon exception de la deuxième ligne dans le bloc try. Voici l'erreur:
Système.InvalidOperationException:
Impossible d'ouvrir le Gestionnaire de Contrôle de Service sur
l'ordinateur "server.domain.com'. Cette
l'opération peut nécessiter d'autres
les privilèges. --->
Système.ComponentModel.Win32Exception:
Accès refusé --- Fin de l'intérieure
trace de pile d'exception --- à
Système.ServiceProcess.ServiceController.GetDataBaseHandleWithAccess(String
machineName, Int32
serviceControlManaqerAccess) à
Système.ServiceProcess.ServiceController.GetServicesOfType(String
machineName, Int32 serviceType) à
TelemarketingWebSite.Utilitaires.StartService()
Merci pour l'aide/info
OriginalL'auteur Miles | 2008-10-16
Vous devez vous connecter pour publier un commentaire.
Remarque: Ce n'est pas l'adresse de l'énumération des services en tant qu'utilisateur différent, mais compte tenu de la grande description de ce que vous faites, je pense que c'est une bonne réponse.
Je pense que vous pouvez simplifier beaucoup de choses, et probablement d'éviter une partie du problème de sécurité, si vous allez directement au service de l'intérêt. Au lieu d'appeler GetServices, essayez ceci:
Ce connecte directement au service de l'intérêt et contourne l'énumération/recherche de l'étape. Par conséquent, il ne nécessite pas l'appelant d'avoir la
SC_MANAGER_ENUMERATE_SERVICE
droit sur le Gestionnaire de Contrôle des Services (SCM), qui à distance les utilisateurs n'ont pas par défaut. Il ne nécessitent encoreSC_MANAGER_CONNECT
, mais selon MSDN qui devraient être accordés à des utilisateurs authentifiés à distance.Une fois que vous avez trouvé le service d'intérêt, vous aurez toujours besoin d'être en mesure d'arrêter et de démarrer, ce qui à vos utilisateurs distants n'ont probablement pas le droit de le faire. Toutefois, il est possible de modifier le descripteur de sécurité (DACL) sur les différents services, ce qui permet d'accorder aux utilisateurs distants d'accéder à arrêter et démarrer le service, sans les obliger à être les administrateurs locaux. Cela se fait via le SetNamedSecurityInfo la fonction de l'API. Les droits d'accès vous avez besoin de subvention sont
SERVICE_START
etSERVICE_STOP
. Selon exactement sur ce qui les groupes de ces utilisateurs appartiennent, vous pourriez aussi avoir besoin de leur accorderGENERIC_READ
. Tous ces droits sont décrite dans MSDN.Voici le code C++ qui permettrait d'effectuer cette installation, en supposant que les utilisateurs d'intérêts sont dans le "Remote Service Contrôleurs" du groupe (qui vous permettrait de créer) et le nom du service est "mon-nom-service". Notez que, si vous souhaitez accorder l'accès à un groupe bien connu, comme les Utilisateurs (pas forcément une bonne idée) plutôt que d'un groupe que vous avez créé, vous avez besoin de changer
TRUSTEE_IS_GROUP
àTRUSTEE_IS_WELL_KNOWN_GROUP
.Le code n'a pas de contrôle d'erreur, que vous souhaitez ajouter. Tous les trois fonctions qui peuvent échouer (Get/SetNamedSecurityInfo et SetEntriesInAcl) retourne 0 pour indiquer la réussite.
Une autre Remarque: Vous pouvez également définir un service de descripteur de sécurité à l'aide de l'outil SC, qui peut être trouvé dans le dossier %WINDIR%\System32, mais qui n'implique pas de programmation.
Cela pourrait aussi être fait à partir de C# à l'aide de P/Invoke, mais c'est un peu plus de travail.
Si vous souhaitez être en mesure d'énumérer les services de ces utilisateurs, vous avez besoin de leur accorder la
SC_MANAGER_ENUMERATE_SERVICE
droit sur le SCM. Malheureusement, selon MSDN, la SCM de sécurité ne peuvent être modifiés que sur Windows Server 2003 sp1 ou version ultérieure.OriginalL'auteur Charlie
Merci pour cette ligne de code Charlie. Voici ce que j'ai fini par faire. J'ai eu l'idée de ce site: http://www.codeproject.com/KB/cs/svcmgr.aspx?display=Print
J'ai également eu à ajouter le compte que je suis en accédant à ce que le groupe Utilisateurs avec Pouvoir sur le serveur.
Et voici mon autre classe avec le ImpersonationUtil.Usurper l'identité d'():
Juste pour être clair, si vous ne modifiez pas l'usurpation d'identité, ce thread va continuer à emprunter l'identité du compte spécifié indéfiniment. C'est au mieux une cause probable de bugs, et au pire un trou de sécurité. Mieux vaut être prudent avec ça.
Cela a fonctionné pour moi.
OriginalL'auteur Miles
Vous pouvez essayer d'utiliser ASP.NET l'emprunt d'identité dans votre site web.le fichier de configuration et spécifiez un compte d'utilisateur qui dispose des autorisations appropriées:
Prendre un coup d'oeil à cet article sur MSDN. Je crois qu'il y a d'autres options qui ne nécessitent pas de stockage du mot de passe dans le web.fichier de configuration tels que les placer dans une clé de registre à la place.
Ce sera la cause de la ASP.NET processus de travail à exécuter dans le contexte de l'utilisateur spécifié à la place de l'utilisateur connecté à l'application web. Cependant, ce qui pose un problème de sécurité et je vous recommande de repenser la conception de votre. Vous souhaitez peut-être envisager d'avoir la ASP.NET page web à éteindre le feu d'une demande à un autre processus qui contrôle réellement les services, même dans un autre service windows ou écrire de la demande à une table de base de données que le service windows sondages régulièrement.
Vous pouvez continuer à utiliser leur compte windows pour l'authentification. Je suppose que vous êtes à l'aide de l'authentification intégrée dans les services internet et la ASP.NET modèle d'authentification. (<authentication mode="Windows" />). Vous pouvez utiliser les deux ensemble et de services internet (IIS) encore en train de négocier l'identification de l'utilisateur avec pas de connexion supplémentaires.
OriginalL'auteur Rich