Correct CloseHandle() call.
[nssm.git] / settings.cpp
index 73b8d0d..43ae559 100644 (file)
@@ -305,7 +305,7 @@ static int setting_set_environment(const TCHAR *service_name, void *param, const
   unsigned long envlen = (unsigned long) _tcslen(value->string) + 1;
   TCHAR *unformatted = 0;
   unsigned long newlen;
-  if (unformat_environment(value->string, envlen, &unformatted, &newlen)) return -1;
+  if (unformat_double_null(value->string, envlen, &unformatted, &newlen)) return -1;
 
   if (test_environment(unformatted)) {
     HeapFree(GetProcessHeap(), 0, unformatted);
@@ -334,7 +334,7 @@ static int setting_get_environment(const TCHAR *service_name, void *param, const
 
   TCHAR *formatted;
   unsigned long newlen;
-  if (format_environment(env, envlen, &formatted, &newlen)) return -1;
+  if (format_double_null(env, envlen, &formatted, &newlen)) return -1;
 
   int ret;
   if (additional) {
@@ -527,21 +527,28 @@ int native_set_objectname(const TCHAR *service_name, void *param, const TCHAR *n
     Logical syntax is: nssm set <service> ObjectName <username> <password>
     That means the username is actually passed in the additional parameter.
   */
-  bool localsystem = true;
+  bool localsystem = false;
   TCHAR *username = NSSM_LOCALSYSTEM_ACCOUNT;
   TCHAR *password = 0;
   if (additional) {
-    if (! str_equiv(additional, NSSM_LOCALSYSTEM_ACCOUNT)) {
-      localsystem = false;
-      username = (TCHAR *) additional;
-      if (value && value->string) password = value->string;
-      else {
-        /* We need a password if the account is not LOCALSYSTEM. */
-        print_message(stderr, NSSM_MESSAGE_MISSING_PASSWORD, name);
-        return -1;
-      }
-    }
+    username = (TCHAR *) additional;
+    if (value && value->string) password = value->string;
   }
+  else if (value && value->string) username = value->string;
+
+  const TCHAR *well_known = well_known_username(username);
+  size_t passwordsize = 0;
+  if (well_known) {
+    if (str_equiv(well_known, NSSM_LOCALSYSTEM_ACCOUNT)) localsystem = true;
+    username = (TCHAR *) well_known;
+    password = _T("");
+  }
+  else if (! password) {
+    /* We need a password if the account requires it. */
+    print_message(stderr, NSSM_MESSAGE_MISSING_PASSWORD, name);
+    return -1;
+  }
+  else passwordsize = _tcslen(password) * sizeof(TCHAR);
 
   /*
     ChangeServiceConfig() will fail to set the username if the service is set
@@ -551,7 +558,7 @@ int native_set_objectname(const TCHAR *service_name, void *param, const TCHAR *n
   if (! localsystem) {
     QUERY_SERVICE_CONFIG *qsc = query_service_config(service_name, service_handle);
     if (! qsc) {
-      if (password) SecureZeroMemory(password, _tcslen(password) * sizeof(TCHAR));
+      if (passwordsize) SecureZeroMemory(password, passwordsize);
       return -1;
     }
 
@@ -559,18 +566,21 @@ int native_set_objectname(const TCHAR *service_name, void *param, const TCHAR *n
     HeapFree(GetProcessHeap(), 0, qsc);
   }
 
-  if (grant_logon_as_service(username)) {
-    if (password) SecureZeroMemory(password, _tcslen(password) * sizeof(TCHAR));
-    print_message(stderr, NSSM_MESSAGE_GRANT_LOGON_AS_SERVICE_FAILED, username);
-    return -1;
+  if (! well_known) {
+    if (grant_logon_as_service(username)) {
+      if (passwordsize) SecureZeroMemory(password, passwordsize);
+      print_message(stderr, NSSM_MESSAGE_GRANT_LOGON_AS_SERVICE_FAILED, username);
+      return -1;
+    }
   }
 
   if (! ChangeServiceConfig(service_handle, type, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, 0, 0, 0, 0, username, password, 0)) {
-    if (password) SecureZeroMemory(password, _tcslen(password) * sizeof(TCHAR));
+    if (passwordsize) SecureZeroMemory(password, passwordsize);
     print_message(stderr, NSSM_MESSAGE_CHANGESERVICECONFIG_FAILED, error_string(GetLastError()));
     return -1;
   }
-  if (password) SecureZeroMemory(password, _tcslen(password) * sizeof(TCHAR));
+
+  if (passwordsize) SecureZeroMemory(password, passwordsize);
 
   if (localsystem) return 0;
 
@@ -838,7 +848,7 @@ settings_t settings[] = {
   { NSSM_NATIVE_DESCRIPTION, REG_SZ, _T(""), true, 0, native_set_description, native_get_description },
   { NSSM_NATIVE_DISPLAYNAME, REG_SZ, NULL, true, 0, native_set_displayname, native_get_displayname },
   { NSSM_NATIVE_IMAGEPATH, REG_EXPAND_SZ, NULL, true, 0, native_set_imagepath, native_get_imagepath },
-  { NSSM_NATIVE_OBJECTNAME, REG_SZ, NSSM_LOCALSYSTEM_ACCOUNT, true, ADDITIONAL_SETTING, native_set_objectname, native_get_objectname },
+  { NSSM_NATIVE_OBJECTNAME, REG_SZ, NSSM_LOCALSYSTEM_ACCOUNT, true, 0, native_set_objectname, native_get_objectname },
   { NSSM_NATIVE_NAME, REG_SZ, NULL, true, 0, native_set_name, native_get_name },
   { NSSM_NATIVE_STARTUP, REG_SZ, NULL, true, 0, native_set_startup, native_get_startup },
   { NSSM_NATIVE_TYPE, REG_SZ, NULL, true, 0, native_set_type, native_get_type },