]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Updated UNIX group helper
authorhno <>
Mon, 12 Aug 2002 19:56:35 +0000 (19:56 +0000)
committerhno <>
Mon, 12 Aug 2002 19:56:35 +0000 (19:56 +0000)
helpers/external_acl/unix_group/Makefile.am
helpers/external_acl/unix_group/Makefile.in
helpers/external_acl/unix_group/README
helpers/external_acl/unix_group/check_group.c [new file with mode: 0644]
helpers/external_acl/unix_group/squid_unix_group.8 [new file with mode: 0644]

index bff957d718d34c8afeab1a547f0d55d4eb4fbaf6..51cb88b6403e60d7fe2ff44cf6c2c866180301e7 100644 (file)
@@ -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
index 99402d1828808d96ca4e096d70e83e6a30453b05..47714243e3fc9fc0acf96f28b0861460e0f8566a 100644 (file)
@@ -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.
index e70be28d9c06f5d4559f7f47c980fb4e19bac8b5..d365be59df8c93758b19aadd364b4762d59b2688 100644 (file)
@@ -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 (file)
index 0000000..2a3b5c0
--- /dev/null
@@ -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 <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;
+}
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 (file)
index 0000000..b1a73ae
--- /dev/null
@@ -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 <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 )