int ZabbixStopService() { SC_HANDLE mgr, service; SERVICE_STATUS status; int ret = FAIL; if (FAIL == svc_OpenSCManager(&mgr)) return ret; if (SUCCEED == svc_OpenService(mgr, &service, SERVICE_STOP)) { if (0 != ControlService(service, SERVICE_CONTROL_STOP, &status)) { zbx_error("service [%s] stopped successfully", ZABBIX_SERVICE_NAME); ret = SUCCEED; } else { zbx_error("ERROR: cannot stop service [%s]: %s", ZABBIX_SERVICE_NAME, strerror_from_system(GetLastError())); } CloseServiceHandle(service); } CloseServiceHandle(mgr); return ret; }
int ZabbixRemoveService() { SC_HANDLE mgr, service; int ret = FAIL; if (FAIL == svc_OpenSCManager(&mgr)) return ret; if (SUCCEED == svc_OpenService(mgr, &service, DELETE)) { if (0 != DeleteService(service)) { zbx_error("service [%s] uninstalled successfully", ZABBIX_SERVICE_NAME); ret = SUCCEED; } else { zbx_error("ERROR: cannot remove service [%s]: %s", ZABBIX_SERVICE_NAME, strerror_from_system(GetLastError())); } CloseServiceHandle(service); } CloseServiceHandle(mgr); if (SUCCEED == ret) ret = svc_RemoveEventSource(); return ret; }
int ZabbixStartService() { SC_HANDLE mgr, service; int ret = FAIL; if (FAIL == svc_OpenSCManager(&mgr)) return ret; if (SUCCEED == svc_OpenService(mgr, &service, SERVICE_START)) { if (0 != StartService(service, 0, NULL)) { zbx_error("service [%s] started successfully", ZABBIX_SERVICE_NAME); ret = SUCCEED; } else { zbx_error("ERROR: cannot start service [%s]: %s", ZABBIX_SERVICE_NAME, strerror_from_system(GetLastError())); } CloseServiceHandle(service); } CloseServiceHandle(mgr); return ret; }
NTSTATUS svc_uninstall(const char *hostname, struct cli_credentials * credentials) { NTSTATUS status; struct dcerpc_pipe *svc_pipe; struct policy_handle scm_handle; struct policy_handle svc_handle; struct SERVICE_STATUS svc_status; status = svc_pipe_connect(&svc_pipe, hostname, credentials); NT_ERR(status, 1, "Cannot connect to svcctl pipe"); status = svc_OpenSCManager(svc_pipe, hostname, &scm_handle); NT_ERR(status, 1, "OpenSCManager failed"); status = svc_OpenService(svc_pipe, &scm_handle, "winexesvc", &svc_handle); NT_ERR(status, 1, "OpenService failed"); DEBUG(1, ("OpenService - %s\n", nt_errstr(status))); if (NT_STATUS_IS_OK(status)) { status = svc_ControlService(svc_pipe, &svc_handle, SERVICE_CONTROL_STOP, &svc_status); { struct SERVICE_STATUS s; do { msleep(100); status = svc_QueryServiceStatus(svc_pipe, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); } while (s.state == SERVICE_STOP_PENDING); if (s.state != SERVICE_STOPPED) { DEBUG(0, ("Service cannot stop, status=0x%08X\n", s.state)); return NT_STATUS_UNSUCCESSFUL; } } DEBUG(1, ("StopService - %s\n", nt_errstr(status))); status = svc_DeleteService(svc_pipe, &svc_handle); DEBUG(1, ("DeleteService - %s\n", nt_errstr(status))); status = svc_CloseServiceHandle(svc_pipe, &svc_handle); DEBUG(1, ("CloseServiceHandle - %s\n", nt_errstr(status))); } svc_CloseServiceHandle(svc_pipe, &scm_handle); DEBUG(1, ("CloseSCMHandle - %s\n", nt_errstr(status))); struct smbcli_state *cli; status = smbcli_full_connection(NULL, &cli, hostname, "ADMIN$", NULL, credentials, NULL); NT_ERR(status, 1, "Failed to open ADMIN$ share"); /* Give winexesvc some time to exit */ msleep(300); status = smbcli_unlink(cli->tree, "winexesvc.exe"); DEBUG(1, ("Delete winexesvc.exe - %s\n", nt_errstr(status))); status = smbcli_tdis(cli); DEBUG(1, ("Closing ADMIN$ - %s\n", nt_errstr(status))); return status; }
int ZabbixCreateService(const char *path, int multiple_agents) { #define MAX_CMD_LEN MAX_PATH * 2 SC_HANDLE mgr, service; SERVICE_DESCRIPTION sd; TCHAR cmdLine[MAX_CMD_LEN]; LPTSTR wservice_name; DWORD code; int ret = FAIL; if (FAIL == svc_OpenSCManager(&mgr)) return ret; svc_get_command_line(path, multiple_agents, cmdLine, MAX_CMD_LEN); wservice_name = zbx_utf8_to_unicode(ZABBIX_SERVICE_NAME); if (NULL == (service = CreateService(mgr, wservice_name, wservice_name, GENERIC_READ, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, cmdLine, NULL, NULL, NULL, NULL, NULL))) { if (ERROR_SERVICE_EXISTS == (code = GetLastError())) zbx_error("ERROR: service [%s] already exists", ZABBIX_SERVICE_NAME); else zbx_error("ERROR: cannot create service [%s]: %s", ZABBIX_SERVICE_NAME, strerror_from_system(code)); } else { zbx_error("service [%s] installed successfully", ZABBIX_SERVICE_NAME); CloseServiceHandle(service); ret = SUCCEED; /* update the service description */ if (SUCCEED == svc_OpenService(mgr, &service, SERVICE_CHANGE_CONFIG)) { sd.lpDescription = TEXT("Provides system monitoring"); if (0 == ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &sd)) zbx_error("service description update failed: %s", strerror_from_system(GetLastError())); CloseServiceHandle(service); } } zbx_free(wservice_name); CloseServiceHandle(mgr); if (SUCCEED == ret) ret = svc_install_event_source(path); return ret; }
NTSTATUS svc_uninstall(struct tevent_context *ev_ctx, const char *hostname, const char *service_name, const char *service_filename, struct cli_credentials *credentials, struct loadparm_context *cllp_ctx) { NTSTATUS status; struct dcerpc_binding_handle *binding_handle; struct dcerpc_pipe *svc_pipe; struct policy_handle scm_handle; struct policy_handle svc_handle; struct SERVICE_STATUS svc_status; struct smbcli_options options; struct smbcli_session_options session_options; lpcfg_smbcli_options(cllp_ctx, &options); lpcfg_smbcli_session_options(cllp_ctx, &session_options); status = svc_pipe_connect(ev_ctx, &svc_pipe, hostname, credentials, cllp_ctx); NT_ERR(status, 1, "Cannot connect to svcctl pipe"); binding_handle = svc_pipe->binding_handle; status = svc_OpenSCManager(binding_handle, hostname, &scm_handle); NT_ERR(status, 1, "OpenSCManager failed"); status = svc_OpenService(binding_handle, &scm_handle, service_name, &svc_handle); NT_ERR(status, 1, "OpenService failed"); DEBUG(1, ("OpenService - %s\n", nt_errstr(status))); if (NT_STATUS_IS_OK(status)) { status = svc_ControlService(binding_handle, &svc_handle, SERVICE_CONTROL_STOP, &svc_status); { struct SERVICE_STATUS s; do { smb_msleep(100); status = svc_QueryServiceStatus(binding_handle, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); } while (s.state == SVCCTL_STOP_PENDING); if (s.state != SVCCTL_STOPPED) { DEBUG(0, ("Service cannot stop, status=0x%08X\n", s.state)); return NT_STATUS_UNSUCCESSFUL; } } DEBUG(1, ("StopService - %s\n", nt_errstr(status))); status = svc_DeleteService(binding_handle, &svc_handle); DEBUG(1, ("DeleteService - %s\n", nt_errstr(status))); status = svc_CloseServiceHandle(binding_handle, &svc_handle); DEBUG(1, ("CloseServiceHandle - %s\n", nt_errstr(status))); } svc_CloseServiceHandle(binding_handle, &scm_handle); DEBUG(1, ("CloseSCMHandle - %s\n", nt_errstr(status))); struct smbcli_state *cli; status = smbcli_full_connection(NULL, &cli, hostname, lpcfg_smb_ports(cllp_ctx), "ADMIN$", NULL, lpcfg_socket_options(cllp_ctx), credentials, lpcfg_resolve_context(cllp_ctx), ev_ctx, &options, &session_options, lpcfg_gensec_settings(NULL, cllp_ctx)); NT_ERR(status, 1, "Failed to open ADMIN$ share"); /* Give svc some time to exit */ smb_msleep(300); status = smbcli_unlink(cli->tree, service_filename); DEBUG(1, ("Delete %s - %s\n", service_filename, nt_errstr(status))); status = smbcli_tdis(cli); DEBUG(1, ("Closing ADMIN$ - %s\n", nt_errstr(status))); talloc_free(svc_pipe); return status; }
/* Start, Creates, Install service if necessary */ NTSTATUS svc_install(struct tevent_context *ev_ctx, const char *hostname, const char *service_name, const char *service_filename, unsigned char *svc32_exe, unsigned int svc32_exe_len, unsigned char *svc64_exe, unsigned int svc64_exe_len, struct cli_credentials *credentials, struct loadparm_context *cllp_ctx, int flags) { NTSTATUS status; struct dcerpc_binding_handle *binding_handle; struct dcerpc_pipe *svc_pipe; struct policy_handle scm_handle; struct policy_handle svc_handle; struct SERVICE_STATUS s; int need_start = 0; int need_conf = 0; status = svc_pipe_connect(ev_ctx, &svc_pipe, hostname, credentials, cllp_ctx); NT_ERR(status, 1, "Cannot connect to svcctl pipe"); binding_handle = svc_pipe->binding_handle; status = svc_OpenSCManager(binding_handle, hostname, &scm_handle); NT_ERR(status, 1, "OpenSCManager failed"); status = svc_OpenService(binding_handle, &scm_handle, service_name, &svc_handle); if (NT_STATUS_EQUAL(status, NT_STATUS_SERVICE_DOES_NOT_EXIST)) { status = svc_UploadService(ev_ctx, hostname, service_filename, svc32_exe, svc32_exe_len, svc64_exe, svc64_exe_len, credentials, cllp_ctx, flags); NT_ERR(status, 1, "UploadService failed"); status = svc_CreateService(binding_handle, &scm_handle, service_name, SERVICE_WIN32_OWN_PROCESS | (flags & SVC_INTERACTIVE ? SERVICE_INTERACTIVE_PROCESS : 0), service_filename, &svc_handle); NT_ERR(status, 1, "CreateService failed"); need_start = 1; } else { NT_ERR(status, 1, "OpenService failed"); } status = svc_QueryServiceStatus(binding_handle, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); if (!(flags & SVC_IGNORE_INTERACTIVE)) need_conf = !(s.type & SERVICE_INTERACTIVE_PROCESS) ^ !(flags & SVC_INTERACTIVE); if (s.state == SVCCTL_STOPPED) { need_start = 1; } else if (need_conf) { status = svc_ControlService(binding_handle, &svc_handle, SERVICE_CONTROL_STOP, &s); NT_ERR(status, 1, "StopService failed"); do { smb_msleep(100); status = svc_QueryServiceStatus(binding_handle, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); } while (s.state == SVCCTL_STOP_PENDING); need_start = 1; } if (need_conf) { status = svc_ChangeServiceConfig(binding_handle, &svc_handle, SERVICE_WIN32_OWN_PROCESS | ((flags & SVC_INTERACTIVE) ? SERVICE_INTERACTIVE_PROCESS : 0), NULL); NT_ERR(status, 1, "ChangeServiceConfig failed"); } if (need_start) { status = svc_StartService(binding_handle, &svc_handle); NT_ERR(status, 1, "StartService failed"); do { smb_msleep(100); status = svc_QueryServiceStatus(binding_handle, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); } while (s.state == SVCCTL_START_PENDING); if (s.state != SVCCTL_RUNNING) { DEBUG(0, ("Service cannot start, status=0x%08X\n", s.state)); return NT_STATUS_UNSUCCESSFUL; } } svc_CloseServiceHandle(binding_handle, &svc_handle); svc_CloseServiceHandle(binding_handle, &scm_handle); talloc_free(svc_pipe); return status; }
/* Start, Creates, Install service if necccesary */ NTSTATUS svc_install(const char *hostname, struct cli_credentials * credentials, int flags) { NTSTATUS status; struct dcerpc_pipe *svc_pipe; struct policy_handle scm_handle; struct policy_handle svc_handle; int need_start; status = svc_pipe_connect(&svc_pipe, hostname, credentials); NT_ERR(status, 1, "Cannot connect to svcctl pipe"); status = svc_UploadService(hostname, credentials, flags); NT_ERR(status, 1, "UploadService failed"); status = svc_OpenSCManager(svc_pipe, hostname, &scm_handle); NT_ERR(status, 1, "OpenSCManager failed"); status = svc_OpenService(svc_pipe, &scm_handle, "winexesvc", &svc_handle); if (NT_STATUS_EQUAL(status, NT_STATUS_SERVICE_DOES_NOT_EXIST)) { status = svc_CreateService(svc_pipe, &scm_handle, "winexesvc", SERVICE_WIN32_OWN_PROCESS | (flags & SVC_INTERACTIVE ? SERVICE_INTERACTIVE_PROCESS : 0), "winexesvc.exe", &svc_handle); NT_ERR(status, 1, "CreateService failed"); need_start = 1; } else if (NT_STATUS_IS_OK(status) && !(flags & SVC_IGNORE_INTERACTIVE)) { struct SERVICE_STATUS s; int what, want; status = svc_QueryServiceStatus(svc_pipe, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); what = s.type & SERVICE_INTERACTIVE_PROCESS; want = flags & SVC_INTERACTIVE; if ((what && !want) || (!what && want)) { need_start = 1; if (s.state != SVCCTL_STOPPED) { status = svc_ControlService(svc_pipe, &svc_handle, SERVICE_CONTROL_STOP, &s); NT_ERR(status, 1, "StopService failed"); } status = svc_ChangeServiceConfig(svc_pipe, &svc_handle, SERVICE_WIN32_OWN_PROCESS | (want ? SERVICE_INTERACTIVE_PROCESS : 0), NULL); NT_ERR(status, 1, "ChangeServiceConfig failed"); do { msleep(100); status = svc_QueryServiceStatus(svc_pipe, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); } while (s.state == SVCCTL_STOP_PENDING); } } else { NT_ERR(status, 1, "OpenService failed"); } if ((flags & SVC_IGNORE_INTERACTIVE) || need_start) { status = svc_StartService(svc_pipe, &svc_handle); NT_ERR(status, 1, "StartService failed"); } { struct SERVICE_STATUS s; do { msleep(100); status = svc_QueryServiceStatus(svc_pipe, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); } while (s.state == SVCCTL_START_PENDING); if (s.state != SVCCTL_RUNNING) { DEBUG(0, ("Service cannot start, status=0x%08X\n", s.state)); return NT_STATUS_UNSUCCESSFUL; } } svc_CloseServiceHandle(svc_pipe, &svc_handle); svc_CloseServiceHandle(svc_pipe, &scm_handle); talloc_free(svc_pipe); return status; }