From f602c423b782d0c1b4233e70a01b337dcbb824a9 Mon Sep 17 00:00:00 2001 From: Markus Moeller Date: Mon, 14 Mar 2011 00:08:24 -0600 Subject: [PATCH] ext_kerberos_ldap_group_acl version 1.3.0sq --- .../kerberos_ldap_group/Makefile.am | 1 + .../ext_kerberos_ldap_group_acl.8 | 14 +- .../kerberos_ldap_group.cc | 147 ++++++++++++------ .../kerberos_ldap_group/support.h | 10 +- .../kerberos_ldap_group/support_lserver.cc | 132 ++++++++++++++++ .../kerberos_ldap_group/support_resolv.cc | 33 +++- 6 files changed, 285 insertions(+), 52 deletions(-) create mode 100644 helpers/external_acl/kerberos_ldap_group/support_lserver.cc diff --git a/helpers/external_acl/kerberos_ldap_group/Makefile.am b/helpers/external_acl/kerberos_ldap_group/Makefile.am index 70950ef3b3..29da57bde2 100644 --- a/helpers/external_acl/kerberos_ldap_group/Makefile.am +++ b/helpers/external_acl/kerberos_ldap_group/Makefile.am @@ -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 = diff --git a/helpers/external_acl/kerberos_ldap_group/ext_kerberos_ldap_group_acl.8 b/helpers/external_acl/kerberos_ldap_group/ext_kerberos_ldap_group_acl.8 index 83f4fb3f58..28ac97a2df 100644 --- a/helpers/external_acl/kerberos_ldap_group/ext_kerberos_ldap_group_acl.8 +++ b/helpers/external_acl/kerberos_ldap_group/ext_kerberos_ldap_group_acl.8 @@ -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 diff --git a/helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc b/helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc index 7019bcb45d..bcef9b859c 100644 --- a/helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc +++ b/helpers/external_acl/kerberos_ldap_group/kerberos_ldap_group.cc @@ -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); diff --git a/helpers/external_acl/kerberos_ldap_group/support.h b/helpers/external_acl/kerberos_ldap_group/support.h index 46b141676a..9a42ec3c54 100644 --- a/helpers/external_acl/kerberos_ldap_group/support.h +++ b/helpers/external_acl/kerberos_ldap_group/support.h @@ -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 @@ -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 index 0000000000..6901fdd590 --- /dev/null +++ b/helpers/external_acl/kerberos_ldap_group/support_lserver.cc @@ -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 diff --git a/helpers/external_acl/kerberos_ldap_group/support_resolv.cc b/helpers/external_acl/kerberos_ldap_group/support_resolv.cc index 08f2ea1039..f5426a1850 100644 --- a/helpers/external_acl/kerberos_ldap_group/support_resolv.cc +++ b/helpers/external_acl/kerberos_ldap_group/support_resolv.cc @@ -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++) { -- 2.47.3