Pārlūkot izejas kodu

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.
Iain Patterson 7 gadi atpakaļ
vecāks
revīzija
b76766ed76
4 mainītis faili ar 32 papildinājumiem un 16 dzēšanām
  1. 14 7
      account.cpp
  2. 1 0
      account.h
  3. 2 3
      gui.cpp
  4. 15 6
      settings.cpp

+ 14 - 7
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;

+ 1 - 0
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 *);

+ 2 - 3
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;
   }

+ 15 - 6
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);
 }