Handle virtual accounts when dumping service config.
authorIain Patterson <me@iain.cx>
Mon, 1 Aug 2016 17:07:45 +0000 (18:07 +0100)
committerIain Patterson <me@iain.cx>
Mon, 1 Aug 2016 17:07:45 +0000 (18:07 +0100)
If we are copying the service we need to build the virtual service
account name for the new service.

account.cpp
account.h
gui.cpp
settings.cpp

index d16d51d..cb7fcdb 100644 (file)
@@ -234,19 +234,26 @@ int is_localsystem(const TCHAR *username) {
   return ret;\r
 }\r
 \r
+/* Build the virtual account name. */\r
+TCHAR *virtual_account(const TCHAR *service_name) {\r
+  size_t len = _tcslen(NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN) + _tcslen(service_name) + 2;\r
+  TCHAR *name = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(TCHAR));\r
+  if (! name) {\r
+    print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("name"), _T("virtual_account"));\r
+    return 0;\r
+  }\r
+\r
+  _sntprintf_s(name, len, _TRUNCATE, _T("%s\\%s"), NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN, service_name);\r
+  return name;\r
+}\r
+\r
 /* Does the username represent a virtual account for the service? */\r
 int is_virtual_account(const TCHAR *service_name, const TCHAR *username) {\r
   if (! imports.IsWellKnownSid) return 0;\r
   if (! service_name) return 0;\r
   if (! username) return 0;\r
 \r
-  size_t len = _tcslen(NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN) + _tcslen(service_name) + 2;\r
-  TCHAR *canon = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(TCHAR));\r
-  if (! canon) {\r
-    print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("canon"), _T("is_virtual_account"));\r
-    return 0;\r
-  }\r
-  _sntprintf_s(canon, len, _TRUNCATE, _T("%s\\%s"), NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN, service_name);\r
+  TCHAR *canon = virtual_account(service_name);\r
   int ret = str_equiv(canon, username);\r
   HeapFree(GetProcessHeap(), 0, canon);\r
   return ret;\r
index a4377b9..04cb10e 100644 (file)
--- a/account.h
+++ b/account.h
@@ -19,6 +19,7 @@ int username_sid(const TCHAR *, SID **);
 int username_equiv(const TCHAR *, const TCHAR *);\r
 int canonicalise_username(const TCHAR *, TCHAR **);\r
 int is_localsystem(const TCHAR *);\r
+TCHAR *virtual_account(const TCHAR *);\r
 int is_virtual_account(const TCHAR *, const TCHAR *);\r
 const TCHAR *well_known_sid(SID *);\r
 const TCHAR *well_known_username(const TCHAR *);\r
diff --git a/gui.cpp b/gui.cpp
index 5fe3384..628b136 100644 (file)
--- a/gui.cpp
+++ b/gui.cpp
@@ -465,13 +465,12 @@ int configure(HWND window, nssm_service_t *service, nssm_service_t *orig_service
   }\r
   else if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_VIRTUAL_SERVICE, BM_GETCHECK, 0, 0) & BST_CHECKED) {\r
     if (service->username) HeapFree(GetProcessHeap(), 0, service->username);\r
-    service->usernamelen = _tcslen(NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN) + _tcslen(service->name) + 2;\r
-    service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));\r
+    service->username = virtual_account(service->name);\r
     if (! service->username) {\r
       popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("account name"), _T("install()"));\r
       return 6;\r
     }\r
-    _sntprintf_s(service->username, service->usernamelen, _TRUNCATE, _T("%s\\%s"), NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN, service->name);\r
+    service->usernamelen = _tcslen(service->username) + 1;\r
     service->password = 0;\r
     service->passwordlen = 0;\r
   }\r
index 11984bc..9e5f666 100644 (file)
@@ -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);\r
   if (ret != 1) return ret;\r
 \r
-  /* Do we need to dump a dummy password? */\r
-  if (! well_known_username(value->string)) {\r
-    /* Parameters are the other way round. */\r
-    value_t inverted;\r
-    inverted.string = _T("****");\r
-    return setting_dump_string(service_name, (void *) REG_SZ, name, &inverted, value->string);\r
+  /* Properly checking for a virtual account requires the actual service name. */\r
+  if (! _tcsnicmp(NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN, value->string, _tcslen(NSSM_VIRTUAL_SERVICE_ACCOUNT_DOMAIN))) {\r
+    TCHAR *name = virtual_account(service_name);\r
+    if (! name) return -1;\r
+    HeapFree(GetProcessHeap(), 0, value->string);\r
+    value->string = name;\r
+  }\r
+  else {\r
+    /* Do we need to dump a dummy password? */\r
+    if (! well_known_username(value->string)) {\r
+      /* Parameters are the other way round. */\r
+      value_t inverted;\r
+      inverted.string = _T("****");\r
+      return setting_dump_string(service_name, (void *) REG_SZ, name, &inverted, value->string);\r
+    }\r
   }\r
   return setting_dump_string(service_name, (void *) REG_SZ, name, value, 0);\r
 }\r