#include "nssm.h"\r
\r
extern unsigned long tls_index;\r
+extern bool is_admin;\r
\r
/* String function */\r
int str_equiv(const char *a, const char *b) {\r
return(ret);\r
}\r
\r
-int check_admin(char *action) {\r
+void check_admin() {\r
+ is_admin = false;\r
+\r
/* Lifted from MSDN examples */\r
PSID AdministratorsGroup;\r
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;\r
- BOOL ok = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup);\r
- if (ok) {\r
- if (! CheckTokenMembership(0, AdministratorsGroup, &ok)) ok = 0;\r
- FreeSid(AdministratorsGroup);\r
-\r
- if (ok) return 0;\r
-\r
- fprintf(stderr, "Administator access is needed to %s a service.\n", action);\r
- return 1;\r
- }\r
-\r
- /* Can't tell if we are admin or not; later operations may fail */\r
- return 0;\r
+ if (! AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup)) return;\r
+ CheckTokenMembership(0, AdministratorsGroup, /*XXX*/(PBOOL) &is_admin);\r
+ FreeSid(AdministratorsGroup);\r
}\r
\r
int main(int argc, char **argv) {\r
+ /* Remember if we are admin */\r
+ check_admin();\r
+\r
/* Elevate */\r
if (argc > 1) {\r
if (str_equiv(argv[1], "install") || str_equiv(argv[1], "remove")) {\r
- if (check_admin(argv[1])) exit(100);\r
+ if (! is_admin) {\r
+ fprintf(stderr, "Administrator access is needed to %s a service.\n", argv[1]);\r
+ exit(100);\r
+ }\r
}\r
\r
/* Valid commands are install or remove */\r
tls_index = TlsAlloc();\r
\r
/* Register messages */\r
- create_messages();\r
+ if (is_admin) create_messages();\r
\r
/* Start service magic */\r
SERVICE_TABLE_ENTRY table[] = { { NSSM, service_main }, { 0, 0 } };\r
#include "nssm.h"\r
\r
+bool is_admin;\r
SERVICE_STATUS service_status;\r
SERVICE_STATUS_HANDLE service_handle;\r
HANDLE process_handle;\r
SC_HANDLE open_service_manager() {\r
SC_HANDLE ret = OpenSCManager(0, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);\r
if (! ret) {\r
- log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENSCMANAGER_FAILED, 0);\r
+ if (is_admin) log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OPENSCMANAGER_FAILED, 0);\r
return 0;\r
}\r
\r
return 6;\r
}\r
\r
+ set_service_recovery(service, name);\r
+\r
/* Cleanup */\r
CloseServiceHandle(service);\r
CloseServiceHandle(services);\r
service_status.dwWaitHint = throttle_delay + NSSM_WAITHINT_MARGIN;\r
SetServiceStatus(service_handle, &service_status);\r
\r
- /* Try to create the exit action parameters; we don't care if it fails */\r
- create_exit_action(argv[0], exit_action_strings[0]);\r
+ if (is_admin) {\r
+ /* Try to create the exit action parameters; we don't care if it fails */\r
+ create_exit_action(argv[0], exit_action_strings[0]);\r
\r
- set_service_recovery(service_name);\r
+ set_service_recovery(0, service_name);\r
+ }\r
\r
/* Used for signalling a resume if the service pauses when throttled. */\r
throttle_timer = CreateWaitableTimer(0, 1, 0);\r
}\r
\r
/* Make sure service recovery actions are taken where necessary */\r
-void set_service_recovery(char *service_name) {\r
- SC_HANDLE services = open_service_manager();\r
- if (! services) return;\r
+void set_service_recovery(SC_HANDLE service, char *service_name) {\r
+ SC_HANDLE services = 0;\r
+\r
+ if (! service) {\r
+ services = open_service_manager();\r
+ if (! services) return;\r
\r
- SC_HANDLE service = OpenService(services, service_name, SC_MANAGER_ALL_ACCESS);\r
- if (! service) return;\r
+ service = OpenService(services, service_name, SC_MANAGER_ALL_ACCESS);\r
+ if (! service) return;\r
+ }\r
\r
SERVICE_FAILURE_ACTIONS_FLAG flag;\r
ZeroMemory(&flag, sizeof(flag));\r
log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_CHANGESERVICECONFIG2_FAILED, service_name, error_string(error), 0);\r
}\r
}\r
+\r
+ if (services) {\r
+ CloseServiceHandle(service);\r
+ CloseServiceHandle(services);\r
+ }\r
}\r
\r
int monitor_service() {\r
int pre_remove_service(int, char **);\r
int install_service(char *, char *, char *);\r
int remove_service(char *);\r
-void set_service_recovery(char *);\r
+void set_service_recovery(SC_HANDLE, char *);\r
int monitor_service();\r
int start_service();\r
int stop_service(unsigned long, bool, bool);\r