]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
ext_kerberos_ldap_group_acl version 1.3.0sq
authorMarkus Moeller <huaraz@moeller.plus.com>
Mon, 14 Mar 2011 06:08:24 +0000 (00:08 -0600)
committerAmos Jeffries <squid3@treenet.co.nz>
Mon, 14 Mar 2011 06:08:24 +0000 (00:08 -0600)
helpers/external_acl/kerberos_ldap_group/Makefile.am
helpers/external_acl/kerberos_ldap_group/ext_kerberos_ldap_group_acl.8
helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc
helpers/external_acl/kerberos_ldap_group/support.h
helpers/external_acl/kerberos_ldap_group/support_lserver.cc [new file with mode: 0644]
helpers/external_acl/kerberos_ldap_group/support_resolv.cc

index 70950ef3b322b611417a67c21a11248df9f642ed..29da57bde2c0eb19464577f23d2dc0e1aabcb95a 100644 (file)
@@ -19,6 +19,7 @@ ext_kerberos_ldap_group_acl_SOURCES = \
        support_ldap.cc \
        support_sasl.cc \
        support_resolv.cc \
+       support_lserver.cc \
        support_log.cc
 
 ext_kerberos_ldap_group_acl_LDFLAGS =
index 83f4fb3f581f43314a4920f8e396bf26a7256d35..28ac97a2df868b4e149109a17cd632e9e3bb088a 100644 (file)
@@ -5,11 +5,11 @@
 .if !'po4a'hide' \-
 Squid LDAP external acl group helper for Kerberos or NTLM credentials.
 .PP
-Version 1.2.2sq
+Version 1.3.0sq
 .
 .SH SYNOPSIS
 .if !'po4a'hide' .B ext_kerberos_ldap_group_acl
-.if !'po4a'hide' .B [\-h] [\-d] [\-i] [\-s] [\-a] [\-D Realm ] [\-N Netbios-Realm-List] [\-m Max-Depth] [\-u Ldap-User] [\-p Ldap-Password] [\-b Ldap-Bind-Path] [\-l Ldap-URL] \-g Group-Realm-List \-t  Hex-Group-Realm-List \-T Hex-Group-Hex-Realm-List 
+.if !'po4a'hide' .B [\-h] [\-d] [\-i] [\-s] [\-a] [\-D Realm ] [\-N Netbios-Realm-List] [\-m Max-Depth] [\-u Ldap-User] [\-p Ldap-Password] [\-b Ldap-Bind-Path] [\-l Ldap-URL] [\-S ldap server list] \-g Group-Realm-List \-t  Hex-Group-Realm-List \-T Hex-Group-Hex-Realm-List 
 .
 .SH DESCRIPTION
 .B ext_kerberos_ldap_group_acl
@@ -96,6 +96,10 @@ LDAP server bind path.
 .if !'po4a'hide' .B \-u Ldap-URL
 LDAP server URL in form ldap[s]://server:port
 .if !'po4a'hide' .TP 12
+.if !'po4a'hide' .B \-S ldap server list
+list of ldap servers of the form
+lserver|lserver@|lserver@Realm[:lserver@|lserver@Realm]
+.if !'po4a'hide' .TP 12
 .if !'po4a'hide' .B \-g Group-Realm-List
 A list of group name per Kerberos domain of the form 
 Group|Group@|Group@Realm[:Group@|Group@Realm]
@@ -190,6 +194,12 @@ The REALM must still be based on the ASCII character set. If REALM contains also
 
 For a translation of hex UTF-8 see for example http://www.utf8-chartable.de/unicode-utf8-table.pl
 
+The ldap server list can be:
+server - In this case server can be used for all Kerberos domains
+server@  - In this case server can be used for all Kerberos domains
+server@domain  - In this case server can be used for Kerberos domain domain
+server1a@domain1:server1b@domain1:server2@domain2:server3@:server4 - A list is build with a colon as seperator
+
 .
 .SH AUTHOR
 This program was written by
