#
# Makefile for the Squid LDAP authentication helper
#
-# $Id: Makefile.am,v 1.1 2002/07/06 12:23:14 hno Exp $
+# $Id: Makefile.am,v 1.2 2002/08/12 13:56:35 hno Exp $
#
# Uncomment and customize the following to suit your needs:
#
libexec_PROGRAMS = squid_unix_group
-#man_MANS = squid_unix_group.8
-#EXTRA_DIST = squid_unix_group.8
-squid_unix_group_SOURCES = check_group-1.0.c
+man_MANS = squid_unix_group.8
+EXTRA_DIST = squid_unix_group.8
+squid_unix_group_SOURCES = check_group.c
#
# Makefile for the Squid LDAP authentication helper
#
-# $Id: Makefile.in,v 1.1 2002/07/06 12:28:45 hno Exp $
+# $Id: Makefile.in,v 1.2 2002/08/12 13:56:35 hno Exp $
#
# Uncomment and customize the following to suit your needs:
#
makesnmplib = @makesnmplib@
libexec_PROGRAMS = squid_unix_group
-#man_MANS = squid_unix_group.8
-#EXTRA_DIST = squid_unix_group.8
-squid_unix_group_SOURCES = check_group-1.0.c
+man_MANS = squid_unix_group.8
+EXTRA_DIST = squid_unix_group.8
+squid_unix_group_SOURCES = check_group.c
subdir = helpers/external_acl/unix_group
mkinstalldirs = $(SHELL) $(top_srcdir)/cfgaux/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/include/autoconf.h
libexec_PROGRAMS = squid_unix_group$(EXEEXT)
PROGRAMS = $(libexec_PROGRAMS)
-am_squid_unix_group_OBJECTS = check_group-1.0.$(OBJEXT)
+am_squid_unix_group_OBJECTS = check_group.$(OBJEXT)
squid_unix_group_OBJECTS = $(am_squid_unix_group_OBJECTS)
squid_unix_group_LDADD = $(LDADD)
squid_unix_group_DEPENDENCIES =
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
depcomp = $(SHELL) $(top_srcdir)/cfgaux/depcomp
-@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/check_group-1.0.Po
+@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/check_group.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
CFLAGS = @CFLAGS@
DIST_SOURCES = $(squid_unix_group_SOURCES)
+
+NROFF = nroff
+MANS = $(man_MANS)
DIST_COMMON = README Makefile.am Makefile.in
SOURCES = $(squid_unix_group_SOURCES)
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/check_group-1.0.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/check_group.Po@am__quote@
distclean-depend:
-rm -rf $(DEPDIR)
CCDEPMODE = @CCDEPMODE@
uninstall-info-am:
+man8dir = $(mandir)/man8
+install-man8: $(man8_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(man8dir)
+ @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
+ done
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
+ rm -f $(DESTDIR)$(man8dir)/$$inst; \
+ done
+
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
done
check-am: all-am
check: check-am
-all-am: Makefile $(PROGRAMS)
+all-am: Makefile $(PROGRAMS) $(MANS)
installdirs:
- $(mkinstalldirs) $(DESTDIR)$(libexecdir)
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir) $(DESTDIR)$(man8dir)
install: install-am
install-exec: install-exec-am
info-am:
-install-data-am:
+install-data-am: install-man
install-exec-am: install-libexecPROGRAMS
install-info: install-info-am
-install-man:
+install-man: install-man8
installcheck-am:
mostlyclean-am: mostlyclean-compile mostlyclean-generic
-uninstall-am: uninstall-info-am uninstall-libexecPROGRAMS
+uninstall-am: uninstall-info-am uninstall-libexecPROGRAMS uninstall-man
+
+uninstall-man: uninstall-man8
.PHONY: GTAGS all all-am check check-am clean clean-generic \
clean-libexecPROGRAMS distclean distclean-compile \
dvi-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-libexecPROGRAMS install-man \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic tags uninstall \
- uninstall-am uninstall-info-am uninstall-libexecPROGRAMS
+ install-man8 install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic tags \
+ uninstall uninstall-am uninstall-info-am \
+ uninstall-libexecPROGRAMS uninstall-man uninstall-man8
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
-$Id: README,v 1.1 2002/06/23 14:31:09 hno Exp $
+$Id: README,v 1.2 2002/08/12 13:56:35 hno Exp $
This is the README file for check_group, an external
helper fo the External ACL Scheme for Squid.
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 tries to match it against
+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]
+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
To compile this program, use:
-gcc -o check_group check_group-1.0.c
+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
--- /dev/null
+/*
+ * $Id: check_group.c,v 1.1 2002/08/12 13:56:35 hno Exp $
+ *
+ * This is a helper for the external ACL interface for Squid Cache
+ * Copyright (C) 2002 Rodrigo Albani de Campos (rodrigo@geekbunker.org)
+ *
+ * It reads STDIN looking for a username that matches a specified group
+ * Returns `OK' if the user belongs to the group or `ERR' otherwise, as
+ * described on http://devel.squid-cache.org/external_acl/config.html
+ * To compile this program, use:
+ *
+ * gcc -o check_group check_group.c
+ *
+ * Author: Rodrigo Albani de Campos
+ * E-Mail: rodrigo@geekbunker.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Change Log:
+ * Revision 1.6 2002/08/12 15:48:32 hno
+ * imported strwordtok from Squid, added man page, some minor fixes
+ *
+ * Revision 1.5 2002/07/27 14:26:49 rcampos
+ * allow groups to be sent on stdin
+ *
+ * Revision 1.4 2002/04/17 01:58:48 camposr
+ * minor corrections in the getopt
+ *
+ * Revision 1.3 2002/04/17 01:43:17 camposr
+ * ready for action
+ *
+ * Revision 1.2 2002/04/17 01:32:16 camposr
+ * all main routines ready
+ *
+ * Revision 1.1 2002/04/16 05:02:32 camposr
+ * Initial revision
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <grp.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <ctype.h>
+
+
+#define BUFSIZE 8192 /* the stdin buffer size */
+#define MAX_GROUP 10 /* maximum number of groups specified
+ * on the command line */
+
+
+/*
+ * Library function to split external_acl messages into tokens
+ * Copied from the Squid sources
+ */
+static char *
+strwordtok(char *buf, char **t)
+{
+ unsigned char *word = NULL;
+ unsigned char *p = (unsigned char *) buf;
+ unsigned char *d;
+ unsigned char ch;
+ int quoted = 0;
+ if (!p)
+ p = (unsigned char *) *t;
+ if (!p)
+ goto error;
+ while (*p && isspace(*p))
+ p++;
+ if (!*p)
+ goto error;
+ word = d = p;
+ while ((ch = *p)) {
+ switch (ch) {
+ case '\\':
+ p++;
+ *d++ = ch = *p;
+ if (ch)
+ p++;
+ break;
+ case '"':
+ quoted = !quoted;
+ p++;
+ default:
+ if (!quoted && isspace(*p)) {
+ p++;
+ goto done;
+ }
+ *d++ = *p++;
+ break;
+ }
+ }
+ done:
+ *d++ = '\0';
+ error:
+ *t = (char *) p;
+ return (char *) word;
+}
+
+
+/*
+ * Verify if user“s primary group matches groupname
+ * Returns 0 if user is not on the group
+ * Returns 1 otherwise
+ */
+static int
+validate_user_pw(char *username, char *groupname)
+{
+ struct passwd *p;
+ struct group *g;
+
+ 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);
+ return 0;
+ } else {
+ /* Verify if the this is the primary user group */
+ if ((g = getgrgid(p->pw_gid)) != NULL) {
+ if ((strcmp(groupname, g->gr_name)) == 0)
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+validate_user_gr(char *username, char *groupname)
+{
+ /*
+ * Verify if the user belongs to groupname as listed in the
+ * /etc/group file
+ */
+ struct group *g;
+
+ if ((g = getgrnam(groupname)) == NULL) {
+ fprintf(stderr, "helper: Group does not exist '%s'\n",
+ groupname);
+ return 0;
+ } else {
+ while (*(g->gr_mem) != NULL) {
+ if (strcmp(*((g->gr_mem)++), username) == 0) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+static void
+usage(char *program)
+{
+ fprintf(stderr, "Usage: %s -g group1 [-g group2 ...] [-p]\n\n",
+ program);
+ fprintf(stderr, "-g group\n");
+ fprintf(stderr,
+ " The group name or id that the user must belong in order to\n");
+ fprintf(stderr,
+ " be allowed to authenticate.\n");
+ fprintf(stderr,
+ "-p Verify primary user group as well\n");
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ char *user, *p, *t;
+ char buf[BUFSIZE];
+ char *grents[MAX_GROUP];
+ int check_pw = 0, ch, i = 0, j = 0;
+
+ /* make standard output line buffered */
+ setvbuf(stdout, NULL, _IOLBF, 0);
+
+ /* get user options */
+ while ((ch = getopt(argc, argv, "pg:")) != -1) {
+ switch (ch) {
+ case 'p':
+ check_pw = 1;
+ break;
+ case 'g':
+ grents[i] = calloc(strlen(optarg) + 1, sizeof(char));
+ strcpy(grents[i], optarg);
+ if (i < MAX_GROUP) {
+ i++;
+ } else {
+ fprintf(stderr,
+ "Exceeded maximum number of allowed groups (%i)\n", i);
+ exit(1);
+ }
+ break;
+ case '?':
+ if (isprint(optopt)) {
+
+ fprintf(stderr, "Unknown option '-%c'.\n", optopt);
+ } else {
+ fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
+ }
+
+ default:
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+ if (optind < argc) {
+ fprintf(stderr, "Unknown option '%s'\n", argv[optind]);
+ usage(argv[0]);
+ exit(1);
+ }
+ while (fgets(buf, BUFSIZE, stdin)) {
+ j = 0;
+ if ((p = strchr(buf, '\n')) != NULL) {
+ *p = '\0';
+ } else {
+ /* too large message received.. skip and deny */
+ fprintf(stderr, "%s: ERROR: Too large: %s\n", argv[0], buf);
+ while (fgets(buf, BUFSIZE, stdin)) {
+ fprintf(stderr, "%s: ERROR: Too large..: %s\n", argv[0], buf);
+ if (strchr(buf, '\n') != NULL)
+ break;
+ }
+ goto error;
+ }
+ if ((p = strwordtok(buf, &t)) == NULL) {
+ goto error;
+ } else {
+ user = p;
+ /* check groups supplied by Squid */
+ while ((p = strwordtok(NULL, &t)) != NULL) {
+ if (check_pw == 1)
+ j += validate_user_pw(user, p);
+
+ j += validate_user_gr(user, p);
+ }
+ }
+
+ /* check groups supplied on the command line */
+ for (i = 0; grents[i] != NULL; i++) {
+ if (check_pw == 1) {
+ j += validate_user_pw(user, grents[i]);
+ }
+ j += validate_user_gr(user, grents[i]);
+ }
+
+ if (j > 0) {
+ printf("OK\n");
+ } else {
+error:
+ printf("ERR\n");
+ }
+ }
+ return 0;
+}
--- /dev/null
+.TH squid_unix_group 8 "12 August 2002" "Squid UNIX Group helper"
+.
+.SH NAME
+squid_unix_group - Squid UNIX Group external_acl helper
+.
+.SH SYNOPSIS
+squid_unix_group [-g groupname] [-g groupname...] [-p]
+.
+.SH DESCRIPTION
+This helper allows Squid to base access controls on users
+memberships in UNIX groups.
+.
+.TP
+.BI "-g " "groupname "
+Specifies a group name to match.
+.
+.TP
+.BI "-p"
+Also match the users primary group from /etc/passwd
+.
+.SH EXAMPLES
+.
+This squid.conf example defines two Squid acls. usergroup1 matches users in group1, and usergroup2
+matches users in group2 or group3
+.IP
+external_acl_type unix_group %LOGIN /usr/local/squid/libexec/squid_unix_group -p
+.IP
+acl usergroup1 external unix_group group1
+.IP
+acl usergroup2 external unix_group group2 group3
+.
+.SH NOTES
+.
+By default up to 11 groups can be matched in one acl (including commandline specified
+groups). This limit is defined by MAX_GROUPS in the source code.
+.
+.SH AUTHOR
+This manual page was written by
+.I Henrik Nordstrom <hno@squid-cache.org>
+.P
+squid_unix_group is written by
+.I Rodrigo Campos <rodrigo@geekbunker.org>
+.
+.SH KNOWN ISSUES
+Does not understand gid aliased groups sometimes used to work around groups size
+limitations. If you are using gid aliased groups then you must specify each alias
+by name.
+.
+.SH QUESTIONS
+Any questions on usage can be sent to
+.IR "Squid Users <squid-users@squid-cache.org>"
+.
+.SH REPORTING BUGS
+Report bugs or bug-fixes to
+.I Rodrigo Campos <rodrigo@geekbunker.org>
+or
+.I Squid Developers <squid-dev@squid-cache.org>
+.
+.SH "SEE ALSO"
+.BR group ( 5 ), passwd ( 5 )