--------------------- PatchSet 2072 Date: 2005/10/31 15:20:39 Author: serassio Branch: nt Tag: (none) Log: Renamed win32_check_group external helper to mswin_check_lm_group Members: configure.in:1.26.2.68->1.26.2.69 helpers/external_acl/Makefile.am:1.3.16.2->1.3.16.3 helpers/external_acl/mswin_lm_group/.cvsignore:1.1->1.1.2.1 helpers/external_acl/mswin_lm_group/Makefile.am:1.1->1.1.2.1 helpers/external_acl/mswin_lm_group/readme.txt:1.1->1.1.2.1 helpers/external_acl/mswin_lm_group/win32_check_group.c:1.1->1.1.2.1 helpers/external_acl/mswin_lm_group/win32_check_group.h:1.1->1.1.2.1 helpers/external_acl/win32_group/.cvsignore:1.1.2.1->1.1.2.2(DEAD) helpers/external_acl/win32_group/Makefile.am:1.2.18.4->1.2.18.5(DEAD) helpers/external_acl/win32_group/readme.txt:1.2.18.6->1.2.18.7(DEAD) helpers/external_acl/win32_group/win32_check_group.c:1.2.18.11->1.2.18.12(DEAD) helpers/external_acl/win32_group/win32_check_group.h:1.2.18.3->1.2.18.4(DEAD) Index: squid3/configure.in =================================================================== RCS file: /cvsroot/squid-sf//squid3/configure.in,v retrieving revision 1.26.2.68 retrieving revision 1.26.2.69 diff -u -r1.26.2.68 -r1.26.2.69 --- squid3/configure.in 30 Oct 2005 19:37:34 -0000 1.26.2.68 +++ squid3/configure.in 31 Oct 2005 15:20:57 -0000 1.26.2.69 @@ -3,7 +3,7 @@ dnl dnl Duane Wessels, wessels@nlanr.net, February 1996 (autoconf v2.9) dnl -dnl $Id: configure.in,v 1.26.2.68 2005/10/30 19:37:34 serassio Exp $ +dnl $Id: configure.in,v 1.26.2.69 2005/10/31 15:20:57 serassio Exp $ dnl dnl dnl @@ -13,7 +13,7 @@ AC_CONFIG_AUX_DIR(cfgaux) AM_INIT_AUTOMAKE(squid, 3.0-PRE3-NT-CVS) AM_CONFIG_HEADER(include/autoconf.h) -AC_REVISION($Revision: 1.26.2.68 $)dnl +AC_REVISION($Revision: 1.26.2.69 $)dnl AC_PREFIX_DEFAULT(/usr/local/squid) AM_MAINTAINER_MODE @@ -3017,7 +3017,7 @@ helpers/external_acl/ldap_group/Makefile \ helpers/external_acl/unix_group/Makefile \ helpers/external_acl/wbinfo_group/Makefile \ - helpers/external_acl/win32_group/Makefile \ + helpers/external_acl/mswin_lm_group/Makefile \ port/Makefile \ port/win32/Makefile \ ]) Index: squid3/helpers/external_acl/Makefile.am =================================================================== RCS file: /cvsroot/squid-sf//squid3/helpers/external_acl/Makefile.am,v retrieving revision 1.3.16.2 retrieving revision 1.3.16.3 diff -u -r1.3.16.2 -r1.3.16.3 --- squid3/helpers/external_acl/Makefile.am 2 Jul 2005 10:16:22 -0000 1.3.16.2 +++ squid3/helpers/external_acl/Makefile.am 31 Oct 2005 15:20:39 -0000 1.3.16.3 @@ -1,7 +1,7 @@ # Makefile for storage modules in the Squid Object Cache server # -# $Id: Makefile.am,v 1.3.16.2 2005/07/02 10:16:22 serassio Exp $ +# $Id: Makefile.am,v 1.3.16.3 2005/10/31 15:20:39 serassio Exp $ # -DIST_SUBDIRS = ip_user ldap_group unix_group wbinfo_group win32_group +DIST_SUBDIRS = ip_user ldap_group unix_group wbinfo_group mswin_lm_group SUBDIRS = @EXTERNAL_ACL_HELPERS@ --- /dev/null Wed Feb 14 13:33:00 2007 +++ squid3/helpers/external_acl/mswin_lm_group/.cvsignore Wed Feb 14 13:35:28 2007 @@ -0,0 +1,4 @@ +.cvsignore +Makefile.in +Makefile +.deps --- /dev/null Wed Feb 14 13:33:00 2007 +++ squid3/helpers/external_acl/mswin_lm_group/Makefile.am Wed Feb 14 13:35:28 2007 @@ -0,0 +1,19 @@ +# +# Makefile for the Squid Object Cache server +# +# $Id: Makefile.am,v 1.1.2.1 2005/10/31 15:20:39 serassio Exp $ +# +# Uncomment and customize the following to suit your needs: +# + + +libexec_PROGRAMS = mswin_check_lm_group + +mswin_check_lm_group_SOURCES = win32_check_group.c win32_check_group.h + +INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)/src + +LDADD = -L$(top_builddir)/lib -lmiscutil -lnetapi32 -ladvapi32 \ + -lntdll $(XTRA_LIBS) + +EXTRA_DIST = readme.txt --- /dev/null Wed Feb 14 13:33:00 2007 +++ squid3/helpers/external_acl/mswin_lm_group/readme.txt Wed Feb 14 13:35:28 2007 @@ -0,0 +1,86 @@ + +This is the readme.txt file for mswin_check_lm_group, an external +helper fo the External ACL Scheme for Squid. + + +This helper must be used in with an authentication scheme, tipically +basic or NTLM, based on Windows NT/2000 domain users. +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. + + +============== +Program Syntax +============== + +mswin_check_lm_group [-D domain][-G][-P][-c][-d][-h] + +-D domain specify the default user's domain +-G start helper in Domain Global Group mode +-P use ONLY PDCs for group validation +-c use case insensitive compare +-d enable debugging +-h this message + + +================ +squid.conf usage +================ + +external_acl_type NT_global_group %LOGIN c:/squid/libexec/mswin_check_lm_group.exe -G +external_acl_type NT_local_group %LOGIN c:/squid/libexec/mswin_check_lm_group.exe + +acl GProxyUsers external NT_global_group GProxyUsers +acl LProxyUsers external NT_local_group LProxyUsers +acl password proxy_auth REQUIRED + +http_access allow password GProxyUsers +http_access allow password LProxyUsers +http_access deny all + +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. + +Groups with spaces in name, for example "Domain Users", must be quoted and +the acl data ("Domain Users") must be placed into a separate file included +by specifying "/path/to/file". The previous example will be: + +acl ProxyUsers external NT_global_group "c:/squid/etc/DomainUsers" + +and the DomainUsers files will contain only the following line: + +"Domain Users" + +NOTES: +- The standard group name comparation is case sensitive, so group name + must be specified with same case as in the NT/2000 Domain. + It's possible to enable not case sensitive group name comparation (-c), + but on on some non - English locales, the results can be unexpected. +- Native WIN32 NTLM and Basic Helpers must be used without the + -A & -D switches. + +Refer to Squid documentation for the more details on squid.conf. + + +======= +Testing +======= + +I strongly reccomend that mswin_check_lm_group is tested prior to being used in a +production environment. It may behave differently on different platforms. +To test it, run it from the command line. Enter username and group +pairs separated by a space (username must entered with domain\\username +syntax). Press ENTER to get an OK or ERR message. +Make sure pressing behaves the same as a carriage return. +Make sure pressing aborts the program. + +Test that entering no details does not result in an OK or ERR message. +Test that entering an invalid username and group results in an ERR message. +Test that entering an valid username and group results in an OK message. + +-- +Serassio Guido +squidnt at acmeconsulting dot it + --- /dev/null Wed Feb 14 13:33:00 2007 +++ squid3/helpers/external_acl/mswin_lm_group/win32_check_group.c Wed Feb 14 13:35:28 2007 @@ -0,0 +1,606 @@ +/* + * win32_group: lookup group membership in a Windows NT/2000 domain + * + * (C)2002,2005 Guido Serassio - Acme Consulting S.r.l. + * + * Authors: + * Guido Serassio + * Acme Consulting S.r.l., Italy + * + * 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 comparation. + * 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 "config.h" +#ifdef _SQUID_CYGWIN_ +#include +int _wcsicmp(const wchar_t*, const wchar_t*); +#endif +#if HAVE_STDIO_H +#include +#endif +#if HAVE_CTYPE_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#if HAVE_GETOPT_H +#include +#endif +#undef assert +#include +#include +#include +#include + +#include "util.h" + +#define BUFSIZE 8192 /* the stdin buffer size */ +int use_global = 0; +int use_PDC_only = 0; +char debug_enabled = 0; +char *myname; +pid_t mypid; +char * machinedomain; +int use_case_insensitive_compare = 0; +char * DefaultDomain = NULL; +const char NTV_VALID_DOMAIN_SEPARATOR[] = "\\/"; + +#include "win32_check_group.h" + + +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 NULL; + + /* copy unicode buffer */ + WideCharToMultiByte(CP_ACP, 0, LsaStr.Buffer, LsaStr.Length, target, len, NULL, NULL ); + + /* add null termination */ + target[len-1] = '\0'; + return target; +} + + +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 = NULL; + + /* + * 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(NULL, 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( + NULL, + &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 useable 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 = NULL; + } + } + } + + /* + * 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 */ +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 = NULL; + 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( + NULL, + 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 */ +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 = NULL; + LPWSTR UsrDCptr = NULL; + LPGROUP_USERS_INFO_0 pUsrBuf = NULL; + LPGROUP_USERS_INFO_0 pTmpBuf; + LPSERVER_INFO_101 pSrvBuf = NULL; + DWORD dwLevel = 0; + DWORD dwPrefMaxLen = -1; + DWORD dwEntriesRead = 0; + DWORD dwTotalEntries = 0; + NET_API_STATUS nStatus; + DWORD i; + DWORD dwTotalCount = 0; + + strncpy(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) { + strcpy(User, NTDomain); + strcpy(NTDomain, DefaultDomain); + } else { + strcpy(User, domain_qualify + 1); + 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(NULL, 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 = NULL; + debug("Running on a DC.\n"); + } + else + nStatus = (use_PDC_only ? NetGetDCName(NULL, wszLocalDomain, (LPBYTE *) & LclDCptr) : NetGetAnyDCName(NULL, wszLocalDomain, (LPBYTE *) & LclDCptr)); + } else { + fprintf(stderr, "%s NetServerGetInfo() failed.'\n", myname); + 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 Can't find DC for user's domain '%s'\n", myname, 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 NetUserGetGroups() failed.'\n", myname); + } + } else { + fprintf(stderr, "%s Can't find DC for local domain '%s'\n", myname, 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(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); +} + +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(0); + case '?': + opt = optopt; + /* fall thru to default */ + default: + fprintf(stderr, "%s Unknown option: -%c. Exiting\n", myname, opt); + usage(argv[0]); + exit(1); + break; /* not reached */ + } + } + return; +} + + +int +main (int argc, char *argv[]) +{ + char *p; + char buf[BUFSIZE]; + char *username; + char *group; + int err = 0; + const char *groups[512]; + int n; + + if (argc > 0) { /* should always be true */ + myname=strrchr(argv[0],'/'); + if (myname==NULL) + myname=argv[0]; + } else { + myname="(unknown)"; + } + mypid=getpid(); + + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + /* Check Command Line */ + process_options(argc, argv); + + if (use_global) { + if ((machinedomain = GetDomainName()) == NULL) { + fprintf(stderr, "%s Can't read machine domain\n", myname); + exit(1); + } + strlwr(machinedomain); + if (!DefaultDomain) + DefaultDomain = xstrdup(machinedomain); + } + + debug("External ACL win32 group helper build " __DATE__ ", " __TIME__ + " starting up...\n"); + 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, sizeof(buf), stdin)) + { + if (NULL == strchr(buf, '\n')) { + /* too large message received.. skip and deny */ + fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], buf); + while (fgets(buf, sizeof(buf), stdin)) { + fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], buf); + if (strchr(buf, '\n') != NULL) + break; + } + goto error; + } + + 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') { + fprintf(stderr, "Invalid Request\n"); + goto error; + } + + username = strtok(buf, " "); + for (n = 0; (group = strtok(NULL, " ")) != NULL; n++) { + rfc1738_unescape(group); + groups[n] = group; + } + groups[n] = NULL; + + if (NULL == username) { + fprintf(stderr, "Invalid Request\n"); + goto error; + } + rfc1738_unescape(username); + + if ((use_global ? Valid_Global_Groups(username, groups) : Valid_Local_Groups(username, groups))) { + printf ("OK\n"); + } else { +error: + printf ("ERR\n"); + } + err = 0; + } + return 0; +} --- /dev/null Wed Feb 14 13:33:00 2007 +++ squid3/helpers/external_acl/mswin_lm_group/win32_check_group.h Wed Feb 14 13:35:28 2007 @@ -0,0 +1,79 @@ +/* + * (C) 2002, 2005 Guido Serassio + * Based on previous work of Francesco Chemolli, Robert Collins and Andrew Doran + * + * Distributed freely under the terms of the GNU General Public License, + * version 2. See the file COPYING for licensing details + * + * 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. + */ + +#undef debug + +/************* CONFIGURATION ***************/ +/* + * define this if you want debugging + */ +#ifndef DEBUG +#define DEBUG +#endif + +/************* END CONFIGURATION ***************/ + +#include + +#define safe_free(x) if (x) { free(x); x = NULL; } + +/* Debugging stuff */ + +#ifdef __GNUC__ /* this is really a gcc-ism */ +#ifdef DEBUG +#include +#include +static char *__foo; +extern char debug_enabled; +#define debug(X...) if (debug_enabled) { \ + fprintf(stderr,"%s[%d](%s:%d): ", myname, mypid, \ + ((__foo=strrchr(__FILE__,'/'))==NULL?__FILE__:__foo+1),\ + __LINE__);\ + fprintf(stderr,X); } +#else /* DEBUG */ +#define debug(X...) /* */ +#endif /* DEBUG */ +#else /* __GNUC__ */ +extern char debug_enabled; +static void +debug(char *format,...) +{ +#ifdef DEBUG +#ifdef _SQUID_MSWIN_ + if (debug_enabled) { + va_list args; + + va_start(args,format); + fprintf(stderr, "%s[%d]: ", myname, mypid); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); + va_end(args); + } +#endif /* _SQUID_MSWIN_ */ +#endif /* DEBUG */ +} +#endif /* __GNUC__ */ + + +/* A couple of harmless helper macros */ +#define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n"); +#ifdef __GNUC__ +#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y); +#else +/* no gcc, no debugging. varargs macros are a gcc extension */ +#define SEND2(X,Y) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y); +#endif --- squid3/helpers/external_acl/win32_group/.cvsignore Wed Feb 14 13:35:28 2007 +++ /dev/null Wed Feb 14 13:33:00 2007 @@ -1,4 +0,0 @@ -.cvsignore -Makefile.in -Makefile -.deps --- squid3/helpers/external_acl/win32_group/Makefile.am Wed Feb 14 13:35:28 2007 +++ /dev/null Wed Feb 14 13:33:00 2007 @@ -1,19 +0,0 @@ -# -# Makefile for the Squid Object Cache server -# -# $Id: Makefile.am,v 1.2.18.4 2005/09/15 09:43:53 serassio Exp $ -# -# Uncomment and customize the following to suit your needs: -# - - -libexec_PROGRAMS = win32_check_group - -win32_check_group_SOURCES = win32_check_group.c win32_check_group.h - -INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)/src - -LDADD = -L$(top_builddir)/lib -lmiscutil -lnetapi32 -ladvapi32 \ - -lntdll $(XTRA_LIBS) - -EXTRA_DIST = readme.txt --- squid3/helpers/external_acl/win32_group/readme.txt Wed Feb 14 13:35:28 2007 +++ /dev/null Wed Feb 14 13:33:00 2007 @@ -1,86 +0,0 @@ - -This is the readme.txt file for win32_check_group, an external -helper fo the External ACL Scheme for Squid. - - -This helper must be used in with an authentication scheme, tipically -basic or NTLM, based on Windows NT/2000 domain users. -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. - - -============== -Program Syntax -============== - -win32_check_group [-D domain][-G][-P][-c][-d][-h] - --D domain specify the default user's domain --G start helper in Domain Global Group mode --P use ONLY PDCs for group validation --c use case insensitive compare --d enable debugging --h this message - - -================ -squid.conf usage -================ - -external_acl_type NT_global_group %LOGIN c:/squid/libexec/win32_check_group.exe -G -external_acl_type NT_local_group %LOGIN c:/squid/libexec/win32_check_group.exe - -acl GProxyUsers external NT_global_group GProxyUsers -acl LProxyUsers external NT_local_group LProxyUsers -acl password proxy_auth REQUIRED - -http_access allow password GProxyUsers -http_access allow password LProxyUsers -http_access deny all - -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. - -Groups with spaces in name, for example "Domain Users", must be quoted and -the acl data ("Domain Users") must be placed into a separate file included -by specifying "/path/to/file". The previous example will be: - -acl ProxyUsers external NT_global_group "c:/squid/etc/DomainUsers" - -and the DomainUsers files will contain only the following line: - -"Domain Users" - -NOTES: -- The standard group name comparation is case sensitive, so group name - must be specified with same case as in the NT/2000 Domain. - It's possible to enable not case sensitive group name comparation (-c), - but on on some non - English locales, the results can be unexpected. -- Native WIN32 NTLM and Basic Helpers must be used without the - -A & -D switches. - -Refer to Squid documentation for the more details on squid.conf. - - -======= -Testing -======= - -I strongly urge that win32_check_group is tested prior to being used in a -production environment. It may behave differently on different platforms. -To test it, run it from the command line. Enter username and group -pairs separated by a space (username must entered with domain\\username -syntax). Press ENTER to get an OK or ERR message. -Make sure pressing behaves the same as a carriage return. -Make sure pressing aborts the program. - -Test that entering no details does not result in an OK or ERR message. -Test that entering an invalid username and group results in an ERR message. -Test that entering an valid username and group results in an OK message. - --- -Serassio Guido -squidnt at acmeconsulting dot it - --- squid3/helpers/external_acl/win32_group/win32_check_group.c Wed Feb 14 13:35:28 2007 +++ /dev/null Wed Feb 14 13:33:00 2007 @@ -1,606 +0,0 @@ -/* - * win32_group: lookup group membership in a Windows NT/2000 domain - * - * (C)2002,2005 Guido Serassio - Acme Consulting S.r.l. - * - * Authors: - * Guido Serassio - * Acme Consulting S.r.l., Italy - * - * 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 comparation. - * 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 "config.h" -#ifdef _SQUID_CYGWIN_ -#include -int _wcsicmp(const wchar_t*, const wchar_t*); -#endif -#if HAVE_STDIO_H -#include -#endif -#if HAVE_CTYPE_H -#include -#endif -#ifdef HAVE_STRING_H -#include -#endif -#if HAVE_GETOPT_H -#include -#endif -#undef assert -#include -#include -#include -#include - -#include "util.h" - -#define BUFSIZE 8192 /* the stdin buffer size */ -int use_global = 0; -int use_PDC_only = 0; -char debug_enabled = 0; -char *myname; -pid_t mypid; -char * machinedomain; -int use_case_insensitive_compare = 0; -char * DefaultDomain = NULL; -const char NTV_VALID_DOMAIN_SEPARATOR[] = "\\/"; - -#include "win32_check_group.h" - - -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 NULL; - - /* copy unicode buffer */ - WideCharToMultiByte(CP_ACP, 0, LsaStr.Buffer, LsaStr.Length, target, len, NULL, NULL ); - - /* add null termination */ - target[len-1] = '\0'; - return target; -} - - -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 = NULL; - - /* - * 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(NULL, 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( - NULL, - &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 useable 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 = NULL; - } - } - } - - /* - * 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 */ -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 = NULL; - 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( - NULL, - 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 */ -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 = NULL; - LPWSTR UsrDCptr = NULL; - LPGROUP_USERS_INFO_0 pUsrBuf = NULL; - LPGROUP_USERS_INFO_0 pTmpBuf; - LPSERVER_INFO_101 pSrvBuf = NULL; - DWORD dwLevel = 0; - DWORD dwPrefMaxLen = -1; - DWORD dwEntriesRead = 0; - DWORD dwTotalEntries = 0; - NET_API_STATUS nStatus; - DWORD i; - DWORD dwTotalCount = 0; - - strncpy(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) { - strcpy(User, NTDomain); - strcpy(NTDomain, DefaultDomain); - } else { - strcpy(User, domain_qualify + 1); - 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(NULL, 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 = NULL; - debug("Running on a DC.\n"); - } - else - nStatus = (use_PDC_only ? NetGetDCName(NULL, wszLocalDomain, (LPBYTE *) & LclDCptr) : NetGetAnyDCName(NULL, wszLocalDomain, (LPBYTE *) & LclDCptr)); - } else { - fprintf(stderr, "%s NetServerGetInfo() failed.'\n", myname); - 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 Can't find DC for user's domain '%s'\n", myname, 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 NetUserGetGroups() failed.'\n", myname); - } - } else { - fprintf(stderr, "%s Can't find DC for local domain '%s'\n", myname, 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(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); -} - -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(0); - case '?': - opt = optopt; - /* fall thru to default */ - default: - fprintf(stderr, "%s Unknown option: -%c. Exiting\n", myname, opt); - usage(argv[0]); - exit(1); - break; /* not reached */ - } - } - return; -} - - -int -main (int argc, char *argv[]) -{ - char *p; - char buf[BUFSIZE]; - char *username; - char *group; - int err = 0; - const char *groups[512]; - int n; - - if (argc > 0) { /* should always be true */ - myname=strrchr(argv[0],'/'); - if (myname==NULL) - myname=argv[0]; - } else { - myname="(unknown)"; - } - mypid=getpid(); - - setbuf(stdout, NULL); - setbuf(stderr, NULL); - - /* Check Command Line */ - process_options(argc, argv); - - if (use_global) { - if ((machinedomain = GetDomainName()) == NULL) { - fprintf(stderr, "%s Can't read machine domain\n", myname); - exit(1); - } - strlwr(machinedomain); - if (!DefaultDomain) - DefaultDomain = xstrdup(machinedomain); - } - - debug("External ACL win32 group helper build " __DATE__ ", " __TIME__ - " starting up...\n"); - 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, sizeof(buf), stdin)) - { - if (NULL == strchr(buf, '\n')) { - /* too large message received.. skip and deny */ - fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], buf); - while (fgets(buf, sizeof(buf), stdin)) { - fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], buf); - if (strchr(buf, '\n') != NULL) - break; - } - goto error; - } - - 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') { - fprintf(stderr, "Invalid Request\n"); - goto error; - } - - username = strtok(buf, " "); - for (n = 0; (group = strtok(NULL, " ")) != NULL; n++) { - rfc1738_unescape(group); - groups[n] = group; - } - groups[n] = NULL; - - if (NULL == username) { - fprintf(stderr, "Invalid Request\n"); - goto error; - } - rfc1738_unescape(username); - - if ((use_global ? Valid_Global_Groups(username, groups) : Valid_Local_Groups(username, groups))) { - printf ("OK\n"); - } else { -error: - printf ("ERR\n"); - } - err = 0; - } - return 0; -} --- squid3/helpers/external_acl/win32_group/win32_check_group.h Wed Feb 14 13:35:28 2007 +++ /dev/null Wed Feb 14 13:33:00 2007 @@ -1,79 +0,0 @@ -/* - * (C) 2002, 2005 Guido Serassio - * Based on previous work of Francesco Chemolli, Robert Collins and Andrew Doran - * - * Distributed freely under the terms of the GNU General Public License, - * version 2. See the file COPYING for licensing details - * - * 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. - */ - -#undef debug - -/************* CONFIGURATION ***************/ -/* - * define this if you want debugging - */ -#ifndef DEBUG -#define DEBUG -#endif - -/************* END CONFIGURATION ***************/ - -#include - -#define safe_free(x) if (x) { free(x); x = NULL; } - -/* Debugging stuff */ - -#ifdef __GNUC__ /* this is really a gcc-ism */ -#ifdef DEBUG -#include -#include -static char *__foo; -extern char debug_enabled; -#define debug(X...) if (debug_enabled) { \ - fprintf(stderr,"%s[%d](%s:%d): ", myname, mypid, \ - ((__foo=strrchr(__FILE__,'/'))==NULL?__FILE__:__foo+1),\ - __LINE__);\ - fprintf(stderr,X); } -#else /* DEBUG */ -#define debug(X...) /* */ -#endif /* DEBUG */ -#else /* __GNUC__ */ -extern char debug_enabled; -static void -debug(char *format,...) -{ -#ifdef DEBUG -#ifdef _SQUID_MSWIN_ - if (debug_enabled) { - va_list args; - - va_start(args,format); - fprintf(stderr, "%s[%d]: ", myname, mypid); - vfprintf(stderr, format, args); - fprintf(stderr, "\n"); - va_end(args); - } -#endif /* _SQUID_MSWIN_ */ -#endif /* DEBUG */ -} -#endif /* __GNUC__ */ - - -/* A couple of harmless helper macros */ -#define SEND(X) debug("sending '%s' to squid\n",X); printf(X "\n"); -#ifdef __GNUC__ -#define SEND2(X,Y...) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y); -#else -/* no gcc, no debugging. varargs macros are a gcc extension */ -#define SEND2(X,Y) debug("sending '" X "' to squid\n",Y); printf(X "\n",Y); -#endif