index 7019bcb45d2ee97e425c377c999a12717dc800c2..bcef9b859c8b85ff4c6aabf118eac4f66406a917 100644 (file)
@@ -45,6 +45,7 @@ init_args(struct main_args *margs)
 {
     margs->nlist = NULL;
     margs->glist = NULL;
+    margs->llist = NULL;
     margs->ulist = NULL;
     margs->tlist = NULL;
     margs->luser = NULL;
@@ -58,41 +59,42 @@ init_args(struct main_args *margs)
     margs->ddomain = NULL;
     margs->groups = NULL;
     margs->ndoms = NULL;
+    margs->lservs = NULL;
 }
 
 void clean_gd(struct gdstruct *gdsp);
 void clean_nd(struct ndstruct *ndsp);
+void clean_ls(struct ndstruct *lssp);
 
 void
 clean_gd(struct gdstruct *gdsp)
 {
     struct gdstruct *p = NULL, *pp = NULL;
 
-start:
     p = gdsp;
-    if (!p)
-        return;
-    while (p->next) {
-        pp = p;
-        p = p->next;
-    }
-    if (p->group) {
-        xfree(p->group);
-        p->group = NULL;
-    }
-    if (p->domain) {
-        xfree(p->domain);
-        p->domain = NULL;
-    }
-    if (pp && pp->next) {
-        xfree(pp->next);
-        pp->next = NULL;
-    }
-    if (p == gdsp) {
-        xfree(gdsp);
-        gdsp = NULL;
+    while (p) {
+        while (p->next) {
+            pp = p;
+            p = p->next;
+        }
+        if (p->group) {
+            xfree(p->group);
+            p->group = NULL;
+        }
+        if (p->domain) {
+            xfree(p->domain);
+            p->domain = NULL;
+        }
+        if (pp && pp->next) {
+            xfree(pp->next);
+            pp->next = NULL;
+        }
+        if (p == gdsp) {
+            xfree(gdsp);
+            gdsp = NULL;
+        }
+        p = gdsp;
     }
-    goto start;
 }
 
 void
@@ -100,31 +102,61 @@ clean_nd(struct ndstruct *ndsp)
 {
     struct ndstruct *p = NULL, *pp = NULL;
 
-start:
     p = ndsp;
-    if (!p)
-        return;
-    while (p->next) {
-        pp = p;
-        p = p->next;
-    }
-    if (p->netbios) {
-        xfree(p->netbios);
-        p->netbios = NULL;
-    }
-    if (p->domain) {
-        xfree(p->domain);
-        p->domain = NULL;
-    }
-    if (pp && pp->next) {
-        xfree(pp->next);
-        pp->next = NULL;
+    while (p) {
+        while (p->next) {
+            pp = p;
+            p = p->next;
+        }
+        if (p->netbios) {
+            xfree(p->netbios);
+            p->netbios = NULL;
+        }
+        if (p->domain) {
+            xfree(p->domain);
+            p->domain = NULL;
+        }
+        if (pp && pp->next) {
+            xfree(pp->next);
+            pp->next = NULL;
+        }
+        if (p == ndsp) {
+            xfree(ndsp);
+            ndsp = NULL;
+        }
+        p = ndsp;
     }
-    if (p == ndsp) {
-        xfree(ndsp);
-        ndsp = NULL;
+}
+
+void
+clean_ls(struct lsstruct *lssp)
+{
+    struct lsstruct *p = NULL, *pp = NULL;
+
+    p = lssp;
+    while (p) {
+        while (p->next) {
+            pp = p;
+            p = p->next;
+        }
+        if (p->lserver) {
+            xfree(p->lserver);
+            p->lserver = NULL;
+        }
+        if (p->domain) {
+            xfree(p->domain);
+            p->domain = NULL;
+        }
+        if (pp && pp->next) {
+            xfree(pp->next);
+            pp->next = NULL;
+        }
+        if (p == lssp) {
+            xfree(lssp);
+            lssp = NULL;
+        }
+        p = lssp;
     }
-    goto start;
 }
 
 void
@@ -146,6 +178,10 @@ clean_args(struct main_args *margs)
         xfree(margs->nlist);
         margs->nlist = NULL;
     }
+    if (margs->llist) {
+        xfree(margs->llist);
+        margs->llist = NULL;
+    }
     if (margs->luser) {
         xfree(margs->luser);
         margs->luser = NULL;
@@ -178,6 +214,10 @@ clean_args(struct main_args *margs)
         clean_nd(margs->ndoms);
         margs->ndoms = NULL;
     }
+    if (margs->lservs) {
+        clean_ls(margs->lservs);
+        margs->lservs = NULL;
+    }
 }
 
 void strup(char *s);
@@ -190,7 +230,6 @@ main(int argc, char *const argv[])
     char *nuser, *nuser8 = NULL, *netbios;
     char *c;
     int opt;
-    int length;
     struct main_args margs;
 
     setbuf(stdout, NULL);
@@ -247,6 +286,9 @@ main(int argc, char *const argv[])
         case 'm':
             margs.mdepth = atoi(optarg);
             break;
+        case 'S':
+            margs.llist = xstrdup(optarg);
+            break;
         case 'h':
             fprintf(stderr, "Usage: \n");
             fprintf(stderr, "squid_kerb_ldap [-d] [-i] -g group list [-D domain] [-N netbios domain map] [-s] [-u ldap user] [-p ldap user password] [-l ldap url] [-b ldap bind path] [-a] [-m max depth] [-h]\n");
@@ -257,6 +299,7 @@ main(int argc, char *const argv[])
             fprintf(stderr, "-T group list (all in hex UTF-8 format - except seperator @)\n");
             fprintf(stderr, "-D default domain\n");
             fprintf(stderr, "-N netbios to dns domain map\n");
+            fprintf(stderr, "-S ldap server to dns domain map\n");
             fprintf(stderr, "-u ldap user\n");
             fprintf(stderr, "-p ldap user password\n");
             fprintf(stderr, "-l ldap url\n");
@@ -278,6 +321,11 @@ main(int argc, char *const argv[])
             fprintf(stderr, "is followed to the top (e.g. if the group is a member of a group)\n");
             fprintf(stderr, "Group membership is determined with non AD servers through the users memberuid (assuming\n");
             fprintf(stderr, "PosixGroup) or primary group membership (assuming PosixAccount)\n");
+            fprintf(stderr, "The ldap server list can be:\n");
+            fprintf(stderr, "server - In this case server can be used for all Kerberos domains\n");
+            fprintf(stderr, "server@  - In this case server can be used for all Kerberos domains\n");
+            fprintf(stderr, "server@domain  - In this case server can be used for Kerberos domain domain\n");
+            fprintf(stderr, "server1a@domain1:server1b@domain1:server2@domain2:server3@:server4 - A list is build with a colon as seperator\n");
             clean_args(&margs);
             exit(0);
         default:
@@ -298,6 +346,12 @@ main(int argc, char *const argv[])
         clean_args(&margs);
         exit(1);
     }
