* Also adds the Fake auth helper for testing Basic authentication.
* Also adds manual pages for most external ACL helpers
TODO: test for and fix any build issues on Windows.
ip_fil.h \
ip_nat.h \
ipl.h \
+ lber.h \
+ ldap.h \
libc.h \
limits.h \
linux/posix_types.h \
helpers/Makefile \
helpers/basic_auth/Makefile \
helpers/basic_auth/DB/Makefile \
+ helpers/basic_auth/fake/Makefile \
helpers/basic_auth/getpwnam/Makefile \
helpers/basic_auth/LDAP/Makefile \
helpers/basic_auth/MSNT/Makefile \
helpers/negotiate_auth/kerberos/Makefile \
helpers/negotiate_auth/SSPI/Makefile \
helpers/external_acl/Makefile \
- helpers/external_acl/ip_user/Makefile \
- helpers/external_acl/ldap_group/Makefile \
+ helpers/external_acl/AD_group/Makefile \
+ helpers/external_acl/file_userip/Makefile \
+ helpers/external_acl/LDAP_group/Makefile \
+ helpers/external_acl/LM_group/Makefile \
helpers/external_acl/session/Makefile \
helpers/external_acl/unix_group/Makefile \
helpers/external_acl/wbinfo_group/Makefile \
- helpers/external_acl/mswin_ad_group/Makefile \
- helpers/external_acl/mswin_lm_group/Makefile \
helpers/log_daemon/Makefile \
helpers/log_daemon/file/Makefile \
helpers/url_rewrite/Makefile \
<item>squid_db_auth - basic_db_auth - Retrieve authentication details from a simple SQL database table.
<item>getpwnam_auth - basic_getpwname_auth - Authenticate with local system user accounts.
<item>squid_ldap_auth - basic_ldap_auth - Authenticate with LDAP user accounts.
+ <item>MSNT-multi-domain - basic_msnt_multi_domain_auth - Authenticate with any one of multiple Windows Domain Controllers.
<item>ncsa_auth - basic_ncsa_auth - Authenticate with NCSA httpd-style password file.
+ <item>yp_auth - basic_nis_auth - Authenticate with NIS security system.
<item>pam_auth - basic_pam_auth - Authenticate with the system PAM infrastructure.
<item>pop3.pl - basic_pop3_auth - Authenticate with a mail server POP3/SMTP credentials
+ <item>squid_radius_auth - basic_radius_auth - Authenticate with RADIUS.
<item>squid_sasl_auth - basic_sasl_auth - Authenticate with SASL.
<item>smb_auth - basic_smb_auth - Authenticate with Samba SMB.
- <item>yp_auth - basic_nis_auth - Authenticate with NIS security system.
<item>mswin_sspi - basic_sspi_auth - Authenticate with a Windows Domain Controller using SSPI.
- <item>MSNT-multi-domain - basic_msnt_multi_domain_auth - Authenticate with any one of multiple Windows Domain Controllers.
- <item>squid_radius_auth - basic_radius_auth - Authenticate with RADIUS.
</itemize>
<sect2>Digest Authentication protocol helpers
<sect2>External ACL helpers
<p><itemize>
- <item>(none yet converted)
+ <item>mswin_check_ad_group - ext_ad_group_acl - Check logged in users Group membership using Active Directory.
+ <item>ip_user_check - ext_file_userip_acl - Restrict users to cetain IP addresses, using a text file backend.
+ <item>squid_ldap_group - ext_ldap_group_acl - Check logged in users Group membership using LDAP.
+ <item>mswin_check_lm_group - ext_lm_group_acl - Check logged in users Group membership using LanManager.
+ <item>squid_session - ext_session_acl - Maintain a session cache of client identifiers (usually IP address).
+ <item>squid_unix_group - ext_unix_group_acl - Check logged in users Group membership using local UNIX groups.
+ <item>wbinfo_group.pl - ext_wbinfo_group_acl - Check logged in users Group membership using wbinfo.
</itemize>
<sect2>Negotiate Authentication protocol helpers
<p><itemize>
- <item>mswin_sspi - negotiate_sspi_auth - Authenticate with a Windows Domain Controller using SSPI.
<item>squid_kerb_auth - negotiate_kerberos_auth - Authenticate with Kerberos servers.
+ <item>mswin_sspi - negotiate_sspi_auth - Authenticate with a Windows Domain Controller using SSPI.
</itemize>
<sect2>NTLM Authentication protocol helpers
<p><itemize>
+ <item>no_check.pl - Deprecated. - Use the faster and less easily decrypted ntlm_fake_auth instead.
<item>fakeauth_auth - ntlm_fake_auth - Perform NTLMSSP to recover the username but don't verify the password.
- <item>mswin_ntlm_auth - ntlm_sspi_auth - Perform NTLMSSP authentication using Windows native Security Support Provider Interface API.
<item>ntlm_auth - ntlm_smb_lm_auth - Perform SMB LanManager domain-less authentication over NTLM protocol.
- <item>no_check.pl - Deprecated. - Use the faster and less easily decrypted ntlm_fake_auth instead.
+ <item>mswin_ntlm_auth - ntlm_sspi_auth - Perform NTLMSSP authentication using Windows native Security Support Provider Interface API.
</itemize>
<sect2>URL re-write helpers
## Alphabetical list of sub-directories to distribute with Squid:
DIST_SUBDIRS = \
DB \
+ fake \
getpwnam \
LDAP \
MSNT \
--- /dev/null
+include $(top_srcdir)/src/Common.am
+
+libexec_PROGRAMS = basic_fake_auth
+basic_fake_auth_SOURCES = fake.cc
+
+LDADD = $(COMPAT_LIB)
+
+EXTRA_DIST = config.test
--- /dev/null
+#!/bin/sh
+exit 0
--- /dev/null
+/*
+ * AUTHOR: Amos Jeffries <squid3@treenet.co.nz>
+ *
+ * Fake Basic Authentication program for Squid.
+ *
+ * This code gets the user details and returns OK.
+ * It is intended for testing use and as a base for further implementation.
+ *
+ *
+ * This code is copyright (C) 2009 by Treehouse Networks Ltd
+ * of New Zealand. It is published and Licensed as an extension of
+ * squid under the same conditions as the main squid application.
+ */
+
+#include "config.h"
+#include "helpers/defines.h"
+
+#if HAVE_CSTRING
+#include <cstring>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+
+/**
+ * options:
+ * -d enable debugging.
+ * -h interface help.
+ */
+char *program_name = NULL;
+
+static void
+usage(void)
+{
+ fprintf(stderr,
+ "Usage: %s [-d] [-v] [-h]\n"
+ " -d enable debugging.\n"
+ " -h this message\n\n",
+ program_name);
+}
+
+static void
+process_options(int argc, char *argv[])
+{
+ int opt;
+
+ opterr = 0;
+ while (-1 != (opt = getopt(argc, argv, "hd"))) {
+ switch (opt) {
+ case 'd':
+ debug_enabled = 1;
+ break;
+ case 'h':
+ usage();
+ exit(0);
+ default:
+ fprintf(stderr, "%s: FATAL: unknown option: -%c. Exiting\n", program_name, opt);
+ usage();
+ exit(1);
+ }
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ char buf[HELPER_INPUT_BUFFER];
+ int buflen = 0;
+
+ setbuf(stdout, NULL);
+ setbuf(stderr, NULL);
+
+ program_name = argv[0];
+
+ process_options(argc, argv);
+
+ debug("%s build " __DATE__ ", " __TIME__ " starting up...\n", program_name);
+
+ while (fgets(buf, HELPER_INPUT_BUFFER, stdin) != NULL) {
+ char *p;
+
+ if ((p = strchr(buf, '\n')) != NULL) {
+ *p = '\0'; /* strip \n */
+ buflen = p - buf; /* length is known already */
+ } else
+ buflen = strlen(buf); /* keep this so we only scan the buffer for \0 once per loop */
+
+ debug("Got %d bytes '%s' from Squid\n", buflen, buf);
+
+ /* send 'OK' result back to Squid */
+ SEND_OK("");
+ }
+ debug("%s build " __DATE__ ", " __TIME__ " shutting down...\n", program_name);
+ exit(0);
+}
/*
* digest_file_auth.cc
*
- * AUTHOR: Robert Collins. Based on ncsa_auth.c by Arjan de Vet
- * <Arjan.deVet@adv.iae.nl>
- * LDAP backend extension by Flavio Pescuma, MARA Systems AB <flavio@marasystems.com>
+ * AUTHOR: Robert Collins.
+ *
+ * Based on ncsa_auth.c by Arjan de Vet <Arjan.deVet@adv.iae.nl>
+ *
+ * LDAP backend extension by Flavio Pescuma,
+ * MARA Systems AB <flavio@marasystems.com>
*
* Example digest authentication program for Squid, based on the original
* proxy_auth code from client_side.c, written by
#include "config.h"
#include "digest_common.h"
+#include "helpers/defines.h"
#include "text_backend.h"
#define PROGRAM_NAME "digest_file_auth"
requestData->error = 0;
GetHHA1(requestData);
if (requestData->error) {
- printf("ERR No such user\n");
+ SEND_ERR("No such user");
return;
}
printf("%s\n", requestData->HHA1);
RequestData requestData;
ParseBuffer(buf, &requestData);
if (!requestData.parsed) {
- printf("ERR\n");
+ SEND_ERR("");
return;
}
OutputHHA1(&requestData);
int
main(int argc, char **argv)
{
- char buf[256];
+ char buf[HELPER_INPUT_BUFFER];
setbuf(stdout, NULL);
ProcessArguments(argc, argv);
- while (fgets(buf, 256, stdin) != NULL)
+ while (fgets(buf, HELPER_INPUT_BUFFER, stdin) != NULL)
DoOneRequest(buf);
return 0;
}
-libexec_PROGRAMS = mswin_check_ad_group
+include $(top_srcdir)/src/Common.am
-mswin_check_ad_group_SOURCES = mswin_check_ad_group.c mswin_check_ad_group.h
-
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/src \
- -I$(top_srcdir)/include
+libexec_PROGRAMS = ext_ad_group_acl
+ext_ad_group_acl_SOURCES = ext_ad_group_acl.cc
+man_MANS = ext_ad_group_acl.8
#
# Currently activeds and adsiid libraries are not available on MinGW or Cygwin,
# This helper can be compiled only using Microsoft Visual Studio.
#
LDADD = \
- $(top_builddir)/compat/libcompat.la \
- -L$(top_builddir)/lib -lmiscutil \
+ $(COMPAT_LIB) \
-lnetapi32 \
-ladvapi32 \
-lole32 \
-ladsiid \
$(XTRA_LIBS)
-EXTRA_DIST = readme.txt config.test
+EXTRA_DIST = config.test ext_ad_group_acl.8
--- /dev/null
+.if !'po4a'hide' .TH ext_ad_group_acl 8
+.
+.SH NAME
+.if !'po4a'hide' .B ext_ad_group_acl
+.if !'po4a'hide' \-
+Squid external ACL helper to check Windows users group membership.
+.PP
+Version 2.0
+.
+.SH SYNOPSIS
+.if !'po4a'hide' .B ext_ad_group_acl
+.if !'po4a'hide' .B "[\-D "
+domain
+.if !'po4a'hide' .B "[\-cdGh]"
+.
+.SH DESCRIPTION
+.B ext_ad_group_acl
+is an installed binary in Squid for Windows builds.
+.PP
+This helper must be used in with an authentication scheme (typically
+Basic, NTLM or Negotiate) based on Windows Active Directory domain users.
+.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.
+.PP
+Two running mode are available:
+.if !'po4a'hide' .TP 12
+.B "\- Local mode:"
+membership is checked against machine's local groups, cannot be used when
+running on a Domain Controller.
+.B "\- Active Directory Global mode:"
+membership is checked against the whole Active Directory Forest of the
+machine where Squid is running.
+.PP
+The minimal Windows version needed to run ext_ad_group_acl is
+a Windows 2000 SP4 member of an Active Directory Domain.
+.PP
+When running in Active Directory Global mode, all types of Active Directory
+security groups are supported:
+.if !'po4a'hide' .TP 12
+.B \- Domain Global
+.B \- Domain Local from user's domain
+.B \- Universal
+and Active Directory group nesting is fully supported.
+.
+.SH OPTIONS
+.if !'po4a'hide' .TP 12
+.if !'po4a'hide' .B \-c
+Use case insensitive compare (local mode only).
+.if !'po4a'hide' .B \-d
+Write debug info to stderr.
+.if !'po4a'hide' .B \-D domain
+Specify the default user's domain.
+.if !'po4a'hide' .B \-G
+Start helper in Active Directory Global mode.
+.if !'po4a'hide' .B \-h
+Display the binary help and command line syntax info using stderr.
+.
+.SH CONFIGURATION
+.PP
+When running in Active Directory Global mode, the AD Group can be specified using the
+following syntax:
+.
+.if !'po4a'hide' .TP 5
+.PP 1. Plain NT4 Group Name
+.PP 2. Full NT4 Group Name
+.PP 3. Active Directory Canonical name
+.
+.PP As Example:
+.if !'po4a'hide' .TP 5
+.if !'po4a'hide' .PP 1. Proxy-Users
+.if !'po4a'hide' .PP 2. MYDOMAIN\Proxy-Users
+.if !'po4a'hide' .PP 3. mydomain.local/Groups/Proxy-Users
+.PP
+When using Plain NT4 Group Name, the Group is searched in the user's domain.
+.if !'po4a'hide' .
+.if !'po4a'hide' external_acl_type AD_global_group %LOGIN c:/squid/libexec/ext_ad_group_acl.exe -G
+.if !'po4a'hide' external_acl_type NT_local_group %LOGIN c:/squid/libexec/ext_ad_group_acl.exe
+.if !'po4a'hide' .
+.if !'po4a'hide' acl GProxyUsers external AD_global_group MYDOMAIN\GProxyUsers
+.if !'po4a'hide' acl LProxyUsers external NT_local_group LProxyUsers
+.if !'po4a'hide' acl password proxy_auth REQUIRED
+.if !'po4a'hide' .
+.if !'po4a'hide' http_access allow password GProxyUsers
+.if !'po4a'hide' http_access allow password LProxyUsers
+.if !'po4a'hide' http_access deny all
+.PP
+In the previous example all validated AD users member of
+.I MYDOMAIN\GProxyUsers
+domain group or member of
+.I 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' .
+.if !'po4a'hide' acl ProxyUsers external NT_global_group "c:/squid/etc/DomainUsers"
+.if !'po4a'hide' .
+and the DomainUsers files will contain only the following line:
+"Domain Users"
+.PP NOTE:
+When running in Active Directory Global mode, for better performance,
+all Domain Controllers of the Active Directory forest should be configured
+as Global Catalog.
+.PP NOTE:
+When running in local mode, the standard group name comparison is case
+sensitive, so group name must be specified with same case as in the
+local SAM database.
+.
+It is possible to enable case insensitive group name comparison (
+.B \-c
+),
+but on some non\-english locales, the results can be unexpected.
+.PP 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
+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>
+.PP
+Based on prior work in
+.B "mswin_check_lm_group (ext_lm_group_acl)"
+.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
+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@squid-cache.org>
+.
+.SH REPORTING BUGS
+Bug reports need to be made in English.
+See http://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 http://bugs.squid-cache.org/
+.PP
+Report serious security bugs to
+.I Squid Bugs <squid-bugs@squid-cache.org>
+.PP
+Report ideas for new improvements to the
+.I Squid Developers mailing list
+.if !'po4a'hide' <squid-dev@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' http://wiki.squid-cache.org/SquidFaq
+.br
+The Squid Configuration Manual
+.if !'po4a'hide' http://www.squid-cache.org/Doc/config/
/*
- * mswin_check_ad_group: lookup group membership in a Windows
+ * ext_ad_group_acl: lookup group membership in a Windows
* Active Directory domain
*
* (C)2008-2009 Guido Serassio - Acme Consulting S.r.l.
*/
#include "config.h"
+#include "helpers/defines.h"
+#include "include/util.h"
+
#ifdef _SQUID_CYGWIN_
#include <wchar.h>
int _wcsicmp(const wchar_t *, const wchar_t *);
#endif
+
#if HAVE_STDIO_H
#include <stdio.h>
#endif
#include <dsrole.h>
#include <sddl.h>
-#include "util.h"
-
enum ADSI_PATH {
LDAP_MODE,
GC_MODE
} ADSI_Path;
-#define BUFSIZE 8192 /* the stdin buffer size */
int use_global = 0;
-char debug_enabled = 0;
-char *myname;
+char *program_name;
pid_t mypid;
char *machinedomain;
int use_case_insensitive_compare = 0;
wchar_t **User_Groups;
int User_Groups_Count = 0;
-#include "mswin_check_ad_group.h"
-
wchar_t *My_NameTranslate(wchar_t *, int, int);
char *Get_WIN32_ErrorMessage(HRESULT);
}
static void
-usage(char *program)
+usage(const char *program)
{
fprintf(stderr, "Usage: %s [-D domain][-G][-c][-d][-h]\n"
" -D default user Domain\n"
opt = optopt;
/* fall thru to default */
default:
- fprintf(stderr, "%s Unknown option: -%c. Exiting\n", myname, opt);
+ fprintf(stderr, "%s: FATAL: Unknown option: -%c. Exiting\n", program_name, opt);
usage(argv[0]);
exit(1);
break; /* not reached */
main(int argc, char *argv[])
{
char *p;
- char buf[BUFSIZE];
+ char buf[HELPER_INPUT_BUFFER];
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];
+ program_name = strrchr(argv[0], '/');
+ if (program_name == NULL)
+ program_name = argv[0];
} else {
- myname = "(unknown)";
+ program_name = "(unknown)";
}
mypid = getpid();
if (use_global) {
if ((machinedomain = GetDomainName()) == NULL) {
- fprintf(stderr, "%s Can't read machine domain\n", myname);
+ fprintf(stderr, "%s: FATAL: Can't read machine domain\n", program_name);
exit(1);
}
strlwr(machinedomain);
/* Main Loop */
- while (fgets(buf, sizeof(buf), stdin)) {
+ while (fgets(buf, HELPER_INPUT_BUFFER, 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)) {
+ while (fgets(buf, HELPER_INPUT_BUFFER, stdin)) {
fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], buf);
if (strchr(buf, '\n') != NULL)
break;
}
- goto error;
+ SEND_ERR("Invalid Request. Too Long.");
+ continue;
}
if ((p = strchr(buf, '\n')) != NULL)
*p = '\0'; /* strip \n */
debug("Got '%s' from Squid (length: %d).\n", buf, strlen(buf));
if (buf[0] == '\0') {
- fprintf(stderr, "Invalid Request\n");
- goto error;
+ SEND_ERR("Invalid Request. No Input.");
+ continue;
}
username = strtok(buf, " ");
for (n = 0; (group = strtok(NULL, " ")) != NULL; n++) {
numberofgroups = n;
if (NULL == username) {
- fprintf(stderr, "Invalid Request\n");
- goto error;
+ SEND_ERR("Invalid Request. No Username.");
+ continue;
}
rfc1738_unescape(username);
if ((use_global ? Valid_Global_Groups(username, groups) : Valid_Local_Groups(username, groups))) {
- SEND("OK");
+ SEND_OK("");
} else {
-error:
- SEND("ERR");
+ SEND_ERR("");
}
err = 0;
}
Version 2.17
+2010-07-12 Amos Jeffries <amosjeffries@squid-cache.org>
+
+ Rename to ext_ldap_group_acl (Squid-3 helper naming schema)
+ Convert to build under C++
+ Remove several goto statements.
+ Update to use helper macro API
+
2005-03-19 Henrik Nordstrom <hno@squid-cache.org>
Bug #1258: LDAP helpers fails to compile with SUN LDAP SDK
--- /dev/null
+include $(top_srcdir)/src/Common.am
+
+libexec_PROGRAMS = ext_ldap_group_acl
+ext_ldap_group_acl_SOURCES = ext_ldap_group_acl.cc
+
+man_MANS = ext_ldap_group_acl.8
+EXTRA_DIST = ext_ldap_group_acl.8 config.test
+
+LDADD = \
+ $(COMPAT_LIB) \
+ $(LDAPLIB) \
+ $(LBERLIB) \
+ $(XTRA_LIBS)
-.if !'po4a'hide' .TH squid_ldap_group 8 "30 January 2005"
+.if !'po4a'hide' .TH ext_ldap_group_acl 8 "30 January 2005"
.
.SH NAME
-.if !'po4a'hide' .B squid_ldap_group
+.if !'po4a'hide' .B ext_ldap_group_acl
.if !'po4a'hide' \-
Squid LDAP external acl group helper
.PP
Version 2.17
.
.SH SYNOPSIS
-.if !'po4a'hide' .B squid_ldap_group
+.if !'po4a'hide' .B ext_ldap_group_acl
.if !'po4a'hide' .B "\-b \""
base DN
.if !'po4a'hide' .B "\" \-f \""
.if !'po4a'hide' .B "\" ["
options
.if !'po4a'hide' .B "] ["
-ldap_server_name
+LDAP server name
.if !'po4a'hide' .B "[:"
port
.if !'po4a'hide' .B "]|"
.if !'po4a'hide' .B "]..."
.
.SH DESCRIPTION
-.B squid_ldap_group
+.B ext_ldap_group_acl
allows Squid to connect to a LDAP directory to authorize users via LDAP groups.
LDAP options are specified as parameters on the command line,
while the username(s) and group(s) to be checked against the
.if !'po4a'hide' .TP
.if !'po4a'hide' .BI \-d
Debug mode where each step taken will get reported in detail.
-Useful for understanding what goes wrong if the results is
-not what is expected.
+Useful for understanding what goes wrong if the result is
+not what was expected.
.
.if !'po4a'hide' .TP
.if !'po4a'hide' .BI "\-D " "binddn " "\-w " password
The DN and password to bind as while performing searches. Required
-if the directory does not allow anonymous searches.
+if the LDAP directory does not allow anonymous searches.
.IP
As the password needs to be printed in plain text in your Squid configuration
and will be sent on the command line to the helper it is strongly recommended
.
.if !'po4a'hide' .TP
.if !'po4a'hide' .BI \-p " ldapport"
-Specify an alternate TCP port where the ldap server is listening if
+Specify an alternate TCP port where the LDAP server is listening if
other than the default LDAP port 389.
.
.if !'po4a'hide' .TP
.if !'po4a'hide' .P
.if !'po4a'hide' .ft CR
.if !'po4a'hide' .nf
-.if !'po4a'hide' external_acl_type ldap_group %LOGIN /path/to/squid_ldap_group ...
+.if !'po4a'hide' external_acl_type ldap_group %LOGIN /path/to/ext_ldap_group_acl ...
.if !'po4a'hide' .br
.if !'po4a'hide' acl group1 external ldap_group Group1
.if !'po4a'hide' .br
using
.B ldapsearch
to verify that the filter matches what you expect before you attempt to use
-.B squid_ldap_group
+.B ext_ldap_group_acl
.
.SH AUTHOR
This program was written by
/*
- * squid_ldap_group: lookup group membership in LDAP
+ * ext_ldap_group_acl: lookup group membership in LDAP
+ *
+ * Version 2.17
*
* (C)2002,2003 MARA Systems AB
*
*/
#define SQUID_NO_ALLOC_PROTECT 1
#include "config.h"
-
-#define LDAP_DEPRECATED 1
-
+#include "helpers/defines.h"
#include "rfc1738.h"
#include "util.h"
+#define LDAP_DEPRECATED 1
+
+#if HAVE_STDIO_H
#include <stdio.h>
+#endif
+#if HAVE_STRING_H
#include <string.h>
+#endif
+#if HAVE_CTYPE_H
#include <ctype.h>
+#endif
#ifdef _SQUID_MSWIN_ /* Native Windows port and MinGW */
#else
+#if HAVE_LBER_H
#include <lber.h>
+#endif
+#if HAVE_LDAP_H
#include <ldap.h>
+#endif
#endif
#include <sys/time.h>
#endif
-#define PROGRAM_NAME "squid_ldap_group"
+#define PROGRAM_NAME "ext_ldap_group_acl"
#define PROGRAM_VERSION "2.17"
/* Globals */
static int searchscope = LDAP_SCOPE_SUBTREE;
static int persistent = 0;
static int noreferrals = 0;
-static int show_debug_messages = 0;
static int aliasderef = LDAP_DEREF_NEVER;
#if defined(NETSCAPE_SSL)
static char *sslpath = NULL;
static void
squid_ldap_set_referrals(LDAP * ld, int referrals)
{
- int *value = referrals ? LDAP_OPT_ON :LDAP_OPT_OFF;
+ int *value = static_cast<int*>(referrals ? LDAP_OPT_ON :LDAP_OPT_OFF);
ldap_set_option(ld, LDAP_OPT_REFERRALS, value);
}
static void
static void
squid_ldap_set_connect_timeout(LDAP * ld, int timelimit)
{
- fprintf(stderr, "Connect timeouts not supported in your LDAP library\n");
+ fprintf(stderr, "WARNING: Connect timeouts not supported in your LDAP library\n");
}
static void
squid_ldap_memfree(char *p)
int
main(int argc, char **argv)
{
- char buf[8192];
+ char buf[HELPER_INPUT_BUFFER];
char *user, *group, *extension_dn = NULL;
char *ldapServer = NULL;
LDAP *ld = NULL;
switch (option) {
case 'H':
#if !HAS_URI_SUPPORT
- fprintf(stderr, "ERROR: Your LDAP library does not have URI support\n");
+ fprintf(stderr, "FATAL: Your LDAP library does not have URI support\n");
exit(1);
#endif
/* Fall thru to -h */
case 'h':
if (ldapServer) {
int len = strlen(ldapServer) + 1 + strlen(value) + 1;
- char *newhost = malloc(len);
+ char *newhost = (char*)malloc(len);
snprintf(newhost, len, "%s %s", ldapServer, value);
free(ldapServer);
ldapServer = newhost;
else if (strcmp(value, "sub") == 0)
searchscope = LDAP_SCOPE_SUBTREE;
else {
- fprintf(stderr, PROGRAM_NAME " ERROR: Unknown search scope '%s'\n", value);
+ fprintf(stderr, PROGRAM_NAME ": FATAL: Unknown search scope '%s'\n", value);
exit(1);
}
break;
if (port == LDAP_PORT)
port = LDAPS_PORT;
#else
- fprintf(stderr, PROGRAM_NAME " ERROR: -E unsupported with this LDAP library\n");
+ fprintf(stderr, PROGRAM_NAME ": FATAL: -E unsupported with this LDAP library\n");
exit(1);
#endif
break;
else if (strcmp(value, "find") == 0)
aliasderef = LDAP_DEREF_FINDING;
else {
- fprintf(stderr, PROGRAM_NAME " ERROR: Unknown alias dereference method '%s'\n", value);
+ fprintf(stderr, PROGRAM_NAME ": FATAL: Unknown alias dereference method '%s'\n", value);
exit(1);
}
break;
version = LDAP_VERSION3;
break;
default:
- fprintf(stderr, "Protocol version should be 2 or 3\n");
+ fprintf(stderr, "FATAL: Protocol version should be 2 or 3\n");
exit(1);
}
break;
case 'Z':
if (version == LDAP_VERSION2) {
- fprintf(stderr, "TLS (-Z) is incompatible with version %d\n",
+ fprintf(stderr, "FATAL: TLS (-Z) is incompatible with version %d\n",
version);
exit(1);
}
break;
#endif
case 'd':
- show_debug_messages = 1;
+ debug_enabled = 1;
break;
case 'g':
use_extension_dn = 1;
strip_kerberos_realm = 1;
break;
default:
- fprintf(stderr, PROGRAM_NAME " ERROR: Unknown command line option '%c'\n", option);
+ fprintf(stderr, PROGRAM_NAME ": FATAL: Unknown command line option '%c'\n", option);
exit(1);
}
}
char *value = argv[1];
if (ldapServer) {
int len = strlen(ldapServer) + 1 + strlen(value) + 1;
- char *newhost = malloc(len);
+ char *newhost = (char*)malloc(len);
snprintf(newhost, len, "%s %s", ldapServer, value);
free(ldapServer);
ldapServer = newhost;
WLDAP32Handle = GetModuleHandle("wldap32");
if ((Win32_ldap_start_tls_s = (PFldap_start_tls_s) GetProcAddress(WLDAP32Handle, LDAP_START_TLS_S)) == NULL) {
- fprintf(stderr, PROGRAM_NAME ": ERROR: TLS (-Z) not supported on this platform.\n");
+ fprintf(stderr, PROGRAM_NAME ": FATAL: TLS (-Z) not supported on this platform.\n");
exit(1);
}
}
#endif
- while (fgets(buf, 256, stdin) != NULL) {
+ while (fgets(buf, HELPER_INPUT_BUFFER, stdin) != NULL) {
int found = 0;
if (!strchr(buf, '\n')) {
/* too large message received.. skip and deny */
- fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], buf);
+ fprintf(stderr, "%s: ERROR: Input Too large: %s\n", argv[0], buf);
while (fgets(buf, sizeof(buf), stdin)) {
- fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], buf);
+ fprintf(stderr, "%s: ERROR: Input Too large..: %s\n", argv[0], buf);
if (strchr(buf, '\n') != NULL)
break;
}
- goto error;
+ SEND_ERR("");
+ continue;
}
user = strtok(buf, " \n");
if (!user) {
- fprintf(stderr, "%s: Invalid request\n", argv[0]);
- goto error;
+ debug("%s: Invalid request: No Username given\n", argv[0]);
+ SEND_ERR("Invalid request. No Username");
+ continue;
}
rfc1738_unescape(user);
if (strip_nt_domain) {
if (use_extension_dn) {
extension_dn = strtok(NULL, " \n");
if (!extension_dn) {
- fprintf(stderr, "%s: Invalid request\n", argv[0]);
- goto error;
+ debug("%s: Invalid request: Extension DN configured, but none sent.\n", argv[0]);
+ SEND_ERR("Invalid Request. Extension DN required.");
+ continue;
}
rfc1738_unescape(extension_dn);
}
if (strstr(ldapServer, "://") != NULL) {
rc = ldap_initialize(&ld, ldapServer);
if (rc != LDAP_SUCCESS) {
- fprintf(stderr, "\nUnable to connect to LDAPURI:%s\n", ldapServer);
+ fprintf(stderr, "%s: ERROR: Unable to connect to LDAPURI:%s\n", argv[0], ldapServer);
break;
}
} else
#if NETSCAPE_SSL
if (sslpath) {
if (!sslinit && (ldapssl_client_init(sslpath, NULL) != LDAP_SUCCESS)) {
- fprintf(stderr, "\nUnable to initialise SSL with cert path %s\n",
- sslpath);
+ fprintf(stderr, "FATAL: Unable to initialise SSL with cert path %s\n", sslpath);
exit(1);
} else {
sslinit++;
}
if ((ld = ldapssl_init(ldapServer, port, 1)) == NULL) {
- fprintf(stderr, "\nUnable to connect to SSL LDAP server: %s port:%d\n",
+ fprintf(stderr, "FATAL: Unable to connect to SSL LDAP server: %s port:%d\n",
ldapServer, port);
exit(1);
}
} else
#endif
if ((ld = ldap_init(ldapServer, port)) == NULL) {
- fprintf(stderr, "\nUnable to connect to LDAP server:%s port:%d\n", ldapServer, port);
+ fprintf(stderr, "ERROR: Unable to connect to LDAP server:%s port:%d\n", ldapServer, port);
break;
}
if (connect_timeout)
version = LDAP_VERSION3;
}
if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_SUCCESS) {
- fprintf(stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
+ fprintf(stderr, "ERROR: Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
version);
ldap_unbind(ld);
ld = NULL;
if (use_tls) {
#ifdef LDAP_OPT_X_TLS
if (version != LDAP_VERSION3) {
- fprintf(stderr, "TLS requires LDAP version 3\n");
+ fprintf(stderr, "FATAL: TLS requires LDAP version 3\n");
exit(1);
} else if (ldap_start_tls_s(ld, NULL, NULL) != LDAP_SUCCESS) {
- fprintf(stderr, "Could not Activate TLS connection\n");
+ fprintf(stderr, "ERROR: Could not Activate TLS connection\n");
ldap_unbind(ld);
ld = NULL;
break;
}
#else
- fprintf(stderr, "TLS not supported with your LDAP library\n");
+ fprintf(stderr, "FATAL: TLS not supported with your LDAP library\n");
exit(1);
#endif
}
if (binddn && bindpasswd && *binddn && *bindpasswd) {
rc = ldap_simple_bind_s(ld, binddn, bindpasswd);
if (rc != LDAP_SUCCESS) {
- fprintf(stderr, PROGRAM_NAME " WARNING, could not bind to binddn '%s'\n", ldap_err2string(rc));
+ fprintf(stderr, PROGRAM_NAME ": WARNING: could not bind to binddn '%s'\n", ldap_err2string(rc));
ldap_unbind(ld);
ld = NULL;
break;
}
}
- if (show_debug_messages)
- fprintf(stderr, "Connected OK\n");
+ debug("Connected OK\n");
}
if (searchLDAP(ld, group, user, extension_dn) == 0) {
found = 1;
}
}
if (found)
- printf("OK\n");
+ SEND_OK("");
else {
-error:
- printf("ERR\n");
+ SEND_ERR("");
}
if (ld != NULL) {
}
static int
-build_filter(char *filter, int size, const char *template, const char *user, const char *group)
+build_filter(char *filter, int size, const char *templ, const char *user, const char *group)
{
int n;
- while (*template && size > 0) {
- switch (*template) {
+ while (*templ && size > 0) {
+ switch (*templ) {
case '%':
- template++;
- switch (*template) {
+ templ++;
+ switch (*templ) {
case 'u':
case 'v':
- template++;
+ templ++;
n = ldap_escape_value(filter, size, user);
size -= n;
filter += n;
break;
case 'g':
case 'a':
- template++;
+ templ++;
n = ldap_escape_value(filter, size, group);
size -= n;
filter += n;
break;
default:
- fprintf(stderr, "ERROR: Unknown filter template string %%%c\n", *template);
+ fprintf(stderr, "ERROR: Unknown filter template string %%%c\n", *templ);
return 1;
break;
}
break;
case '\\':
- template++;
- if (*template) {
- *filter++ = *template++;
+ templ++;
+ if (*templ) {
+ *filter++ = *templ++;
size--;
}
break;
default:
- *filter++ = *template++;
+ *filter++ = *templ++;
size--;
break;
}
snprintf(searchbase, sizeof(searchbase), "%s", basedn);
if (build_filter(filter, sizeof(filter), searchfilter, member, group) != 0) {
- fprintf(stderr, PROGRAM_NAME " ERROR, Failed to construct LDAP search filter. filter=\"%s\", user=\"%s\", group=\"%s\"\n", filter, member, group);
+ fprintf(stderr, PROGRAM_NAME ": ERROR: Failed to construct LDAP search filter. filter=\"%s\", user=\"%s\", group=\"%s\"\n", filter, member, group);
return 1;
}
- if (show_debug_messages)
- fprintf(stderr, "group filter '%s', searchbase '%s'\n", filter, searchbase);
+ debug("group filter '%s', searchbase '%s'\n", filter, searchbase);
rc = ldap_search_s(ld, searchbase, searchscope, filter, searchattr, 1, &res);
if (rc != LDAP_SUCCESS) {
* are disabled.
*/
} else {
- fprintf(stderr, PROGRAM_NAME " WARNING, LDAP search error '%s'\n", ldap_err2string(rc));
+ fprintf(stderr, PROGRAM_NAME ": WARNING: LDAP search error '%s'\n", ldap_err2string(rc));
#if defined(NETSCAPE_SSL)
if (sslpath && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR))) {
int sslerr = PORT_GetError();
- fprintf(stderr, PROGRAM_NAME ": WARNING, SSL error %d (%s)\n", sslerr, ldapssl_err2string(sslerr));
+ fprintf(stderr, PROGRAM_NAME ": WARNING: SSL error %d (%s)\n", sslerr, ldapssl_err2string(sslerr));
}
#endif
ldap_msgfree(res);
snprintf(searchbase, sizeof(searchbase), "%s", userbasedn ? userbasedn : basedn);
ldap_escape_value(escaped_login, sizeof(escaped_login), login);
snprintf(filter, sizeof(filter), usersearchfilter, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login);
- if (show_debug_messages)
- fprintf(stderr, "user filter '%s', searchbase '%s'\n", filter, searchbase);
+ debug("user filter '%s', searchbase '%s'\n", filter, searchbase);
rc = ldap_search_s(ld, searchbase, searchscope, filter, searchattr, 1, &res);
if (rc != LDAP_SUCCESS) {
if (noreferrals && rc == LDAP_PARTIAL_RESULTS) {
* are disabled.
*/
} else {
- fprintf(stderr, PROGRAM_NAME " WARNING, LDAP search error '%s'\n", ldap_err2string(rc));
+ fprintf(stderr, PROGRAM_NAME ": WARNING: LDAP search error '%s'\n", ldap_err2string(rc));
#if defined(NETSCAPE_SSL)
if (sslpath && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR))) {
int sslerr = PORT_GetError();
- fprintf(stderr, PROGRAM_NAME ": WARNING, SSL error %d (%s)\n", sslerr, ldapssl_err2string(sslerr));
+ fprintf(stderr, PROGRAM_NAME ": WARNING: SSL error %d (%s)\n", sslerr, ldapssl_err2string(sslerr));
}
#endif
ldap_msgfree(res);
}
entry = ldap_first_entry(ld, res);
if (!entry) {
- fprintf(stderr, PROGRAM_NAME " WARNING, User '%s' not found in '%s'\n", login, searchbase);
+ fprintf(stderr, PROGRAM_NAME ": WARNING: User '%s' not found in '%s'\n", login, searchbase);
ldap_msgfree(res);
return 1;
}
FILE *f;
if (!(f = fopen(filename, "r"))) {
- fprintf(stderr, PROGRAM_NAME " ERROR: Can not read secret file %s\n", filename);
+ fprintf(stderr, PROGRAM_NAME ": ERROR: Can not read secret file %s\n", filename);
return 1;
}
if (!fgets(buf, sizeof(buf) - 1, f)) {
- fprintf(stderr, PROGRAM_NAME " ERROR: Secret file %s is empty\n", filename);
+ fprintf(stderr, PROGRAM_NAME ": ERROR: Secret file %s is empty\n", filename);
fclose(f);
return 1;
}
bindpasswd = xstrdup(buf);
if (!bindpasswd) {
- fprintf(stderr, PROGRAM_NAME " ERROR: can not allocate memory\n");
+ fprintf(stderr, PROGRAM_NAME ": ERROR: can not allocate memory\n");
}
fclose(f);
--- /dev/null
+include $(top_srcdir)/src/Common.am
+
+libexec_PROGRAMS = ext_lm_group_acl
+ext_lm_group_acl_SOURCES = ext_lm_group_acl.cc
+
+LDADD = \
+ $(COMPAT_LIB) \
+ -lnetapi32 \
+ -ladvapi32 \
+ -lntdll \
+ $(XTRA_LIBS)
+
+man_MANS = ext_lm_group_acl.8
+
+EXTRA_DIST = config.test ext_lm_group_acl.8
--- /dev/null
+.if !'po4a'hide' .TH ext_lm_group_acl 8
+.
+.SH NAME
+.if !'po4a'hide' .B ext_lm_group_acl
+.if !'po4a'hide' \-
+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' .B \-d
+Write debug info to stderr.
+.if !'po4a'hide' .B \-D domain
+Specify the default user's domain.
+.if !'po4a'hide' .B \-G
+Start helper in Domain Global Group mode.
+.if !'po4a'hide' .B \-h
+Display the binary help and command line syntax info using stderr.
+.if !'po4a'hide' .B \-P
+Use ONLY PDCs for group validation.
+.
+.SH CONFIGURATION
+.
+.if !'po4a'hide' external_acl_type NT_global_group %LOGIN c:/squid/libexec/ext_lm_group_acl.exe -G
+.if !'po4a'hide' external_acl_type NT_local_group %LOGIN c:/squid/libexec/ext_lm_group_acl.exe
+.if !'po4a'hide' .
+.if !'po4a'hide' acl GProxyUsers external NT_global_group GProxyUsers
+.if !'po4a'hide' acl LProxyUsers external NT_local_group LProxyUsers
+.if !'po4a'hide' acl password proxy_auth REQUIRED
+.if !'po4a'hide' .
+.if !'po4a'hide' http_access allow password GProxyUsers
+.if !'po4a'hide' http_access allow password LProxyUsers
+.if !'po4a'hide' http_access deny all
+.
+.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' acl ProxyUsers external NT_global_group "c:/squid/etc/DomainUsers.txt"
+.
+and the
+.B DomainUsers.txt
+files will contain only the following line:
+.B "Domain Users"
+.
+.PP 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 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
+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@squid-cache.org>
+.
+.SH REPORTING BUGS
+Bug reports need to be made in English.
+See http://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 http://bugs.squid-cache.org/
+.PP
+Report serious security bugs to
+.I Squid Bugs <squid-bugs@squid-cache.org>
+.PP
+Report ideas for new improvements to the
+.I Squid Developers mailing list
+.if !'po4a'hide' <squid-dev@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' http://wiki.squid-cache.org/SquidFaq
+.br
+The Squid Configuration Manual
+.if !'po4a'hide' http://www.squid-cache.org/Doc/config/
*/
#include "config.h"
+#include "helpers/defines.h"
+#include "include/util.h"
+
+
#ifdef _SQUID_CYGWIN_
#include <wchar.h>
int _wcsicmp(const wchar_t *, const wchar_t *);
#endif
+
#if HAVE_STDIO_H
#include <stdio.h>
#endif
#include <lm.h>
#include <ntsecapi.h>
-#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;
+char *program_name;
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)
} else
nStatus = (use_PDC_only ? NetGetDCName(NULL, wszLocalDomain, (LPBYTE *) & LclDCptr) : NetGetAnyDCName(NULL, wszLocalDomain, (LPBYTE *) & LclDCptr));
} else {
- fprintf(stderr, "%s NetServerGetInfo() failed.'\n", myname);
+ fprintf(stderr, "%s: ERROR: NetServerGetInfo() failed.'\n", program_name);
if (pSrvBuf != NULL)
NetApiBufferFree(pSrvBuf);
return result;
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);
+ 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)
}
} else {
result = 0;
- fprintf(stderr, "%s NetUserGetGroups() failed.'\n", myname);
+ fprintf(stderr, "%s: ERROR: NetUserGetGroups() failed.'\n", program_name);
}
} else {
- fprintf(stderr, "%s Can't find DC for local domain '%s'\n", myname, machinedomain);
+ fprintf(stderr, "%s: ERROR: Can't find DC for local domain '%s'\n", program_name, machinedomain);
}
/*
* Free the allocated memory.
}
static void
-usage(char *program)
+usage(const char *program)
{
fprintf(stderr, "Usage: %s [-D domain][-G][-P][-c][-d][-h]\n"
" -D default user Domain\n"
opt = optopt;
/* fall thru to default */
default:
- fprintf(stderr, "%s Unknown option: -%c. Exiting\n", myname, opt);
+ fprintf(stderr, "%s: FATAL: Unknown option: -%c. Exiting\n", program_name, opt);
usage(argv[0]);
exit(1);
break; /* not reached */
main(int argc, char *argv[])
{
char *p;
- char buf[BUFSIZE];
+ char buf[HELPER_INPUT_BUFFER];
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];
+ program_name = strrchr(argv[0], '/');
+ if (program_name == NULL)
+ program_name = argv[0];
} else {
- myname = "(unknown)";
+ program_name = "(unknown)";
}
mypid = getpid();
if (use_global) {
if ((machinedomain = GetDomainName()) == NULL) {
- fprintf(stderr, "%s Can't read machine domain\n", myname);
+ fprintf(stderr, "%s: FATAL: Can't read machine domain\n", program_name);
exit(1);
}
strlwr(machinedomain);
debug("Warning: using only PDCs for group validation !!!\n");
/* Main Loop */
- while (fgets(buf, sizeof(buf), stdin)) {
+ while (fgets(buf, HELPER_INPUT_BUFFER, 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);
+ 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;
}
- goto error;
+ SEND_ERR("Input Too Long.");
+ continue;
}
if ((p = strchr(buf, '\n')) != NULL)
*p = '\0'; /* strip \n */
debug("Got '%s' from Squid (length: %d).\n", buf, strlen(buf));
if (buf[0] == '\0') {
- fprintf(stderr, "Invalid Request\n");
- goto error;
+ SEND_ERR("Invalid Request.");
+ continue;
}
username = strtok(buf, " ");
for (n = 0; (group = strtok(NULL, " ")) != NULL; n++) {
groups[n] = NULL;
if (NULL == username) {
- fprintf(stderr, "Invalid Request\n");
- goto error;
+ SEND_ERR("Invalid Request. No Username.");
+ continue;
}
rfc1738_unescape(username);
if ((use_global ? Valid_Global_Groups(username, groups) : Valid_Local_Groups(username, groups))) {
- printf("OK\n");
+ SEND_OK("");
} else {
-error:
- printf("ERR\n");
+ SEND_ERR("");
}
- err = 0;
}
return 0;
}
-# Makefile for storage modules in the Squid Object Cache server
-#
-# $Id$
-#
-
-DIST_SUBDIRS = ip_user ldap_group mswin_ad_group mswin_lm_group session unix_group wbinfo_group
+DIST_SUBDIRS = AD_group file_userip LDAP_group LM_group session unix_group wbinfo_group
SUBDIRS = $(EXTERNAL_ACL_HELPERS)
--- /dev/null
+include $(top_srcdir)/src/Common.am
+
+libexec_PROGRAMS = ext_file_userip_acl
+ext_file_userip_acl_SOURCES = ext_file_userip_acl.cc
+man_MANS = ext_file_userip_acl.8
+
+EXTRA_DIST = \
+ example.conf \
+ example-deny_all_but.conf \
+ ext_file_userip_acl.8 \
+ config.test
+
+LDADD = \
+ $(COMPAT_LIB) \
+ $(XTRA_LIBS)
-# $Id$
+# Configuration File for Squid ext_file_userip_acl helper
+#
# Lines that begin with a # are ignored
# The main format is:
#
# Single user
# ip[/mask] user
#
-# Users that belong to `group“ (/etc/group)
+# Users that belong to "group" (/etc/group)
# ip[/mask] @group
#
# No User from this IP
# IP and MASK must be in dotted quad format.
#
# Ths first match wins, so you may create rules that
-# `allow everyone but foo bar“ or
-# `deny everyone but foo bar“
+# "allow everyone but foo bar" or
+# "deny everyone but foo bar"
#
# Examples:
# All users from the 192.168.1.0/24 network are allowed
# 192.168.1.0/255.255.255.0 ALL
#
# Users from the 192.168.2.0/24 network are not allowed
-# except for user `boss“ that can authenticate from
+# except for user "boss" that can authenticate from
# anywhere
# 0.0.0.0/0.0.0.0 boss
# 192.168.2.0/255.255.255.0 NONE
#
-# User `jayk“ may athenticate only from his station
-# ip address
+# User "jayk" may athenticate only from his station ip address
# 192.168.3.45 jayk
#
-# Users of the `tol“ group may authenticate from
-# their VLAN
+# Users of the "tol" group may authenticate from their VLAN
# 10.0.0.0/255.255.0.0 @tol
--- /dev/null
+.if !'po4a'hide' .TH ext_file_userip_acl 8
+.
+.SH NAME
+.if !'po4a'hide' .B ext_file_userip_acl
+.if !'po4a'hide' \-
+Restrict users to cetain IP addresses, using a text file backend.
+.PP
+Version 1.0
+.
+.SH SYNOPSIS
+.if !'po4a'hide' .B ext_file_userip_acl
+.if !'po4a'hide' .B [\-dh] [\-f
+file name
+.if !'po4a'hide' .B ]
+.
+.SH DESCRIPTION
+.B ext_file_userip_acl
+is an installed binary. An external helper for the Squid external acl scheme.
+.PP
+It works by reading a pair composed by an ip address and an username
+on STDIN and matching it against a configuration file.
+.
+.SH OPTIONS
+.if !'po4a'hide' .TP 12
+.if !'po4a'hide' .B \-d
+Write debug info to stderr.
+.if !'po4a'hide' .B \-f
+Configuration file to load.
+.if !'po4a'hide' .B \-h
+Display the binary help and command line syntax info using stderr.
+.
+.SH CONFIGURATION
+.PP
+The
+.B squid.conf
+configuration for the external ACL should be:
+.if !'po4a'hide' .
+.if !'po4a'hide' external_acl_type type-name %SRC %LOGIN /path/to/ext_file_userip_acl -f /path/to/config.file
+.if !'po4a'hide' .
+.PP
+If the helper program finds a matching username/ip in the configuration file, it returns
+.B OK
+, otherwise it returns
+.B ERR .
+.PP
+The configuration file format is as follows:
+.
+ip_addr[/netmask] username|@group|ALL|NONE
+.PP
+Where
+.B ip_addr
+is a dotted quad format IP address, the
+.B netmask
+must be in dotted quad format too.
+.PP
+When the second parameter is prefixed with an
+.B "@"
+, the program will lookup the
+.B "/etc/group"
+file entry for the specified username.
+.PP
+There are other two directives,
+.B ALL
+and
+.B NONE
+, which mean \"any user on this IP address may authenticate\" or \"no user on this ip address may authenticate\".
+.
+.SH AUTHOR
+This program was written by
+.if !'po4a'hide' .I Rodrigo Campos <rodrigo@geekbunker.org>
+.PP
+This manual was written by
+.if !'po4a'hide' .I Rodrigo Campos <rodrigo@geekbunker.org>
+.if !'po4a'hide' .I Amos Jeffries <amosjeffries@squid-cache.org>
+.
+.SH COPYRIGHT
+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@squid-cache.org>
+.
+.SH REPORTING BUGS
+Bug reports need to be made in English.
+See http://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 http://bugs.squid-cache.org/
+.PP
+Report serious security bugs to
+.I Squid Bugs <squid-bugs@squid-cache.org>
+.PP
+Report ideas for new improvements to the
+.I Squid Developers mailing list
+.if !'po4a'hide' <squid-dev@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' http://wiki.squid-cache.org/SquidFaq
+.br
+The Squid Configuration Manual
+.if !'po4a'hide' http://www.squid-cache.org/Doc/config/
--- /dev/null
+/* $Id$
+* Copyright (C) 2002 Rodrigo Campos
+*
+* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+* Author: Rodrigo Campos (rodrigo@geekbunker.org)
+*
+*/
+#define SQUID_NO_ALLOC_PROTECT 1
+#include "config.h"
+#include "helpers/defines.h"
+#include "rfc1738.h"
+#include "util.h"
+
+#if HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_GRP_H
+#include <grp.h>
+#endif
+
+
+struct ip_user_dict {
+ unsigned long address; // IP address (assumes IPv4)
+ unsigned long netmask; // IP netmask
+ char *username;
+ struct ip_user_dict *next_entry;
+};
+
+int match_user(char *, char *);
+int match_group(char *, char *);
+struct ip_user_dict *load_dict(FILE *);
+int dict_lookup(struct ip_user_dict *, char *, char *);
+
+/** Size of lines read from the dictionary file */
+#define DICT_BUFFER_SIZE 8196
+
+/** This function parses the dictionary file and loads it
+ * in memory. All IP addresses are processed with a bitwise AND
+ * with their netmasks before they are stored.
+ * If there“s no netmask (no /) in the in the lhs , a mask
+ * 255.255.255.255 is assumed.
+ * It returns a pointer to the first entry of the linked list
+ */
+struct ip_user_dict *
+load_dict(FILE * FH)
+{
+ struct ip_user_dict *current_entry; /* the structure used to
+ store data */
+ struct ip_user_dict *first_entry = NULL; /* the head of the
+ linked list */
+ char line[DICT_BUFFER_SIZE]; /* the buffer for the lines read
+ from the dict file */
+ char *cp; /* a char pointer used to parse
+ each line */
+ char *username; /* for the username */
+ char *tmpbuf; /* for the address before the
+ bitwise AND */
+
+ /* the pointer to the first entry in the linked list */
+ first_entry = (struct ip_user_dict*)malloc(sizeof(struct ip_user_dict));
+ current_entry = first_entry;
+
+ while ((cp = fgets (line, DICT_BUFFER_SIZE, FH)) != NULL) {
+ if (line[0] == '#') {
+ continue;
+ }
+ if ((cp = strchr (line, '\n')) != NULL) {
+ /* chop \n characters */
+ *cp = '\0';
+ }
+ if ((cp = strtok (line, "\t ")) != NULL) {
+ /* get the username */
+ username = strtok (NULL, "\t ");
+ /* look for a netmask */
+ if ((cp = strtok (line, "/")) != NULL) {
+ /* store the ip address in a temporary buffer */
+ tmpbuf = cp;
+ cp = strtok (NULL, "/");
+ if (cp != NULL) {
+ /* if we have a slash in the lhs, we have a netmask */
+ current_entry->netmask = (inet_addr(cp));
+ current_entry->address =
+ (((inet_addr (tmpbuf))) & current_entry->netmask);
+ } else {
+ /* when theres no slash, we figure the netmask is /32 */
+ current_entry->address = (inet_addr(tmpbuf));
+ current_entry->netmask = (inet_addr("255.255.255.255"));
+ }
+ }
+ /* get space for the username */
+ current_entry->username =
+ (char*)calloc(strlen(username) + 1, sizeof(char));
+ strcpy(current_entry->username, username);
+
+ /* get space and point current_entry to the new entry */
+ current_entry->next_entry =
+ (struct ip_user_dict*)malloc(sizeof(struct ip_user_dict));
+ current_entry = current_entry->next_entry;
+ }
+
+ }
+
+ /* Return a pointer to the first entry linked list */
+ return first_entry;
+}
+
+/** This function looks for a matching ip/mask in
+ * the dict file loaded in memory.
+ * It returns 1 if it finds a match or 0 if no match is found
+ */
+int
+dict_lookup(struct ip_user_dict *first_entry, char *username,
+ char *address)
+{
+ /* Move the pointer to the first entry of the linked list. */
+ struct ip_user_dict *current_entry = first_entry;
+
+ while (current_entry->username != NULL) {
+ debug("user: %s\naddr: %lu\nmask: %lu\n\n",
+ current_entry->username, current_entry->address,
+ current_entry->netmask);
+
+ if ((inet_addr (address) & (unsigned long) current_entry->
+ netmask) == current_entry->address) {
+ /* If the username contains an @ we assume it“s a group and
+ call the corresponding function */
+ if ((strchr (current_entry->username, '@')) == NULL) {
+ if ((match_user (current_entry->username, username)) == 1)
+ return 1;
+ } else {
+ if ((match_group (current_entry->username, username)) == 1)
+ return 1;
+ }
+ }
+ current_entry = current_entry->next_entry;
+ }
+
+ /* If no match was found we return 0 */
+ return 0;
+}
+
+int
+match_user(char *dict_username, char *username)
+{
+ if ((strcmp(dict_username, username)) == 0) {
+ return 1;
+ } else {
+ if ((strcmp(dict_username, "ALL")) == 0) {
+ return 1;
+ }
+ }
+ return 0;
+} /* match_user */
+
+int
+match_group(char *dict_group, char *username)
+{
+ struct group *g; /* a struct to hold group entries */
+ dict_group++; /* the @ should be the first char
+ so we rip it off by incrementing
+ * the pointer by one */
+
+ if ((g = getgrnam(dict_group)) == NULL) {
+ debug("Group does not exist '%s'\n", dict_group);
+ return 0;
+ } else {
+ while (*(g->gr_mem) != NULL) {
+ if (strcmp(*((g->gr_mem)++), username) == 0) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+
+}
+
+static void
+usage(const char *program_name)
+{
+ fprintf (stderr, "Usage:\n%s [-d] -f <configuration file>\n",
+ program_name);
+}
+
+int
+main (int argc, char *argv[])
+{
+ FILE *FH;
+ char *filename = NULL;
+ char *program_name = argv[0];
+ char *cp;
+ char *username, *address;
+ char line[HELPER_INPUT_BUFFER];
+ struct ip_user_dict *current_entry;
+ int ch;
+
+ setvbuf (stdout, NULL, _IOLBF, 0);
+ while ((ch = getopt(argc, argv, "df:h")) != -1) {
+ switch (ch) {
+ case 'f':
+ filename = optarg;
+ break;
+ case 'd':
+ debug_enabled = 1;
+ break;
+ case 'h':
+ usage(program_name);
+ exit (0);
+ default:
+ fprintf(stderr, "%s: FATAL: Unknown parameter option '%c'", program_name, ch);
+ usage(program_name);
+ exit (1);
+ }
+ }
+ if (filename == NULL) {
+ fprintf(stderr, "%s: FATAL: No Filename configured.", program_name);
+ usage(program_name);
+ exit(1);
+ }
+ FH = fopen(filename, "r");
+ current_entry = load_dict(FH);
+
+ while (fgets(line, HELPER_INPUT_BUFFER, stdin)) {
+ if ((cp = strchr (line, '\n')) == NULL) {
+ /* too large message received.. skip and deny */
+ fprintf(stderr, "%s: ERROR: Input Too Large: %s\n", program_name, line);
+ while (fgets(line, sizeof(line), stdin)) {
+ fprintf(stderr, "%s: ERROR: Input Too Large..: %s\n", program_name, line);
+ if (strchr(line, '\n') != NULL)
+ break;
+ }
+ SEND_ERR("Input Too Large.");
+ continue;
+ }
+ *cp = '\0';
+ address = strtok(line, " \t");
+ username = strtok(NULL, " \t");
+ if (!address || !username) {
+ debug("%s: unable to read tokens\n", program_name);
+ SEND_ERR("Invalid Input.");
+ continue;
+ }
+ rfc1738_unescape(address);
+ rfc1738_unescape(username);
+ int result = dict_lookup(current_entry, username, address);
+ debug("%s: result: %d\n", program_name, result);
+ if (result != 0) {
+ SEND_OK("");
+ } else {
+ SEND_ERR("");
+ }
+ }
+
+ fclose (FH);
+ return 0;
+}
+++ /dev/null
-include $(top_srcdir)/src/Common.am
-
-## we need our local files too (but avoid -I. at all costs)
-INCLUDES += -I$(srcdir)
-
-
-libexec_PROGRAMS = ip_user_check
-
-ip_user_check_SOURCES = \
- dict.c \
- ip_user.h \
- main.c \
- match.c
-
-EXTRA_DIST = \
- example.conf \
- example-deny_all_but.conf \
- license \
- README \
- config.test
-
-LDADD = \
- $(top_builddir)/compat/libcompat.la \
- -L$(top_builddir)/lib -lmiscutil \
- $(XTRA_LIBS)
+++ /dev/null
-# $Id$
-CC=gcc
-CFLAGS=-Wall
-LIBS=
-# For Solaris
-# LIBS=-lnsl -lsocket
-
-ip_user_check: ip_user.h dict.o match.c main.c
- $(CC) $(CFLAGS) -o ip_user_check dict.o match.c main.c $(LIBS)
-
-dict.o: ip_user.h dict.c
- $(CC) $(CFLAGS) -c dict.c
-
-clean:
- rm -f dict.o ip_user_check
-
+++ /dev/null
-$Id$
-
-README file for ip_user_check, an external helper for the
-Squid external acl scheme.
-
-It works by reading a pair composed by an ip address and an username
-on STDIN and matching it against a configuration file.
-
-The configuration for the external ACL should be:
-
-external_acl_type type-name %SRC %LOGIN /path/to/ip_user_check -f /path/to/config.file
-
-If the program finds a matching username/ip in the configuration file,
-it returns `OK', or `ERR' otherwise.
-
-The usage for the program is:
-
-ip_user_check -f <configuration_file>
-
-
-The configuration file format is as follows:
-
-ip_addr[/mask] user|@group|ALL|NONE
-
-Where ip_addr is a dotted quad format IP address, the mask
-must be in dotted quad format too.
-
-When the second parameter is prefixed with an @, the program will lookup in the
-/etc/group entry for the specified username.
-
-There are other two directives, `ALL' and `NONE', which mean "any user on this ip
-address may authenticate" or "no user on this ip address may authenticate".
-
-TODO
-- Deny operator, to create `allow all but' rules
-- Check for a valid user in the OS
-- Accept decimal format netmasks
-
-
---
-Rodrigo Campos
-rodrigo@geekbunker.org
+++ /dev/null
-/* $Id$
-* Copyright (C) 2002 Rodrigo Campos
-*
-* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Author: Rodrigo Campos (rodrigo@geekbunker.org)
-*
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include "ip_user.h"
-
-#ifndef DEBUG
-#undef DEBUG
-#endif
-
-
-/* This function parses the dictionary file and loads it
- * in memory. All IP addresses are processed with a bitwise AND
- * with their netmasks before they are stored.
- * If there“s no netmask (no /) in the in the lhs , a mask
- * 255.255.255.255 is assumed.
- * It returns a pointer to the first entry of the linked list
- */
-struct ip_user_dict *
-load_dict (FILE * FH) {
- struct ip_user_dict *current_entry; /* the structure used to
- store data */
- struct ip_user_dict *first_entry = NULL; /* the head of the
- linked list */
- char line[BUFSIZE]; /* the buffer for the lines read
- from the dict file */
- char *cp; /* a char pointer used to parse
- each line */
- char *username; /* for the username */
- char *tmpbuf; /* for the address before the
- bitwise AND */
-
- /* the pointer to the first entry in the linked list */
- first_entry = malloc (sizeof (struct ip_user_dict));
- current_entry = first_entry;
-
- while ((cp = fgets (line, sizeof (line), FH)) != NULL) {
- if (line[0] == '#') {
- continue;
- }
- if ((cp = strchr (line, '\n')) != NULL) {
- /* chop \n characters */
- *cp = '\0';
- }
- if ((cp = strtok (line, "\t ")) != NULL) {
- /* get the username */
- username = strtok (NULL, "\t ");
- /* look for a netmask */
- if ((cp = strtok (line, "/")) != NULL) {
- /* store the ip address in a temporary buffer */
- tmpbuf = cp;
- cp = strtok (NULL, "/");
- if (cp != NULL) {
- /* if we have a slash in the lhs, we have a netmask */
- current_entry->netmask = (inet_addr (cp));
- current_entry->address =
- (((inet_addr (tmpbuf))) & current_entry->netmask);
- } else {
- /* when theres no slash, we figure the netmask is /32 */
- current_entry->address = (inet_addr (tmpbuf));
- current_entry->netmask = (inet_addr ("255.255.255.255"));
- }
- }
- /* get space for the username */
- current_entry->username =
- calloc (strlen (username) + 1, sizeof (char));
- strcpy (current_entry->username, username);
-
- /* get space and point current_entry to the new entry */
- current_entry->next_entry =
- malloc (sizeof (struct ip_user_dict));
- current_entry = current_entry->next_entry;
- }
-
- }
-
- /* Return a pointer to the first entry linked list */
- return first_entry;
-} /* load_dict */
-
-/* This function looks for a matching ip/mask in
- * the dict file loaded in memory.
- * It returns 1 if it finds a match or 0 if no match is found
- */
-int
-dict_lookup (struct ip_user_dict *first_entry, char *username,
- char *address)
-{
- /* Move the pointer to the first entry of the linked list. */
- struct ip_user_dict *current_entry = first_entry;
-
- while (current_entry->username != NULL) {
-#ifdef DEBUG
- printf ("user: %s\naddr: %lu\nmask: %lu\n\n",
- current_entry->username, current_entry->address,
- current_entry->netmask);
-#endif
-
- if ((inet_addr (address) & (unsigned long) current_entry->
- netmask) == current_entry->address) {
- /* If the username contains an @ we assume it“s a group and
- call the corresponding function */
- if ((strchr (current_entry->username, '@')) == NULL) {
- if ((match_user (current_entry->username, username)) == 1)
- return 1;
- } else {
- if ((match_group (current_entry->username, username)) == 1)
- return 1;
- }
- }
- current_entry = current_entry->next_entry;
- }
-
- /* If no match was found we return 0 */
- return 0;
-} /* dict_lookup */
+++ /dev/null
-/* $Id$
-* Copyright (C) 2002 Rodrigo Campos
-*
-* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Author: Rodrigo Campos (rodrigo@geekbunker.org)
-*
-*/
-
-
-
-
-struct ip_user_dict {
- unsigned long address;
- unsigned long netmask;
- char *username;
- struct ip_user_dict *next_entry;
-};
-
-extern int match_user(char *, char *);
-extern int match_group(char *, char *);
-extern struct ip_user_dict *load_dict(FILE *);
-extern int dict_lookup(struct ip_user_dict *, char *, char *);
-
-
-#define BUFSIZE 1024
+++ /dev/null
-* Copyright (C) 2002 Rodrigo Campos
-*
-* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Author: Rodrigo Campos (rodrigo@geekbunker.org)
-*
-*/
+++ /dev/null
-/* $Id$
-* Copyright (C) 2002 Rodrigo Campos
-*
-* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Author: Rodrigo Campos (rodrigo@geekbunker.org)
-*
-*/
-
-#include "rfc1738.h"
-#include "util.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "ip_user.h"
-
-static void
-usage (char *program_name)
-{
- fprintf (stderr, "Usage:\n%s -f <configuration file>\n",
- program_name);
-}
-
-int
-main (int argc, char *argv[])
-{
- FILE *FH;
- char *filename = NULL;
- char *program_name = argv[0];
- char *cp;
- char *username, *address;
- char line[BUFSIZE];
- struct ip_user_dict *current_entry;
- int ch;
-
- setvbuf (stdout, NULL, _IOLBF, 0);
- while ((ch = getopt (argc, argv, "f:")) != -1) {
- switch (ch) {
- case 'f':
- filename = optarg;
- break;
- default:
- usage (program_name);
- exit (1);
- }
- }
- if (filename == NULL) {
- usage (program_name);
- exit(1);
- }
- FH = fopen (filename, "r");
- current_entry = load_dict (FH);
-
- while (fgets (line, sizeof (line), stdin)) {
- if ((cp = strchr (line, '\n')) == NULL) {
- /* too large message received.. skip and deny */
- fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], line);
- while (fgets(line, sizeof(line), stdin)) {
- fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], line);
- if (strchr(line, '\n') != NULL)
- break;
- }
- goto error;
- }
- *cp = '\0';
- address = strtok (line, " \t");
- username = strtok (NULL, " \t");
- if (!address || !username) {
- fprintf (stderr, "%s: unable to read tokens\n", argv[0]);
- goto error;
- }
- rfc1738_unescape(address);
- rfc1738_unescape(username);
-#ifdef DEBUG
- printf ("result: %d\n",
- dict_lookup (current_entry, username, address));
-#endif
- if ((dict_lookup (current_entry, username, address)) != 0) {
- printf ("OK\n");
- } else {
-error:
- printf ("ERR\n");
- }
- }
-
-
- fclose (FH);
- return 0;
-}
+++ /dev/null
-/* $Id$
-* Copyright (C) 2002 Rodrigo Campos
-*
-* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* Author: Rodrigo Campos (rodrigo@geekbunker.org)
-*
-*/
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <grp.h>
-
-#include "ip_user.h"
-
-int
-match_user (char *dict_username, char *username)
-{
- if ((strcmp (dict_username, username)) == 0) {
- return 1;
- } else {
- if ((strcmp (dict_username, "ALL")) == 0) {
- return 1;
- }
- }
- return 0;
-} /* match_user */
-
-int
-match_group (char *dict_group, char *username)
-{
- struct group *g; /* a struct to hold group entries */
- dict_group++; /* the @ should be the first char
- so we rip it off by incrementing
- * the pointer by one */
-
- if ((g = getgrnam (dict_group)) == NULL) {
- fprintf (stderr, "helper: Group does not exist '%s'\n",
- dict_group);
- return 0;
- } else {
- while (*(g->gr_mem) != NULL) {
- if (strcmp (*((g->gr_mem)++), username) == 0) {
- return 1;
- }
- }
- }
- return 0;
-
-} /* match_group */
+++ /dev/null
-include $(top_srcdir)/src/Common.am
-
-## we need our local files too (but avoid -I. at all costs)
-INCLUDES += -I$(srcdir)
-
-
-libexec_PROGRAMS = squid_ldap_group
-man_MANS = squid_ldap_group.8
-EXTRA_DIST = squid_ldap_group.8 config.test
-squid_ldap_group_SOURCES = squid_ldap_group.c
-
-LDADD = \
- $(top_builddir)/compat/libcompat.la \
- -L$(top_builddir)/lib -lmiscutil \
- $(LDAPLIB) \
- $(LBERLIB) \
- $(XTRA_LIBS)
+++ /dev/null
-This program is a LDAP group helper for Squid.
-
-See the included manpage for documentation.
-
- nroff -man squid_ldap_group.8 | less
-
-See INSTALL for installation instructions
-
-The latest version of this program can always be found from
-MARA Systems at http://marasystems.com/download/LDAP_Group/
+++ /dev/null
-/*
- * (C) 2002, 2005 Guido Serassio <guido.serassio@acmeconsulting.it>
- * 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 <sys/types.h>
-
-#define safe_free(x) if (x) { free(x); x = NULL; }
-
-/* Debugging stuff */
-
-#ifdef __GNUC__ /* this is really a gcc-ism */
-#ifdef DEBUG
-#include <stdio.h>
-#include <unistd.h>
-static char *__foo;
-extern char debug_enabled;
-extern char *WIN32_ErrorMessage;
-#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); \
- if (WIN32_ErrorMessage != NULL){ \
- LocalFree(WIN32_ErrorMessage); \
- WIN32_ErrorMessage = NULL; \
- } }
-#else /* DEBUG */
-#define debug(X...) /* */
-#endif /* DEBUG */
-#else /* __GNUC__ */
-extern char debug_enabled;
-extern char *WIN32_ErrorMessage;
-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);
- if (WIN32_ErrorMessage != NULL) {
- LocalFree(WIN32_ErrorMessage);
- WIN32_ErrorMessage = NULL;
- }
- }
-#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
+++ /dev/null
-
-This is the readme.txt file for mswin_check_ad_group 2.0, an external
-helper for the External ACL Scheme for Squid.
-
-
-This helper must be used in with an authentication scheme (tipically
-basic, NTLM or Negotiate) based on Windows Active Directory 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.
-
-Two running mode are available:
-
-- Local mode:
-membership is checked against machine's local groups, cannot be used when
-running on a Domain Controller.
-
-- Active Directory Global mode:
-membership is checked against the whole Active Directory Forest of the
-machine where Squid is running.
-
-The minimal Windows version needed to run mswin_check_ad_group is
-a Windows 2000 SP4 member of an Active Directory Domain.
-
-When running in Active Directory Global mode, all types of Active Directory
-security groups are supported:
-- Domain Global
-- Domain Local from user's domain
-- Universal
-and Active Directory group nesting is fully supported.
-
-
-==============
-Program Syntax
-==============
-
-mswin_check_ad_group [-D domain][-G][-c][-d][-h]
-
--D domain specify the default user's domain
--G start helper in Active Directory Global mode
--c use case insensitive compare (local mode only)
--d enable debugging
--h this message
-
-
-================
-squid.conf usage
-================
-
-When running in Active Directory Global mode, the AD Group can be specified using the
-following syntax:
-
-1. Plain NT4 Group Name
-2. Full NT4 Group Name
-3. Active Directory Canonical name
-
-As Example:
-1. Proxy-Users
-2. MYDOMAIN\Proxy-Users
-3. mydomain.local/Groups/Proxy-Users
-
-When using Plain NT4 Group Name, the Group is searched in the user's domain.
-
-external_acl_type AD_global_group %LOGIN c:/squid/libexec/mswin_check_ad_group.exe -G
-external_acl_type NT_local_group %LOGIN c:/squid/libexec/mswin_check_ad_group.exe
-
-acl GProxyUsers external AD_global_group MYDOMAIN\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 AD users member of MYDOMAIN\GProxyUsers
-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:
-- When running in Active Directory Global mode, for better performance,
- all Domain Controllers of the Active Directory forest should be configured
- as Global Catalog.
-- When running in local mode, the standard group name comparison is case
- sensitive, so group name must be specified with same case as in the
- local SAM database.
- It's possible to enable case insensitive group name comparison (-c),
- but on some not-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_ad_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%5cusername
-syntax). Press ENTER to get an OK or ERR message.
-Make sure pressing <CTRL><D> behaves the same as a carriage return.
-Make sure pressing <CTRL><C> 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.
-
+++ /dev/null
-#
-# Makefile for the Squid Object Cache server
-#
-# $Id$
-#
-# 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_srcdir) \
- -I$(top_builddir)/include \
- -I$(top_srcdir)/include
-
-LDADD = \
- $(top_builddir)/compat/libcompat.la \
- -L$(top_builddir)/lib -lmiscutil \
- -lnetapi32 \
- -ladvapi32 \
- -lntdll \
- $(XTRA_LIBS)
-
-EXTRA_DIST = readme.txt config.test
+++ /dev/null
-
-This is the readme.txt file for mswin_check_lm_group, an external
-helper for 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 (LM mode).
-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 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 (-c),
- but on some not-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%5cusername
-syntax). Press ENTER to get an OK or ERR message.
-Make sure pressing <CTRL><D> behaves the same as a carriage return.
-Make sure pressing <CTRL><C> 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.
-
+++ /dev/null
-/*
- * (C) 2002, 2005 Guido Serassio <guido.serassio@acmeconsulting.it>
- * 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 <sys/types.h>
-
-#define safe_free(x) if (x) { free(x); x = NULL; }
-
-/* Debugging stuff */
-
-#ifdef __GNUC__ /* this is really a gcc-ism */
-#ifdef DEBUG
-#include <stdio.h>
-#include <unistd.h>
-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
include $(top_srcdir)/src/Common.am
-## we need our local files too (but avoid -I. at all costs)
-INCLUDES += -I$(srcdir)
-
-
-libexec_PROGRAMS = squid_session
-man_MANS = squid_session.8
-EXTRA_DIST = squid_session.8 config.test
-squid_session_SOURCES = squid_session.c
+libexec_PROGRAMS = ext_session_acl
+man_MANS = ext_session_acl.8
+EXTRA_DIST = ext_session_acl.8 config.test
+ext_session_acl_SOURCES = ext_session_acl.cc
LDADD = \
- $(top_builddir)/compat/libcompat.la \
+ $(COMPAT_LIB) \
$(LIB_DB)
-.if !'po4a'hide' .TH squid_session 8 "19 March 2006"
+.if !'po4a'hide' .TH ext_session_acl 8 "19 March 2006"
.
.SH NAME
-.if !'po4a'hide' .B squid_session
+.if !'po4a'hide' .B ext_session_acl
.if !'po4a'hide' \-
-Squid session tracking external acl group helper.
+Squid session tracking external acl helper.
.PP
Version 1.0
.
.SH SYNOPSIS
-.if !'po4a'hide' .B squid_session
+.if !'po4a'hide' .B ext_session_acl
.if !'po4a'hide' .B "[\-t"
timeout
.if !'po4a'hide' .B "] [\-b"
.if !'po4a'hide' .B "] [\-a]"
.
.SH DESCRIPTION
-.B squid_session
+.B ext_session_acl
maintains a concept of sessions by monitoring requests
and timing out sessions if no requests have been seen for the idle timeout
timer.
.PP
Configuration example using the default automatic mode
.if !'po4a'hide' .RS
-.if !'po4a'hide' external_acl_type session ttl=300 negative_ttl=0 children=1 concurrency=200 %LOGIN /usr/local/squid/libexec/squid_session
+.if !'po4a'hide' external_acl_type session ttl=300 negative_ttl=0 children=1 concurrency=200 %LOGIN /usr/local/squid/libexec/ext_session_acl
.if !'po4a'hide' acl session external session
.if !'po4a'hide' http_access deny !session
.if !'po4a'hide' deny_info http://your.server.example.com/bannerpage?url=%s session
/*
- * squid_session: Squid external acl helper for tracking sessions
+ * ext_session_acl: Squid external acl helper for tracking sessions
*
* Copyright (C) 2006 Henrik Nordstrom <henrik@henriknordstrom.net>
*
#if HAVE_CONFIG_H
#include "config.h"
#endif
+#include "helpers/defines.h"
#include <sys/types.h>
#include <sys/stat.h>
{
db = dbopen(db_path, O_CREAT | O_RDWR, 0666, DB_BTREE, NULL);
if (!db) {
- fprintf(stderr, "%s: Failed to open session db '%s'\n", program_name, db_path);
+ fprintf(stderr, "FATAL: %s: Failed to open session db '%s'\n", program_name, db_path);
exit(1);
}
}
int session_is_active = 0;
-static int session_active(const char *details)
+static int session_active(const char *details, size_t len)
{
DBT key, data;
key.data = (void *)details;
- key.size = strlen(details);
+ key.size = len;
if (db->get(db, &key, &data, 0) == 0) {
time_t timestamp;
if (data.size != sizeof(timestamp)) {
- fprintf(stderr, "%s: CORRUPTED DATABASE (%s)\n", program_name, details);
+ fprintf(stderr, "ERROR: %s: CORRUPTED DATABASE (%s)\n", program_name, details);
db->del(db, &key, 0);
return 0;
}
return 0;
}
-static void session_login(const char *details)
+static void session_login(const char *details, size_t len)
{
DBT key, data;
time_t now = time(NULL);
key.data = (void *)details;
- key.size = strlen(details);
+ key.size = len;
data.data = &now;
data.size = sizeof(now);
db->put(db, &key, &data, 0);
}
-static void session_logout(const char *details)
+static void session_logout(const char *details, size_t len)
{
DBT key;
key.data = (void *)details;
- key.size = strlen(details);
+ key.size = len;
db->del(db, &key, 0);
}
}
int main(int argc, char **argv)
{
- char request[256];
+ char request[HELPER_INPUT_BUFFER];
int opt;
int default_action = 1;
init_db();
- while (fgets(request, sizeof(request), stdin)) {
- const char *user_key, *detail;
- char *lastdetail;
+ while (fgets(request, HELPER_INPUT_BUFFER, stdin)) {
int action = 0;
- user_key = strtok(request, " \n");
- detail = strtok(NULL, "\n");
- lastdetail = strrchr(detail, ' ');
+ const char *user_key = strtok(request, " \n");
+ const char *detail = strtok(NULL, "\n");
+ const char *lastdetail = strrchr(detail, ' ');
+ size_t detail_len;
if (lastdetail) {
if (strcmp(lastdetail, " LOGIN") == 0) {
- *lastdetail++ = '\0';
action = 1;
+ detail_len = (size_t)(lastdetail-detail);
} else if (strcmp(lastdetail, " LOGOUT") == 0) {
action = -1;
- *lastdetail++ = '\0';
+ detail_len = (size_t)(lastdetail-detail);
}
}
if (action == -1) {
- session_logout(detail);
+ session_logout(detail, detail_len);
printf("%s OK message=\"Bye\"\n", user_key);
} else if (action == 1) {
- session_login(detail);
+ session_login(detail, detail_len);
printf("%s OK message=\"Welcome\"\n", user_key);
- } else if (session_active(detail)) {
- session_login(detail);
+ } else if (session_active(detail, detail_len)) {
+ session_login(detail, detail_len);
printf("%s OK\n", user_key);
} else if (default_action == 1) {
- session_login(detail);
+ session_login(detail, detail_len);
printf("%s ERR message=\"Welcome\"\n", user_key);
} else {
printf("%s ERR message=\"No session available\"\n", user_key);
include $(top_srcdir)/src/Common.am
-## we need our local files too (but avoid -I. at all costs)
-INCLUDES += -I$(srcdir)
-
-
-libexec_PROGRAMS = squid_unix_group
-man_MANS = squid_unix_group.8
-EXTRA_DIST = squid_unix_group.8 config.test
-squid_unix_group_SOURCES = check_group.c
+libexec_PROGRAMS = ext_unix_group_acl
+man_MANS = ext_unix_group_acl.8
+EXTRA_DIST = ext_unix_group_acl.8 config.test
+ext_unix_group_acl_SOURCES = check_group.cc
LDADD = \
- $(top_builddir)/compat/libcompat.la \
- -L$(top_builddir)/lib -lmiscutil \
+ $(COMPAT_LIB) \
$(XTRA_LIBS)
+++ /dev/null
-$Id$
-
-This is the README file for check_group, an external
-helper fo the External ACL Scheme for Squid.
-
-More information about the External ACL scheme may
-be found at http://devel.squid-cache.org/external_acl/
-
-This program reads one new line terminated argument in the
-standard input (the username and groups) and tries to match it against
-several command-line specified groups.
-
-The syntax for the program is as follows:
-
-check_group [-g group1 -g group2 -g group3 ...] [-p]
-
-You may specify up to 11 different groups, this limit may be
-increased by changing the MAX_GROUP define in the source code
-and recompiling the program.
-
-To compile this program, use:
-
-gcc -o check_group check_group.c
-
-
-You may specify the group names in the acl, as follows:
-
-acl ckgroup external ckgroup_helper %LOGIN group1 group2 group3
-
-
-You may get the latest release and more information about this
-program at http://geekbunker.org/rodrigo/check_group.html
-
-
---
-Rodrigo Campos
-rodrigo@geekbunker.org
* Initial revision
*
*/
-
+#include "config.h"
+#include "helpers/defines.h"
#include "rfc1738.h"
#include "util.h"
+#if HAVE_STDIO_H
#include <stdio.h>
-#include <stdlib.h>
+#endif
+#if HAVE_STRING_H
#include <string.h>
-#include <sys/types.h>
+#endif
+#if HAVE_GRP_H
#include <grp.h>
+#endif
+#if HAVE_UNISTD_H
#include <unistd.h>
+#endif
+#if HAVE_PWD_H
#include <pwd.h>
+#endif
+#if HAVE_CTYPE_H
#include <ctype.h>
-
-#define BUFSIZE 8192 /* the stdin buffer size */
+#endif
/*
* Verify if user“s primary group matches groupname
if ((p = getpwnam(username)) == NULL) {
/* Returns an error if user does not exist in the /etc/passwd */
- fprintf(stderr, "helper: User does not exist '%s'\n", username);
+ fprintf(stderr, "ERROR: User does not exist '%s'\n", username);
return 0;
} else {
/* Verify if the this is the primary user group */
struct group *g;
if ((g = getgrnam(groupname)) == NULL) {
- fprintf(stderr, "helper: Group does not exist '%s'\n",
- groupname);
+ fprintf(stderr, "ERROR: Group does not exist '%s'\n", groupname);
return 0;
} else {
while (*(g->gr_mem) != NULL) {
main(int argc, char *argv[])
{
char *user, *suser, *p;
- char buf[BUFSIZE];
+ char buf[HELPER_INPUT_BUFFER];
char **grents = NULL;
int check_pw = 0, ch, ngroups = 0, i, j = 0, strip_dm = 0;
setvbuf(stdout, NULL, _IOLBF, 0);
/* get user options */
- while ((ch = getopt(argc, argv, "spg:")) != -1) {
+ while ((ch = getopt(argc, argv, "dspg:")) != -1) {
switch (ch) {
+ case 'd':
+ debug_enabled = 1;
+ break;
case 's':
strip_dm = 1;
break;
check_pw = 1;
break;
case 'g':
- grents = realloc(grents, sizeof(*grents) * (ngroups+1));
+ grents = (char**)realloc(grents, sizeof(*grents) * (ngroups+1));
grents[ngroups++] = optarg;
break;
case '?':
}
}
if (optind < argc) {
- fprintf(stderr, "Unknown option '%s'\n", argv[optind]);
+ fprintf(stderr, "FATAL: Unknown option '%s'\n", argv[optind]);
usage(argv[0]);
exit(1);
}
- while (fgets(buf, sizeof(buf), stdin)) {
+ while (fgets(buf, HELPER_INPUT_BUFFER, stdin)) {
j = 0;
if ((p = strchr(buf, '\n')) == NULL) {
/* too large message received.. skip and deny */
- fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], buf);
+ fprintf(stderr, "ERROR: %s: Too large: %s\n", argv[0], buf);
while (fgets(buf, sizeof(buf), stdin)) {
- fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], buf);
+ fprintf(stderr, "ERROR: %s: Too large..: %s\n", argv[0], buf);
if (strchr(buf, '\n') != NULL)
break;
}
- goto error;
+ SEND_ERR("Username Input too large.");
+ continue;
}
*p = '\0';
if ((p = strtok(buf, " ")) == NULL) {
- goto error;
+ SEND_ERR("No username given.");
+ continue;
} else {
user = p;
rfc1738_unescape(user);
}
if (j > 0) {
- printf("OK\n");
+ SEND_OK("");
} else {
-error:
- printf("ERR\n");
+ SEND_ERR("");
}
}
return 0;
-.if !'po4a'hide' .TH squid_unix_group 8 "12 August 2002"
+.if !'po4a'hide' .TH ext_unix_group_acl 8 "12 August 2002"
.
.SH NAME
-.if !'po4a'hide' .B squid_unix_group
+.if !'po4a'hide' .B ext_unix_group_acl
.if !'po4a'hide' \-
-Squid UNIX Group helper
+Squid UNIX Group ACL helper
.
.SH SYNOPSIS
-.if !'po4a'hide' .B "squid_unix_group [\-g "
+.if !'po4a'hide' .B "ext_unix_group_acl [\-d] [\-g "
group
.if !'po4a'hide' .B "] [\-g "
group
-.if !'po4a'hide' .B "...] [\-p] [\-s]"
+.if !'po4a'hide' .B " ...] [\-p] [\-s]"
.
.SH DESCRIPTION
-.B squid_unix_group
+.B ext_unix_group_acl
allows Squid to base access controls on users memberships in UNIX groups.
.
.SH OPTIONS
.if !'po4a'hide' .TP
+.if !'po4a'hide' .BI "\-d "
+Write debug info to stderr.
+.
.if !'po4a'hide' .BI "\-g " "group "
Specifies a group name to match.
.
or
.I group3
.if !'po4a'hide' .RS
-.if !'po4a'hide' .IP external_acl_type unix_group %LOGIN /usr/local/squid/libexec/squid_unix_group -p
+.if !'po4a'hide' .IP external_acl_type unix_group %LOGIN /usr/local/squid/libexec/ext_unix_group_acl -p
.if !'po4a'hide' .IP acl usergroup1 external unix_group group1
.if !'po4a'hide' .IP acl usergroup2 external unix_group group2 group3
.if !'po4a'hide' .RE
.br
The Squid Configuration Manual
.if !'po4a'hide' http://www.squid-cache.org/Doc/config/
-
-libexec_SCRIPTS = wbinfo_group.pl
-#man_MANS = squid_wbinfo_group.8
-#EXTRA_DIST = squid_wbinfo_group.8
-EXTRA_DIST = wbinfo_group.pl config.test
+include $(top_srcdir)/src/Common.am
+
+libexec_SCRIPTS = ext_wbinfo_group_acl
+EXTRA_DIST = ext_wbinfo_group_acl.pl.in config.test
+
+ext_wbinfo_group_acl: ext_wbinfo_group_acl.pl.in
+ $(subst_perlshell)
+
+EXTRA_DIST += ext_wbinfo_group_acl.8
+man_MANS = ext_wbinfo_group_acl.8
+
+ext_wbinfo_group_acl.8: ext_wbinfo_group_acl.pl.in
+ pod2man $(srcdir)/ext_wbinfo_group_acl.pl.in ext_wbinfo_group_acl.8
-#!/usr/bin/perl -w
+#!@PERL@ -w
#
# external_acl helper to Squid to verify NT Domain group
# membership using wbinfo
#
# 2002-07-05 Jerry Murdock <jmurdock@itraktech.com>
# Initial release
+=pod
+=head1 NAME
+
+ext_wbinfo_group_acl - external ACL helper for Squid to verify NT Domain group membership using wbinfo.
+
+=head1 SYNOPSIS
+
+ext_wbinfo_group_acl [-dh]
+
+=head1 DESCRIPTION
+
+ext_wbinfo_group_acl is an installed executable script.
+It uses wbinfo from Samba to lookup group membership of logged in users.
+
+This helper must be used in with an authentication scheme (typically
+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 each against the groups membership of the specified
+username.
+
+=head1 OPTIONS
+
+ -d Write debug info to stderr.
+ -h Print the help.
+
+=head1 CONFIGURATION
+
+ external_acl_type wbinfo_check %LOGIN /path/to/ext_wbinfo_group_acl
+ acl allowed_group external wbinfo_check Group1 Group2
+ http_access allow allowed_group
+
+If the local perl interpreter is in a unusual location it may need to be added:
+
+ external_acl_type wbinfo_check %LOGIN /path/to/perl /path/to/ext_wbinfo_group_acl
+
+=head1 AUTHOR
+
+This program was written by Jerry Murdock <jmurdock@itraktech.com>
+
+This manual was written by Amos Jeffries <amosjeffries@squid-cache.org>
+
+=head1 COPYRIGHT
+
+This program is put in the public domain by Jerry Murdock
+<jmurdock@itraktech.com>. It 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.
+
+=head1 QUESTIONS
+
+Questions on the usage of this program can be sent to the
+Squid Users mailing list <squid-users@squid-cache.org>
+
+=head1 REPORTING BUGS
+
+Bug reports need to be made in English.
+See http://wiki.squid-cache.org/SquidFaq/BugReporting for details of what you need to include with your bug report.
+
+Report bugs or bug fixes using http://bugs.squid-cache.org/
+
+Report serious security bugs to Squid Bugs <squid-bugs@squid-cache.org>
+
+Report ideas for new improvements to the
+Squid Developers mailing list <squid-dev@squid-cache.org>
+
+=head1 SEE ALSO
+
+The Squid FAQ wiki http://wiki.squid-cache.org/SquidFaq
+
+The Squid Configuration Manual http://www.squid-cache.org/Doc/config/
+
+=cut
#
# Globals
#
sub usage()
{
- print "Usage: wbinfo_group.pl -dh\n";
+ print "Usage: ext_wbinfo_group_acl -dh\n";
print "\t-d enable debugging\n";
print "\t-h print the help\n";
exit;
&debug("Sending $ans to squid");
print "$ans\n";
}
-