]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
win: allow OpenVPN service account to use any command-line options
authorLev Stipakov <lev@openvpn.net>
Tue, 15 Apr 2025 15:51:24 +0000 (17:51 +0200)
committerGert Doering <gert@greenie.muc.de>
Tue, 15 Apr 2025 18:14:59 +0000 (20:14 +0200)
Since 2.7, OpenVPN service (used to start persistent connections)
runs under limited virtual service account NT SERVICE\OpenVPNService.

Since it should be able to use all command-line options
and cannot be made member of "OpenVPN Administrators" group,
it has to be handled separately.

Change-Id: I44d308301dfb7c22600d8632a553288f52b3068f
Signed-off-by: Lev Stipakov <lev@openvpn.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20250415155131.12458-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg31435.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
src/openvpnserv/common.c
src/openvpnserv/interactive.c
src/openvpnserv/service.h
src/openvpnserv/validate.c
src/openvpnserv/validate.h

index 39b39aa448be58725029bfc525b27b1debf6ed0c..4a11e6cd30261cffb428135879e4b02290553ffc 100644 (file)
@@ -130,6 +130,14 @@ GetOpenvpnSettings(settings_t *s)
     {
         goto out;
     }
+
+    error = GetRegString(key, L"ovpn_service_user", s->ovpn_service_user,
+                         sizeof(s->ovpn_service_user), OVPN_SERVICE_USER);
+    if (error != ERROR_SUCCESS)
+    {
+        goto out;
+    }
+
     /* set process priority */
     if (!_wcsicmp(priority, L"IDLE_PRIORITY_CLASS"))
     {
index 3cefcc7b018ef263f89458142187dde2eedea991..f06d38655428d33c9902a2d3a27bbac81e640546 100644 (file)
@@ -3410,7 +3410,7 @@ RunOpenvpn(LPVOID p)
      * OR user is authorized to run any config.
      */
     if (!ValidateOptions(pipe, sud.directory, sud.options, errmsg, _countof(errmsg))
-        && !IsAuthorizedUser(ovpn_user->User.Sid, imp_token, settings.ovpn_admin_group))
+        && !IsAuthorizedUser(ovpn_user->User.Sid, imp_token, settings.ovpn_admin_group, settings.ovpn_service_user))
     {
         ReturnError(pipe, ERROR_STARTUP_DATA, errmsg, 1, &exit_event);
         goto out;
index 7112f26d383de06cb12db988646a34040b66be21..cbe213b1e77add3df8f9fd3259d375c2ca534eb0 100644 (file)
@@ -66,6 +66,7 @@ typedef struct {
     WCHAR ext_string[16];
     WCHAR log_dir[MAX_PATH];
     WCHAR ovpn_admin_group[MAX_NAME];
+    WCHAR ovpn_service_user[MAX_NAME];
     DWORD priority;
     BOOL append;
 } settings_t;
index 23d78af27297712685b853c9e4832f8faf600747..9f176c07e19f7635bc5e501fa444275c8a5c4225 100644 (file)
@@ -140,12 +140,8 @@ GetBuiltinAdminGroupName(WCHAR *name, DWORD nlen)
     return b;
 }
 
-/*
- * Check whether user is a member of Administrators group or
- * the group specified in ovpn_admin_group
- */
 BOOL
-IsAuthorizedUser(PSID sid, const HANDLE token, const WCHAR *ovpn_admin_group)
+IsAuthorizedUser(PSID sid, const HANDLE token, const WCHAR *ovpn_admin_group, const WCHAR *ovpn_service_user)
 {
     const WCHAR *admin_group[2];
     WCHAR username[MAX_NAME];
@@ -164,6 +160,12 @@ IsAuthorizedUser(PSID sid, const HANDLE token, const WCHAR *ovpn_admin_group)
         domain[0] = '\0';
     }
 
+    /* is this service account? */
+    if ((wcscmp(username, ovpn_service_user) == 0) && (wcscmp(domain, L"NT SERVICE") == 0))
+    {
+        return TRUE;
+    }
+
     if (GetBuiltinAdminGroupName(sysadmin_group, _countof(sysadmin_group)))
     {
         admin_group[0] = sysadmin_group;
index 61a0ad660b6fd7d68b0b9206490c0e4d956db1ac..5cd6d169ef849d209e5ea97c8558ca9346ba1ed8 100644 (file)
 
 /* Authorized groups who can use any options and config locations */
 #define SYSTEM_ADMIN_GROUP L"Administrators"
-#define OVPN_ADMIN_GROUP L"OpenVPN Administrators"
-/* The last one may be reset in registry: HKLM\Software\OpenVPN\ovpn_admin_group */
+#define OVPN_ADMIN_GROUP L"OpenVPN Administrators" /* may be set in HKLM\Software\OpenVPN\ovpn_admin_group */
+#define OVPN_SERVICE_USER L"OpenVPNService" /* may be set in HKLM\Software\OpenVPN\ovpn_service_user */
 
+/*
+ * Check whether user is a member of Administrators group or
+ * the group specified in ovpn_admin_group or
+ * OpenVPN Virtual Service Account user
+ */
 BOOL
-IsAuthorizedUser(PSID sid, const HANDLE token, const WCHAR *ovpn_admin_group);
+IsAuthorizedUser(PSID sid, const HANDLE token, const WCHAR *ovpn_admin_group, const WCHAR *ovpn_service_user);
 
 BOOL
 CheckOption(const WCHAR *workdir, int narg, WCHAR *argv[], const settings_t *s);