+    if (create_ls(&margs)) {
+        debug((char *) "%s| %s: Error in ldap server list: %s\n", LogTime(), PROGRAM, margs.llist ? margs.llist : "NULL");
+        SEND_ERR("");
+        clean_args(&margs);
+        exit(1);
+    }
     while (1) {
         if (fgets(buf, sizeof(buf) - 1, stdin) == NULL) {
             if (ferror(stdin)) {
@@ -315,7 +369,6 @@ main(int argc, char *const argv[])
         c = (char *) memchr(buf, '\n', sizeof(buf) - 1);
         if (c) {
             *c = '\0';
-            length = c - buf;
         } else {
             SEND_ERR("");
             debug((char *) "%s| %s: ERR\n", LogTime(), PROGRAM);
index 46b141676a4d0c7c0db1c98ac7a789fe20c58b47..9a42ec3c54e95f3b076f4ed5a3c0855772c47489 100644 (file)
@@ -22,7 +22,7 @@
  * -----------------------------------------------------------------------------
  */
 
-#define KERBEROS_LDAP_GROUP_VERSION "1.2.2sq"
+#define KERBEROS_LDAP_GROUP_VERSION "1.3.0sq"
 
 #if HAVE_STRING_H
 #include <string.h>
@@ -99,12 +99,18 @@ struct ndstruct {
     char *domain;
     struct ndstruct *next;
 };
+struct lsstruct {
+    char *lserver;
+    char *domain;
+    struct lsstruct *next;
+};
 
 struct main_args {
     char *glist;
     char *ulist;
     char *tlist;
     char *nlist;
+    char *llist;
     char *luser;
     char *lpass;
     char *lbind;
@@ -116,6 +122,7 @@ struct main_args {
     char *ddomain;
     struct gdstruct *groups;
     struct ndstruct *ndoms;
+    struct lsstruct *lservs;
 };
 
 SQUIDCEXTERN int log_enabled;
@@ -171,6 +178,7 @@ char *get_netbios_name(struct main_args *margs, char *netbios);
 
 int create_gd(struct main_args *margs);
 int create_nd(struct main_args *margs);
+int create_ls(struct main_args *margs);
 
 int krb5_create_cache(struct main_args *margs, char *domain);
 void krb5_cleanup(void);
diff --git a/helpers/external_acl/kerberos_ldap_group/support_lserver.cc b/helpers/external_acl/kerberos_ldap_group/support_lserver.cc
new file mode 100644 (file)
index 0000000..6901fdd
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * -----------------------------------------------------------------------------
+ *
+ * Author: Markus Moeller (markus_moeller at compuserve.com)
+ *
+ * Copyright (C) 2007 Markus Moeller. All rights reserved.
+ *
+ *   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-1307, USA.
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "config.h"
+#include "util.h"
+
+#ifdef HAVE_LDAP
+
+#include "support.h"
+struct lsstruct *init_ls(void);
+
+struct lsstruct *
+init_ls(void) {
+    struct lsstruct *lssp;
+    lssp = (struct lsstruct *) xmalloc(sizeof(struct lsstruct));
+    lssp->lserver = NULL;
+    lssp->domain = NULL;
+    lssp->next = NULL;
+    return lssp;
+}
+
+int
+create_ls(struct main_args *margs)
+{
+    char *np, *dp;
+    char *p;
+    struct lsstruct *lssp = NULL, *lsspn = NULL;
+    /*
+     *  netbios list format:
+     *
+     *     nlist=Pattern1[:Pattern2]
+     *
+     *     Pattern=ldap-server@Domain    ldap server Name for a specific Kerberos domain
+     *                             lsstruct.domain=Domain, lsstruct.lserver=ldap server
+     *
+     *
+     */
+    p = margs->llist;
+    np = margs->llist;
+    debug((char *) "%s| %s: DEBUG: ldap server list %s\n", LogTime(), PROGRAM, margs->llist ? margs->llist : "NULL");
+    dp = NULL;
+
+    if (!p) {
+        debug((char *) "%s| %s: DEBUG: No ldap servers defined.\n", LogTime(), PROGRAM);
+        return (0);
+    }
+    while (*p) {               /* loop over group list */
+        if (*p == '\n' || *p == '\r') {                /* Ignore CR and LF if exist */
+            p++;
+            continue;
+        }
+        if (*p == '@') {       /* end of group name - start of domain name */
+            if (p == np) {     /* empty group name not allowed */
+                debug((char *) "%s| %s: DEBUG: No ldap servers defined for domain %s\n", LogTime(), PROGRAM, p);
+                return (1);
+            }
+            *p = '\0';
+            p++;
+            lssp = init_ls();
+            lssp->lserver = xstrdup(np);
+            if (lsspn)         /* Have already an existing structure */
+                lssp->next = lsspn;
+            dp = p;            /* after @ starts new domain name */
+        } else if (*p == ':') {        /* end of group name or end of domain name */
+            if (p == np) {     /* empty group name not allowed */
+                debug((char *) "%s| %s: DEBUG: No ldap servers defined for domain %s\n", LogTime(), PROGRAM, p);
+                return (1);
+            }
+            *p = '\0';
+            p++;
+            if (dp) {          /* end of domain name */
+                lssp->domain = xstrdup(dp);
+                dp = NULL;
+            } else {           /* end of group name and no domain name */
+                lssp = init_ls();
+                lssp->lserver = xstrdup(np);
+                if (lsspn)     /* Have already an existing structure */
+                    lssp->next = lsspn;
+            }
+            lsspn = lssp;
+            np = p;            /* after : starts new group name */
+            if (!lssp->domain || !strcmp(lssp->domain, "")) {
+                debug((char *) "%s| %s: DEBUG: No domain defined for ldap server %s\n", LogTime(), PROGRAM, lssp->lserver);
+                return (1);
+            }
+            debug((char *) "%s| %s: DEBUG: ldap server %s  Domain %s\n", LogTime(), PROGRAM, lssp->lserver, lssp->domain);
+        } else
+            p++;
+    }
+    if (p == np) {             /* empty group name not allowed */
+        debug((char *) "%s| %s: DEBUG: No ldap servers defined for domain %s\n", LogTime(), PROGRAM, p);
+        return (1);
+    }
+    if (dp) {                  /* end of domain name */
+        lssp->domain = xstrdup(dp);
+    } else {                   /* end of group name and no domain name */
+        lssp = init_ls();
+        lssp->lserver = xstrdup(np);
+        if (lsspn)             /* Have already an existing structure */
+            lssp->next = lsspn;
+    }
+    if (!lssp->domain || !strcmp(lssp->domain, "")) {
+        debug((char *) "%s| %s: DEBUG: No domain defined for ldap server %s\n", LogTime(), PROGRAM, lssp->lserver);
+        return (1);
+    }
+    debug((char *) "%s| %s: DEBUG: ldap server %s  Domain %s\n", LogTime(), PROGRAM, lssp->lserver, lssp->domain);
+
+    margs->lservs = lssp;
+    return (0);
+}
+#endif
index 08f2ea1039e4b949a88b65ff2886384507fe73cd..f5426a185005036671b72b6e094285c174767ef1 100644 (file)
@@ -83,6 +83,7 @@ swap(struct hstruct *a, struct hstruct *b)
     c.host = a->host;
     c.priority = a->priority;
     c.weight = a->weight;
+    a->host = b->host;
     a->priority = b->priority;
     a->weight = b->weight;
     b->host = c.host;
@@ -228,17 +229,36 @@ get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, int nh,
      */
     char name[1024];
     char host[NS_MAXDNAME];
-    char *service;
+    char *service = NULL;
     struct hstruct *hp = NULL;
+    struct lsstruct *ls = NULL;
     int nhosts = 0;
     int size;
     int type, rdlength;
     int priority, weight, port;
     int len, olen;
     int i, j, k;
-    u_char *buffer;
+    u_char *buffer = NULL;
     u_char *p;
 
+    ls = margs->lservs;
+    while (ls) {
+        debug((char *) "%s| %s: DEBUG: Ldap server loop: lserver@domain %s@%s\n", LogTime(), PROGRAM, ls->lserver, ls->domain);
+        if (ls->domain && !strcasecmp(ls->domain, domain)) {
+            debug((char *) "%s| %s: DEBUG: Found lserver@domain %s@%s\n", LogTime(), PROGRAM, ls->lserver, ls->domain);
+            hp = (struct hstruct *) xrealloc(hp, sizeof(struct hstruct) * (nhosts + 1));
+            hp[nhosts].host = strdup(ls->lserver);
+            hp[nhosts].port = -1;
+            hp[nhosts].priority = -2;
+            hp[nhosts].weight = -2;
+            nhosts++;
+        }
+        ls = ls->next;
+    }
+    /* found ldap servers in predefined list -> exit */
+    if (nhosts > 0)
+        goto cleanup;
+
     if (margs->ssl) {
         service = (char *) xmalloc(strlen("_ldaps._tcp.") + strlen(domain) + 1);
         strcpy(service, "_ldaps._tcp.");
@@ -372,6 +392,15 @@ get_ldap_hostname_list(struct main_args *margs, struct hstruct **hlist, int nh,
     }
     nhosts = get_hostname_list(margs, &hp, nh, domain);
 
+    debug("%s| %s: DEBUG: Adding %s to list\n", LogTime(), PROGRAM, domain);
+
+    hp = (struct hstruct *) xrealloc(hp, sizeof(struct hstruct) * (nhosts + 1));
+    hp[nhosts].host = strdup(domain);
+    hp[nhosts].port = -1;
+    hp[nhosts].priority = -2;
+    hp[nhosts].weight = -2;
+    nhosts++;
+
     /* Remove duplicates */
     for (i = 0; i < nhosts; i++) {
         for (j = i + 1; j < nhosts; j++) {