From b76766ed76f1bf26c31e0c73b154e2f6a95b278d Mon Sep 17 00:00:00 2001 From: Iain Patterson Date: Mon, 1 Aug 2016 18:07:45 +0100 Subject: [PATCH] Handle virtual accounts when dumping service config. If we are copying the service we need to build the virtual service account name for the new service. --- account.cpp | 21 ++++++++++++++------- account.h | 1 + gui.cpp | 5 ++--- settings.cpp | 21 +++++++++++++++------ 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/account.cpp b/account.cpp index d16d51d..cb7fcdb 100644 --- a/account.cpp +++ b/account.cpp @@ -234,19 +234,26 @@ int is_localsystem(const TCHAR *username) { return ret; } +/* Build the virtual account name. */ +TCHAR *virtual_account(const TCHAR *service_name) { + size_t len = _tcslen(NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN) + _tcslen(service_name) + 2; + TCHAR *name = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(TCHAR)); + if (! name) { + print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("name"), _T("virtual_account")); + return 0; + } + + _sntprintf_s(name, len, _TRUNCATE, _T("%s\\%s"), NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN, service_name); + return name; +} + /* Does the username represent a virtual account for the service? */ int is_virtual_account(const TCHAR *service_name, const TCHAR *username) { if (! imports.IsWellKnownSid) return 0; if (! service_name) return 0; if (! username) return 0; - size_t len = _tcslen(NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN) + _tcslen(service_name) + 2; - TCHAR *canon = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(TCHAR)); - if (! canon) { - print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("canon"), _T("is_virtual_account")); - return 0; - } - _sntprintf_s(canon, len, _TRUNCATE, _T("%s\\%s"), NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN, service_name); + TCHAR *canon = virtual_account(service_name); int ret = str_equiv(canon, username); HeapFree(GetProcessHeap(), 0, canon); return ret; diff --git a/account.h b/account.h index a4377b9..04cb10e 100644 --- a/account.h +++ b/account.h @@ -19,6 +19,7 @@ int username_sid(const TCHAR *, SID **); int username_equiv(const TCHAR *, const TCHAR *); int canonicalise_username(const TCHAR *, TCHAR **); int is_localsystem(const TCHAR *); +TCHAR *virtual_account(const TCHAR *); int is_virtual_account(const TCHAR *, const TCHAR *); const TCHAR *well_known_sid(SID *); const TCHAR *well_known_username(const TCHAR *); diff --git a/gui.cpp b/gui.cpp index 5fe3384..628b136 100644 --- a/gui.cpp +++ b/gui.cpp @@ -465,13 +465,12 @@ int configure(HWND window, nssm_service_t *service, nssm_service_t *orig_service } else if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_VIRTUAL_SERVICE, BM_GETCHECK, 0, 0) & BST_CHECKED) { if (service->username) HeapFree(GetProcessHeap(), 0, service->username); - service->usernamelen = _tcslen(NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN) + _tcslen(service->name) + 2; - service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR)); + service->username = virtual_account(service->name); if (! service->username) { popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("account name"), _T("install()")); return 6; } - _sntprintf_s(service->username, service->usernamelen, _TRUNCATE, _T("%s\\%s"), NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN, service->name); + service->usernamelen = _tcslen(service->username) + 1; service->password = 0; service->passwordlen = 0; } diff --git a/settings.cpp b/settings.cpp index 11984bc..9e5f666 100644 --- a/settings.cpp +++ b/settings.cpp @@ -1152,12 +1152,21 @@ int native_dump_objectname(const TCHAR *service_name, void *param, const TCHAR * int ret = native_get_objectname(service_name, param, name, default_value, value, additional); if (ret != 1) return ret; - /* Do we need to dump a dummy password? */ - if (! well_known_username(value->string)) { - /* Parameters are the other way round. */ - value_t inverted; - inverted.string = _T("****"); - return setting_dump_string(service_name, (void *) REG_SZ, name, &inverted, value->string); + /* Properly checking for a virtual account requires the actual service name. */ + if (! _tcsnicmp(NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN, value->string, _tcslen(NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN))) { + TCHAR *name = virtual_account(service_name); + if (! name) return -1; + HeapFree(GetProcessHeap(), 0, value->string); + value->string = name; + } + else { + /* Do we need to dump a dummy password? */ + if (! well_known_username(value->string)) { + /* Parameters are the other way round. */ + value_t inverted; + inverted.string = _T("****"); + return setting_dump_string(service_name, (void *) REG_SZ, name, &inverted, value->string); + } } return setting_dump_string(service_name, (void *) REG_SZ, name, value, 0); } -- 2.20.1