diff options
author | Alberto Gonzalez Iniesta <agi@inittab.org> | 2017-06-22 13:16:46 +0200 |
---|---|---|
committer | Alberto Gonzalez Iniesta <agi@inittab.org> | 2017-06-22 13:16:46 +0200 |
commit | 9683f890944ffb114f5f8214f694e0b339cf5a5a (patch) | |
tree | fa391f5f343554b2861b1f8722d0a2a627e1c1fc /src/openvpnserv | |
parent | 3a2bbdb05ca6a6996e424c9fb225cb0d53804125 (diff) |
New upstream version 2.4.3upstream/2.4.3
Diffstat (limited to 'src/openvpnserv')
-rw-r--r-- | src/openvpnserv/Makefile.in | 36 | ||||
-rw-r--r-- | src/openvpnserv/automatic.c | 10 | ||||
-rw-r--r-- | src/openvpnserv/common.c | 7 | ||||
-rw-r--r-- | src/openvpnserv/interactive.c | 84 | ||||
-rw-r--r-- | src/openvpnserv/service.h | 7 | ||||
-rw-r--r-- | src/openvpnserv/validate.c | 178 | ||||
-rw-r--r-- | src/openvpnserv/validate.h | 9 |
7 files changed, 246 insertions, 85 deletions
diff --git a/src/openvpnserv/Makefile.in b/src/openvpnserv/Makefile.in index e113fee..234a927 100644 --- a/src/openvpnserv/Makefile.in +++ b/src/openvpnserv/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.13.4 from Makefile.am. +# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2013 Free Software Foundation, Inc. +# Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -37,7 +37,17 @@ # Required to build Windows resource file VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -100,8 +110,6 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -DIST_COMMON = $(top_srcdir)/build/ltrc.inc $(srcdir)/Makefile.in \ - $(srcdir)/Makefile.am $(top_srcdir)/depcomp @WIN32_TRUE@sbin_PROGRAMS = openvpnserv$(EXEEXT) subdir = src/openvpnserv ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -114,6 +122,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_emptyarray.m4 \ $(top_srcdir)/compat.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h \ $(top_builddir)/include/openvpn-plugin.h @@ -196,6 +205,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/ltrc.inc \ + $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -244,6 +255,7 @@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ LZ4_CFLAGS = @LZ4_CFLAGS@ LZ4_LIBS = @LZ4_LIBS@ LZO_CFLAGS = @LZO_CFLAGS@ @@ -292,6 +304,7 @@ PKCS11_HELPER_LIBS = @PKCS11_HELPER_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PLUGINDIR = @PLUGINDIR@ PLUGIN_AUTH_PAM_CFLAGS = @PLUGIN_AUTH_PAM_CFLAGS@ PLUGIN_AUTH_PAM_LIBS = @PLUGIN_AUTH_PAM_LIBS@ RANLIB = @RANLIB@ @@ -304,12 +317,14 @@ SHELL = @SHELL@ SOCKETS_LIBS = @SOCKETS_LIBS@ STRIP = @STRIP@ SYSTEMD_ASK_PASSWORD = @SYSTEMD_ASK_PASSWORD@ +SYSTEMD_UNIT_DIR = @SYSTEMD_UNIT_DIR@ TAP_CFLAGS = @TAP_CFLAGS@ TAP_WIN_COMPONENT_ID = @TAP_WIN_COMPONENT_ID@ TAP_WIN_MIN_MAJOR = @TAP_WIN_MIN_MAJOR@ TAP_WIN_MIN_MINOR = @TAP_WIN_MIN_MINOR@ TEST_CFLAGS = @TEST_CFLAGS@ TEST_LDFLAGS = @TEST_LDFLAGS@ +TMPFILES_DIR = @TMPFILES_DIR@ VENDOR_BUILD_ROOT = @VENDOR_BUILD_ROOT@ VENDOR_DIST_ROOT = @VENDOR_DIST_ROOT@ VENDOR_SRC_ROOT = @VENDOR_SRC_ROOT@ @@ -366,7 +381,9 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdunitdir = @systemdunitdir@ target_alias = @target_alias@ +tmpfilesdir = @tmpfilesdir@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @@ -413,7 +430,6 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/build/ltrc.inc $(am_ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/openvpnserv/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/openvpnserv/Makefile -.PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ @@ -422,7 +438,7 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; -$(top_srcdir)/build/ltrc.inc: +$(top_srcdir)/build/ltrc.inc $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh @@ -504,14 +520,14 @@ distclean-compile: @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -817,6 +833,8 @@ uninstall-am: uninstall-sbinPROGRAMS mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags tags-am uninstall uninstall-am uninstall-sbinPROGRAMS +.PRECIOUS: Makefile + .rc.lo: $(LTRCCOMPILE) -i "$<" -o "$@" diff --git a/src/openvpnserv/automatic.c b/src/openvpnserv/automatic.c index 6be6c6d..4123d0f 100644 --- a/src/openvpnserv/automatic.c +++ b/src/openvpnserv/automatic.c @@ -16,10 +16,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* @@ -293,7 +292,8 @@ ServiceStartAutomatic(DWORD dwArgc, LPTSTR *lpszArgv) /* * Loop over each config file */ - do { + do + { HANDLE log_handle = NULL; STARTUPINFO start_info; PROCESS_INFORMATION proc_info; diff --git a/src/openvpnserv/common.c b/src/openvpnserv/common.c index 3b9b396..0c9098f 100644 --- a/src/openvpnserv/common.c +++ b/src/openvpnserv/common.c @@ -16,10 +16,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include <service.h> diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c index dbe2b9b..607c8a9 100644 --- a/src/openvpnserv/interactive.c +++ b/src/openvpnserv/interactive.c @@ -16,10 +16,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ @@ -94,6 +93,13 @@ typedef enum { } undo_type_t; typedef list_item_t *undo_lists_t[_undo_type_max]; +typedef struct { + HANDLE engine; + int index; + int metric_v4; + int metric_v6; +} block_dns_data_t; + static DWORD AddListItem(list_item_t **pfirst, LPVOID data) @@ -215,7 +221,9 @@ AsyncPipeOp(async_op_t op, HANDLE pipe, LPVOID buffer, DWORD size, DWORD count, handles[0] = io_event; for (i = 0; i < count; i++) + { handles[i + 1] = events[i]; + } res = WaitForMultipleObjects(count + 1, handles, FALSE, op == peek ? INFINITE : IO_TIMEOUT); @@ -883,6 +891,7 @@ static DWORD HandleBlockDNSMessage(const block_dns_message_t *msg, undo_lists_t *lists) { DWORD err = 0; + block_dns_data_t *interface_data; HANDLE engine = NULL; LPCWSTR exe_path; @@ -899,16 +908,57 @@ HandleBlockDNSMessage(const block_dns_message_t *msg, undo_lists_t *lists) err = add_block_dns_filters(&engine, msg->iface.index, exe_path, BlockDNSErrHandler); if (!err) { - err = AddListItem(&(*lists)[block_dns], engine); + interface_data = malloc(sizeof(block_dns_data_t)); + if (!interface_data) + { + return ERROR_OUTOFMEMORY; + } + interface_data->engine = engine; + interface_data->index = msg->iface.index; + interface_data->metric_v4 = get_interface_metric(msg->iface.index, + AF_INET); + if (interface_data->metric_v4 < 0) + { + interface_data->metric_v4 = -1; + } + interface_data->metric_v6 = get_interface_metric(msg->iface.index, + AF_INET6); + if (interface_data->metric_v6 < 0) + { + interface_data->metric_v6 = -1; + } + err = AddListItem(&(*lists)[block_dns], interface_data); + if (!err) + { + err = set_interface_metric(msg->iface.index, AF_INET, + BLOCK_DNS_IFACE_METRIC); + if (!err) + { + set_interface_metric(msg->iface.index, AF_INET6, + BLOCK_DNS_IFACE_METRIC); + } + } } } else { - engine = RemoveListItem(&(*lists)[block_dns], CmpEngine, NULL); - if (engine) + interface_data = RemoveListItem(&(*lists)[block_dns], CmpEngine, NULL); + if (interface_data) { + engine = interface_data->engine; err = delete_block_dns_filters(engine); engine = NULL; + if (interface_data->metric_v4 >= 0) + { + set_interface_metric(msg->iface.index, AF_INET, + interface_data->metric_v4); + } + if (interface_data->metric_v6 >= 0) + { + set_interface_metric(msg->iface.index, AF_INET6, + interface_data->metric_v6); + } + free(interface_data); } else { @@ -1323,6 +1373,7 @@ static VOID Undo(undo_lists_t *lists) { undo_type_t type; + block_dns_data_t *interface_data; for (type = 0; type < _undo_type_max; type++) { list_item_t **pnext = &(*lists)[type]; @@ -1348,8 +1399,18 @@ Undo(undo_lists_t *lists) break; case block_dns: - delete_block_dns_filters(item->data); - item->data = NULL; + interface_data = (block_dns_data_t*)(item->data); + delete_block_dns_filters(interface_data->engine); + if (interface_data->metric_v4 >= 0) + { + set_interface_metric(interface_data->index, AF_INET, + interface_data->metric_v4); + } + if (interface_data->metric_v6 >= 0) + { + set_interface_metric(interface_data->index, AF_INET6, + interface_data->metric_v6); + } break; } @@ -1475,7 +1536,7 @@ RunOpenvpn(LPVOID p) } /* Check user is authorized or options are white-listed */ - if (!IsAuthorizedUser(ovpn_user->User.Sid, &settings) + if (!IsAuthorizedUser(ovpn_user->User.Sid, imp_token, settings.ovpn_admin_group) && !ValidateOptions(pipe, sud.directory, sud.options)) { goto out; @@ -1840,7 +1901,8 @@ ServiceStartInteractive(DWORD dwArgc, LPTSTR *lpszArgv) PHANDLE handles = NULL; DWORD handle_count; BOOL - CmpHandle(LPVOID item, LPVOID hnd) { + CmpHandle(LPVOID item, LPVOID hnd) + { return item == hnd; } diff --git a/src/openvpnserv/service.h b/src/openvpnserv/service.h index b1130c9..9fe573e 100644 --- a/src/openvpnserv/service.h +++ b/src/openvpnserv/service.h @@ -16,10 +16,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef _SERVICE_H diff --git a/src/openvpnserv/validate.c b/src/openvpnserv/validate.c index c9c3855..f6a97e9 100644 --- a/src/openvpnserv/validate.c +++ b/src/openvpnserv/validate.c @@ -16,10 +16,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "validate.h" @@ -49,6 +48,9 @@ static const WCHAR *white_list[] = NULL /* last value */ }; +static BOOL IsUserInGroup(PSID sid, const PTOKEN_GROUPS groups, const WCHAR *group_name); +static PTOKEN_GROUPS GetTokenGroups(const HANDLE token); + /* * Check workdir\fname is inside config_dir * The logic here is simple: we may reject some valid paths if ..\ is in any of the strings @@ -147,21 +149,16 @@ GetBuiltinAdminGroupName(WCHAR *name, DWORD nlen) /* * Check whether user is a member of Administrators group or - * the group specified in s->ovpn_admin_group + * the group specified in ovpn_admin_group */ BOOL -IsAuthorizedUser(SID *sid, settings_t *s) +IsAuthorizedUser(PSID sid, const HANDLE token, const WCHAR *ovpn_admin_group) { - LOCALGROUP_USERS_INFO_0 *groups = NULL; - DWORD nread; - DWORD nmax; - WCHAR *tmp = NULL; const WCHAR *admin_group[2]; WCHAR username[MAX_NAME]; WCHAR domain[MAX_NAME]; WCHAR sysadmin_group[MAX_NAME]; - DWORD err, len = MAX_NAME; - int i; + DWORD len = MAX_NAME; BOOL ret = FALSE; SID_NAME_USE sid_type; @@ -169,17 +166,9 @@ IsAuthorizedUser(SID *sid, settings_t *s) if (!LookupAccountSidW(NULL, sid, username, &len, domain, &len, &sid_type)) { MsgToEventLog(M_SYSERR, TEXT("LookupAccountSid")); - goto out; - } - - /* Get an array of groups the user is member of */ - err = NetUserGetLocalGroups(NULL, username, 0, LG_INCLUDE_INDIRECT, (LPBYTE *) &groups, - MAX_PREFERRED_LENGTH, &nread, &nmax); - if (err && err != ERROR_MORE_DATA) - { - SetLastError(err); - MsgToEventLog(M_SYSERR, TEXT("NetUserGetLocalGroups")); - goto out; + /* not fatal as this is now used only for logging */ + username[0] = '\0'; + domain[0] = '\0'; } if (GetBuiltinAdminGroupName(sysadmin_group, _countof(sysadmin_group))) @@ -192,41 +181,136 @@ IsAuthorizedUser(SID *sid, settings_t *s) /* use the default value */ admin_group[0] = SYSTEM_ADMIN_GROUP; } + admin_group[1] = ovpn_admin_group; -#ifdef UNICODE - admin_group[1] = s->ovpn_admin_group; -#else - tmp = NULL; - len = MultiByteToWideChar(CP_UTF8, 0, s->ovpn_admin_group, -1, NULL, 0); - if (len == 0 || (tmp = malloc(len*sizeof(WCHAR))) == NULL) + PTOKEN_GROUPS token_groups = GetTokenGroups(token); + for (int i = 0; i < 2; ++i) { - MsgToEventLog(M_SYSERR, TEXT("Failed to convert admin group name to WideChar")); - goto out; + ret = IsUserInGroup(sid, token_groups, admin_group[i]); + if (ret) + { + MsgToEventLog(M_INFO, TEXT("Authorizing user '%s@%s' by virtue of membership in group '%s'"), + username, domain, admin_group[i]); + goto out; + } } - MultiByteToWideChar(CP_UTF8, 0, s->ovpn_admin_group, -1, tmp, len); - admin_group[1] = tmp; -#endif - /* Check if user's groups include any of the admin groups */ - for (i = 0; i < nread; i++) +out: + free(token_groups); + return ret; +} + +/** + * Get a list of groups in token. + * Returns a pointer to TOKEN_GROUPS struct or NULL on error. + * The caller should free the returned pointer. + */ +static PTOKEN_GROUPS +GetTokenGroups(const HANDLE token) +{ + PTOKEN_GROUPS groups = NULL; + DWORD buf_size = 0; + + if (!GetTokenInformation(token, TokenGroups, groups, buf_size, &buf_size) + && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + groups = malloc(buf_size); + } + if (!groups) + { + MsgToEventLog(M_SYSERR, L"GetTokenGroups"); + } + else if (!GetTokenInformation(token, TokenGroups, groups, buf_size, &buf_size)) { - if (wcscmp(groups[i].lgrui0_name, admin_group[0]) == 0 - || wcscmp(groups[i].lgrui0_name, admin_group[1]) == 0 - ) + MsgToEventLog(M_SYSERR, L"GetTokenInformation"); + free(groups); + } + return groups; +} + +/* + * Find SID from name + * + * On input sid buffer should have space for at least sid_size bytes. + * Returns true on success, false on failure. + * Suggest: in caller allocate sid to hold SECURITY_MAX_SID_SIZE bytes + */ +static BOOL +LookupSID(const WCHAR *name, PSID sid, DWORD sid_size) +{ + SID_NAME_USE su; + WCHAR domain[MAX_NAME]; + DWORD dlen = _countof(domain); + + if (!LookupAccountName(NULL, name, sid, &sid_size, domain, &dlen, &su)) + { + return FALSE; /* not fatal as the group may not exist */ + } + return TRUE; +} + +/** + * User is in group if the token groups contain the SID of the group + * of if the user is a direct member of the group. The latter check + * catches dynamic changes in group membership in the local user + * database not reflected in the token. + * If token_groups or sid is NULL the corresponding check is skipped. + * + * Using sid and list of groups in token avoids reference to domains so that + * this could be completed without access to a Domain Controller. + * + * Returns true if the user is in the group, false otherwise. + */ +static BOOL +IsUserInGroup(PSID sid, const PTOKEN_GROUPS token_groups, const WCHAR *group_name) +{ + BOOL ret = FALSE; + DWORD_PTR resume = 0; + DWORD err; + BYTE grp_sid[SECURITY_MAX_SID_SIZE]; + int nloop = 0; /* a counter used to not get stuck in the do .. while() */ + + /* first check in the token groups */ + if (token_groups && LookupSID(group_name, (PSID) grp_sid, _countof(grp_sid))) + { + for (DWORD i = 0; i < token_groups->GroupCount; ++i) { - MsgToEventLog(M_INFO, TEXT("Authorizing user %s by virtue of membership in group %s"), - username, groups[i].lgrui0_name); - ret = TRUE; - break; + if (EqualSid((PSID) grp_sid, token_groups->Groups[i].Sid)) + { + return TRUE; + } } } -out: - if (groups) + /* check user's SID is a member of the group */ + if (!sid) + { + return FALSE; + } + do + { + DWORD nread, nmax; + LOCALGROUP_MEMBERS_INFO_0 *members = NULL; + err = NetLocalGroupGetMembers(NULL, group_name, 0, (LPBYTE *) &members, + MAX_PREFERRED_LENGTH, &nread, &nmax, &resume); + if ((err != NERR_Success && err != ERROR_MORE_DATA)) + { + break; + } + /* If a match is already found, ret == TRUE and the loop is skipped */ + for (int i = 0; i < nread && !ret; ++i) + { + ret = EqualSid(members[i].lgrmi0_sid, sid); + } + NetApiBufferFree(members); + /* MSDN says the lookup should always iterate until err != ERROR_MORE_DATA */ + } while (err == ERROR_MORE_DATA && nloop++ < 100); + + if (err != NERR_Success && err != NERR_GroupNotFound) { - NetApiBufferFree(groups); + SetLastError(err); + MsgToEventLog(M_SYSERR, TEXT("In NetLocalGroupGetMembers for group '%s'"), group_name); } - free(tmp); return ret; } diff --git a/src/openvpnserv/validate.h b/src/openvpnserv/validate.h index ece8704..cc443e6 100644 --- a/src/openvpnserv/validate.h +++ b/src/openvpnserv/validate.h @@ -17,10 +17,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef VALIDATE_H @@ -34,7 +33,7 @@ /* The last one may be reset in registry: HKLM\Software\OpenVPN\ovpn_admin_group */ BOOL -IsAuthorizedUser(SID *sid, settings_t *s); +IsAuthorizedUser(PSID sid, const HANDLE token, const WCHAR *ovpn_admin_group); BOOL CheckOption(const WCHAR *workdir, int narg, WCHAR *argv[], const settings_t *s); |