From 6328cedceb815cfc5537237fe58fe2023e0ed6b7 Mon Sep 17 00:00:00 2001 From: hno <> Date: Mon, 12 Aug 2002 19:56:35 +0000 Subject: [PATCH] Updated UNIX group helper --- helpers/external_acl/unix_group/Makefile.am | 8 +- helpers/external_acl/unix_group/Makefile.in | 77 +++-- helpers/external_acl/unix_group/README | 14 +- helpers/external_acl/unix_group/check_group.c | 269 ++++++++++++++++++ .../unix_group/squid_unix_group.8 | 60 ++++ 5 files changed, 403 insertions(+), 25 deletions(-) create mode 100644 helpers/external_acl/unix_group/check_group.c create mode 100644 helpers/external_acl/unix_group/squid_unix_group.8 diff --git a/helpers/external_acl/unix_group/Makefile.am b/helpers/external_acl/unix_group/Makefile.am index bff957d718..51cb88b640 100644 --- a/helpers/external_acl/unix_group/Makefile.am +++ b/helpers/external_acl/unix_group/Makefile.am @@ -1,12 +1,12 @@ # # 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 diff --git a/helpers/external_acl/unix_group/Makefile.in b/helpers/external_acl/unix_group/Makefile.in index 99402d1828..47714243e3 100644 --- a/helpers/external_acl/unix_group/Makefile.in +++ b/helpers/external_acl/unix_group/Makefile.in @@ -16,7 +16,7 @@ # # 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: # @@ -124,9 +124,9 @@ install_sh = @install_sh@ 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 @@ -134,7 +134,7 @@ CONFIG_CLEAN_FILES = 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 = @@ -146,13 +146,16 @@ CPPFLAGS = @CPPFLAGS@ 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) @@ -200,7 +203,7 @@ mostlyclean-compile: 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) @@ -219,6 +222,45 @@ distclean-depend: 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) @@ -274,10 +316,10 @@ distdir: $(DISTFILES) 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 @@ -319,13 +361,13 @@ info: info-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: @@ -337,7 +379,9 @@ mostlyclean: mostlyclean-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 \ @@ -345,10 +389,11 @@ uninstall-am: uninstall-info-am uninstall-libexecPROGRAMS 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. diff --git a/helpers/external_acl/unix_group/README b/helpers/external_acl/unix_group/README index e70be28d9c..d365be59df 100644 --- a/helpers/external_acl/unix_group/README +++ b/helpers/external_acl/unix_group/README @@ -1,4 +1,4 @@ -$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. @@ -7,13 +7,12 @@ 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 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 @@ -21,7 +20,12 @@ and recompiling the program. 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 diff --git a/helpers/external_acl/unix_group/check_group.c b/helpers/external_acl/unix_group/check_group.c new file mode 100644 index 0000000000..2a3b5c09e9 --- /dev/null +++ b/helpers/external_acl/unix_group/check_group.c @@ -0,0 +1,269 @@ +/* + * $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 +#include +#include +#include +#include +#include +#include +#include + + +#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; +} diff --git a/helpers/external_acl/unix_group/squid_unix_group.8 b/helpers/external_acl/unix_group/squid_unix_group.8 new file mode 100644 index 0000000000..b1a73aeeaf --- /dev/null +++ b/helpers/external_acl/unix_group/squid_unix_group.8 @@ -0,0 +1,60 @@ +.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 +.P +squid_unix_group is written by +.I Rodrigo Campos +. +.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 " +. +.SH REPORTING BUGS +Report bugs or bug-fixes to +.I Rodrigo Campos +or +.I Squid Developers +. +.SH "SEE ALSO" +.BR group ( 5 ), passwd ( 5 ) -- 2.47.2