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