1
0
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:
Francesco Chemolli 2025-03-04 19:06:59 +00:00 committed by Squid Anubis
parent 17645a33f5
commit 4b7b6df85c
10 changed files with 13 additions and 874 deletions

29
CREDITS
View File

@ -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/:

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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/

View File

@ -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;
}

View File

@ -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"])

View File

@ -13,7 +13,6 @@ DIST_SUBDIRS= \
kerberos_ldap_group \
kerberos_sid_group \
LDAP_group \
LM_group \
session \
SQL_session \
time_quota \

View File

@ -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])