mirror of
https://github.com/squid-cache/squid.git
synced 2025-04-18 22:04:07 +03:00
Remove ext_lm_group_acl helper (#2011)
Lan Manager (LM) is an obsolete variant of the SMB protocol. No product on the market has supported it for several years now, in favour of NTLMv1 , NTLMv2 and Kerberos.
This commit is contained in:
parent
17645a33f5
commit
4b7b6df85c
29
CREDITS
29
CREDITS
@ -957,35 +957,6 @@ src/acl/external/LDAP_group/:
|
||||
*
|
||||
* In part based on squid_ldap_auth by Glen Newton and Henrik Nordstrom.
|
||||
|
||||
|
||||
==============================================================================
|
||||
|
||||
src/acl/external/LM_group/:
|
||||
|
||||
* (C)2002,2005 Guido Serassio - Acme Consulting S.r.l.
|
||||
*
|
||||
* Authors:
|
||||
* Guido Serassio <guido.serassio@acmeconsulting.it>
|
||||
* Acme Consulting S.r.l., Italy <http://www.acmeconsulting.it>
|
||||
|
||||
* In part based on check_group by Rodrigo Albani de Campos.
|
||||
*
|
||||
* Dependencies: Windows NT4 SP4 and later.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* 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; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
|
||||
|
||||
==============================================================================
|
||||
|
||||
src/acl/external/SQL_session/:
|
||||
|
@ -2514,7 +2514,6 @@ AC_CONFIG_FILES([
|
||||
src/acl/external/kerberos_ldap_group/Makefile
|
||||
src/acl/external/kerberos_sid_group/Makefile
|
||||
src/acl/external/LDAP_group/Makefile
|
||||
src/acl/external/LM_group/Makefile
|
||||
src/acl/external/session/Makefile
|
||||
src/acl/external/SQL_session/Makefile
|
||||
src/acl/external/unix_group/Makefile
|
||||
|
@ -33,6 +33,16 @@ The Squid-@SQUID_RELEASE@ change history can be <url url="https://github.com/squ
|
||||
<item>
|
||||
</itemize>
|
||||
|
||||
<sect1>Helper changes
|
||||
<p>
|
||||
<descrip>
|
||||
<p>Removed <em>ext_lm_group_acl</em> external acl helper. No product
|
||||
currently on the market suports the LanManager protocol
|
||||
in their default configuration.
|
||||
|
||||
</descrip>
|
||||
|
||||
|
||||
Most user-facing changes are reflected in squid.conf (see below).
|
||||
|
||||
|
||||
@ -89,7 +99,9 @@ This section gives an account of those changes in three categories:
|
||||
<sect1>Changes to existing options<label id="modifiedoptions">
|
||||
<p>
|
||||
<descrip>
|
||||
<p>No changed options in this version.
|
||||
<tag>--enable-external-acl-helpers=</tag>
|
||||
<p>Removed <em>LM_Group</em> helper. The LM protocol is
|
||||
insecure and no longer supported on the market since 2008.
|
||||
|
||||
</descrip>
|
||||
</p>
|
||||
|
@ -12,8 +12,6 @@
|
||||
|
||||
[type: man] src/acl/external/LDAP_group/ext_ldap_group_acl.8 $lang:doc/manuals/$lang/ext_ldap_group_acl.8
|
||||
|
||||
[type: man] src/acl/external/LM_group/ext_lm_group_acl.8 $lang:doc/manuals/$lang/ext_lm_group_acl.8
|
||||
|
||||
[type: man] src/acl/external/session/ext_session_acl.8 $lang:doc/manuals/$lang/ext_session_acl.8
|
||||
|
||||
[type: man] src/acl/external/time_quota/ext_time_quota_acl.8 $lang:doc/manuals/$lang/ext_time_quota_acl.8
|
||||
|
24
src/acl/external/LM_group/Makefile.am
vendored
24
src/acl/external/LM_group/Makefile.am
vendored
@ -1,24 +0,0 @@
|
||||
## Copyright (C) 1996-2023 The Squid Software Foundation and contributors
|
||||
##
|
||||
## Squid software is distributed under GPLv2+ license and includes
|
||||
## contributions from numerous individuals and organizations.
|
||||
## Please see the COPYING and CONTRIBUTORS files for details.
|
||||
##
|
||||
|
||||
include $(top_srcdir)/src/Common.am
|
||||
|
||||
libexec_PROGRAMS= ext_lm_group_acl
|
||||
man_MANS= ext_lm_group_acl.8
|
||||
|
||||
ext_lm_group_acl_SOURCES = ext_lm_group_acl.cc
|
||||
ext_lm_group_acl_LDADD= \
|
||||
$(top_builddir)/lib/libmiscencoding.la \
|
||||
$(COMPAT_LIB) \
|
||||
-lnetapi32 \
|
||||
-ladvapi32 \
|
||||
-lntdll \
|
||||
$(XTRA_LIBS)
|
||||
|
||||
EXTRA_DIST= \
|
||||
required.m4 \
|
||||
ext_lm_group_acl.8
|
208
src/acl/external/LM_group/ext_lm_group_acl.8
vendored
208
src/acl/external/LM_group/ext_lm_group_acl.8
vendored
@ -1,208 +0,0 @@
|
||||
.if !'po4a'hide' .TH ext_lm_group_acl 8
|
||||
.
|
||||
.SH NAME
|
||||
ext_lm_group_acl \- Squid external ACL helper to check Windows users group membership.
|
||||
.PP
|
||||
Version 1.22
|
||||
.
|
||||
.SH SYNOPSIS
|
||||
.if !'po4a'hide' .B ext_lm_group_acl
|
||||
.if !'po4a'hide' .B "[\-D "
|
||||
domain
|
||||
.if !'po4a'hide' .B "] [\-cdhGP]"
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
.B ext_lm_group_acl
|
||||
is an installed binary in Squid for Windows builds.
|
||||
.PP
|
||||
This helper must be used in with an authentication scheme (typically
|
||||
Basic or NTLM) based on Windows NT/2000 domain users (LM mode).
|
||||
.PP
|
||||
It reads from the standard input the domain username and a list of groups
|
||||
and tries to match each against the groups membership of the specified
|
||||
username.
|
||||
.
|
||||
.SH OPTIONS
|
||||
.if !'po4a'hide' .TP 12
|
||||
.if !'po4a'hide' .B \-c
|
||||
Use case insensitive compare.
|
||||
.
|
||||
.if !'po4a'hide' .TP
|
||||
.if !'po4a'hide' .B \-d
|
||||
Write debug info to stderr.
|
||||
.
|
||||
.if !'po4a'hide' .TP
|
||||
.if !'po4a'hide' .B \-D domain
|
||||
Specify the default user's domain.
|
||||
.
|
||||
.if !'po4a'hide' .TP
|
||||
.if !'po4a'hide' .B \-G
|
||||
Start helper in Domain Global Group mode.
|
||||
.
|
||||
.if !'po4a'hide' .TP
|
||||
.if !'po4a'hide' .B \-h
|
||||
Display the binary help and command line syntax info using stderr.
|
||||
.
|
||||
.if !'po4a'hide' .TP
|
||||
.if !'po4a'hide' .B \-P
|
||||
Use ONLY PDCs for group validation.
|
||||
.
|
||||
.SH CONFIGURATION
|
||||
.if !'po4a'hide' .RS
|
||||
.if !'po4a'hide' .B external_acl_type NT_global_group %LOGIN c:/squid/libexec/ext_lm_group_acl.exe -G
|
||||
.if !'po4a'hide' .br
|
||||
.if !'po4a'hide' .B external_acl_type NT_local_group %LOGIN c:/squid/libexec/ext_lm_group_acl.exe
|
||||
.if !'po4a'hide' .br
|
||||
.if !'po4a'hide' .br
|
||||
.if !'po4a'hide' .B acl GProxyUsers external NT_global_group GProxyUsers
|
||||
.if !'po4a'hide' .br
|
||||
.if !'po4a'hide' .B acl LProxyUsers external NT_local_group LProxyUsers
|
||||
.if !'po4a'hide' .br
|
||||
.if !'po4a'hide' .B acl password proxy_auth REQUIRED
|
||||
.if !'po4a'hide' .br
|
||||
.if !'po4a'hide' .br
|
||||
.if !'po4a'hide' .B http_access allow password GProxyUsers
|
||||
.if !'po4a'hide' .br
|
||||
.if !'po4a'hide' .B http_access allow password LProxyUsers
|
||||
.if !'po4a'hide' .br
|
||||
.if !'po4a'hide' .B http_access deny all
|
||||
.if !'po4a'hide' .RE
|
||||
.
|
||||
.PP
|
||||
In the previous example all validated NT users member of GProxyUsers Global
|
||||
domain group or member of LProxyUsers machine local group are allowed to
|
||||
use the cache.
|
||||
.
|
||||
.PP
|
||||
Groups with spaces in name, for example
|
||||
.B "Domain Users"
|
||||
, must be quoted and the acl data (
|
||||
.B "Domain Users"
|
||||
) must be placed into a separate file included by specifying
|
||||
.B "/path/to/file"
|
||||
.
|
||||
The previous example will be:
|
||||
.if !'po4a'hide' .RS
|
||||
.if !'po4a'hide' acl ProxyUsers external NT_global_group "c:/squid/etc/DomainUsers.txt"
|
||||
.if !'po4a'hide' .RE
|
||||
.
|
||||
The
|
||||
.B DomainUsers.txt
|
||||
file will contain only the following line:
|
||||
.if !'po4a'hide' .RS
|
||||
.B "Domain Users"
|
||||
.if !'po4a'hide' .RE
|
||||
.
|
||||
.PP
|
||||
.B NOTE:
|
||||
The standard group name comparison is case sensitive, so group name
|
||||
must be specified with same case as in the NT/2000 Domain.
|
||||
It's possible to enable case insensitive group name comparison (
|
||||
.B \-c
|
||||
), but on some not-english locales, the results can be unexpected.
|
||||
.
|
||||
.PP
|
||||
.B NOTE:
|
||||
Native WIN32 NTLM and Basic Helpers must be used without the
|
||||
.B \-A
|
||||
and
|
||||
.B \-D
|
||||
switches.
|
||||
.PP
|
||||
Refer to Squid documentation for the more details on squid.conf.
|
||||
.
|
||||
.SH TESTING
|
||||
.PP
|
||||
I strongly recommend that
|
||||
.B ext_lm_group_acl
|
||||
is tested prior to being used in a production environment. It may behave differently on different platforms.
|
||||
.
|
||||
.PP
|
||||
To test it, run it from the command line. Enter username and group
|
||||
pairs separated by a space (username must entered with URL-encoded
|
||||
.I domain%5Cusername
|
||||
syntax). Press
|
||||
.B ENTER
|
||||
to get an
|
||||
.B OK
|
||||
or
|
||||
.B ERR
|
||||
message.
|
||||
.PP
|
||||
Make sure pressing
|
||||
.B CTRL+D
|
||||
behaves the same as a carriage return.
|
||||
.PP
|
||||
Make sure pressing
|
||||
.B CTRL+C
|
||||
aborts the program.
|
||||
.
|
||||
.PP
|
||||
Test that entering no details does not result in an
|
||||
.B OK
|
||||
or
|
||||
.B ERR
|
||||
message.
|
||||
.PP
|
||||
Test that entering an invalid username and group results in an
|
||||
.B ERR
|
||||
message.
|
||||
.PP
|
||||
Test that entering an valid username and group results in an
|
||||
.B OK
|
||||
message.
|
||||
.
|
||||
.SH AUTHOR
|
||||
This program was written by
|
||||
.if !'po4a'hide' .I Guido Serassio <guido.serassio@acmeconsulting.it>
|
||||
with contributions by
|
||||
.if !'po4a'hide' .I Henrik Nordstrom <hno@squid-cache.org>
|
||||
.PP
|
||||
Based in part on prior work in
|
||||
.B check_group
|
||||
by
|
||||
.if !'po4a'hide' .I Rodrigo Albani de Campos
|
||||
.PP
|
||||
This manual was written by
|
||||
.if !'po4a'hide' .I Guido Serassio <guido.serassio@acmeconsulting.it>
|
||||
.if !'po4a'hide' .I Amos Jeffries <amosjeffries@squid-cache.org>
|
||||
.
|
||||
.SH COPYRIGHT
|
||||
.PP
|
||||
* Copyright (C) 1996-2023 The Squid Software Foundation and contributors
|
||||
*
|
||||
* Squid software is distributed under GPLv2+ license and includes
|
||||
* contributions from numerous individuals and organizations.
|
||||
* Please see the COPYING and CONTRIBUTORS files for details.
|
||||
.PP
|
||||
This program and documentation is copyright to the authors named above.
|
||||
.PP
|
||||
Distributed under the GNU General Public License (GNU GPL) version 2 or later (GPLv2+).
|
||||
.
|
||||
.SH QUESTIONS
|
||||
Questions on the usage of this program can be sent to the
|
||||
.I Squid Users mailing list
|
||||
.if !'po4a'hide' <squid-users@lists.squid-cache.org>
|
||||
.
|
||||
.SH REPORTING BUGS
|
||||
Bug reports need to be made in English.
|
||||
See https://wiki.squid-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report.
|
||||
.PP
|
||||
Report bugs or bug fixes using https://bugs.squid-cache.org/
|
||||
.PP
|
||||
Report serious security bugs to
|
||||
.I Squid Bugs <squid-bugs@lists.squid-cache.org>
|
||||
.PP
|
||||
Report ideas for new improvements to the
|
||||
.I Squid Developers mailing list
|
||||
.if !'po4a'hide' <squid-dev@lists.squid-cache.org>
|
||||
.
|
||||
.SH SEE ALSO
|
||||
.if !'po4a'hide' .BR squid "(8), "
|
||||
.if !'po4a'hide' .BR GPL "(7), "
|
||||
.br
|
||||
The Squid FAQ wiki
|
||||
.if !'po4a'hide' https://wiki.squid-cache.org/SquidFaq
|
||||
.br
|
||||
The Squid Configuration Manual
|
||||
.if !'po4a'hide' http://www.squid-cache.org/Doc/config/
|
599
src/acl/external/LM_group/ext_lm_group_acl.cc
vendored
599
src/acl/external/LM_group/ext_lm_group_acl.cc
vendored
@ -1,599 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1996-2023 The Squid Software Foundation and contributors
|
||||
*
|
||||
* Squid software is distributed under GPLv2+ license and includes
|
||||
* contributions from numerous individuals and organizations.
|
||||
* Please see the COPYING and CONTRIBUTORS files for details.
|
||||
*/
|
||||
|
||||
/*
|
||||
* mswin_check_lm_group: lookup group membership in a Windows NT/2000 domain
|
||||
*
|
||||
* (C)2002,2005 Guido Serassio - Acme Consulting S.r.l.
|
||||
*
|
||||
* Authors:
|
||||
* Guido Serassio <guido.serassio@acmeconsulting.it>
|
||||
* Acme Consulting S.r.l., Italy <http://www.acmeconsulting.it>
|
||||
*
|
||||
* With contributions from others mentioned in the change history section
|
||||
* below.
|
||||
*
|
||||
* In part based on check_group by Rodrigo Albani de Campos.
|
||||
*
|
||||
* Dependencies: Windows NT4 SP4 and later.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* 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; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* Version 1.22
|
||||
* 08-07-2005 Guido Serassio
|
||||
* Added -P option for force usage of PDCs for group validation.
|
||||
* Added support for '/' char as domain separator.
|
||||
* Fixed Bugzilla #1336.
|
||||
* Version 1.21
|
||||
* 23-04-2005 Guido Serassio
|
||||
* Added -D option for specify default user's domain.
|
||||
* Version 1.20.1
|
||||
* 15-08-2004 Guido Serassio
|
||||
* Helper protocol changed to use URL escaped strings in Squid-3.0
|
||||
* (Original work of Henrik Nordstrom)
|
||||
* Version 1.20
|
||||
* 13-06-2004 Guido Serassio
|
||||
* Added support for running on a Domain Controller.
|
||||
* Version 1.10
|
||||
* 01-05-2003 Guido Serassio
|
||||
* Added option for case insensitive group name comparison.
|
||||
* More debug info.
|
||||
* Updated documentation.
|
||||
* Segfault bug fix (Bugzilla #574)
|
||||
* Version 1.0
|
||||
* 24-06-2002 Guido Serassio
|
||||
* Using the main function from check_group and sections
|
||||
* from wbinfo wrote win32_group
|
||||
*
|
||||
* This is a helper for the external ACL interface for Squid Cache
|
||||
*
|
||||
* It reads from the standard input the domain username and a list of
|
||||
* groups and tries to match it against the groups membership of the
|
||||
* specified username.
|
||||
*
|
||||
* Returns `OK' if the user belongs to a group or `ERR' otherwise, as
|
||||
* described on http://devel.squid-cache.org/external_acl/config.html
|
||||
*
|
||||
*/
|
||||
|
||||
#include "squid.h"
|
||||
#include "helper/protocol_defines.h"
|
||||
#include "rfc1738.h"
|
||||
#include "util.h"
|
||||
|
||||
#if _SQUID_CYGWIN_
|
||||
#include <cwchar>
|
||||
int _wcsicmp(const wchar_t *, const wchar_t *);
|
||||
#endif
|
||||
|
||||
#undef assert
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <cstring>
|
||||
#if HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <lm.h>
|
||||
#include <ntsecapi.h>
|
||||
|
||||
int use_global = 0;
|
||||
int use_PDC_only = 0;
|
||||
const char *program_name;
|
||||
pid_t mypid;
|
||||
char *machinedomain;
|
||||
int use_case_insensitive_compare = 0;
|
||||
char *DefaultDomain = nullptr;
|
||||
const char NTV_VALID_DOMAIN_SEPARATOR[] = "\\/";
|
||||
|
||||
static char *
|
||||
AllocStrFromLSAStr(LSA_UNICODE_STRING LsaStr)
|
||||
{
|
||||
size_t len;
|
||||
static char *target;
|
||||
|
||||
len = LsaStr.Length / sizeof(WCHAR) + 1;
|
||||
|
||||
/* allocate buffer for str + null termination */
|
||||
safe_free(target);
|
||||
target = (char *) xmalloc(len);
|
||||
if (target == NULL)
|
||||
return nullptr;
|
||||
|
||||
/* copy unicode buffer */
|
||||
WideCharToMultiByte(CP_ACP, 0, LsaStr.Buffer, LsaStr.Length, target, len, nullptr, nullptr);
|
||||
|
||||
/* add null termination */
|
||||
target[len - 1] = '\0';
|
||||
return target;
|
||||
}
|
||||
|
||||
static char *
|
||||
GetDomainName(void)
|
||||
{
|
||||
LSA_HANDLE PolicyHandle;
|
||||
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
NTSTATUS status;
|
||||
PPOLICY_PRIMARY_DOMAIN_INFO ppdiDomainInfo;
|
||||
PWKSTA_INFO_100 pwkiWorkstationInfo;
|
||||
DWORD netret;
|
||||
char *DomainName = nullptr;
|
||||
|
||||
/*
|
||||
* Always initialize the object attributes to all zeroes.
|
||||
*/
|
||||
memset(&ObjectAttributes, '\0', sizeof(ObjectAttributes));
|
||||
|
||||
/*
|
||||
* You need the local workstation name. Use NetWkstaGetInfo at level
|
||||
* 100 to retrieve a WKSTA_INFO_100 structure.
|
||||
*
|
||||
* The wki100_computername field contains a pointer to a UNICODE
|
||||
* string containing the local computer name.
|
||||
*/
|
||||
netret = NetWkstaGetInfo(nullptr, 100, (LPBYTE *) & pwkiWorkstationInfo);
|
||||
if (netret == NERR_Success) {
|
||||
/*
|
||||
* We have the workstation name in:
|
||||
* pwkiWorkstationInfo->wki100_computername
|
||||
*
|
||||
* Next, open the policy object for the local system using
|
||||
* the LsaOpenPolicy function.
|
||||
*/
|
||||
status = LsaOpenPolicy(
|
||||
nullptr,
|
||||
&ObjectAttributes,
|
||||
GENERIC_READ | POLICY_VIEW_LOCAL_INFORMATION,
|
||||
&PolicyHandle
|
||||
);
|
||||
|
||||
/*
|
||||
* Error checking.
|
||||
*/
|
||||
if (status) {
|
||||
debug("OpenPolicy Error: %ld\n", status);
|
||||
} else {
|
||||
|
||||
/*
|
||||
* You have a handle to the policy object. Now, get the
|
||||
* domain information using LsaQueryInformationPolicy.
|
||||
*/
|
||||
status = LsaQueryInformationPolicy(PolicyHandle,
|
||||
PolicyPrimaryDomainInformation,
|
||||
(PVOID *) & ppdiDomainInfo);
|
||||
if (status) {
|
||||
debug("LsaQueryInformationPolicy Error: %ld\n", status);
|
||||
} else {
|
||||
|
||||
/* Get name in usable format */
|
||||
DomainName = AllocStrFromLSAStr(ppdiDomainInfo->Name);
|
||||
|
||||
/*
|
||||
* Check the Sid pointer, if it is null, the
|
||||
* workstation is either a stand-alone computer
|
||||
* or a member of a workgroup.
|
||||
*/
|
||||
if (ppdiDomainInfo->Sid) {
|
||||
|
||||
/*
|
||||
* Member of a domain. Display it in debug mode.
|
||||
*/
|
||||
debug("Member of Domain %s\n", DomainName);
|
||||
} else {
|
||||
DomainName = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up all the memory buffers created by the LSA and
|
||||
* Net* APIs.
|
||||
*/
|
||||
NetApiBufferFree(pwkiWorkstationInfo);
|
||||
LsaFreeMemory((LPVOID) ppdiDomainInfo);
|
||||
} else
|
||||
debug("NetWkstaGetInfo Error: %ld\n", netret);
|
||||
return DomainName;
|
||||
}
|
||||
|
||||
/* returns 0 on match, -1 if no match */
|
||||
static int
|
||||
wcstrcmparray(const wchar_t * str, const char **array)
|
||||
{
|
||||
WCHAR wszGroup[GNLEN + 1]; // Unicode Group
|
||||
|
||||
while (*array) {
|
||||
MultiByteToWideChar(CP_ACP, 0, *array,
|
||||
strlen(*array) + 1, wszGroup, sizeof(wszGroup) / sizeof(wszGroup[0]));
|
||||
debug("Windows group: %S, Squid group: %S\n", str, wszGroup);
|
||||
if ((use_case_insensitive_compare ? _wcsicmp(str, wszGroup) : wcscmp(str, wszGroup)) == 0)
|
||||
return 0;
|
||||
++array;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* returns 1 on success, 0 on failure */
|
||||
static int
|
||||
Valid_Local_Groups(char *UserName, const char **Groups)
|
||||
{
|
||||
int result = 0;
|
||||
char *Domain_Separator;
|
||||
WCHAR wszUserName[UNLEN + 1]; // Unicode user name
|
||||
|
||||
LPLOCALGROUP_USERS_INFO_0 pBuf = nullptr;
|
||||
LPLOCALGROUP_USERS_INFO_0 pTmpBuf;
|
||||
DWORD dwLevel = 0;
|
||||
DWORD dwFlags = LG_INCLUDE_INDIRECT;
|
||||
DWORD dwPrefMaxLen = -1;
|
||||
DWORD dwEntriesRead = 0;
|
||||
DWORD dwTotalEntries = 0;
|
||||
NET_API_STATUS nStatus;
|
||||
DWORD i;
|
||||
DWORD dwTotalCount = 0;
|
||||
|
||||
if ((Domain_Separator = strchr(UserName, '/')) != NULL)
|
||||
*Domain_Separator = '\\';
|
||||
|
||||
debug("Valid_Local_Groups: checking group membership of '%s'.\n", UserName);
|
||||
|
||||
/* Convert ANSI User Name and Group to Unicode */
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, UserName,
|
||||
strlen(UserName) + 1, wszUserName, sizeof(wszUserName) / sizeof(wszUserName[0]));
|
||||
|
||||
/*
|
||||
* Call the NetUserGetLocalGroups function
|
||||
* specifying information level 0.
|
||||
*
|
||||
* The LG_INCLUDE_INDIRECT flag specifies that the
|
||||
* function should also return the names of the local
|
||||
* groups in which the user is indirectly a member.
|
||||
*/
|
||||
nStatus = NetUserGetLocalGroups(
|
||||
nullptr,
|
||||
wszUserName,
|
||||
dwLevel,
|
||||
dwFlags,
|
||||
(LPBYTE *) & pBuf,
|
||||
dwPrefMaxLen,
|
||||
&dwEntriesRead,
|
||||
&dwTotalEntries);
|
||||
/*
|
||||
* If the call succeeds,
|
||||
*/
|
||||
if (nStatus == NERR_Success) {
|
||||
if ((pTmpBuf = pBuf) != NULL) {
|
||||
for (i = 0; i < dwEntriesRead; ++i) {
|
||||
assert(pTmpBuf != NULL);
|
||||
if (pTmpBuf == NULL) {
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
if (wcstrcmparray(pTmpBuf->lgrui0_name, Groups) == 0) {
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
++pTmpBuf;
|
||||
++dwTotalCount;
|
||||
}
|
||||
}
|
||||
} else
|
||||
result = 0;
|
||||
/*
|
||||
* Free the allocated memory.
|
||||
*/
|
||||
if (pBuf != NULL)
|
||||
NetApiBufferFree(pBuf);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* returns 1 on success, 0 on failure */
|
||||
static int
|
||||
Valid_Global_Groups(char *UserName, const char **Groups)
|
||||
{
|
||||
int result = 0;
|
||||
WCHAR wszUserName[UNLEN + 1]; // Unicode user name
|
||||
|
||||
WCHAR wszLocalDomain[DNLEN + 1]; // Unicode Local Domain
|
||||
|
||||
WCHAR wszUserDomain[DNLEN + 1]; // Unicode User Domain
|
||||
|
||||
char NTDomain[DNLEN + UNLEN + 2];
|
||||
char *domain_qualify;
|
||||
char User[UNLEN + 1];
|
||||
size_t j;
|
||||
|
||||
LPWSTR LclDCptr = nullptr;
|
||||
LPWSTR UsrDCptr = nullptr;
|
||||
LPGROUP_USERS_INFO_0 pUsrBuf = nullptr;
|
||||
LPGROUP_USERS_INFO_0 pTmpBuf;
|
||||
LPSERVER_INFO_101 pSrvBuf = nullptr;
|
||||
DWORD dwLevel = 0;
|
||||
DWORD dwPrefMaxLen = -1;
|
||||
DWORD dwEntriesRead = 0;
|
||||
DWORD dwTotalEntries = 0;
|
||||
NET_API_STATUS nStatus;
|
||||
DWORD i;
|
||||
DWORD dwTotalCount = 0;
|
||||
|
||||
xstrncpy(NTDomain, UserName, sizeof(NTDomain));
|
||||
|
||||
for (j = 0; j < strlen(NTV_VALID_DOMAIN_SEPARATOR); ++j) {
|
||||
if ((domain_qualify = strchr(NTDomain, NTV_VALID_DOMAIN_SEPARATOR[j])) != NULL)
|
||||
break;
|
||||
}
|
||||
if (domain_qualify == NULL) {
|
||||
xstrncpy(User, NTDomain, sizeof(User));
|
||||
xstrncpy(NTDomain, DefaultDomain, sizeof(NTDomain));
|
||||
} else {
|
||||
xstrncpy(User, domain_qualify + 1, sizeof(User));
|
||||
domain_qualify[0] = '\0';
|
||||
strlwr(NTDomain);
|
||||
}
|
||||
|
||||
debug("Valid_Global_Groups: checking group membership of '%s\\%s'.\n", NTDomain, User);
|
||||
|
||||
/* Convert ANSI User Name and Group to Unicode */
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, User,
|
||||
strlen(User) + 1, wszUserName,
|
||||
sizeof(wszUserName) / sizeof(wszUserName[0]));
|
||||
MultiByteToWideChar(CP_ACP, 0, machinedomain,
|
||||
strlen(machinedomain) + 1, wszLocalDomain, sizeof(wszLocalDomain) / sizeof(wszLocalDomain[0]));
|
||||
|
||||
/* Call the NetServerGetInfo function for local computer, specifying level 101. */
|
||||
dwLevel = 101;
|
||||
nStatus = NetServerGetInfo(nullptr, dwLevel, (LPBYTE *) & pSrvBuf);
|
||||
|
||||
if (nStatus == NERR_Success) {
|
||||
/* Check if we are running on a Domain Controller */
|
||||
if ((pSrvBuf->sv101_type & SV_TYPE_DOMAIN_CTRL) ||
|
||||
(pSrvBuf->sv101_type & SV_TYPE_DOMAIN_BAKCTRL)) {
|
||||
LclDCptr = nullptr;
|
||||
debug("Running on a DC.\n");
|
||||
} else
|
||||
nStatus = (use_PDC_only ? NetGetDCName(nullptr, wszLocalDomain, (LPBYTE *) & LclDCptr) : NetGetAnyDCName(nullptr, wszLocalDomain, (LPBYTE *) & LclDCptr));
|
||||
} else {
|
||||
fprintf(stderr, "%s: ERROR: NetServerGetInfo() failed.'\n", program_name);
|
||||
if (pSrvBuf != NULL)
|
||||
NetApiBufferFree(pSrvBuf);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (nStatus == NERR_Success) {
|
||||
debug("Using '%S' as DC for '%S' local domain.\n", LclDCptr, wszLocalDomain);
|
||||
|
||||
if (strcmp(NTDomain, machinedomain) != 0) {
|
||||
MultiByteToWideChar(CP_ACP, 0, NTDomain,
|
||||
strlen(NTDomain) + 1, wszUserDomain, sizeof(wszUserDomain) / sizeof(wszUserDomain[0]));
|
||||
nStatus = (use_PDC_only ? NetGetDCName(LclDCptr, wszUserDomain, (LPBYTE *) & UsrDCptr) : NetGetAnyDCName(LclDCptr, wszUserDomain, (LPBYTE *) & UsrDCptr));
|
||||
if (nStatus != NERR_Success) {
|
||||
fprintf(stderr, "%s: ERROR: Can't find DC for user's domain '%s'\n", program_name, NTDomain);
|
||||
if (pSrvBuf != NULL)
|
||||
NetApiBufferFree(pSrvBuf);
|
||||
if (LclDCptr != NULL)
|
||||
NetApiBufferFree((LPVOID) LclDCptr);
|
||||
if (UsrDCptr != NULL)
|
||||
NetApiBufferFree((LPVOID) UsrDCptr);
|
||||
return result;
|
||||
}
|
||||
} else
|
||||
UsrDCptr = LclDCptr;
|
||||
|
||||
debug("Using '%S' as DC for '%s' user's domain.\n", UsrDCptr, NTDomain);
|
||||
/*
|
||||
* Call the NetUserGetGroups function
|
||||
* specifying information level 0.
|
||||
*/
|
||||
dwLevel = 0;
|
||||
nStatus = NetUserGetGroups(UsrDCptr,
|
||||
wszUserName,
|
||||
dwLevel,
|
||||
(LPBYTE *) & pUsrBuf,
|
||||
dwPrefMaxLen,
|
||||
&dwEntriesRead,
|
||||
&dwTotalEntries);
|
||||
/*
|
||||
* If the call succeeds,
|
||||
*/
|
||||
if (nStatus == NERR_Success) {
|
||||
if ((pTmpBuf = pUsrBuf) != NULL) {
|
||||
for (i = 0; i < dwEntriesRead; ++i) {
|
||||
assert(pTmpBuf != NULL);
|
||||
if (pTmpBuf == NULL) {
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
if (wcstrcmparray(pTmpBuf->grui0_name, Groups) == 0) {
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
++pTmpBuf;
|
||||
++dwTotalCount;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = 0;
|
||||
fprintf(stderr, "%s: ERROR: NetUserGetGroups() failed.'\n", program_name);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: ERROR: Can't find DC for local domain '%s'\n", program_name, machinedomain);
|
||||
}
|
||||
/*
|
||||
* Free the allocated memory.
|
||||
*/
|
||||
if (pSrvBuf != NULL)
|
||||
NetApiBufferFree(pSrvBuf);
|
||||
if (pUsrBuf != NULL)
|
||||
NetApiBufferFree(pUsrBuf);
|
||||
if ((UsrDCptr != NULL) && (UsrDCptr != LclDCptr))
|
||||
NetApiBufferFree((LPVOID) UsrDCptr);
|
||||
if (LclDCptr != NULL)
|
||||
NetApiBufferFree((LPVOID) LclDCptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(const char *program)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-D domain][-G][-P][-c][-d][-h]\n"
|
||||
" -D default user Domain\n"
|
||||
" -G enable Domain Global group mode\n"
|
||||
" -P use ONLY PDCs for group validation\n"
|
||||
" -c use case insensitive compare\n"
|
||||
" -d enable debugging\n"
|
||||
" -h this message\n",
|
||||
program);
|
||||
}
|
||||
|
||||
static void
|
||||
process_options(int argc, char *argv[])
|
||||
{
|
||||
int opt;
|
||||
|
||||
opterr = 0;
|
||||
while (-1 != (opt = getopt(argc, argv, "D:GPcdh"))) {
|
||||
switch (opt) {
|
||||
case 'D':
|
||||
DefaultDomain = xstrndup(optarg, DNLEN + 1);
|
||||
strlwr(DefaultDomain);
|
||||
break;
|
||||
case 'G':
|
||||
use_global = 1;
|
||||
break;
|
||||
case 'P':
|
||||
use_PDC_only = 1;
|
||||
break;
|
||||
case 'c':
|
||||
use_case_insensitive_compare = 1;
|
||||
break;
|
||||
case 'd':
|
||||
debug_enabled = 1;
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(EXIT_SUCCESS);
|
||||
case '?':
|
||||
opt = optopt;
|
||||
[[fallthrough]];
|
||||
default:
|
||||
fprintf(stderr, "%s: FATAL: Unknown option: -%c. Exiting\n", program_name, opt);
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
break; /* not reached */
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *p;
|
||||
char buf[HELPER_INPUT_BUFFER];
|
||||
char *username;
|
||||
char *group;
|
||||
const char *groups[512];
|
||||
int n;
|
||||
|
||||
if (argc > 0) { /* should always be true */
|
||||
program_name = strrchr(argv[0], '/');
|
||||
if (program_name == NULL)
|
||||
program_name = argv[0];
|
||||
} else {
|
||||
program_name = "(unknown)";
|
||||
}
|
||||
mypid = getpid();
|
||||
|
||||
setbuf(stdout, nullptr);
|
||||
setbuf(stderr, nullptr);
|
||||
|
||||
/* Check Command Line */
|
||||
process_options(argc, argv);
|
||||
|
||||
if (use_global) {
|
||||
if ((machinedomain = GetDomainName()) == NULL) {
|
||||
fprintf(stderr, "%s: FATAL: Can't read machine domain\n", program_name);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
strlwr(machinedomain);
|
||||
if (!DefaultDomain)
|
||||
DefaultDomain = xstrdup(machinedomain);
|
||||
}
|
||||
debug("%s " VERSION " " SQUID_BUILD_INFO " starting up...\n", argv[0]);
|
||||
if (use_global) {
|
||||
debug("Domain Global group mode enabled using '%s' as default domain.\n", DefaultDomain);
|
||||
}
|
||||
if (use_case_insensitive_compare) {
|
||||
debug("Warning: running in case insensitive mode !!!\n");
|
||||
}
|
||||
if (use_PDC_only) {
|
||||
debug("Warning: using only PDCs for group validation !!!\n");
|
||||
}
|
||||
|
||||
/* Main Loop */
|
||||
while (fgets(buf, HELPER_INPUT_BUFFER, stdin)) {
|
||||
if (NULL == strchr(buf, '\n')) {
|
||||
/* too large message received.. skip and deny */
|
||||
debug("%s: ERROR: Too large: %s\n", argv[0], buf);
|
||||
while (fgets(buf, HELPER_INPUT_BUFFER, stdin)) {
|
||||
debug("%s: ERROR: Too large..: %s\n", argv[0], buf);
|
||||
if (strchr(buf, '\n') != NULL)
|
||||
break;
|
||||
}
|
||||
SEND_BH(HLP_MSG("Input Too Long."));
|
||||
continue;
|
||||
}
|
||||
if ((p = strchr(buf, '\n')) != NULL)
|
||||
*p = '\0'; /* strip \n */
|
||||
if ((p = strchr(buf, '\r')) != NULL)
|
||||
*p = '\0'; /* strip \r */
|
||||
|
||||
debug("Got '%s' from Squid (length: %d).\n", buf, strlen(buf));
|
||||
|
||||
if (buf[0] == '\0') {
|
||||
SEND_BH(HLP_MSG("Invalid Request."));
|
||||
continue;
|
||||
}
|
||||
username = strtok(buf, " ");
|
||||
for (n = 0; (group = strtok(nullptr, " ")) != NULL; ++n) {
|
||||
rfc1738_unescape(group);
|
||||
groups[n] = group;
|
||||
}
|
||||
groups[n] = nullptr;
|
||||
|
||||
if (NULL == username) {
|
||||
SEND_BH(HLP_MSG("Invalid Request. No Username."));
|
||||
continue;
|
||||
}
|
||||
rfc1738_unescape(username);
|
||||
|
||||
if ((use_global ? Valid_Global_Groups(username, groups) : Valid_Local_Groups(username, groups))) {
|
||||
SEND_OK("");
|
||||
} else {
|
||||
SEND_ERR("");
|
||||
}
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
8
src/acl/external/LM_group/required.m4
vendored
8
src/acl/external/LM_group/required.m4
vendored
@ -1,8 +0,0 @@
|
||||
## Copyright (C) 1996-2023 The Squid Software Foundation and contributors
|
||||
##
|
||||
## Squid software is distributed under GPLv2+ license and includes
|
||||
## contributions from numerous individuals and organizations.
|
||||
## Please see the COPYING and CONTRIBUTORS files for details.
|
||||
|
||||
# Only build this helper on Windows
|
||||
AC_CHECK_HEADERS([w32api/windows.h windows.h],[BUILD_HELPER="LM_group"])
|
1
src/acl/external/Makefile.am
vendored
1
src/acl/external/Makefile.am
vendored
@ -13,7 +13,6 @@ DIST_SUBDIRS= \
|
||||
kerberos_ldap_group \
|
||||
kerberos_sid_group \
|
||||
LDAP_group \
|
||||
LM_group \
|
||||
session \
|
||||
SQL_session \
|
||||
time_quota \
|
||||
|
1
src/acl/external/helpers.m4
vendored
1
src/acl/external/helpers.m4
vendored
@ -12,7 +12,6 @@ SQUID_HELPER_FEATURE_CHECK([external_acl_helpers],[yes],[acl/external],[
|
||||
# NP: we only need this list because m4_include() does not accept variables
|
||||
SQUID_CHECK_HELPER([AD_group],[acl/external])
|
||||
SQUID_CHECK_HELPER([LDAP_group],[acl/external])
|
||||
SQUID_CHECK_HELPER([LM_group],[acl/external])
|
||||
SQUID_CHECK_HELPER([delayer],[acl/external])
|
||||
SQUID_CHECK_HELPER([SQL_session],[acl/external])
|
||||
SQUID_CHECK_HELPER([eDirectory_userip],[acl/external])
|
||||
|
Loading…
x
Reference in New Issue
Block a user