=== removed file 'helpers/external_acl/eDirectory_userip/INSTALL' --- helpers/external_acl/eDirectory_userip/INSTALL 2010-07-20 14:16:00 +0000 +++ helpers/external_acl/eDirectory_userip/INSTALL 1970-01-01 00:00:00 +0000 @@ -1,38 +0,0 @@ -* squid_edir_iplookup - Copyright (C) 2009, 2010 Chad E. Naugle -* -******************************************************************************** -* -* INSTALL -- -* - -To install squid_edir_lookup, you need to do the following. - -1- Unpack this tarball. -2- Port? - (See PORTING, program was written under a SuSe Linux Enterprise Server 10 SP2 + - Open Enterprise Server 2 SP1 environment) -3- Run 'make'. -4- Run 'make install'. (Or optionally copy 'squid_edir_iplookup' to somewhere. -5- Edit squid.conf with the following lines as an example: - -# Setup External ACL Helper with parameters (if required) -external_acl_type IPUser ttl=1800 negative_ttl=30 children=10 %SRC /usr/sbin/squid_edir_iplookup - -# Next line sets how long the credentials last before re-authentication is required. -auth_param basic credentialsttl 30 minutes - -# Next lines are required, and the actual ACL's may be customized to suit your needs. -# In this example, the 'Internet_Allowed' and 'Internet_Denied' are Groups that users may -# be used to control internet access, which can also be stacked against other ACL's. -# Use of the groups is NOT REQUIRED. -acl edirectory_users_allowed external IPUser Internet_Allowed -acl edirectory_users_denied external IPUser Internet_Denied - -# Next lines are used to bind ACL's to what they actually do. Remember that Squid's -# Default is to ALLOW ALL. -http_access deny edirectory_users_denied -http_access allow edirectory_users_allowed -http_access deny all - -6- START Squid. With some luck, you should have a blind eDirectory authenticator, - That is, without the Users' knowledge that there even *IS* a proxy server! === removed file 'helpers/external_acl/eDirectory_userip/ISSUES' --- helpers/external_acl/eDirectory_userip/ISSUES 2010-07-20 14:16:00 +0000 +++ helpers/external_acl/eDirectory_userip/ISSUES 1970-01-01 00:00:00 +0000 @@ -1,29 +0,0 @@ -* squid_edir_iplookup - Copyright (C) 2009, 2010 Chad E. Naugle -* -******************************************************************************** -* -* ISSUES -- -* - -- Possible Spelling errors :) - -- IPv6 support has yet to be TESTED in a real IPv6 environment, but the code is in place to read IPv6 - networkAddress fields, please attempt this in a TESTING environment first. Please read the - README file to contact me regarding IPv6 support development. - -- There is a known issue regarding Novell's Client for Windows, that is mostly fixed by using - version 4.91 SP3+, with the 'Auto-Reconnect' feature not re-populating the networkAddress - field in eDirectory. - -- I have also expereinced an issue related to using NetWare 6.5 (SP6 and lower?) and connection licsensing. - It appears that whenever a server runs low on connection licsenes, that it SOMETIMES does - NOT populate the networkAddress fields correctly. - -- I *STRONGLY RECOMMEND* using the latest version of the Novell Client in all situations *BEFORE* - seeking support! You may also want to MAKE SURE your servers also have the latest service packs. - -- Majority of Proxy Authentication issues can be resolved by having the users' REBOOT if their networkAddress - is not correct, or using squid_auth_ldap as a fallback. Check ConsoleOne, etc to verify thier - networkAddress fields to troubleshoot. - -- More PROBLEMS using the helper? Check README for contact information. === modified file 'helpers/external_acl/eDirectory_userip/Makefile.am' --- helpers/external_acl/eDirectory_userip/Makefile.am 2010-08-13 05:53:22 +0000 +++ helpers/external_acl/eDirectory_userip/Makefile.am 2010-08-31 21:20:05 +0000 @@ -3,8 +3,7 @@ libexec_PROGRAMS = ext_edirectory_userip_acl ext_edirectory_userip_acl_SOURCES = \ - edui_config.h main.h edui_util.h iplookup.h \ - main.c edui_util.c iplookup.c + ext_edirectory_userip_acl.c ext_edirectory_userip_acl_LDADD = \ $(COMPAT_LIB) \ @@ -12,4 +11,4 @@ $(LBERLIB) \ $(XTRA_LIBS) -EXTRA_DIST = config.test README ISSUES INSTALL +EXTRA_DIST = config.test === removed file 'helpers/external_acl/eDirectory_userip/README' --- helpers/external_acl/eDirectory_userip/README 2010-07-20 14:16:00 +0000 +++ helpers/external_acl/eDirectory_userip/README 1970-01-01 00:00:00 +0000 @@ -1,23 +0,0 @@ -* squid_edir_iplookup - Copyright (C) 2009, 2010 Chad E. Naugle -* -******************************************************************************** -* -* README -- -* - -This program has been written in order to solve the problems associated with running the -Perl squid_ip_lookup.pl as a squid external helper that has been provided by various -sources, including Novell, Inc. - -The limitations of the Perl script involved memory/cpu utilization, speed, and the lack -of eDirectory 8.8 support, and IPv6 support. - -This program is being provided to the Squid Cache Developers as a donation of code to -help further develop Squid, and it's seamless integration with a Novell Open Enterprise Server -deployment. Hopefully one day Novell will include updated versions of squid into their -mainstream OES releases, such as the 3.1.x code tree. - -This program has been used in a STABLE PRODUCTION ENTERPRISE environment for months before -being released to the Squid Development team, but that does not mean that bugs do not exist. - -If they do, please contact myself for right now. chad.naugle@travimp.com. === modified file 'helpers/external_acl/eDirectory_userip/config.test' (properties changed: -x to +x) === added directory 'helpers/external_acl/eDirectory_userip/doc' === added file 'helpers/external_acl/eDirectory_userip/doc/INSTALL' --- helpers/external_acl/eDirectory_userip/doc/INSTALL 1970-01-01 00:00:00 +0000 +++ helpers/external_acl/eDirectory_userip/doc/INSTALL 2010-08-23 13:46:25 +0000 @@ -0,0 +1,38 @@ +* squid_edir_iplookup - Copyright (C) 2009, 2010 Chad E. Naugle +* +******************************************************************************** +* +* INSTALL -- +* + +To install squid_edir_lookup, you need to do the following. + +1- Unpack this tarball. +2- Port? + (See PORTING, program was written under a SuSe Linux Enterprise Server 10 SP2 + + Open Enterprise Server 2 SP1 environment) +3- Run 'make'. +4- Run 'make install'. (Or optionally copy 'squid_edir_iplookup' to somewhere. +5- Edit squid.conf with the following lines as an example: + +# Setup External ACL Helper with parameters (if required) +external_acl_type IPUser ttl=1800 negative_ttl=30 children=10 %SRC /usr/sbin/squid_edir_iplookup + +# Next line sets how long the credentials last before re-authentication is required. +auth_param basic credentialsttl 30 minutes + +# Next lines are required, and the actual ACL's may be customized to suit your needs. +# In this example, the 'Internet_Allowed' and 'Internet_Denied' are Groups that users may +# be used to control internet access, which can also be stacked against other ACL's. +# Use of the groups is NOT REQUIRED. +acl edirectory_users_allowed external IPUser Internet_Allowed +acl edirectory_users_denied external IPUser Internet_Denied + +# Next lines are used to bind ACL's to what they actually do. Remember that Squid's +# Default is to ALLOW ALL. +http_access deny edirectory_users_denied +http_access allow edirectory_users_allowed +http_access deny all + +6- START Squid. With some luck, you should have a blind eDirectory authenticator, + That is, without the Users' knowledge that there even *IS* a proxy server! === added file 'helpers/external_acl/eDirectory_userip/doc/ISSUES' --- helpers/external_acl/eDirectory_userip/doc/ISSUES 1970-01-01 00:00:00 +0000 +++ helpers/external_acl/eDirectory_userip/doc/ISSUES 2010-08-23 14:42:53 +0000 @@ -0,0 +1,29 @@ +* ext_edirectory_userip_acl - Copyright (C) 2009, 2010 Chad E. Naugle +* +******************************************************************************** +* +* ISSUES -- List of KNOWN ISSUES +* + +- Possible Spelling errors :) + +- IPv6 support has yet to be TESTED in a real IPv6 environment, but the code is in place to read IPv6 + networkAddress fields, please attempt this in a TESTING environment first. Please read the + README file to contact me regarding IPv6 support development. + +- There is a known issue regarding Novell's Client for Windows, that is mostly fixed by using + version 4.91 SP3+, with the 'Auto-Reconnect' feature not re-populating the networkAddress + field in eDirectory. + +- I have also expereinced an issue related to using NetWare 6.5 (SP6 and lower?) and connection licsensing. + It appears that whenever a server runs low on connection licsenes, that it SOMETIMES does + NOT populate the networkAddress fields correctly. + +- I *STRONGLY RECOMMEND* using the latest version of the Novell Client in all situations *BEFORE* + seeking support! You may also want to MAKE SURE your servers also have the latest service packs. + +- Majority of Proxy Authentication issues can be resolved by having the users' REBOOT if their networkAddress + is not correct, or using squid_auth_ldap as a fallback. Check ConsoleOne, etc to verify thier + networkAddress fields to troubleshoot. + +- More PROBLEMS using the helper? Check README for contact information. === added file 'helpers/external_acl/eDirectory_userip/doc/Makefile' --- helpers/external_acl/eDirectory_userip/doc/Makefile 1970-01-01 00:00:00 +0000 +++ helpers/external_acl/eDirectory_userip/doc/Makefile 2010-08-23 20:47:42 +0000 @@ -0,0 +1,26 @@ +CC = gcc +LD = gcc +CFLAGS = -O2 -Wall -Wextra +PROGNAME = ext_edirectory_userip_acl +UID = squid +GID = nogroup +OBJECTS = ext_edirectory_userip_acl.c +LIBS = -lldap -llber +HEADERS = kludge.h + +all: ${PROGNAME} + +${PROGNAME}: ${OBJECTS} + ${LD} ${CFLAGS} -o ${PROGNAME} ${OBJECTS} ${LIBS} + chmod 0550 ${PROGNAME} + chown ${UID} ${PROGNAME} + chgrp ${GID} ${PROGNAME} + +clean: + rm -f *.o ${PROGNAME} + +install: ${PROGNAME} + cp ${PROGNAME} ${DESTDIR}/usr/sbin + +ext_edirectory_userip_acl.o: ${HEADERS} ext_edirectory_userip_acl.c + ${CC} ${CFLAGS} -c ext_edirectory_userip_acl.c === added file 'helpers/external_acl/eDirectory_userip/doc/Makefile.test' --- helpers/external_acl/eDirectory_userip/doc/Makefile.test 1970-01-01 00:00:00 +0000 +++ helpers/external_acl/eDirectory_userip/doc/Makefile.test 2010-08-23 19:49:01 +0000 @@ -0,0 +1,41 @@ +# squid_edir_iplookup - Copyright (C) 2009, 2010 Chad E. Naugle +# +#******************************************************************************* +# +# Makefile -- 2010-08-03 +# +# Builds squid_edir_lookup when run. PORTING NEEDED. +# + +CC = gcc +LD = gcc +CFLAGS = -O2 -Wall -Wextra +PROGNAME = ext_edirectory_userip_acl +UID = squid +GID = nogroup +OBJECTS = edui_main.o edui_iplookup.o edui_util.o +LIBS = -lldap -llber +HEADERS = edui_incl.h + +all: ${PROGNAME} + +${PROGNAME}: ${OBJECTS} + ${LD} ${CFLAGS} -o ${PROGNAME} ${OBJECTS} ${LIBS} + chmod 0550 ${PROGNAME} + chown ${UID} ${PROGNAME} + chgrp ${GID} ${PROGNAME} + +clean: + rm -f *.o ${PROGNAME} + +install: ${PROGNAME} + cp ${PROGNAME} ${DESTDIR}/usr/sbin + +edui_main.o: ${HEADERS} edui_main.c + ${CC} ${CFLAGS} -c edui_main.c + +edui_iplookup.o: ${HEADERS} edui_iplookup.c + ${CC} ${CFLAGS} -c edui_iplookup.c + +edui_util.o: ${HEADERS} edui_util.c + ${CC} ${CFLAGS} -c edui_util.c === added file 'helpers/external_acl/eDirectory_userip/doc/README' --- helpers/external_acl/eDirectory_userip/doc/README 1970-01-01 00:00:00 +0000 +++ helpers/external_acl/eDirectory_userip/doc/README 2010-08-23 14:42:20 +0000 @@ -0,0 +1,23 @@ +* ext_edirectory_userip_acl - Copyright (C) 2009, 2010 Chad E. Naugle +* +******************************************************************************** +* +* README -- +* + +This program has been written in order to solve the problems associated with running the +Perl squid_ip_lookup.pl as a squid external helper that has been provided by various +sources, including Novell, Inc. + +The limitations of the Perl script involved memory/cpu utilization, speed, and the lack +of eDirectory 8.8 support, and IPv6 support. + +This program is being provided to the Squid Cache Developers as a donation of code to +help further develop Squid, and it's seamless integration with a Novell Open Enterprise Server +deployment. Hopefully one day Novell will include updated versions of squid into their +mainstream OES releases, such as the 3.1.x code tree. + +This program has been used in a STABLE PRODUCTION ENTERPRISE environment for months before +being released to the Squid Development team, but that does not mean that bugs do not exist. + +If they do, please contact myself for right now. chad.naugle@travimp.com. === added file 'helpers/external_acl/eDirectory_userip/doc/kludge.h' --- helpers/external_acl/eDirectory_userip/doc/kludge.h 1970-01-01 00:00:00 +0000 +++ helpers/external_acl/eDirectory_userip/doc/kludge.h 2010-08-23 20:46:34 +0000 @@ -0,0 +1,18 @@ +/* Defines fake autoconf.h for test building */ + +#ifndef _H_KLUDGE +#define _H_KLUDGE + +#define HAVE_STDIO_H +#define HAVE_STDLIB_H +#define HAVE_STDARG_H +#define HAVE_STRING_H +#define HAVE_CTYPE_H +#define HAVE_ERRNO_H +#define HAVE_SIGNAL_H +#define HAVE_ARPA_INET_H +#define HAVE_LBER_H +#define HAVE_LDAP_H +#define HAVE_TIME_H + +#endif === removed file 'helpers/external_acl/eDirectory_userip/edui_config.h' --- helpers/external_acl/eDirectory_userip/edui_config.h 2010-08-30 00:05:19 +0000 +++ helpers/external_acl/eDirectory_userip/edui_config.h 1970-01-01 00:00:00 +0000 @@ -1,76 +0,0 @@ -/* squid_edir_iplookup - Copyright (C) 2009, 2010 Chad E. Naugle - * - ******************************************************************************** - * - * This file is part of squid_edir_iplookup. - * - * squid_edir_iplookup 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. - * - * squid_edir_iplookup 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 squid_edir_iplookup. If not, see . - * - ******************************************************************************** - * - * config.h -- - * - * Runtime default configuration. - * - */ - -#ifndef _HAVE_CONFIG_H -#define _HAVE_CONFIG_H - -/* Default program name */ -#define DEFAULT_PROGRAM_NAME "ext_edirectory_userip_acl" - -/* Hostname or IP address of LDAP server, default is IPv4 localhost (127.0.0.1) */ -/* #define DEFAULT_LDAP_HOST */ - -/* Should be 389 or 636 for SSL, but you can change it here */ -/* #define DEFAULT_LDAP_PORT */ - -/* Default LDAP protocol version, 1, 2, or 3 -- 3 for TLS/SSL is defaulted */ -/* #define DEFAULT_LDAP_VERSION */ - -/* Base DN to search from, Ie. o=TREE */ -/* #define DEFAULT_BASE_DN */ - -/* Bind DN to perform searches, Base DN will be appended, or you can specify it here */ -/* #define DEFAULT_BIND_DN */ - -/* Binding password to perform searches */ -/* #define DEFAULT_BIND_PASS */ - -/* 0 - base, 1 - one level, 2 - subtree */ -/* #define DEFAULT_SEARCH_SCOPE 2 */ - -/* Base search filter. Ie. (&(objectClass=Person)(networkAddress=*)) */ -/* #define DEFAULT_SEARCH_FILTER "(&(objectClass=User)(networkAddress=*))" */ - -/* Default maximum length of all generic array variables */ -#define DEFAULT_MAXLEN 1024 - -/* Default to IPv4 enabled? */ -#define DEFAULT_USE_IPV4 - -/* Default to IPv6 enabled? (Enable both for IPv4-in-IPv6) */ -/* #define DEFAULT_USE_IPV6 */ - -/* Default to REQUIRE a groupMembership? */ -/* #define DEFAULT_GROUP_REQUIRED */ - -/* Default to TLS enabled? */ -#define DEFAULT_USE_TLS - -/* Default to debugging output? (ie. No -d required) */ -/* #define DEFAULT_DEBUG */ - -#endif === removed file 'helpers/external_acl/eDirectory_userip/edui_util.c' --- helpers/external_acl/eDirectory_userip/edui_util.c 2010-08-30 00:05:19 +0000 +++ helpers/external_acl/eDirectory_userip/edui_util.c 1970-01-01 00:00:00 +0000 @@ -1,217 +0,0 @@ -/* squid_edir_iplookup - Copyright (C) 2009, 2010 Chad E. Naugle - * - ******************************************************************************** - * - * This file is part of squid_edir_iplookup. - * - * squid_edir_iplookup 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. - * - * squid_edir_iplookup 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 squid_edir_iplookup. If not, see . - * - ******************************************************************************** - * - * util.c -- - * - * Program utility functions. - * - */ - -#include "main.h" -#include "edui_util.h" - -/* debug() - - * - * Print formatted message of func() to stderr if MODE_DEBUG is set. - * - */ -void debug(char *func, const char *msg,...) -{ - char prog[MAXLEN], dbuf[MAXLEN], cbuf[MAXLEN]; - size_t sz, x; - va_list ap; - if (!(conf.mode & MODE_DEBUG)) - return; - - if (conf.program[0] == '\0') - strcpy(prog, DEFAULT_PROGRAM_NAME); - else - strncpy(prog, conf.program, sizeof(prog)); - if ((func == NULL) || (msg == NULL) || (strlen(prog) > 256)) { - /* FAIL */ - snprintf(dbuf, sizeof(dbuf), "%s: debug() EPIC FAILURE.\n", prog); - fputs(dbuf, stderr); - return; - } - sz = sizeof(dbuf); - strncpy(cbuf, prog, sizeof(cbuf)); - strcat(cbuf, ": [DB] "); - strncat(cbuf, func, sizeof(cbuf)); - strcat(cbuf, "() - "); - va_start(ap, msg); - x = vsnprintf(dbuf, sz, msg, ap); - va_end(ap); - if (x > 0) { - strncat(cbuf, dbuf, x); - fputs(cbuf, stderr); - memset(dbuf, '\0', strlen(dbuf)); - } else { - /* FAIL */ - snprintf(dbuf, sz, "%s: debug(%s) FAILURE: %zd\n", prog, dbuf, x); - fputs(dbuf, stderr); - } -} - -/* debugx() - - * - * Print formatted message to stderr if MODE_DEBUG is set, without preformatting. - * - */ -void debugx(const char *msg,...) -{ - char prog[MAXLEN], dbuf[MAXLEN]; - size_t sz, x; - va_list ap; - if (!(conf.mode & MODE_DEBUG)) - return; - - if (conf.program[0] == '\0') - strcpy(prog, DEFAULT_PROGRAM_NAME); - else - strncpy(prog, conf.program, sizeof(prog)); - if ((msg == NULL) || (strlen(prog) > 256)) { - /* FAIL */ - snprintf(dbuf, sizeof(dbuf), "%s: debugx() EPIC FAILURE.\n", prog); - fputs(dbuf, stderr); - return; - } - sz = sizeof(dbuf); - va_start(ap, msg); - x = vsnprintf(dbuf, sz, msg, ap); - va_end(ap); - if (x > 0) { - fputs(dbuf, stderr); - memset(dbuf, '\0', strlen(dbuf)); - } else { - /* FAIL */ - snprintf(dbuf, sz, "%s: debug(%s) FAILURE: %zd\n", prog, dbuf, x); - fputs(dbuf, stderr); - } -} - -/* printfx() - - * - * Print formatted message to stderr AND stdout, without preformatting. - * - */ -void printfx(const char *msg,...) -{ - char prog[MAXLEN], dbuf[MAXLEN]; - size_t sz, x; - va_list ap; - - if (conf.program[0] == '\0') - strcpy(prog, DEFAULT_PROGRAM_NAME); - else - strncpy(prog, conf.program, sizeof(prog)); - - if ((msg == NULL) || (strlen(prog) > 256)) { - /* FAIL */ - snprintf(dbuf, sizeof(dbuf), "%s: printfx() EPIC FAILURE.\n", prog); - fputs(dbuf, stderr); - return; - } - sz = sizeof(dbuf); - va_start(ap, msg); - x = vsnprintf(dbuf, sz, msg, ap); - va_end(ap); - if (x > 0) { - dbuf[x] = '\0'; - x++; - fputs(dbuf, stdout); -// debug("printfx", "DATA: %s", dbuf); - memset(dbuf, '\0', strlen(dbuf)); - } else { - /* FAIL */ - snprintf(dbuf, sz, "%s: printfx(%s) FAILURE: %zd\n", prog, dbuf, x); - fputs(dbuf, stderr); - } - - /* stdout needs to be flushed for it to work with Squid */ - fflush(stdout); -} - -/* - * SplitString() - - * - * Breaks down string, splitting out element into , and removing it from string. - * Will not exceed size tolerances. - * - * NOTE: We could have used a strchr() pointer, but then '\0' would break it. - * (Which DOES commonly exist in IP Addressing) - * - */ -int SplitString(char *input, size_t insz, char c, char *obj, size_t objsz) -{ - size_t i, j; - int swi; - char buf[MAXLEN]; - if ((input == NULL) || (obj == NULL) || (insz <= 0) || (objsz <= 0)) return -1; - - /* Copy input, and clear */ - memset(buf, '\0', sizeof(buf)); - memcpy(buf, input, insz); - memset(input, '\0', insz); - memset(obj, '\0', objsz); - j = 0; /* obj position */ - swi = 0; /* found data yet ? */ - - /* Scan for data, and copy */ - for (i = 0; i < insz; i++) { - /* Scan input for first non-space character */ - if (buf[i] != c) { - if (swi == 0) { - swi++; /* Data found, begin copying. */ - obj[j] = buf[i]; - j++; - } else if (swi == 1) { - obj[j] = buf[i]; - j++; - } else - break; /* end of data */ - } else { - /* Found a character c */ - if (swi == 1) - swi++; - else if (swi == 2) - break; /* end of data */ - } - } - obj[j] = '\0'; /* Terminate, i = point of split */ - - j = 0; /* Position of input */ - for (; i < insz; i++) { - /* Commented out for BINARY MODE, ie. May have '\0' as legit data * - if (buf[i] == '\0') - break; - */ - input[j] = buf[i]; - j++; - } - /* Should be correctly split back into input, and - * split object in obj. memset() at next call will - * clear array data. - */ - i = strlen(input); - j = strlen(obj); - - return j; -} === removed file 'helpers/external_acl/eDirectory_userip/edui_util.h' --- helpers/external_acl/eDirectory_userip/edui_util.h 2010-08-30 00:05:19 +0000 +++ helpers/external_acl/eDirectory_userip/edui_util.h 1970-01-01 00:00:00 +0000 @@ -1,40 +0,0 @@ -/* squid_edir_iplookup - Copyright (C) 2009, 2010 Chad E. Naugle - * - ******************************************************************************** - * - * This file is part of squid_edir_iplookup. - * - * squid_edir_iplookup 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. - * - * squid_edir_iplookup 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 squid_edir_iplookup. If not, see . - * - ******************************************************************************** - * - * util.h -- - * - * Program utility functions. - * - */ - -#ifndef _HAVE_UTIL_H -#define _HAVE_UTIL_H -#ifndef _HAVE_MAIN_H -#include "main.h" -#endif -#include - -/* util.c - Functions */ -void debug(char *, const char *,...); -void debugx(const char *,...); -void printfx(const char *,...); -int SplitString(char *, size_t, char, char *, size_t); -#endif === added file 'helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.c' --- helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.c 1970-01-01 00:00:00 +0000 +++ helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.c 2010-08-31 21:21:04 +0000 @@ -0,0 +1,2083 @@ +/* ext_edirectory_userip_acl - Copyright (C) 2009, 2010 Chad E. Naugle + * + ******************************************************************************** + * + * This file is part of ext_edirectory_userip_acl. + * + * ext_edirectory_userip_acl 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. + * + * ext_edirectory_userip_acl 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 squid_edir_iplookup. If not, see . + * + ******************************************************************************** + * + * ext_edirectory_userip_acl.cc -- + * + * Program includes & struct typedef for program configuration. + * + */ + +/* +#include "kludge.h" +int debug_enabled; +*/ + +/* Squid-3.X includes */ +/* X */ +#define SQUID_NO_ALLOC_PROTECT 1 +#include "config.h" +#include "helpers/defines.h" +#include "rfc1738.h" +#include "util.h" +/* X */ + +#define EDUI_PROGRAM_NAME "ext_edirectory_userip_acl" +#define EDUI_PROGRAM_VERSION "2.0" + +/* System includes */ +#ifdef HAVE_STDIO_H +#include +#endif +#define _GNU_SOURCE +#define __USE_GNU +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_CTYPE_H +#include +#endif +#ifdef HAVE_ERRNO_H +#include +#endif +#ifdef HAVE_SIGNAL_H +#include +#endif +#ifdef HAVE_ARPA_INET_H +#include +#endif +#define LDAP_DEPRECATED 1 /* Set flag for enabling classic ldap functions */ +#ifdef HAVE_LBER_H +#include +#endif +#ifdef HAVE_LDAP_H +#include +#endif +#ifdef HAVE_STDARG_H +#include +#endif +#ifdef HAVE_TIME_H +#include +#endif + +#ifdef HELPER_INPUT_BUFFER +#define EDUI_MAXLEN HELPER_INPUT_BUFFER +#else +#define EDUI_MAXLEN 8196 +#endif + +/* ldap compile options */ +#define USE_LDAP_INIT +#ifndef NETSCAPE_SSL +# define NETSCAPE_SSL +#endif + +/* define LDAP_AUTH_TLS */ +#ifdef NETSCAPE_SSL +# ifndef LDAP_AUTH_TLS +# define LDAP_AUTH_TLS ((ber_tag_t) 0xb3U) +# endif +#endif + +/* conf_t - status flags */ +#define EDUI_MODE_INIT 0x01 +#define EDUI_MODE_DEBUG 0x02 /* Replace with Squid's debug system */ +#define EDUI_MODE_TLS 0x04 +#define EDUI_MODE_IPV4 0x08 +#define EDUI_MODE_IPV6 0x10 +#define EDUI_MODE_GROUP 0x20 /* Group is REQUIRED */ +#define EDUI_MODE_PERSIST 0x40 /* Persistent LDAP connections */ +#define EDUI_MODE_KILL 0x80 + +/* conf_t - Program configuration struct typedef */ +typedef struct { + char program[EDUI_MAXLEN]; + char basedn[EDUI_MAXLEN]; + char host[EDUI_MAXLEN]; + char attrib[EDUI_MAXLEN]; + char dn[EDUI_MAXLEN]; + char passwd[EDUI_MAXLEN]; + char search_filter[EDUI_MAXLEN]; /* Base search_filter that gets copied to edui_ldap_t */ + int ver; + int scope; + int port; + time_t persist_timeout; + unsigned int mode; +} edui_conf_t; + +/* edui_ldap_t - status flags */ +#define LDAP_INIT_S 0x0001 +#define LDAP_OPEN_S 0x0002 +#define LDAP_BIND_S 0x0004 +#define LDAP_SEARCH_S 0x0008 /* We got data */ +#define LDAP_VAL_S 0x0010 /* Data has been copied to l->val */ +#define LDAP_CLOSE_S 0x0020 +#define LDAP_PERSIST_S 0x0040 /* Persistent connection */ +#define LDAP_IDLE_S 0x0080 /* Connection is idle */ +#define LDAP_SSL_S 0x0100 +#define LDAP_TLS_S 0x0200 +#define LDAP_IPV4_S 0x0400 /* Search IP is IPv4 */ +#define LDAP_IPV6_S 0x0800 /* Search IP is IPv6 */ + +/* edui_ldap_t - Meaningful error codes */ +#define LDAP_ERR_NULL -1 /* Null edui_ldap_t pointer */ +#define LDAP_ERR_POINTER -2 /* Null l->lp pointer */ +#define LDAP_ERR_PARAM -3 /* Null or Missing parameters */ +#define LDAP_ERR_INIT -4 /* Not initalized */ +#define LDAP_ERR_OPEN -5 /* Not open */ +#define LDAP_ERR_CONNECT -6 /* Unable to connect */ +#define LDAP_ERR_BIND -7 /* Not bound */ +#define LDAP_ERR_SEARCHED -8 /* Already Searched */ +#define LDAP_ERR_NOT_SEARCHED -9 /* Not searching */ +#define LDAP_ERR_INVALID -10 /* Invalid parameter */ +#define LDAP_ERR_OOB -11 /* Out of bounds value */ +#define LDAP_ERR_PERSIST -12 /* Persistent mode is not active */ +#define LDAP_ERR_DATA -13 /* Required data missing */ +#define LDAP_ERR_NOTFOUND -14 /* Item not found */ +#define LDAP_ERR_OTHER -15 /* Other Generic Error condition */ +#define LDAP_ERR_FAILED -16 /* Operation failed */ +#define LDAP_ERR_SUCCESS -17 /* Operation successful */ + +/* edui_ldap_t - struct typedef */ +typedef struct { + LDAP *lp; + LDAPMessage *lm; + struct berval **val; + char basedn[EDUI_MAXLEN]; + char host[EDUI_MAXLEN]; + char dn[EDUI_MAXLEN]; + char passwd[EDUI_MAXLEN]; + char search_filter[EDUI_MAXLEN]; /* search_group gets appended here by GroupLDAP */ + char search_ip[EDUI_MAXLEN]; /* Could be IPv4 or IPv6, set by ConvertIP */ + char userid[EDUI_MAXLEN]; /* Resulting userid */ + unsigned int status; + unsigned int port; + unsigned long type; /* Type of bind */ + int ver; + int scope; + int err; /* LDAP error code */ + time_t idle_time; + int num_ent; /* Number of entry's found via search */ + int num_val; /* Number of value's found via getval */ +} edui_ldap_t; + +/* Global variables */ +char *search_attrib[] = { "cn", "uid", "networkAddress", "groupMembership", NULL }; +edui_conf_t edui_conf; +edui_ldap_t edui_ldap; +time_t edui_now; +time_t edui_elap; + +/* local_debug() - + * + * Print formatted message of func() to stderr if EDUI_MODE_DEBUG is set. + * + */ +void local_debug(char *func, const char *msg,...) +{ + char prog[EDUI_MAXLEN], dbuf[EDUI_MAXLEN], cbuf[EDUI_MAXLEN]; + size_t sz, x; + va_list ap; + if (!(edui_conf.mode & EDUI_MODE_DEBUG)) + return; + + if (edui_conf.program[0] == '\0') + strcpy(prog, EDUI_PROGRAM_NAME); + else + strncpy(prog, edui_conf.program, sizeof(prog)); + if ((func == NULL) || (msg == NULL) || (strlen(prog) > 256)) { + /* FAIL */ + snprintf(dbuf, sizeof(dbuf), "%s: local_debug() EPIC FAILURE.\n", prog); + fputs(dbuf, stderr); + return; + } + sz = sizeof(dbuf); + strncpy(cbuf, prog, sizeof(cbuf)); + strcat(cbuf, ": [DB] "); + strncat(cbuf, func, sizeof(cbuf)); + strcat(cbuf, "() - "); + va_start(ap, msg); + x = vsnprintf(dbuf, sz, msg, ap); + va_end(ap); + if (x > 0) { + strncat(cbuf, dbuf, x); + fputs(cbuf, stderr); + memset(dbuf, '\0', strlen(dbuf)); + } else { + /* FAIL */ + snprintf(dbuf, sz, "%s: local_debug(%s) FAILURE: %zd\n", prog, dbuf, x); + fputs(dbuf, stderr); + } +} + +/* local_debugx() - + * + * Print formatted message to stderr if EDUI_MODE_DEBUG is set, without preformatting. + * + */ +void local_debugx(const char *msg,...) +{ + char prog[EDUI_MAXLEN], dbuf[EDUI_MAXLEN]; + size_t sz, x; + va_list ap; + if (!(edui_conf.mode & EDUI_MODE_DEBUG)) + return; + + if (edui_conf.program[0] == '\0') + strcpy(prog, EDUI_PROGRAM_NAME); + else + strncpy(prog, edui_conf.program, sizeof(prog)); + if ((msg == NULL) || (strlen(prog) > 256)) { + /* FAIL */ + snprintf(dbuf, sizeof(dbuf), "%s: local_debugx() EPIC FAILURE.\n", prog); + fputs(dbuf, stderr); + return; + } + sz = sizeof(dbuf); + va_start(ap, msg); + x = vsnprintf(dbuf, sz, msg, ap); + va_end(ap); + if (x > 0) { + fputs(dbuf, stderr); + memset(dbuf, '\0', strlen(dbuf)); + } else { + /* FAIL */ + snprintf(dbuf, sz, "%s: local_debugx(%s) FAILURE: %zd\n", prog, dbuf, x); + fputs(dbuf, stderr); + } +} + +/* local_printfx() - + * + * Print formatted message to stderr AND stdout, without preformatting. + * + */ +void local_printfx(const char *msg,...) +{ + char prog[EDUI_MAXLEN], dbuf[EDUI_MAXLEN]; + size_t sz, x; + va_list ap; + + if (edui_conf.program[0] == '\0') + strcpy(prog, EDUI_PROGRAM_NAME); + else + strncpy(prog, edui_conf.program, sizeof(prog)); + + if ((msg == NULL) || (strlen(prog) > 256)) { + /* FAIL */ + snprintf(dbuf, sizeof(dbuf), "%s: local_printfx() EPIC FAILURE.\n", prog); + fputs(dbuf, stderr); + return; + } + sz = sizeof(dbuf); + va_start(ap, msg); + x = vsnprintf(dbuf, sz, msg, ap); + va_end(ap); + if (x > 0) { + dbuf[x] = '\0'; + x++; + fputs(dbuf, stdout); +// debug("printfx", "DATA: %s", dbuf); + memset(dbuf, '\0', strlen(dbuf)); + } else { + /* FAIL */ + snprintf(dbuf, sz, "%s: local_printfx(%s) FAILURE: %zd\n", prog, dbuf, x); + fputs(dbuf, stderr); + } + + /* stdout needs to be flushed for it to work with Squid */ + fflush(stdout); +} + +/* + * SplitString() - + * + * Breaks down string, splitting out element into , and removing it from string. + * Will not exceed size tolerances. + * + * NOTE: We could have used a strchr() pointer, but then '\0' would break it. + * (Which DOES commonly exist in IP Addressing) + * + */ +int SplitString(char *input, size_t insz, char c, char *obj, size_t objsz) +{ + size_t i, j; + int swi; + char buf[EDUI_MAXLEN]; + if ((input == NULL) || (obj == NULL) || (insz <= 0) || (objsz <= 0)) return -1; + + /* Copy input, and clear */ + memset(buf, '\0', sizeof(buf)); + memcpy(buf, input, insz); + memset(input, '\0', insz); + memset(obj, '\0', objsz); + j = 0; /* obj position */ + swi = 0; /* found data yet ? */ + + /* Scan for data, and copy */ + for (i = 0; i < insz; i++) { + /* Scan input for first non-space character */ + if (buf[i] != c) { + if (swi == 0) { + swi++; /* Data found, begin copying. */ + obj[j] = buf[i]; + j++; + } else if (swi == 1) { + obj[j] = buf[i]; + j++; + } else + break; /* end of data */ + } else { + /* Found a character c */ + if (swi == 1) + swi++; + else if (swi == 2) + break; /* end of data */ + } + } + obj[j] = '\0'; /* Terminate, i = point of split */ + + j = 0; /* Position of input */ + for (; i < insz; i++) { + /* Commented out for BINARY MODE, ie. May have '\0' as legit data * + if (buf[i] == '\0') + break; + */ + input[j] = buf[i]; + j++; + } + /* Should be correctly split back into input, and + * split object in obj. memset() at next call will + * clear array data. + */ + i = strlen(input); + j = strlen(obj); + + return j; +} + +/* Displays version information */ +void DisplayVersion() +{ + local_printfx("Squid eDirectory IP Lookup Helper %s. Copyright (C) 2009, 2010 Chad E. Naugle\n", EDUI_PROGRAM_VERSION); +} + +/* Displays program usage information */ +void DisplayUsage() +{ + DisplayVersion(); + local_printfx("\n"); + local_printfx("Usage: %s\n", edui_conf.program); + local_printfx(" -H -p [-Z] [-P] [-v 3] -b -s \n"); + local_printfx(" -D -W -F [-G] \n\n"); + local_printfx(" -d : Debug Mode.\n"); + local_printfx(" -4 : Force Addresses to be in IPv4 (127.0.0.1 format).\n"); + local_printfx(" -6 : Force Addresses to be in IPv6 (::1 format).\n"); + local_printfx(" -H : Specify hostname/ip of server.\n"); + local_printfx(" -p : Specify port number. (Range 1-65535)\n"); + local_printfx(" -Z : Enable TLS security.\n"); + local_printfx(" -P : Use persistent connections.\n"); + local_printfx(" -t : Timeout factor for persistent connections. (Default is 60 sec, set to 0 for never timeout)\n"); + local_printfx(" -v <1,2,3> : Set LDAP version to 1, 2, or 3.\n"); + local_printfx(" -b : Specify Base DN. (ie. \"o=ORG\")\n"); + local_printfx(" -s : Specify LDAP Search Scope (base, one, sub; defaults to 'base').\n"); + local_printfx(" -D : Specify Binding DN. (ie. cn=squid,o=ORG)\n"); + local_printfx(" -W : Specify Binding password.\n"); + local_printfx(" -u : Set userid attribute (Defaults to \"cn\").\n"); + local_printfx(" -F : Specify LDAP search filter. (ie. \"(objectClass=User)\")\n"); + local_printfx(" -G : Specify if LDAP search group is required. (ie. \"groupMembership=\")\n"); + local_printfx(" -V : Display version & exit.\n"); + local_printfx(" -h : This screen & exit.\n"); + local_printfx("\n"); +} + +/* Initalizes program's configuration paremeters */ +void InitConf() +{ + memset(edui_conf.program, '\0', sizeof(edui_conf.program)); + memset(edui_conf.basedn, '\0', sizeof(edui_conf.basedn)); + memset(edui_conf.host, '\0', sizeof(edui_conf.host)); + memset(edui_conf.attrib, '\0', sizeof(edui_conf.attrib)); + memset(edui_conf.dn, '\0', sizeof(edui_conf.dn)); + memset(edui_conf.passwd, '\0', sizeof(edui_conf.passwd)); + memset(edui_conf.search_filter, '\0', sizeof(edui_conf.search_filter)); + edui_conf.scope = -1; + edui_conf.ver = -1; + edui_conf.port = -1; + edui_conf.persist_timeout = -1; + edui_conf.mode = 0; + edui_conf.mode |= EDUI_MODE_INIT; + + /* Set defaults from compile-time-options */ +#ifdef EDUI_BASE_DN + strcpy(edui_conf.basedn, EDUI_BASE_DN); +#endif +#ifdef EDUI_DEFAULT_HOST + strcpy(edui_conf.host, EDUI_DEFAULT_HOST); +#endif +#ifdef EDUI_BIND_DN + strcpy(edui_conf.dn, EDUI_BIND_DN); +#endif +#ifdef EDUI_BIND_PASS + strcpy(edui_conf.passwd, EDUI_BIND_PASS); +#endif +#ifdef EDUI_USER_ATTRIB + strcpy(edui_conf.attrib, EDUI_USER_ATTRIB); +#endif +#ifdef EDUI_SEARCH_FILTER + strcpy(edui_conf.search_filter, EDUI_SEARCH_FILTER); +#endif +#ifdef EDUI_SEARCH_SCOPE + if (!strcmp(EDUI_SEARCH_SCOPE, "base")) + edui_conf.scope = 0; + else if (!strcmp(EDUI_SEARCH_SCOPE, "one")) + edui_conf.scope = 1; + else if (!strcmp(EDUI_SEARCH_SCOPE, "sub")) + edui_conf.scope = 2; + else + edui_conf.scope = 1; +#endif +#ifdef EDUI_LDAP_VERSION + edui_conf.ver = EDUI_LDAP_VERSION; +#endif +#ifdef EDUI_DEFAULT_PORT + edui_conf.port = EDUI_DEFAULT_PORT; +#endif +#ifdef EDUI_FORCE_IPV4 + edui_conf.mode |= EDUI_MODE_IPV4; +#endif +#ifdef EDUI_FORCE_IPV6 + edui_conf.mode |= EDUI_MODE_IPV6; +#endif +#ifdef EDUI_USE_TLS + edui_conf.mode |= EDUI_MODE_TLS; +#endif +#ifdef EDUI_USE_PERSIST + edui_conf.mode |= EDUI_MODE_PERSIST; +#endif +#ifdef EDUI_PERSIST_TIMEOUT + edui_conf.persist_timeout = EDUI_PERSIST_TIMEOUT; +#endif +#ifdef EDUI_GROUP_REQUIRED + edui_conf.mode |= EDUI_MODE_GROUP; +#endif +#ifdef EDUI_DEBUG + edui_conf.mode |= EDUI_MODE_DEBUG; +#endif +} + +/* Displays running configuration */ +void DisplayConf() +{ + if (!(edui_conf.mode & EDUI_MODE_DEBUG)) + return; + DisplayVersion(); + local_printfx("\n"); + local_printfx("Configuration:\n"); + if (edui_conf.mode & EDUI_MODE_DEBUG) + local_printfx(" Debug mode: ON\n"); + else + local_printfx(" Debug mode: OFF\n"); + if (edui_conf.mode & EDUI_MODE_IPV4) + local_printfx(" Address format: IPv4 (127.0.0.1)\n"); + else if (edui_conf.mode & EDUI_MODE_IPV6) + local_printfx(" Address format: IPv6 (::1)\n"); + else + local_printfx(" Address format: Not enforced.\n"); + if (edui_conf.host[0] != '\0') + local_printfx(" Hostname: %s\n", edui_conf.host); + else + local_printfx(" Hostname: localhost\n"); + if (edui_conf.port > 0) + local_printfx(" Port: %d\n", edui_conf.port); + else + local_printfx(" Port: %d\n", LDAP_PORT); + if (edui_conf.mode & EDUI_MODE_TLS) + local_printfx(" TLS mode: ON\n"); + else + local_printfx(" TLS mode: OFF\n"); + if (edui_conf.mode & EDUI_MODE_PERSIST) { + local_printfx(" Persistent mode: ON\n"); + if (edui_conf.persist_timeout > 0) + local_printfx(" Persistent mode idle timeout: %d\n", edui_conf.persist_timeout); + else + local_printfx(" Persistent mode idle timeout: OFF\n"); + } else + local_printfx(" Persistent mode: OFF\n"); + local_printfx(" LDAP Version: %d\n", edui_conf.ver); + if (edui_conf.basedn[0] != '\0') + local_printfx(" Base DN: %s\n", edui_conf.basedn); + else + local_printfx(" Base DN: None\n"); + if (edui_conf.dn[0] != '\0') + local_printfx(" Binding DN: %s\n", edui_conf.dn); + else + local_printfx(" Binding DN: Anonymous\n"); + if (edui_conf.passwd[0] != '\0') + local_printfx(" Binding Password: %s\n", edui_conf.passwd); + else + local_printfx(" Binding Password: None\n"); + switch (edui_conf.scope) { + case 0: + local_printfx(" Search Scope: base\n"); + break; + case 1: + local_printfx(" Search Scope: one level\n"); + break; + case 2: + local_printfx(" Search Scope: subtree\n"); + break; + default: + local_printfx(" Search Scope: base\n"); + break; + } + if (edui_conf.search_filter[0] != '\0') + local_printfx(" Search Filter: %s\n", edui_conf.search_filter); + else + local_printfx(" Search Filter: (&(objectClass=User)(networkAddress=*))\n"); + if (edui_conf.mode & EDUI_MODE_GROUP) + local_printfx(" Search Group Required: Yes\n"); + else + local_printfx(" Search Group Required: No\n"); + local_printfx("\n"); +} + +/* InitLDAP() - + * + * Initalize LDAP structure for use, zeroing out all variables. + * + */ +void InitLDAP(edui_ldap_t *l) +{ + if (l == NULL) return; /* Duh! */ + + l->lp = NULL; + if (l->lm != NULL) + ldap_msgfree(l->lm); + if (l->val != NULL) + ldap_value_free_len(l->val); + l->lm = NULL; + l->val = NULL; + memset(l->basedn, '\0', sizeof(l->basedn)); + memset(l->host, '\0', sizeof(l->host)); + memset(l->dn, '\0', sizeof(l->dn)); + memset(l->passwd, '\0', sizeof(l->passwd)); + memset(l->search_filter, '\0', sizeof(l->search_filter)); + memset(l->search_ip, '\0', sizeof(l->search_ip)); + memset(l->userid, '\0', sizeof(l->userid)); + l->status = 0; + l->status |= LDAP_INIT_S; + l->port = 0; + l->scope = -1; + l->type = 0; + l->err = -1; /* Set error to LDAP_SUCCESS by default */ + l->ver = 0; + l->idle_time = 0; + l->num_ent = 0; /* Number of entries in l->lm */ + l->num_val = 0; /* Number of entries in l->val */ + + /* Set default settings from conf */ + if (edui_conf.basedn[0] != '\0') + strncpy(l->basedn, edui_conf.basedn, sizeof(l->basedn)); + if (edui_conf.host[0] != '\0') + strncpy(l->host, edui_conf.host, sizeof(l->host)); + if (edui_conf.port != 0) + l->port = edui_conf.port; + if (edui_conf.dn[0] != '\0') + strncpy(l->dn, edui_conf.dn, sizeof(l->dn)); + if (edui_conf.passwd[0] != '\0') + strncpy(l->passwd, edui_conf.passwd, sizeof(l->passwd)); + if (edui_conf.search_filter[0] != '\0') + strncpy(l->search_filter, edui_conf.search_filter, sizeof(l->search_filter)); + if (!(edui_conf.scope < 0)) + l->scope = edui_conf.scope; +// local_debug("InitLDAP", "New status = %u\n", l->status); +} + +/* OpenLDAP() - + * + * Build LDAP struct with hostname and port, and ready it for binding. + * + */ +int OpenLDAP(edui_ldap_t *l, char *h, unsigned int p) +{ + if ((l == NULL) || (h == NULL)) return LDAP_ERR_NULL; + if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized, or might be in use */ + if (l->status & LDAP_OPEN_S) return LDAP_ERR_OPEN; /* Already open */ + if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND; /* Already bound */ + + strncpy(l->host, h, sizeof(l->host)); + if (p > 0) + l->port = p; + else + l->port = LDAP_PORT; /* Default is port 389 */ + +#ifdef NETSCAPE_SSL + if (l->port == LDAPS_PORT) + l->status |= (LDAP_SSL_S | LDAP_TLS_S); /* SSL Port: 636 */ +#endif + +#ifdef USE_LDAP_INIT + l->lp = ldap_init(l->host, l->port); +#else + l->lp = ldap_open(l->host, l->port); +#endif + if (l->lp == NULL) { + l->err = LDAP_CONNECT_ERROR; + return LDAP_ERR_CONNECT; /* Unable to connect */ + } else { + /* set status */ +// l->status &= ~(LDAP_INIT_S); + l->status |= LDAP_OPEN_S; + l->err = LDAP_SUCCESS; + return LDAP_ERR_SUCCESS; + } +} + +/* CloseLDAP() - + * + * Close LDAP connection, and clean up data structure. + * + */ +int CloseLDAP(edui_ldap_t *l) +{ + int s; + if (l == NULL) return LDAP_ERR_NULL; + if (l->lp == NULL) return LDAP_ERR_NULL; + if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Connection not initalized */ + if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Connection not open */ + + if (l->lm != NULL) { + ldap_msgfree(l->lm); + l->lm = NULL; + } + if (l->val != NULL) { + ldap_value_free_len(l->val); + l->val = NULL; + } + + /* okay, so it's open, close it - No need to check other criteria */ + s = ldap_unbind(l->lp); + if (s == LDAP_SUCCESS) { + l->status = LDAP_INIT_S; +// local_debug("CloseLDAP", "New status = %u\n", l->status); + l->idle_time = 0; + l->err = s; /* Set LDAP error code */ + return LDAP_ERR_SUCCESS; + } else { + l->err = s; /* Set LDAP error code */ + return LDAP_ERR_FAILED; + } +} + +/* SetVerLDAP() - + * + * Set LDAP version number for connection to of 1, 2, or 3 + * + */ +int SetVerLDAP(edui_ldap_t *l, int v) +{ + int x; + if (l == NULL) return LDAP_ERR_NULL; + if ((v > 3) || (v < 1)) return LDAP_ERR_PARAM; + if (l->lp == NULL) return LDAP_ERR_POINTER; + if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ + if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ + if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND; /* Already bound */ + + /* set version */ + x = ldap_set_option(l->lp, LDAP_OPT_PROTOCOL_VERSION, &v); + if (x == LDAP_SUCCESS) { + l->ver = v; + l->err = x; /* Set LDAP error code */ + return LDAP_ERR_SUCCESS; + } else { + l->err = x; /* Set LDAP error code */ + return LDAP_ERR_FAILED; + } +} + +/* BindLDAP() - + * + * Bind LDAP connection (Open) using optional dn and password, of + * + */ +int BindLDAP(edui_ldap_t *l, char *dn, char *pw, unsigned int t) +{ + int s; + if (l == NULL) return LDAP_ERR_NULL; + if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ + if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ + if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND; /* Already bound */ + if (l->lp == NULL) return LDAP_ERR_POINTER; /* Error */ + + /* Copy details - dn and pw CAN be NULL for anonymous and/or TLS */ + if (dn != NULL) { + if ((l->basedn[0] != '\0') && (strstr(dn, l->basedn) == NULL)) { + /* We got a basedn, but it's not part of dn */ + strncpy(l->dn, dn, sizeof(l->dn)); + strcat(l->dn, ","); + strncat(l->dn, l->basedn, sizeof(l->dn)); + } else + strncpy(l->dn, dn, sizeof(l->dn)); + } + if (pw != NULL) + strncpy(l->passwd, pw, sizeof(l->passwd)); + + /* Type ? */ + switch (t) { + case LDAP_AUTH_NONE: + l->type = t; + break; + case LDAP_AUTH_SIMPLE: + l->type = t; + break; + case LDAP_AUTH_SASL: + l->type = t; + break; + case LDAP_AUTH_KRBV4: + l->type = t; + break; + case LDAP_AUTH_KRBV41: + l->type = t; + break; + case LDAP_AUTH_KRBV42: + l->type = t; + break; +#ifdef LDAP_AUTH_TLS + case LDAP_AUTH_TLS: /* Added for chicken switch to TLS-enabled without using SSL */ + l->type = t; + break; +#endif + default: + l->type = LDAP_AUTH_NONE; + break; /* Default to anonymous bind */ + } + + /* Bind */ +#ifdef NETSCAPE_SSL + if (l->type == LDAP_AUTH_TLS) + s = ldap_start_tls_s(l->lp, NULL, NULL); + else +#endif + s = ldap_bind_s(l->lp, l->dn, l->passwd, l->type); + if (s == LDAP_SUCCESS) { + l->status |= LDAP_BIND_S; /* Success */ + l->err = s; /* Set LDAP error code */ + return LDAP_ERR_SUCCESS; + } else { + l->err = s; /* Set LDAP error code */ + return LDAP_ERR_FAILED; + } +} + +/* + * ConvertIP() - + * + * Take an IPv4 address in dot-decimal or IPv6 notation, and convert to 2-digit HEX stored in l->search_ip + * This is the networkAddress that we search LDAP for. + * + * PENDING -- CHANGE OVER TO inet*_pton + * + */ +int ConvertIP(edui_ldap_t *l, char *ip) +{ + char bufa[EDUI_MAXLEN], bufb[EDUI_MAXLEN], obj[EDUI_MAXLEN]; + char hexc[4], *p; + void *y, *z; + size_t s; + long x; + int i, j, t, swi; /* IPv6 "::" cut over toggle */ + if (l == NULL) return LDAP_ERR_NULL; + if (ip == NULL) return LDAP_ERR_PARAM; + if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ + if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ + if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND; /* Not bound */ + + y = memchr((void *)ip, ':', EDUI_MAXLEN); + z = memchr((void *)ip, '.', EDUI_MAXLEN); + if ((y != NULL) && (z != NULL)) { + y = NULL; + z = NULL; + return LDAP_ERR_INVALID; + } + if ((y != NULL) && (edui_conf.mode & EDUI_MODE_IPV4)) { + /* IPv4 Mode forced */ + return LDAP_ERR_INVALID; + } + else if (y != NULL) { + /* Set IPv6 mode */ +// local_debug("ConvertIP", "Setting IPv6 Mode.\n"); + if (l->status & LDAP_IPV4_S) + l->status &= ~(LDAP_IPV4_S); + if (!(l->status & LDAP_IPV6_S)) + l->status |= (LDAP_IPV6_S); + y = NULL; + } + if ((z != NULL) && (edui_conf.mode & EDUI_MODE_IPV6)) { + /* IPv6 Mode forced */ + return LDAP_ERR_INVALID; + } + else if (z != NULL) { +// local_debug("ConvertIP", "Setting IPv4 Mode.\n"); + /* Set IPv4 mode */ + if (l->status & LDAP_IPV6_S) + l->status &= ~(LDAP_IPV6_S); + if (!(l->status & LDAP_IPV4_S)) + l->status |= (LDAP_IPV4_S); + z = NULL; + } + s = strlen(ip); + memset(bufa, '\0', sizeof(bufa)); + memset(bufb, '\0', sizeof(bufb)); + memset(obj, '\0', sizeof(obj)); + /* SplitString() will zero out bufa & obj at each call */ + memset(l->search_ip, '\0', sizeof(l->search_ip)); + strncpy(bufa, ip, s); /* To avoid segfaults, use bufa instead of ip */ + swi = 0; + if (l->status & LDAP_IPV6_S) { + /* Search for :: in string */ + if ((bufa[0] == ':') && (bufa[1] == ':')) { + /* bufa starts with a ::, so just copy and clear */ + strncpy(bufb, bufa, sizeof(bufa)); + memset(bufa, '\0', strlen(bufa)); + swi++; /* Indicates that there is a bufb */ + } else if ((bufa[0] == ':') && (bufa[1] != ':')) { + /* bufa starts with a :, a typo so just fill in a ':', cat and clear */ + bufb[0] = ':'; + strncat(bufb, bufa, sizeof(bufa)); + memset(bufa, '\0', strlen(bufa)); + swi++; /* Indicates that there is a bufb */ + } else { + p = strstr(bufa, "::"); + if (p != NULL) { + /* Found it, break bufa down and split into bufb here */ + memset(bufb, '\0', strlen(bufb)); + i = strlen(p); + memcpy(bufb, p, i); + *p = '\0'; + bufb[i] = '\0'; + swi++; /* Indicates that there is a bufb */ + } + } + } + s = strlen(bufa); + if (s < 1) + s = strlen(bufb); + while (s > 0) { + if ((l->status & LDAP_IPV4_S) && (swi == 0)) { + /* Break down IPv4 address */ + t = SplitString(bufa, s, '.', obj, sizeof(obj)); + if (t > 0) { + errno = 0; + x = strtol(obj, (char **)NULL, 10); + if (((x < 0) || (x > 255)) || ((errno != 0) && (x == 0)) || ((obj[0] != '0') && (x == 0))) + return LDAP_ERR_OOB; /* Out of bounds -- Invalid address */ + memset(hexc, '\0', sizeof(hexc)); + snprintf(hexc, sizeof(hexc), "%.2X", (int)x); + strncat(l->search_ip, hexc, sizeof(l->search_ip)); + } else + break; /* reached end of octet */ + } else if (l->status & LDAP_IPV6_S) { + /* Break down IPv6 address */ + if (swi > 1) + t = SplitString(bufb, s, ':', obj, sizeof(obj)); /* After "::" */ + else + t = SplitString(bufa, s, ':', obj, sizeof(obj)); /* Before "::" */ + /* Convert octet by size (t) - and fill 0's */ + switch (t) { /* IPv6 is already in HEX, copy contents */ + case 4: + hexc[0] = (char) toupper((int)obj[0]); + i = (int)hexc[0]; + if (!isxdigit(i)) + return LDAP_ERR_OOB; /* Out of bounds */ + hexc[1] = (char) toupper((int)obj[1]); + i = (int)hexc[1]; + if (!isxdigit(i)) + return LDAP_ERR_OOB; /* Out of bounds */ + hexc[2] = '\0'; + strncat(l->search_ip, hexc, sizeof(l->search_ip)); + hexc[0] = (char) toupper((int)obj[2]); + i = (int)hexc[0]; + if (!isxdigit(i)) + return LDAP_ERR_OOB; /* Out of bounds */ + hexc[1] = (char) toupper((int)obj[3]); + i = (int)hexc[1]; + if (!isxdigit(i)) + return LDAP_ERR_OOB; /* Out of bounds */ + hexc[2] = '\0'; + strncat(l->search_ip, hexc, sizeof(l->search_ip)); + break; + case 3: + hexc[0] = '0'; + hexc[1] = (char) toupper((int)obj[0]); + i = (int)hexc[1]; + if (!isxdigit(i)) + return LDAP_ERR_OOB; /* Out of bounds */ + hexc[2] = '\0'; + strncat(l->search_ip, hexc, sizeof(l->search_ip)); + hexc[0] = (char) toupper((int)obj[1]); + i = (int)hexc[0]; + if (!isxdigit(i)) + return LDAP_ERR_OOB; /* Out of bounds */ + hexc[1] = (char) toupper((int)obj[2]); + i = (int)hexc[1]; + if (!isxdigit(i)) + return LDAP_ERR_OOB; /* Out of bounds */ + hexc[2] = '\0'; + strncat(l->search_ip, hexc, sizeof(l->search_ip)); + break; + case 2: + strncat(l->search_ip, "00", sizeof(l->search_ip)); + hexc[0] = (char) toupper((int)obj[0]); + i = (int)hexc[0]; + if (!isxdigit(i)) + return LDAP_ERR_OOB; /* Out of bounds */ + hexc[1] = (char) toupper((int)obj[1]); + i = (int)hexc[1]; + if (!isxdigit(i)) + return LDAP_ERR_OOB; /* Out of bounds */ + hexc[2] = '\0'; + strncat(l->search_ip, hexc, sizeof(l->search_ip)); + break; + case 1: + strncat(l->search_ip, "00", sizeof(l->search_ip)); + hexc[0] = '0'; + hexc[1] = (char) toupper((int)obj[0]); + i = (int)hexc[1]; + if (!isxdigit(i)) + return LDAP_ERR_OOB; /* Out of bounds */ + hexc[2] = '\0'; + strncat(l->search_ip, hexc, sizeof(l->search_ip)); + break; + default: + if (t > 4) + return LDAP_ERR_OOB; + break; + } + /* Code to pad the address with 0's between a '::' */ + if ((strlen(bufa) == 0) && (swi == 1)) { + /* We are *AT* the split, pad in some 0000 */ + t = strlen(bufb); + /* How many ':' exist in bufb ? */ + j = 0; + for (i = 0; i < t; i++) { + if (bufb[i] == ':') + j++; + } + j--; /* Preceeding "::" doesn't count */ + t = 8 - (strlen(l->search_ip) / 4) - j; /* Remainder */ + if (t > 0) { + for (i = 0; i < t; i++) + strncat(l->search_ip, "0000", sizeof(l->search_ip)); + } + } + } + if ((bufa[0] == '\0') && (swi > 0)) { + s = strlen(bufb); + swi++; + } else + s = strlen(bufa); + } + s = strlen(l->search_ip); + + /* CHECK sizes of address, truncate or pad */ + /* if "::" is at end of ip, then pad another block or two */ + while ((l->status & LDAP_IPV6_S) && (s < 32)) { + strncat(l->search_ip, "0000", sizeof(l->search_ip)); + s = strlen(l->search_ip); + } + if ((l->status & LDAP_IPV6_S) && (s > 32)) { + /* Too long, truncate */ + l->search_ip[32] = '\0'; + s = strlen(l->search_ip); + } + /* If at end of ip, and its not long enough, then pad another block or two */ + while ((l->status & LDAP_IPV4_S) && (s < 8)) { + strncat(l->search_ip, "00", sizeof(l->search_ip)); + s = strlen(l->search_ip); + } + if ((l->status & LDAP_IPV4_S) && (s > 8)) { + /* Too long, truncate */ + l->search_ip[8] = '\0'; + s = strlen(l->search_ip); + } + + /* Completed, s is length of address in HEX */ + return s; +} + +/* ResetLDAP() - + * + * Resets LDAP connection for next search query. + * + */ +int ResetLDAP(edui_ldap_t *l) { + if (l == NULL) return LDAP_ERR_NULL; + if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ + if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ + if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND; /* Not bound */ + if (!(l->status & LDAP_PERSIST_S)) return LDAP_ERR_PERSIST; /* Not persistent */ + + /* Cleanup data struct */ +// local_debug("ResetLDAP", "Resetting LDAP connection for next query. (status = %u)\n", l->status); + if (l->status & LDAP_VAL_S) + l->status &= ~(LDAP_VAL_S); + if (l->status & LDAP_SEARCH_S) + l->status &= ~(LDAP_SEARCH_S); + if (l->status & LDAP_IPV4_S) + l->status &= ~(LDAP_IPV4_S); + if (l->status & LDAP_IPV6_S) + l->status &= ~(LDAP_IPV6_S); + if (l->lm != NULL) { + ldap_msgfree(l->lm); + l->lm = NULL; + } + if (l->val != NULL) { + ldap_value_free_len(l->val); + l->val = NULL; + } + memset(l->search_ip, '\0', sizeof(l->search_ip)); + memset(l->search_filter, '\0', strlen(l->search_filter)); + strncpy(l->search_filter, edui_conf.search_filter, sizeof(l->search_filter)); + memset(l->userid, '\0', strlen(l->userid)); + if (!(l->status & LDAP_IDLE_S)) + l->status |= LDAP_IDLE_S; /* Set idle mode */ + l->num_ent = 0; + l->num_val = 0; +// local_debug("ResetLDAP", "New status = %u\n", l->status); + l->err = LDAP_SUCCESS; + return LDAP_ERR_SUCCESS; +} + +/* + * SearchFilterLDAP() - + * + * Build LDAP Search Filter string and copy to l->search_filter + * + */ +int SearchFilterLDAP(edui_ldap_t *l, char *group) +{ + size_t i, j, s; + int swi; + char bufa[EDUI_MAXLEN], bufb[EDUI_MAXLEN], bufc[EDUI_MAXLEN], bufd[EDUI_MAXLEN], bufg[EDUI_MAXLEN]; + if (l == NULL) return LDAP_ERR_NULL; +// if (group == NULL) return LDAP_ERR_PARAM; + if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ + if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ + if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND; /* Not Bound */ + if (l->search_ip[0] == '\0') return LDAP_ERR_DATA; /* Search IP is required */ + + /* Zero out if not already */ + memset(bufa, '\0', strlen(bufa)); + memset(bufb, '\0', strlen(bufb)); + memset(bufc, '\0', strlen(bufc)); + memset(bufd, '\0', strlen(bufd)); + memset(bufg, '\0', strlen(bufg)); + +// local_debug("SearchFilterLDAP", "Building... (Adding '\\' to IP...) "); + s = strlen(l->search_ip); + bufc[0] = '\134'; + swi = 0; + j = 1; + for (i = 0; i < s; i++) { + if (swi == 2) { + bufc[j] = '\134'; + j++; + bufc[j] = l->search_ip[i]; + j++; + swi = 1; + } else { + bufc[j] = l->search_ip[i]; + j++; + swi++; + } + } + if (group == NULL) { + /* No groupMembership= to add, yay! */ + strcpy(bufa, "(&"); + strncat(bufa, edui_conf.search_filter, sizeof(bufa)); + /* networkAddress */ + snprintf(bufb, sizeof(bufb), "(|(networkAddress=1\\23%s)", \ + bufc); + if (l->status & LDAP_IPV4_S) { + snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s))", \ + bufc, bufc); + strncat(bufb, bufd, sizeof(bufb)); + } else if (l->status & LDAP_IPV6_S) { + snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s))", \ + bufc, bufc); + strncat(bufb, bufd, sizeof(bufb)); + } else + strncat(bufb, ")", sizeof(bufb)); +// local_debug("SearchFilterLDAP", "bufb: %s\n", bufb); + strncat(bufa, bufb, sizeof(bufa)); + strncat(bufa, ")", sizeof(bufa)); + } else { + /* Needs groupMembership= to add... */ + strcpy(bufa, "(&(&"); + strncat(bufa, edui_conf.search_filter, sizeof(bufa)); + /* groupMembership -- NOTE: Squid *MUST* provide "cn=" from squid.conf */ + snprintf(bufg, sizeof(bufg), "(groupMembership=%s", group); + if ((l->basedn[0] != '\0') && (strstr(group, l->basedn) == NULL)) { + strncat(bufg, ",", sizeof(bufg)); + strncat(bufg, l->basedn, sizeof(bufg)); + } + strncat(bufg, ")", sizeof(bufg)); +// local_debug("SearchFilterLDAP", "bufg: %s\n", bufg); + strncat(bufa, bufg, sizeof(bufa)); + /* networkAddress */ + snprintf(bufb, sizeof(bufb), "(|(networkAddress=1\\23%s)", \ + bufc); + if (l->status & LDAP_IPV4_S) { + snprintf(bufd, sizeof(bufd), "(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s))", \ + bufc, bufc); + strncat(bufb, bufd, sizeof(bufb)); + } else if (l->status & LDAP_IPV6_S) { + snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s))", \ + bufc, bufc); + strncat(bufb, bufd, sizeof(bufb)); + } else + strncat(bufb, ")", sizeof(bufb)); +// local_debug("SearchFilterLDAP", "bufb: %s\n", bufb); + strncat(bufa, bufb, sizeof(bufa)); + strncat(bufa, "))", sizeof(bufa)); + } + s = strlen(bufa); + strcpy(l->search_filter, bufa); + return s; +} + +/* + * SearchLDAP() - + * + * Initate LDAP query, under levels, filtering matches with and optionally + * will generally be networkAddress ... + * + */ +int SearchLDAP(edui_ldap_t *l, int scope, char *filter, char **attrs) +{ + int s; + char ft[EDUI_MAXLEN]; + if (l == NULL) return LDAP_ERR_NULL; + if ((scope < 0) || (filter == NULL)) return LDAP_ERR_PARAM; /* If attrs is NULL, then all attrs will return */ + if (l->lp == NULL) return LDAP_ERR_POINTER; + if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ + if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ + if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND; /* Not bound */ + if (l->status & LDAP_SEARCH_S) return LDAP_ERR_SEARCHED; /* Already searching */ + if (l->basedn[0] == '\0') return LDAP_ERR_DATA; /* We require a basedn */ + if (l->lm != NULL) + ldap_msgfree(l->lm); /* Make sure l->lm is empty */ + + if (filter == NULL) /* if filter is NULL, then return ALL networkAddress */ + strcpy(ft, "(&(objectClass=User)(networkAddress=*))"); + else + strncpy(ft, filter, sizeof(ft)); + + /* We have a binded connection, with a free l->lm, so let's get this done */ + switch (scope) { + case 0: + s = ldap_search_s(l->lp, l->basedn, LDAP_SCOPE_BASE, ft, attrs, 0, &(l->lm)); + break; + case 1: + s = ldap_search_s(l->lp, l->basedn, LDAP_SCOPE_ONELEVEL, ft, attrs, 0, &(l->lm)); + break; + case 2: + s = ldap_search_s(l->lp, l->basedn, LDAP_SCOPE_SUBTREE, ft, attrs, 0, &(l->lm)); + break; + default: + /* Only search BASE by default */ + s = ldap_search_s(l->lp, l->basedn, LDAP_SCOPE_BASE, ft, attrs, 0, &(l->lm)); + break; + } + if (s == LDAP_SUCCESS) { + l->status |= (LDAP_SEARCH_S); /* Mark as searched */ + l->err = s; + l->idle_time = 0; /* Connection in use, reset idle timer */ + l->num_ent = ldap_count_entries(l->lp, l->lm); /* Counted */ + return LDAP_ERR_SUCCESS; + } else { + l->err = s; + l->num_ent = (-1); + return LDAP_ERR_FAILED; + } +} + +/* + * GetValLDAP() - + * + * Scan LDAP and look for search-attr, then return results in l->val + * + */ +int GetValLDAP(edui_ldap_t *l, char *attr) +{ + ber_len_t x; + /* + ber_len_t i, j; + int c; + */ + LDAPMessage *ent; + if (l == NULL) return LDAP_ERR_NULL; + if (attr == NULL) return LDAP_ERR_PARAM; + if (l->lp == NULL) return LDAP_ERR_POINTER; + if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ + if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ + if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND; /* Not bound */ + if (!(l->status & LDAP_SEARCH_S)) return LDAP_ERR_NOT_SEARCHED; /* Not searched */ + if (l->num_ent <= 0) return LDAP_ERR_DATA; /* No entries found */ + if (l->val != NULL) + ldap_value_free_len(l->val); /* Clear data before populating */ + l->num_val = 0; + if (l->status & LDAP_VAL_S) + l->status &= ~(LDAP_VAL_S); /* Clear VAL bit */ + + /* Sift through entries -- Look for matches */ + for (ent = ldap_first_entry(l->lp, l->lm); ent != NULL; ent = ldap_next_entry(l->lp, ent)) { + l->val = ldap_get_values_len(l->lp, ent, attr); + if (l->val != NULL) { + x = ldap_count_values_len(l->val); /* We got x values ... */ + l->num_val = x; + if (x > 0) { + /* Display all values */ + /* + for (i = 0; i < x; i++) { + local_debug("GetValLDAP", "value[%zd]: \"%s\"\n", i, l->val[i]->bv_val); + local_debug("GetValLDAP", "value[%zd]: ", i); + for (j = 0; j < (l->val[i]->bv_len); j++) { + c = (int) l->val[i]->bv_val[j]; + if (c < 0) + c = c + 256; + local_debugx("%.2X", c); + } + local_debugx("\n"); + } + */ + /* CRASHES?!?! + if (ent != NULL) + ldap_msgfree(ent); + */ + if (l->lm != NULL) { + ldap_msgfree(l->lm); + l->lm = NULL; + } + l->num_ent = 0; + l->status &= ~(LDAP_SEARCH_S); + l->status |= LDAP_VAL_S; + l->err = LDAP_SUCCESS; + return LDAP_ERR_SUCCESS; /* Found it */ + } + } + /* Attr not found, continue */ + } + /* No entries found using attr */ + if (l->val != NULL) + ldap_value_free_len(l->val); + /* + if (ent != NULL) + ldap_msgfree(ent); + */ + if (l->lm != NULL) { + ldap_msgfree(l->lm); + l->lm = NULL; + } + l->num_ent = 0; + l->num_val = 0; + l->err = LDAP_NO_SUCH_OBJECT; + l->status &= ~(LDAP_SEARCH_S); + return LDAP_ERR_NOTFOUND; /* Not found */ +} + +/* + * SearchIPLDAP() - + * + * Scan LDAP and get all networkAddress Values, and see if they match l->search_ip + * Actual IP matching routine for eDirectory + * + */ +int SearchIPLDAP(edui_ldap_t *l, char *uid) +{ + ber_len_t i, x; + ber_len_t j, k; + ber_len_t y, z; + int c; + char bufa[EDUI_MAXLEN], bufb[EDUI_MAXLEN], hexc[4]; + LDAPMessage *ent; + struct berval **ber; + if (l == NULL) return LDAP_ERR_NULL; + if (uid == NULL) return LDAP_ERR_PARAM; + if (l->lp == NULL) return LDAP_ERR_POINTER; + if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ + if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ + if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND; /* Not bound */ + if (!(l->status & LDAP_SEARCH_S)) return LDAP_ERR_NOT_SEARCHED; /* Not searched */ + if (l->num_ent <= 0) return LDAP_ERR_DATA; /* No entries found */ + if (l->val != NULL) + ldap_value_free_len(l->val); /* Clear data before populating */ + l->num_val = 0; + if (l->status & LDAP_VAL_S) + l->status &= ~(LDAP_VAL_S); /* Clear VAL bit */ + if (edui_conf.attrib[0] == '\0') + strcpy(edui_conf.attrib, "cn"); /* Make sure edui_conf.attrib is set */ + + /* Sift through entries */ + for (ent = ldap_first_entry(l->lp, l->lm); ent != NULL; ent = ldap_next_entry(l->lp, ent)) { + l->val = ldap_get_values_len(l->lp, ent, "networkAddress"); + ber = ldap_get_values_len(l->lp, ent, edui_conf.attrib); /* edui_conf.attrib is the mapping */ + if (l->val != NULL) { + x = ldap_count_values_len(l->val); /* We got x values ... */ + l->num_val = x; + if (x > 0) { + /* Display all values */ + for (i = 0; i < x; i++) { + j = l->val[i]->bv_len; + memcpy(bufa, l->val[i]->bv_val, j); + z = SplitString(bufa, j, '#', bufb, sizeof(bufb)); + /* + local_debug("SearchIPLDAP", "value[%zd]: SplitString(", i); + for (k = 0; k < z; k++) { + c = (int) bufb[k]; + if (c < 0) + c = c + 256; + local_debugx("%.2X", c); + } + local_debugx(", "); + for (k = 0; k < (j - z - 1); k++) { + c = (int) bufa[k]; + if (c < 0) + c = c + 256; + local_debugx("%.2X", c); + } + local_debugx("): %zd\n", z); + */ + z = j - z - 1; + j = atoi(bufb); + switch (j) { + case 0: /* IPX address (We don't support these right now) */ + break; + case 1: /* IPv4 address (eDirectory 8.7 and below) */ + /* bufa is the address, just compare it */ + if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S)) + break; /* Not looking for IPv4 */ + for (k = 0; k < z; k++) { + c = (int) bufa[k]; + if (c < 0) + c = c + 256; + snprintf(hexc, sizeof(hexc), "%.2X", c); + if (k == 0) + strncpy(bufb, hexc, sizeof(bufb)); + else + strncat(bufb, hexc, sizeof(bufb)); + } + y = strlen(bufb); + /* Compare value with IP */ + if (bcmp(l->search_ip, bufb, y) == 0) { + /* We got a match! - Scan 'ber' for 'cn' values */ + z = ldap_count_values_len(ber); + for (j = 0; j < z; j++) + strncpy(uid, ber[j]->bv_val, ber[j]->bv_len); + ldap_value_free_len(l->val); + l->val = NULL; + ldap_value_free_len(ber); + ber = NULL; + l->num_val = 0; + l->err = LDAP_SUCCESS; + l->status &= ~(LDAP_SEARCH_S); + return LDAP_ERR_SUCCESS; /* We got our userid */ + } + /* Not matched, continue */ + break; + case 8: /* IPv4 (UDP) address (eDirectory 8.8 and higher) */ + /* bufa + 2 is the address (skip 2 digit port) */ + if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S)) + break; /* Not looking for IPv4 */ + for (k = 2; k < z; k++) { + c = (int) bufa[k]; + if (c < 0) + c = c + 256; + snprintf(hexc, sizeof(hexc), "%.2X", c); + if (k == 2) + strncpy(bufb, hexc, sizeof(bufb)); + else + strncat(bufb, hexc, sizeof(bufb)); + } + y = strlen(bufb); + /* Compare value with IP */ + if (bcmp(l->search_ip, bufb, y) == 0) { + /* We got a match! - Scan 'ber' for 'cn' values */ + z = ldap_count_values_len(ber); + for (j = 0; j < z; j++) + strncpy(uid, ber[j]->bv_val, ber[j]->bv_len); + ldap_value_free_len(l->val); + l->val = NULL; + ldap_value_free_len(ber); + ber = NULL; + l->num_val = 0; + l->err = LDAP_SUCCESS; + l->status &= ~(LDAP_SEARCH_S); + return LDAP_ERR_SUCCESS; /* We got our userid */ + } + /* Not matched, continue */ + break; + case 9: /* IPv4 (TCP) address (eDirectory 8.8 and higher) */ + /* bufa + 2 is the address (skip 2 digit port) */ + if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S)) + break; /* Not looking for IPv4 */ + for (k = 2; k < z; k++) { + c = (int) bufa[k]; + if (c < 0) + c = c + 256; + snprintf(hexc, sizeof(hexc), "%.2X", c); + if (k == 2) + strncpy(bufb, hexc, sizeof(bufb)); + else + strncat(bufb, hexc, sizeof(bufb)); + } + y = strlen(bufb); + /* Compare value with IP */ + if (bcmp(l->search_ip, bufb, y) == 0) { + /* We got a match! - Scan 'ber' for 'cn' values */ + z = ldap_count_values_len(ber); + for (j = 0; j < z; j++) + strncpy(uid, ber[j]->bv_val, ber[j]->bv_len); + ldap_value_free_len(l->val); + l->val = NULL; + ldap_value_free_len(ber); + ber = NULL; + l->num_val = 0; + l->err = LDAP_SUCCESS; + l->status &= ~(LDAP_SEARCH_S); + return LDAP_ERR_SUCCESS; /* We got our userid */ + } + /* Not matched, continue */ + break; + case 10: /* IPv6 (UDP) address (eDirectory 8.8 and higher) */ + /* bufa + 2 is the address (skip 2 digit port) */ + if (!(l->status & LDAP_IPV6_S)) + break; /* Not looking for IPv6 */ + for (k = 2; k < z; k++) { + c = (int) bufa[k]; + if (c < 0) + c = c + 256; + snprintf(hexc, sizeof(hexc), "%.2X", c); + if (k == 2) + strncpy(bufb, hexc, sizeof(bufb)); + else + strncat(bufb, hexc, sizeof(bufb)); + } + y = strlen(bufb); + /* Compare value with IP */ + if (bcmp(l->search_ip, bufb, y) == 0) { + /* We got a match! - Scan 'ber' for 'cn' values */ + z = ldap_count_values_len(ber); + for (j = 0; j < z; j++) + strncpy(uid, ber[j]->bv_val, ber[j]->bv_len); + ldap_value_free_len(l->val); + l->val = NULL; + ldap_value_free_len(ber); + ber = NULL; + l->num_val = 0; + l->err = LDAP_SUCCESS; + l->status &= ~(LDAP_SEARCH_S); + return LDAP_ERR_SUCCESS; /* We got our userid */ + } + /* Not matched, continue */ + break; + case 11: /* IPv6 (TCP) address (eDirectory 8.8 and higher) */ + /* bufa + 2 is the address (skip 2 digit port) */ + if (!(l->status & LDAP_IPV6_S)) + break; /* Not looking for IPv6 */ + for (k = 2; k < z; k++) { + c = (int) bufa[k]; + if (c < 0) + c = c + 256; + snprintf(hexc, sizeof(hexc), "%.2X", c); + if (k == 2) + strncpy(bufb, hexc, sizeof(bufb)); + else + strncat(bufb, hexc, sizeof(bufb)); + } + y = strlen(bufb); + /* Compare value with IP */ + if (bcmp(l->search_ip, bufb, y) == 0) { + /* We got a match! - Scan 'ber' for 'cn' values */ + z = ldap_count_values_len(ber); + for (j = 0; j < z; j++) + strncpy(uid, ber[j]->bv_val, ber[j]->bv_len); + ldap_value_free_len(l->val); + l->val = NULL; + ldap_value_free_len(ber); + ber = NULL; + l->num_val = 0; + l->err = LDAP_SUCCESS; + l->status &= ~(LDAP_SEARCH_S); + return LDAP_ERR_SUCCESS; /* We gout our userid */ + } + /* Not matched, continue */ + break; + default: /* Other, unsupported */ + break; + } + } + if (ber != NULL) { + ldap_value_free_len(ber); + ber = NULL; + } + } + ldap_value_free_len(l->val); + l->val = NULL; + } + if (ber != NULL) { + ldap_value_free_len(ber); + ber = NULL; + } + /* Attr not found, continue */ + } + /* No entries found using given attr */ + if (l->val != NULL) { + ldap_value_free_len(l->val); + l->val = NULL; + } + if (ber != NULL) { + ldap_value_free_len(ber); + ber = NULL; + } + if (ent != NULL) { + ldap_msgfree(ent); + ent = NULL; + } + if (l->lm != NULL) { + ldap_msgfree(l->lm); + l->lm = NULL; + } + l->num_ent = 0; + l->num_val = 0; + l->err = LDAP_NO_SUCH_OBJECT; + l->status &= ~(LDAP_SEARCH_S); + return LDAP_ERR_NOTFOUND; /* Not found ... Sorry :) */ +} + +char *ErrLDAP(int e) +{ + switch (e) { + case LDAP_ERR_NULL: + return "Null pointer provided"; + case LDAP_ERR_POINTER: + return "Null LDAP pointer"; + case LDAP_ERR_PARAM: + return "Null or Missing paremeter(s)"; + case LDAP_ERR_INIT: + return "LDAP data not initalized"; + case LDAP_ERR_OPEN: + return "LDAP connection is not active"; + case LDAP_ERR_CONNECT: + return "Unable to connect to LDAP host"; + case LDAP_ERR_BIND: + return "LDAP connection is not bound"; + case LDAP_ERR_SEARCHED: + return "LDAP connection has already been searched"; + case LDAP_ERR_NOT_SEARCHED: + return "LDAP connection has not been searched"; + case LDAP_ERR_INVALID: + return "Invalid paremeters"; + case LDAP_ERR_OOB: + return "Paremeter is out of bounds"; + case LDAP_ERR_PERSIST: + return "Persistent mode is not active"; + case LDAP_ERR_DATA: + return "Required data has not been found"; + case LDAP_ERR_NOTFOUND: + return "Item or object has not been found"; + case LDAP_ERR_OTHER: + return "An unknown error has occured"; + case LDAP_ERR_FAILED: + return "Operation has failed"; + case LDAP_ERR_SUCCESS: + return "Operation is successful"; + default: + return "An unknown error has occured"; + } +} + +/* Signal Trap routine */ +static void SigTrap(int s) +{ + if (!(edui_conf.mode & EDUI_MODE_KILL)) + edui_conf.mode |= EDUI_MODE_KILL; + + /* Clean Up */ + if (edui_ldap.status & LDAP_OPEN_S) + CloseLDAP(&edui_ldap); + + local_debug("SigTrap", "Terminating, Signal: %d\n", s); + exit(0); +} + +/* main() - function */ +int main(int argc, char **argv) +{ + char bufa[EDUI_MAXLEN], bufb[EDUI_MAXLEN], *p = NULL; + char bufc[EDUI_MAXLEN]; + char sfmod[EDUI_MAXLEN]; + int x; + size_t i, j, s, k; + time_t t; + struct sigaction sv; + + /* Init */ + k = (size_t) argc; + memset(bufa, '\0', sizeof(bufa)); + memset(bufb, '\0', sizeof(bufb)); + memset(bufc, '\0', sizeof(bufc)); + memset(sfmod, '\0', sizeof(sfmod)); + InitConf(); + strncpy(edui_conf.program, argv[0], sizeof(edui_conf.program)); + edui_now = -1; + t = -1; + local_debug("main", "InitConf() done.\n"); + + /* Scan args */ + if (k > 1) { + for (i = 1; i < k; i++) { + /* Classic / novelty usage schemes */ + if (!strcmp(argv[i], "--help")) { + DisplayUsage(); + return 1; + } else if (!strcmp(argv[i], "--usage")) { + DisplayUsage(); + return 1; + } else if (!strcmp(argv[i], "--version")) { + DisplayVersion(); + return 1; + } else if (argv[i][0] == '-') { + s = strlen(argv[i]); + for (j = 1; j < s; j++) { + switch (argv[i][j]) { + case 'h': + DisplayUsage(); + return 1; + case 'V': + DisplayVersion(); + return 1; + case 'd': + if (!(edui_conf.mode & EDUI_MODE_DEBUG)) + edui_conf.mode |= EDUI_MODE_DEBUG; /* Don't set mode more than once */ + debug_enabled = 1; /* Squid-3 Debug Mode */ + break; + case '4': + if (!(edui_conf.mode & EDUI_MODE_IPV4) || !(edui_conf.mode & EDUI_MODE_IPV6)) + edui_conf.mode |= EDUI_MODE_IPV4; /* Don't set mode more than once */ + break; + case '6': + if (!(edui_conf.mode & EDUI_MODE_IPV4) || !(edui_conf.mode & EDUI_MODE_IPV6)) + edui_conf.mode |= EDUI_MODE_IPV6; /* Don't set mode more than once */ + break; + case 'Z': + if (!(edui_conf.mode & EDUI_MODE_TLS)) + edui_conf.mode |= EDUI_MODE_TLS; /* Don't set mode more than once */ + break; + case 'P': + if (!(edui_conf.mode & EDUI_MODE_PERSIST)) + edui_conf.mode |= EDUI_MODE_PERSIST; /* Don't set mode more than once */ + break; + case 'v': + i++; + if (argv[i] != NULL) { + edui_conf.ver = atoi(argv[i]); + if (edui_conf.ver < 1) + edui_conf.ver = 1; + else if (edui_conf.ver > 3) + edui_conf.ver = 3; + } else { + local_printfx("No parameters given for 'v'.\n"); + DisplayUsage(); + return 1; + } + break; + case 't': + i++; + if (argv[i] != NULL) { + edui_conf.persist_timeout = atoi(argv[i]); + if (edui_conf.persist_timeout < 0) + edui_conf.persist_timeout = 0; + } else { + local_printfx("No parameters given for 't'.\n"); + DisplayUsage(); + return 1; + } + break; + case 'b': + i++; /* Set Base DN */ + if (argv[i] != NULL) + strncpy(edui_conf.basedn, argv[i], sizeof(edui_conf.basedn)); + else { + local_printfx("No parameters given for 'b'.\n"); + DisplayUsage(); + return 1; + } + break; + case 'H': + i++; /* Set Hostname */ + if (argv[i] != NULL) + strncpy(edui_conf.host, argv[i], sizeof(edui_conf.host)); + else { + local_printfx("No parameters given for 'H'.\n"); + DisplayUsage(); + return 1; + } + break; + case 'p': + i++; /* Set port */ + if (argv[i] != NULL) + edui_conf.port = atoi(argv[i]); + else { + local_printfx("No parameters given for 'p'.\n"); + DisplayUsage(); + return 1; + } + break; + case 'D': + i++; /* Set Bind DN */ + if (argv[i] != NULL) + strncpy(edui_conf.dn, argv[i], sizeof(edui_conf.dn)); + else { + local_printfx("No parameters given for 'D'.\n"); + DisplayUsage(); + return 1; + } + break; + case 'W': + i++; /* Set Bind PWD */ + if (argv[i] != NULL) + strncpy(edui_conf.passwd, argv[i], sizeof(edui_conf.passwd)); + else { + local_printfx("No parameters given for 'W'.\n"); + DisplayUsage(); + return 1; + } + break; + case 'F': + i++; /* Set Search Filter */ + if (argv[i] != NULL) + strncpy(edui_conf.search_filter, argv[i], sizeof(edui_conf.search_filter)); + else { + local_printfx("No parameters given for 'F'.\n"); + DisplayUsage(); + return 1; + } + break; + case 'G': + if (!(edui_conf.mode & EDUI_MODE_GROUP)) + edui_conf.mode |= EDUI_MODE_GROUP; /* Don't set mode more than once */ + break; + case 's': + i++; /* Set Scope Level */ + if (argv[i] != NULL) { + if (!strncmp(argv[i], "base", 4)) + edui_conf.scope = 0; + else if (!strncmp(argv[i], "one", 4)) + edui_conf.scope = 1; + else if (!strncmp(argv[i], "sub", 4)) + edui_conf.scope = 2; + else + edui_conf.scope = 1; /* Default is 'one' */ + } else { + local_printfx("No parameters given for 's'.\n"); + DisplayUsage(); + return 1; + } + break; + case '-': /* We got a second '-' ... ignore */ + break; + default: + local_printfx("Invalid parameter - '%c'.\n", argv[i][j]); + break; + } + } + } else { + /* Incorrect parameter, display usage */ + DisplayUsage(); + return 1; + } + } + } + + /* Set predefined required paremeters if none are given, localhost:LDAP_PORT, etc */ + if (edui_conf.host[0] == '\0') /* Default to localhost */ + strcpy(edui_conf.host, "localhost"); + if (edui_conf.port < 0) + edui_conf.port = LDAP_PORT; /* Default: LDAP_PORT */ + if ((edui_conf.mode & EDUI_MODE_IPV4) && (edui_conf.mode & EDUI_MODE_IPV6)) + edui_conf.mode &= ~(EDUI_MODE_IPV6); /* Default to IPv4 */ + if (edui_conf.ver < 0) + edui_conf.ver = 2; + if (!(edui_conf.mode & EDUI_MODE_TLS)) + edui_conf.mode |= EDUI_MODE_TLS; /* eDirectory requires TLS mode */ + if ((edui_conf.mode & EDUI_MODE_TLS) && (edui_conf.ver < 3)) + edui_conf.ver = 3; /* TLS requires version 3 */ + if (edui_conf.persist_timeout < 0) + edui_conf.persist_timeout = 600; /* Default: 600 seconds (10 minutes) */ + if (edui_conf.scope < 0) + edui_conf.scope = 1; /* Default: one */ + if (edui_conf.search_filter[0] == '\0') + strcpy(edui_conf.search_filter, "(&(objectclass=User)(networkAddress=*))"); + if (edui_conf.attrib[0] == '\0') + strcpy(edui_conf.attrib, "cn"); + if (edui_conf.basedn[0] == '\0') { + local_printfx("FATAL: No '-b' option provided (Base DN).\n"); + DisplayUsage(); + return 1; + } + local_debug("main", "Configuration done.\n"); + + DisplayConf(); + /* Done with arguments */ + + /* Trap the following signals */ + sigemptyset(&sv.sa_mask); + sv.sa_handler = SigTrap; + sigaction(SIGTERM, &sv, NULL); + sv.sa_handler = SigTrap; + sigaction(SIGHUP, &sv, NULL); + sv.sa_handler = SigTrap; + sigaction(SIGABRT, &sv, NULL); + sv.sa_handler = SigTrap; + sigaction(SIGINT, &sv, NULL); + sv.sa_handler = SigTrap; + sigaction(SIGSEGV, &sv, NULL); + local_debug("main", "Signals trapped.\n"); + + /* Set elap timer */ + time(&edui_now); + t = edui_now; + + /* Main loop -- Waits for stdin input before action */ + while (fgets(bufa, sizeof(bufa), stdin) != NULL) { + if (edui_conf.mode & EDUI_MODE_KILL) + break; + time(&edui_now); + if (t < edui_now) { + /* Elapse seconds */ + edui_elap = edui_now - t; +// local_debug("main", "while() -> %d seconds elapsed.\n", edui_elap); + t = edui_now; + } else + edui_elap = 0; + k = strlen(bufa); + /* + local_debug("main", "while() -> bufa[%zd]: %s", k, bufa); + local_debug("main", "while() -> bufa[%zd]: "); + for (i = 0; i < k; i++) + local_debugx("%.2X", bufa[i]); + local_debugx("\n"); + */ + /* Check for CRLF */ + p = strchr(bufa, '\n'); + if (p != NULL) + *p = '\0'; + p = strchr(bufa, '\r'); + if (p != NULL) + *p = '\0'; + p = strchr(bufa, ' '); + + /* No space given, but group string is required --> ERR */ + if ((edui_conf.mode & EDUI_MODE_GROUP) && (p == NULL)) { + local_debug("main", "while() -> Search group is required.\n"); + local_printfx("ERR\n"); + continue; + } + x = 0; + + /* Open LDAP connection */ + if (!(edui_ldap.status & LDAP_INIT_S)) { + InitLDAP(&edui_ldap); + local_debug("main", "InitLDAP() -> %s\n", ErrLDAP(LDAP_ERR_SUCCESS)); + if (edui_conf.mode & EDUI_MODE_PERSIST) /* Setup persistant mode */ + edui_ldap.status |= LDAP_PERSIST_S; + } + if ((edui_ldap.status & LDAP_IDLE_S) && (edui_elap > 0)) { + edui_ldap.idle_time = edui_ldap.idle_time + edui_elap; + } + if ((edui_ldap.status & LDAP_PERSIST_S) && (edui_ldap.status & LDAP_IDLE_S) && (edui_ldap.idle_time > edui_conf.persist_timeout)) { + local_debug("main", "while() -> Connection timed out after %u seconds\n", edui_ldap.idle_time); + x = CloseLDAP(&edui_ldap); + local_debug("main", "CloseLDAP(-) -> %s\n", ErrLDAP(x)); + } + edui_ldap.err = -1; + if (!(edui_ldap.status & LDAP_OPEN_S)) { + x = OpenLDAP(&edui_ldap, edui_conf.host, edui_conf.port); + if (x != LDAP_ERR_SUCCESS) { + /* Failed to connect */ + local_debug("main", "OpenLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err)); + } else { + local_debug("main", "OpenLDAP(-, %s, %d) -> %s\n", edui_conf.host, edui_conf.port, ErrLDAP(x)); + x = SetVerLDAP(&edui_ldap, edui_conf.ver); + if (x != LDAP_ERR_SUCCESS) { + /* Failed to set version */ + local_debug("main", "SetVerLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err)); + } else + local_debug("main", "SetVerLDAP(-, %d) -> %s\n", edui_conf.ver, ErrLDAP(x)); + } + } + edui_ldap.err = -1; + if (!(edui_ldap.status & LDAP_BIND_S) && (edui_conf.mode & EDUI_MODE_TLS)) { + /* TLS binding */ + x = BindLDAP(&edui_ldap, edui_conf.dn, edui_conf.passwd, LDAP_AUTH_TLS); + if (x != LDAP_ERR_SUCCESS) { + /* Unable to bind */ + local_debug("main", "BindLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err)); + } else + local_debug("main", "BindLDAP(-, %s, %s, %ul) -> %s\n", edui_conf.dn, edui_conf.passwd, LDAP_AUTH_TLS, ErrLDAP(x)); + } else if (!(edui_ldap.status & LDAP_BIND_S)) { + if (edui_conf.dn[0] != '\0') { + /* Simple binding - using dn / passwd for authorization */ + x = BindLDAP(&edui_ldap, edui_conf.dn, edui_conf.passwd, LDAP_AUTH_SIMPLE); + if (x != LDAP_ERR_SUCCESS) { + /* Unable to bind */ + local_debug("main", "BindLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err)); + } else + local_debug("main", "BindLDAP(-, %s, %s, %ul) -> %s\n", edui_conf.dn, edui_conf.passwd, LDAP_AUTH_SIMPLE, ErrLDAP(x)); + } else { + /* Anonymous binding */ + x = BindLDAP(&edui_ldap, edui_conf.dn, edui_conf.passwd, LDAP_AUTH_NONE); + if (x != LDAP_ERR_SUCCESS) { + /* Unable to bind */ + local_debug("main", "BindLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err)); + } else + local_debug("main", "BindLDAP(-, -, -, %ul) -> %s\n", LDAP_AUTH_NONE, ErrLDAP(x)); + } + } + edui_ldap.err = -1; + if (edui_ldap.status & LDAP_PERSIST_S) { + x = ResetLDAP(&edui_ldap); + if (x != LDAP_ERR_SUCCESS) { + /* Unable to reset */ + local_debug("main", "ResetLDAP() -> %s\n", ErrLDAP(x)); + } else + local_debug("main", "ResetLDAP() -> %s\n", ErrLDAP(x)); + } + if (x != LDAP_ERR_SUCCESS) { + /* Everything failed --> ERR */ + local_debug("main", "while() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err)); + CloseLDAP(&edui_ldap); + local_printfx("ERR\n"); + continue; + } + edui_ldap.err = -1; + /* If we got a group string, split it */ + if (p != NULL) { + /* Split string */ + local_debug("main", "SplitString(%s, %zd, ' ', %s, %zd)\n", bufa, strlen(bufa), bufb, sizeof(bufb)); + i = SplitString(bufa, strlen(bufa), ' ', bufb, sizeof(bufb)); + if (i > 0) { + local_debug("main", "SplitString(%s, %s) done. Result: %zd\n", bufa, bufb, i); + /* Got a group to match against */ + x = ConvertIP(&edui_ldap, bufb); + if (x < 0) { + local_debug("main", "ConvertIP() -> %s\n", ErrLDAP(x)); + local_printfx("ERR\n"); + } else { + edui_ldap.err = -1; + local_debug("main", "ConvertIP(-, %s) -> Result[%zd]: %s\n", bufb, x, edui_ldap.search_ip); + x = SearchFilterLDAP(&edui_ldap, bufa); + if (x < 0) { + local_debug("main", "SearchFilterLDAP() -> %s\n", ErrLDAP(x)); + local_printfx("ERR\n"); + } else { + /* Do Search */ + edui_ldap.err = -1; + local_debug("main", "SearchFilterLDAP(-, %s) -> Length: %u\n", bufa, x); + x = SearchLDAP(&edui_ldap, edui_ldap.scope, edui_ldap.search_filter, search_attrib); + if (x != LDAP_ERR_SUCCESS) { + local_debug("main", "SearchLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err)); + local_printfx("ERR\n"); + } else { + edui_ldap.err = -1; + local_debug("main", "SearchLDAP(-, %d, %s, -) -> %s\n", edui_conf.scope, edui_ldap.search_filter, ErrLDAP(x)); + x = SearchIPLDAP(&edui_ldap, bufc); + if (x != LDAP_ERR_SUCCESS) { + local_debug("main", "SearchIPLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err)); + local_printfx("ERR\n"); + } else { + local_debug("main", "SearchIPLDAP(-, %s) -> %s\n", bufc, ErrLDAP(x)); + local_printfx("OK user=%s\n", bufc); /* Got userid --> OK user= */ + } + } + /* Clear for next query */ + memset(bufc, '\0', strlen(bufc)); + } + } + } else { + local_debug("main", "SplitString() -> Error: %d\n", i); + local_printfx("ERR\n"); + } + } else { + /* No group to match against, only an IP */ + x = ConvertIP(&edui_ldap, bufa); + if (x < 0) { + local_debug("main", "ConvertIP() -> %s\n", ErrLDAP(x)); + local_printfx("ERR\n"); + } else { + local_debug("main", "ConvertIP(-, %s) -> Result[%zd]: %s\n", bufa, x, edui_ldap.search_ip); + /* Do search */ + x = SearchFilterLDAP(&edui_ldap, NULL); + if (x < 0) { + local_debug("main", "SearchFilterLDAP() -> %s\n", ErrLDAP(x)); + local_printfx("ERR\n"); + } else { + edui_ldap.err = -1; + local_debug("main", "SearchFilterLDAP(-, NULL) -> Length: %u\n", x); + x = SearchLDAP(&edui_ldap, edui_ldap.scope, edui_ldap.search_filter, search_attrib); + if (x != LDAP_ERR_SUCCESS) { + local_debug("main", "SearchLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(x)); + local_printfx("ERR\n"); + } else { + edui_ldap.err = -1; + local_debug("main", "SearchLDAP(-, %d, %s, -) -> %s\n", edui_conf.scope, edui_ldap.search_filter, ErrLDAP(x)); + x = SearchIPLDAP(&edui_ldap, bufc); + if (x != LDAP_ERR_SUCCESS) { + local_debug("main", "SearchIPLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(edui_ldap.err)); + local_printfx("ERR\n"); + } else { + local_debug("main", "SearchIPLDAP(-, %s) -> %s\n", bufc, ErrLDAP(x)); + local_printfx("OK user=%s\n", bufc); /* Got a userid --> OK user= */ + } + } + } + /* Clear for next query */ + memset(bufc, '\0', strlen(bufc)); + } + } + + /* Clear buffer and close for next data, if not persistent */ + edui_ldap.err = -1; + memset(bufa, '\0', strlen(bufa)); + if (!(edui_ldap.status & LDAP_PERSIST_S)) { + x = CloseLDAP(&edui_ldap); + local_debug("main", "CloseLDAP(-) -> %s\n", ErrLDAP(x)); + } + } + + local_debug("main", "Terminating.\n"); + exit(1); +} === removed file 'helpers/external_acl/eDirectory_userip/iplookup.c' --- helpers/external_acl/eDirectory_userip/iplookup.c 2010-08-30 00:05:19 +0000 +++ helpers/external_acl/eDirectory_userip/iplookup.c 1970-01-01 00:00:00 +0000 @@ -1,1032 +0,0 @@ -/* squid_edir_iplookup - Copyright (C) 2009, 2010 Chad E. Naugle - * - ******************************************************************************** - * - * This file is part of squid_edir_iplookup. - * - * squid_edir_iplookup 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. - * - * squid_edir_iplookup 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 squid_edir_iplookup. If not, see . - * - ******************************************************************************** - * - * iplookup.c -- - * - * ldap_t data struct manipulation, and LDAP server communication. - * - */ - -#include "main.h" -#include "edui_util.h" -#include "iplookup.h" - -/* InitLDAP() - - * - * Initalize LDAP structure for use, zeroing out all variables. - * - */ -void InitLDAP(ldap_t *l) -{ - if (l == NULL) return; /* Duh! */ - - l->lp = NULL; - if (l->lm != NULL) - ldap_msgfree(l->lm); - if (l->val != NULL) - ldap_value_free_len(l->val); - l->lm = NULL; - l->val = NULL; - memset(l->basedn, '\0', sizeof(l->basedn)); - memset(l->host, '\0', sizeof(l->host)); - memset(l->dn, '\0', sizeof(l->dn)); - memset(l->passwd, '\0', sizeof(l->passwd)); - memset(l->search_filter, '\0', sizeof(l->search_filter)); - memset(l->search_ip, '\0', sizeof(l->search_ip)); - memset(l->userid, '\0', sizeof(l->userid)); - l->status = 0; - l->status |= LDAP_INIT_S; - l->port = 0; - l->scope = -1; - l->type = 0; - l->err = -1; /* Set error to LDAP_SUCCESS by default */ - l->ver = 0; - l->idle_time = 0; - l->num_ent = 0; /* Number of entries in l->lm */ - l->num_val = 0; /* Number of entries in l->val */ - - /* Set default settings from conf */ - if (conf.basedn[0] != '\0') - strncpy(l->basedn, conf.basedn, sizeof(l->basedn)); - if (conf.host[0] != '\0') - strncpy(l->host, conf.host, sizeof(l->host)); - if (conf.port != 0) - l->port = conf.port; - if (conf.dn[0] != '\0') - strncpy(l->dn, conf.dn, sizeof(l->dn)); - if (conf.passwd[0] != '\0') - strncpy(l->passwd, conf.passwd, sizeof(l->passwd)); - if (conf.search_filter[0] != '\0') - strncpy(l->search_filter, conf.search_filter, sizeof(l->search_filter)); - if (!(conf.scope < 0)) - l->scope = conf.scope; - if (conf.mode & MODE_IPV4) - l->status |= LDAP_IPV4_S; - if (conf.mode & MODE_IPV6) - l->status |= LDAP_IPV6_S; -} - -/* OpenLDAP() - - * - * Build LDAP struct with hostname and port, and ready it for binding. - * - */ -int OpenLDAP(ldap_t *l, char *h, unsigned int p) -{ - if ((l == NULL) || (h == NULL)) return LDAP_ERR_NULL; - if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized, or might be in use */ - if (l->status & LDAP_OPEN_S) return LDAP_ERR_OPEN; /* Already open */ - if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND; /* Already bound */ - - strncpy(l->host, h, sizeof(l->host)); - if (p > 0) - l->port = p; - else - l->port = LDAP_PORT; /* Default is port 389 */ - -#ifdef NETSCAPE_SSL - if (l->port == LDAPS_PORT) - l->status |= (LDAP_SSL_S | LDAP_TLS_S); /* SSL Port: 636 */ -#endif - -#ifdef USE_LDAP_INIT - l->lp = ldap_init(l->host, l->port); -#else - l->lp = ldap_open(l->host, l->port); -#endif - if (l->lp == NULL) { - l->err = LDAP_CONNECT_ERROR; - return LDAP_ERR_CONNECT; /* Unable to connect */ - } else { - /* set status */ -// l->status &= ~(LDAP_INIT_S); - l->status |= LDAP_OPEN_S; - l->err = LDAP_SUCCESS; - return LDAP_ERR_SUCCESS; - } -} - -/* CloseLDAP() - - * - * Close LDAP connection, and clean up data structure. - * - */ -int CloseLDAP(ldap_t *l) -{ - int s; - if (l == NULL) return LDAP_ERR_NULL; - if (l->lp == NULL) return LDAP_ERR_NULL; - if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Connection not initalized */ - if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Connection not open */ - - if (l->lm != NULL) { - ldap_msgfree(l->lm); - l->lm = NULL; - } - if (l->val != NULL) { - ldap_value_free_len(l->val); - l->val = NULL; - } - - /* okay, so it's open, close it - No need to check other criteria */ - s = ldap_unbind(l->lp); - if (s == LDAP_SUCCESS) { - l->status &= ~(LDAP_OPEN_S | LDAP_BIND_S); - l->idle_time = 0; - l->err = s; /* Set LDAP error code */ - return LDAP_ERR_SUCCESS; - } else { - l->err = s; /* Set LDAP error code */ - return LDAP_ERR_FAILED; - } -} - -/* SetVerLDAP() - - * - * Set LDAP version number for connection to of 1, 2, or 3 - * - */ -int SetVerLDAP(ldap_t *l, int v) -{ - int x; - if (l == NULL) return LDAP_ERR_NULL; - if ((v > 3) || (v < 1)) return LDAP_ERR_PARAM; - if (l->lp == NULL) return LDAP_ERR_POINTER; - if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ - if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ - if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND; /* Already bound */ - - /* set version */ - x = ldap_set_option(l->lp, LDAP_OPT_PROTOCOL_VERSION, &v); - if (x == LDAP_SUCCESS) { - l->ver = v; - l->err = x; /* Set LDAP error code */ - return LDAP_ERR_SUCCESS; - } else { - l->err = x; /* Set LDAP error code */ - return LDAP_ERR_FAILED; - } -} - -/* BindLDAP() - - * - * Bind LDAP connection (Open) using optional dn and password, of - * - */ -int BindLDAP(ldap_t *l, char *dn, char *pw, unsigned int t) -{ - int s; - if (l == NULL) return LDAP_ERR_NULL; - if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ - if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ - if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND; /* Already bound */ - if (l->lp == NULL) return LDAP_ERR_POINTER; /* Error */ - - /* Copy details - dn and pw CAN be NULL for anonymous and/or TLS */ - if (dn != NULL) { - if ((l->basedn[0] != '\0') && (strstr(dn, l->basedn) == NULL)) { - /* We got a basedn, but it's not part of dn */ - strncpy(l->dn, dn, sizeof(l->dn)); - strcat(l->dn, ","); - strncat(l->dn, l->basedn, sizeof(l->dn)); - } else - strncpy(l->dn, dn, sizeof(l->dn)); - } - if (pw != NULL) - strncpy(l->passwd, pw, sizeof(l->passwd)); - - /* Type ? */ - switch (t) { - case LDAP_AUTH_NONE: - l->type = t; - break; - case LDAP_AUTH_SIMPLE: - l->type = t; - break; - case LDAP_AUTH_SASL: - l->type = t; - break; - case LDAP_AUTH_KRBV4: - l->type = t; - break; - case LDAP_AUTH_KRBV41: - l->type = t; - break; - case LDAP_AUTH_KRBV42: - l->type = t; - break; -#ifdef LDAP_AUTH_TLS - case LDAP_AUTH_TLS: /* Added for chicken switch to TLS-enabled without using SSL */ - l->type = t; - break; -#endif - default: - l->type = LDAP_AUTH_NONE; - break; /* Default to anonymous bind */ - } - - /* Bind */ -#ifdef NETSCAPE_SSL - if (l->type == LDAP_AUTH_TLS) - s = ldap_start_tls_s(l->lp, NULL, NULL); - else -#endif - s = ldap_bind_s(l->lp, l->dn, l->passwd, l->type); - if (s == LDAP_SUCCESS) { - l->status |= LDAP_BIND_S; /* Success */ - l->err = s; /* Set LDAP error code */ - return LDAP_ERR_SUCCESS; - } else { - l->err = s; /* Set LDAP error code */ - return LDAP_ERR_FAILED; - } -} - -/* - * ConvertIP() - - * - * Take an IPv4 address in dot-decimal or IPv6 notation, and convert to 2-digit HEX stored in l->search_ip - * This is the networkAddress that we search LDAP for. - * - */ -int ConvertIP(ldap_t *l, char *ip) -{ - char bufa[MAXLEN], bufb[MAXLEN], obj[MAXLEN]; - char hexc[4], *p; - size_t s; - long x; - int i, j, t, swi; /* IPv6 "::" cut over toggle */ - if (l == NULL) return LDAP_ERR_NULL; - if (ip == NULL) return LDAP_ERR_PARAM; - if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ - if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ - if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND; /* Not bound */ - - s = strlen(ip); - memset(bufa, '\0', sizeof(bufa)); - memset(bufb, '\0', sizeof(bufb)); - memset(obj, '\0', sizeof(obj)); - /* SplitString() will zero out bufa & obj at each call */ - memset(l->search_ip, '\0', sizeof(l->search_ip)); - strncpy(bufa, ip, s); /* To avoid segfaults, use bufa instead of ip */ - swi = 0; - - if ((conf.mode & MODE_IPV6) && (conf.mode & MODE_IPV4)) { - if (strcasestr(bufa, ":FFFF:") == NULL) - return LDAP_ERR_INVALID; /* Unable to find IPv4-in-IPv6 notation */ - } - if (conf.mode & MODE_IPV6) { - /* Search for :: in string */ - if ((bufa[0] == ':') && (bufa[1] == ':')) { - /* bufa starts with a ::, so just copy and clear */ - strncpy(bufb, bufa, sizeof(bufa)); - memset(bufa, '\0', strlen(bufa)); - swi++; /* Indicates that there is a bufb */ - } else if ((bufa[0] == ':') && (bufa[1] != ':')) { - /* bufa starts with a :, a typo so just fill in a ':', cat and clear */ - bufb[0] = ':'; - strncat(bufb, bufa, sizeof(bufa)); - memset(bufa, '\0', strlen(bufa)); - swi++; /* Indicates that there is a bufb */ - } else { - p = strstr(bufa, "::"); - if (p != NULL) { - /* Found it, break bufa down and split into bufb here */ - memset(bufb, '\0', strlen(bufb)); - i = strlen(p); - memcpy(bufb, p, i); - *p = '\0'; - bufb[i] = '\0'; - swi++; /* Indicates that there is a bufb */ - } - } - } - s = strlen(bufa); - if (s < 1) - s = strlen(bufb); - while (s > 0) { - if ((conf.mode & MODE_IPV4) && (conf.mode & MODE_IPV6) && (swi > 1)) { - if (strchr(bufb, ':') != NULL) { - /* Split Off leading :ffff: */ - t = SplitString(bufb, s, ':', obj, sizeof(obj)); - if (t > 0) { - strcpy(hexc, "FFFF"); - strncat(l->search_ip, hexc, sizeof(l->search_ip)); - } else - break; /* reached end */ - } else { - /* Break down IPv4 address nested in the IPv6 address */ - t = SplitString(bufb, s, '.', obj, sizeof(obj)); - if (t > 0) { - errno = 0; - x = strtol(obj, (char **)NULL, 10); - if (((x < 0) || (x > 255)) || ((errno != 0) && (x == 0)) || ((obj[0] != '0') && (x == 0))) - return LDAP_ERR_OOB; /* Out of bounds -- Invalid address */ - memset(hexc, '\0', sizeof(hexc)); - snprintf(hexc, sizeof(hexc), "%.2X", (int)x); - strncat(l->search_ip, hexc, sizeof(l->search_ip)); - } else - break; /* reached end of octet */ - } - } else if ((conf.mode & MODE_IPV4) && (swi == 0)) { - /* Break down IPv4 address */ - t = SplitString(bufa, s, '.', obj, sizeof(obj)); - if (t > 0) { - errno = 0; - x = strtol(obj, (char **)NULL, 10); - if (((x < 0) || (x > 255)) || ((errno != 0) && (x == 0)) || ((obj[0] != '0') && (x == 0))) - return LDAP_ERR_OOB; /* Out of bounds -- Invalid address */ - memset(hexc, '\0', sizeof(hexc)); - snprintf(hexc, sizeof(hexc), "%.2X", (int)x); - strncat(l->search_ip, hexc, sizeof(l->search_ip)); - } else - break; /* reached end of octet */ - } else if (conf.mode & MODE_IPV6) { - /* Break down IPv6 address */ - if (swi > 1) - t = SplitString(bufb, s, ':', obj, sizeof(obj)); /* After "::" */ - else - t = SplitString(bufa, s, ':', obj, sizeof(obj)); /* Before "::" */ - /* Convert octet by size (t) - and fill 0's */ - switch (t) { /* IPv6 is already in HEX, copy contents */ - case 4: - hexc[0] = (char) toupper((int)obj[0]); - i = (int)hexc[0]; - if (!isxdigit(i)) - return LDAP_ERR_OOB; /* Out of bounds */ - hexc[1] = (char) toupper((int)obj[1]); - i = (int)hexc[1]; - if (!isxdigit(i)) - return LDAP_ERR_OOB; /* Out of bounds */ - hexc[2] = '\0'; - strncat(l->search_ip, hexc, sizeof(l->search_ip)); - hexc[0] = (char) toupper((int)obj[2]); - i = (int)hexc[0]; - if (!isxdigit(i)) - return LDAP_ERR_OOB; /* Out of bounds */ - hexc[1] = (char) toupper((int)obj[3]); - i = (int)hexc[1]; - if (!isxdigit(i)) - return LDAP_ERR_OOB; /* Out of bounds */ - hexc[2] = '\0'; - strncat(l->search_ip, hexc, sizeof(l->search_ip)); - break; - case 3: - hexc[0] = '0'; - hexc[1] = (char) toupper((int)obj[0]); - i = (int)hexc[1]; - if (!isxdigit(i)) - return LDAP_ERR_OOB; /* Out of bounds */ - hexc[2] = '\0'; - strncat(l->search_ip, hexc, sizeof(l->search_ip)); - hexc[0] = (char) toupper((int)obj[1]); - i = (int)hexc[0]; - if (!isxdigit(i)) - return LDAP_ERR_OOB; /* Out of bounds */ - hexc[1] = (char) toupper((int)obj[2]); - i = (int)hexc[1]; - if (!isxdigit(i)) - return LDAP_ERR_OOB; /* Out of bounds */ - hexc[2] = '\0'; - strncat(l->search_ip, hexc, sizeof(l->search_ip)); - break; - case 2: - strncat(l->search_ip, "00", sizeof(l->search_ip)); - hexc[0] = (char) toupper((int)obj[0]); - i = (int)hexc[0]; - if (!isxdigit(i)) - return LDAP_ERR_OOB; /* Out of bounds */ - hexc[1] = (char) toupper((int)obj[1]); - i = (int)hexc[1]; - if (!isxdigit(i)) - return LDAP_ERR_OOB; /* Out of bounds */ - hexc[2] = '\0'; - strncat(l->search_ip, hexc, sizeof(l->search_ip)); - break; - case 1: - strncat(l->search_ip, "00", sizeof(l->search_ip)); - hexc[0] = '0'; - hexc[1] = (char) toupper((int)obj[0]); - i = (int)hexc[1]; - if (!isxdigit(i)) - return LDAP_ERR_OOB; /* Out of bounds */ - hexc[2] = '\0'; - strncat(l->search_ip, hexc, sizeof(l->search_ip)); - break; - default: - if (t > 4) - return LDAP_ERR_OOB; - break; - } - /* Code to pad the address with 0's between a '::' */ - if ((strlen(bufa) == 0) && (swi == 1)) { - /* We are *AT* the split, pad in some 0000 */ - if ((conf.mode & MODE_IPV4) && (conf.mode & MODE_IPV6)) - t = 5; /* IPv4-in-IPv6 mode, 5 blocks only */ - else { - t = strlen(bufb); - /* How many ':' exist in bufb ? */ - j = 0; - for (i = 0; i < t; i++) { - if (bufb[i] == ':') - j++; - } - j--; /* Preceeding "::" doesn't count */ - t = 8 - (strlen(l->search_ip) / 4) - j; /* Remainder */ - } - if (t > 0) { - for (i = 0; i < t; i++) - strncat(l->search_ip, "0000", sizeof(l->search_ip)); - } - } - } - if ((bufa[0] == '\0') && (swi > 0)) { - s = strlen(bufb); - swi++; - } else - s = strlen(bufa); - } - s = strlen(l->search_ip); - - /* CHECK sizes of address, truncate or pad */ - /* if "::" is at end of ip, then pad another block or two */ - while ((conf.mode & MODE_IPV6) && (s < 32)) { - strncat(l->search_ip, "0000", sizeof(l->search_ip)); - s = strlen(l->search_ip); - } - if ((conf.mode & MODE_IPV6) && (s > 32)) { - /* Too long, truncate */ - l->search_ip[32] = '\0'; - s = strlen(l->search_ip); - } - /* If at end of ip, and its not long enough, then pad another block or two */ - while ((conf.mode & MODE_IPV4) && (s < 8)) { - strncat(l->search_ip, "00", sizeof(l->search_ip)); - s = strlen(l->search_ip); - } - if ((conf.mode & MODE_IPV4) && !(conf.mode & MODE_IPV6) && (s > 8)) { - /* Too long, truncate */ - l->search_ip[8] = '\0'; - s = strlen(l->search_ip); - } - - /* Completed, s is length of address in HEX */ - return s; -} - -/* - * SearchFilterLDAP() - - * - * Build LDAP Search Filter string and copy to l->search_filter - * - */ -int SearchFilterLDAP(ldap_t *l, char *group) -{ - size_t i, j, s; - int swi; - char bufa[MAXLEN], bufb[MAXLEN], bufc[MAXLEN], bufd[MAXLEN], bufg[MAXLEN]; - if (l == NULL) return LDAP_ERR_NULL; -// if (group == NULL) return LDAP_ERR_PARAM; - if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ - if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ - if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND; /* Not Bound */ - if (l->search_ip[0] == '\0') return LDAP_ERR_DATA; /* Search IP is required */ - - /* Zero out if not already */ - memset(bufa, '\0', strlen(bufa)); - memset(bufb, '\0', strlen(bufb)); - memset(bufc, '\0', strlen(bufc)); - memset(bufd, '\0', strlen(bufd)); - memset(bufg, '\0', strlen(bufg)); - -// debug("SearchFilterLDAP", "Building... (Adding '\\' to IP...) "); - s = strlen(l->search_ip); - bufc[0] = '\134'; - swi = 0; - j = 1; - for (i = 0; i < s; i++) { - if (swi == 2) { - bufc[j] = '\134'; - j++; - bufc[j] = l->search_ip[i]; - j++; - swi = 1; - } else { - bufc[j] = l->search_ip[i]; - j++; - swi++; - } - } - if (group == NULL) { - /* No groupMembership= to add, yay! */ - strcpy(bufa, "(&"); - strncat(bufa, conf.search_filter, sizeof(bufa)); - /* networkAddress */ - snprintf(bufb, sizeof(bufb), "(|(networkAddress=1\\23%s)(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s)", \ - bufc, bufc, bufc); - if (conf.mode & MODE_IPV6) { - snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s))", \ - bufc, bufc); - strncat(bufb, bufd, sizeof(bufb)); - } else - strncat(bufb, ")", sizeof(bufb)); -// debug("SearchFilterLDAP", "bufb: %s\n", bufb); - strncat(bufa, bufb, sizeof(bufa)); - strncat(bufa, ")", sizeof(bufa)); - } else { - /* Needs groupMembership= to add... */ - strcpy(bufa, "(&(&"); - strncat(bufa, conf.search_filter, sizeof(bufa)); - /* groupMembership */ - snprintf(bufg, sizeof(bufg), "(groupMembership=cn=%s", group); - if ((l->basedn[0] != '\0') && (strstr(group, l->basedn) == NULL)) { - strncat(bufg, ",", sizeof(bufg)); - strncat(bufg, l->basedn, sizeof(bufg)); - } - strncat(bufg, ")", sizeof(bufg)); -// debug("SearchFilterLDAP", "bufg: %s\n", bufg); - strncat(bufa, bufg, sizeof(bufa)); - /* networkAddress */ - snprintf(bufb, sizeof(bufb), "(|(networkAddress=1\\23%s)(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s)", \ - bufc, bufc, bufc); - if (conf.mode & MODE_IPV6) { - snprintf(bufd, sizeof(bufd), "(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s))", \ - bufc, bufc); - strncat(bufb, bufd, sizeof(bufb)); - } else - strncat(bufb, ")", sizeof(bufb)); -// debug("SearchFilterLDAP", "bufb: %s\n", bufb); - strncat(bufa, bufb, sizeof(bufa)); - strncat(bufa, "))", sizeof(bufa)); - } - s = strlen(bufa); - strcpy(l->search_filter, bufa); - return s; -} - -/* - * SearchLDAP() - - * - * Initate LDAP query, under levels, filtering matches with and optionally - * will generally be networkAddress ... - * - */ -int SearchLDAP(ldap_t *l, int scope, char *filter, char **attrs) -{ - int s; - char ft[MAXLEN]; - if (l == NULL) return LDAP_ERR_NULL; - if ((scope < 0) || (filter == NULL)) return LDAP_ERR_PARAM; /* If attrs is NULL, then all attrs will return */ - if (l->lp == NULL) return LDAP_ERR_POINTER; - if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ - if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ - if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND; /* Not bound */ - if (l->status & LDAP_SEARCH_S) return LDAP_ERR_SEARCHED; /* Already searching */ - if (l->basedn[0] == '\0') return LDAP_ERR_DATA; /* We require a basedn */ - if (l->lm != NULL) - ldap_msgfree(l->lm); /* Make sure l->lm is empty */ - - if (filter == NULL) /* if filter is NULL, then return ALL networkAddress */ - strcpy(ft, "(&(objectClass=User)(networkAddress=*))"); - else - strncpy(ft, filter, sizeof(ft)); - - /* We have a binded connection, with a free l->lm, so let's get this done */ - switch (scope) { - case 0: - s = ldap_search_s(l->lp, l->basedn, LDAP_SCOPE_BASE, ft, attrs, 0, &(l->lm)); - break; - case 1: - s = ldap_search_s(l->lp, l->basedn, LDAP_SCOPE_ONELEVEL, ft, attrs, 0, &(l->lm)); - break; - case 2: - s = ldap_search_s(l->lp, l->basedn, LDAP_SCOPE_SUBTREE, ft, attrs, 0, &(l->lm)); - break; - default: - /* Only search BASE by default */ - s = ldap_search_s(l->lp, l->basedn, LDAP_SCOPE_BASE, ft, attrs, 0, &(l->lm)); - break; - } - if (s == LDAP_SUCCESS) { - l->status |= (LDAP_SEARCH_S); /* Mark as searched */ - l->err = s; - l->idle_time = 0; /* Connection in use, reset idle timer */ - l->num_ent = ldap_count_entries(l->lp, l->lm); /* Counted */ - return LDAP_ERR_SUCCESS; - } else { - l->err = s; - l->num_ent = (-1); - return LDAP_ERR_FAILED; - } -} - -/* - * GetValLDAP() - - * - * Scan LDAP and look for search-attr, then return results in l->val - * - */ -int GetValLDAP(ldap_t *l, char *attr) -{ - ber_len_t x; - /* - ber_len_t i, j; - int c; - */ - LDAPMessage *ent; - if (l == NULL) return LDAP_ERR_NULL; - if (attr == NULL) return LDAP_ERR_PARAM; - if (l->lp == NULL) return LDAP_ERR_POINTER; - if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ - if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ - if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND; /* Not bound */ - if (!(l->status & LDAP_SEARCH_S)) return LDAP_ERR_NOT_SEARCHED; /* Not searched */ - if (l->num_ent <= 0) return LDAP_ERR_DATA; /* No entries found */ - if (l->val != NULL) - ldap_value_free_len(l->val); /* Clear data before populating */ - l->num_val = 0; - if (l->status & LDAP_VAL_S) - l->status &= ~(LDAP_VAL_S); /* Clear VAL bit */ - - /* Sift through entries -- Look for matches */ - for (ent = ldap_first_entry(l->lp, l->lm); ent != NULL; ent = ldap_next_entry(l->lp, ent)) { - l->val = ldap_get_values_len(l->lp, ent, attr); - if (l->val != NULL) { - x = ldap_count_values_len(l->val); /* We got x values ... */ - l->num_val = x; - if (x > 0) { - /* Display all values */ - /* - for (i = 0; i < x; i++) { - debug("GetValLDAP", "value[%zd]: \"%s\"\n", i, l->val[i]->bv_val); - debug("GetValLDAP", "value[%zd]: ", i); - for (j = 0; j < (l->val[i]->bv_len); j++) { - c = (int) l->val[i]->bv_val[j]; - if (c < 0) - c = c + 256; - debugx("%.2X", c); - } - debugx("\n"); - } - */ - /* CRASHES?!?! - if (ent != NULL) - ldap_msgfree(ent); - */ - if (l->lm != NULL) { - ldap_msgfree(l->lm); - l->lm = NULL; - } - l->num_ent = 0; - l->status &= ~(LDAP_SEARCH_S); - l->status |= LDAP_VAL_S; - l->err = LDAP_SUCCESS; - return LDAP_ERR_SUCCESS; /* Found it */ - } - } - /* Attr not found, continue */ - } - /* No entries found using attr */ - if (l->val != NULL) - ldap_value_free_len(l->val); - /* - if (ent != NULL) - ldap_msgfree(ent); - */ - if (l->lm != NULL) { - ldap_msgfree(l->lm); - l->lm = NULL; - } - l->num_ent = 0; - l->num_val = 0; - l->err = LDAP_NO_SUCH_OBJECT; - l->status &= ~(LDAP_SEARCH_S); - return LDAP_ERR_NOTFOUND; /* Not found */ -} - -/* - * SearchIPLDAP() - - * - * Scan LDAP and get all networkAddress Values, and see if they match l->search_ip - * Actual IP matching routine for eDirectory - * - */ -int SearchIPLDAP(ldap_t *l, char *uid) -{ - ber_len_t i, x; - ber_len_t j, k; - ber_len_t y, z; - int c; - char bufa[MAXLEN], bufb[MAXLEN], hexc[4]; - LDAPMessage *ent; - struct berval **ber; - if (l == NULL) return LDAP_ERR_NULL; - if (uid == NULL) return LDAP_ERR_PARAM; - if (l->lp == NULL) return LDAP_ERR_POINTER; - if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT; /* Not initalized */ - if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN; /* Not open */ - if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND; /* Not bound */ - if (!(l->status & LDAP_SEARCH_S)) return LDAP_ERR_NOT_SEARCHED; /* Not searched */ - if (l->num_ent <= 0) return LDAP_ERR_DATA; /* No entries found */ - if (l->val != NULL) - ldap_value_free_len(l->val); /* Clear data before populating */ - l->num_val = 0; - if (l->status & LDAP_VAL_S) - l->status &= ~(LDAP_VAL_S); /* Clear VAL bit */ - - /* Sift through entries */ - for (ent = ldap_first_entry(l->lp, l->lm); ent != NULL; ent = ldap_next_entry(l->lp, ent)) { - l->val = ldap_get_values_len(l->lp, ent, "networkAddress"); - ber = ldap_get_values_len(l->lp, ent, conf.attrib); /* conf.attrib is the mapping */ - if (l->val != NULL) { - x = ldap_count_values_len(l->val); /* We got x values ... */ - l->num_val = x; - if (x > 0) { - /* Display all values */ - for (i = 0; i < x; i++) { - j = l->val[i]->bv_len; - memcpy(bufa, l->val[i]->bv_val, j); - z = SplitString(bufa, j, '#', bufb, sizeof(bufb)); - /* - debug("SearchIPLDAP", "value[%zd]: SplitString(", i); - for (k = 0; k < z; k++) { - c = (int) bufb[k]; - if (c < 0) - c = c + 256; - debugx("%.2X", c); - } - debugx(", "); - for (k = 0; k < (j - z - 1); k++) { - c = (int) bufa[k]; - if (c < 0) - c = c + 256; - debugx("%.2X", c); - } - debugx("): %zd\n", z); - */ - z = j - z - 1; - j = atoi(bufb); - switch (j) { - case 0: /* IPX address (We don't support these right now) */ - break; - case 1: /* IPv4 address (eDirectory 8.7 and below) */ - /* bufa is the address, just compare it */ - if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S)) - break; /* Not looking for IPv4 */ - for (k = 0; k < z; k++) { - c = (int) bufa[k]; - if (c < 0) - c = c + 256; - snprintf(hexc, sizeof(hexc), "%.2X", c); - if (k == 0) - strncpy(bufb, hexc, sizeof(bufb)); - else - strncat(bufb, hexc, sizeof(bufb)); - } - y = strlen(bufb); - /* Compare value with IP */ - if (bcmp(l->search_ip, bufb, y) == 0) { - /* We got a match! - Scan 'ber' for 'cn' values */ - z = ldap_count_values_len(ber); - for (j = 0; j < z; j++) - strncpy(uid, ber[j]->bv_val, ber[j]->bv_len); - ldap_value_free_len(l->val); - l->val = NULL; - ldap_value_free_len(ber); - ber = NULL; - l->num_val = 0; - l->err = LDAP_SUCCESS; - l->status &= ~(LDAP_SEARCH_S); - return LDAP_ERR_SUCCESS; /* We got our userid */ - } - /* Not matched, continue */ - break; - case 8: /* IPv4 (UDP) address (eDirectory 8.8 and higher) */ - /* bufa + 2 is the address (skip 2 digit port) */ - if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S)) - break; /* Not looking for IPv4 */ - for (k = 2; k < z; k++) { - c = (int) bufa[k]; - if (c < 0) - c = c + 256; - snprintf(hexc, sizeof(hexc), "%.2X", c); - if (k == 2) - strncpy(bufb, hexc, sizeof(bufb)); - else - strncat(bufb, hexc, sizeof(bufb)); - } - y = strlen(bufb); - /* Compare value with IP */ - if (bcmp(l->search_ip, bufb, y) == 0) { - /* We got a match! - Scan 'ber' for 'cn' values */ - z = ldap_count_values_len(ber); - for (j = 0; j < z; j++) - strncpy(uid, ber[j]->bv_val, ber[j]->bv_len); - ldap_value_free_len(l->val); - l->val = NULL; - ldap_value_free_len(ber); - ber = NULL; - l->num_val = 0; - l->err = LDAP_SUCCESS; - l->status &= ~(LDAP_SEARCH_S); - return LDAP_ERR_SUCCESS; /* We got our userid */ - } - /* Not matched, continue */ - break; - case 9: /* IPv4 (TCP) address (eDirectory 8.8 and higher) */ - /* bufa + 2 is the address (skip 2 digit port) */ - if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S)) - break; /* Not looking for IPv4 */ - for (k = 2; k < z; k++) { - c = (int) bufa[k]; - if (c < 0) - c = c + 256; - snprintf(hexc, sizeof(hexc), "%.2X", c); - if (k == 2) - strncpy(bufb, hexc, sizeof(bufb)); - else - strncat(bufb, hexc, sizeof(bufb)); - } - y = strlen(bufb); - /* Compare value with IP */ - if (bcmp(l->search_ip, bufb, y) == 0) { - /* We got a match! - Scan 'ber' for 'cn' values */ - z = ldap_count_values_len(ber); - for (j = 0; j < z; j++) - strncpy(uid, ber[j]->bv_val, ber[j]->bv_len); - ldap_value_free_len(l->val); - l->val = NULL; - ldap_value_free_len(ber); - ber = NULL; - l->num_val = 0; - l->err = LDAP_SUCCESS; - l->status &= ~(LDAP_SEARCH_S); - return LDAP_ERR_SUCCESS; /* We got our userid */ - } - /* Not matched, continue */ - break; - case 10: /* IPv6 (UDP) address (eDirectory 8.8 and higher) */ - /* bufa + 2 is the address (skip 2 digit port) */ - if (!(l->status & LDAP_IPV6_S)) - break; /* Not looking for IPv6 */ - for (k = 2; k < z; k++) { - c = (int) bufa[k]; - if (c < 0) - c = c + 256; - snprintf(hexc, sizeof(hexc), "%.2X", c); - if (k == 2) - strncpy(bufb, hexc, sizeof(bufb)); - else - strncat(bufb, hexc, sizeof(bufb)); - } - y = strlen(bufb); - /* Compare value with IP */ - if (bcmp(l->search_ip, bufb, y) == 0) { - /* We got a match! - Scan 'ber' for 'cn' values */ - z = ldap_count_values_len(ber); - for (j = 0; j < z; j++) - strncpy(uid, ber[j]->bv_val, ber[j]->bv_len); - ldap_value_free_len(l->val); - l->val = NULL; - ldap_value_free_len(ber); - ber = NULL; - l->num_val = 0; - l->err = LDAP_SUCCESS; - l->status &= ~(LDAP_SEARCH_S); - return LDAP_ERR_SUCCESS; /* We got our userid */ - } - /* Not matched, continue */ - break; - case 11: /* IPv6 (TCP) address (eDirectory 8.8 and higher) */ - /* bufa + 2 is the address (skip 2 digit port) */ - if (!(l->status & LDAP_IPV6_S)) - break; /* Not looking for IPv6 */ - for (k = 2; k < z; k++) { - c = (int) bufa[k]; - if (c < 0) - c = c + 256; - snprintf(hexc, sizeof(hexc), "%.2X", c); - if (k == 2) - strncpy(bufb, hexc, sizeof(bufb)); - else - strncat(bufb, hexc, sizeof(bufb)); - } - y = strlen(bufb); - /* Compare value with IP */ - if (bcmp(l->search_ip, bufb, y) == 0) { - /* We got a match! - Scan 'ber' for 'cn' values */ - z = ldap_count_values_len(ber); - for (j = 0; j < z; j++) - strncpy(uid, ber[j]->bv_val, ber[j]->bv_len); - ldap_value_free_len(l->val); - l->val = NULL; - ldap_value_free_len(ber); - ber = NULL; - l->num_val = 0; - l->err = LDAP_SUCCESS; - l->status &= ~(LDAP_SEARCH_S); - return LDAP_ERR_SUCCESS; /* We gout our userid */ - } - /* Not matched, continue */ - break; - default: /* Other, unsupported */ - break; - } - } - if (ber != NULL) { - ldap_value_free_len(ber); - ber = NULL; - } - } - ldap_value_free_len(l->val); - l->val = NULL; - } - if (ber != NULL) { - ldap_value_free_len(ber); - ber = NULL; - } - /* Attr not found, continue */ - } - /* No entries found using given attr */ - if (l->val != NULL) { - ldap_value_free_len(l->val); - l->val = NULL; - } - if (ber != NULL) { - ldap_value_free_len(ber); - ber = NULL; - } - if (ent != NULL) { - ldap_msgfree(ent); - ent = NULL; - } - if (l->lm != NULL) { - ldap_msgfree(l->lm); - l->lm = NULL; - } - l->num_ent = 0; - l->num_val = 0; - l->err = LDAP_NO_SUCH_OBJECT; - l->status &= ~(LDAP_SEARCH_S); - return LDAP_ERR_NOTFOUND; /* Not found ... Sorry :) */ -} - -char *ErrLDAP(int e) -{ - switch (e) { - case LDAP_ERR_NULL: - return "Null pointer provided"; - case LDAP_ERR_POINTER: - return "Null LDAP pointer"; - case LDAP_ERR_PARAM: - return "Null or Missing paremeter(s)"; - case LDAP_ERR_INIT: - return "LDAP data not initalized"; - case LDAP_ERR_OPEN: - return "LDAP connection is not active"; - case LDAP_ERR_CONNECT: - return "Unable to connect to LDAP host"; - case LDAP_ERR_BIND: - return "LDAP connection is not bound"; - case LDAP_ERR_SEARCHED: - return "LDAP connection has already been searched"; - case LDAP_ERR_NOT_SEARCHED: - return "LDAP connection has not been searched"; - case LDAP_ERR_INVALID: - return "Invalid paremeters"; - case LDAP_ERR_OOB: - return "Paremeter is out of bounds"; - case LDAP_ERR_PERSIST: - return "Persistent mode is not active"; - case LDAP_ERR_DATA: - return "Required data has not been found"; - case LDAP_ERR_NOTFOUND: - return "Item or object has not been found"; - case LDAP_ERR_OTHER: - return "An unknown error has occured"; - case LDAP_ERR_FAILED: - return "Operation has failed"; - case LDAP_ERR_SUCCESS: - return "Operation is successful"; - default: - return "An unknown error has occured"; - } -} === removed file 'helpers/external_acl/eDirectory_userip/iplookup.h' --- helpers/external_acl/eDirectory_userip/iplookup.h 2010-08-30 00:05:19 +0000 +++ helpers/external_acl/eDirectory_userip/iplookup.h 1970-01-01 00:00:00 +0000 @@ -1,97 +0,0 @@ -/* squid_edir_iplookup - Copyright (C) 2009, 2010 Chad E. Naugle - * - ******************************************************************************** - * - * This file is part of squid_edir_iplookup. - * - * squid_edir_iplookup 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. - * - * squid_edir_iplookup 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 squid_edir_iplookup. If not, see . - * - ******************************************************************************** - * - * iplookup.h -- - * - * ldap_t data struct typedef and related functions. - * - */ - -#ifndef _HAVE_IPLOOKUP_H -#define _HAVE_IPLOOKUP_H -#ifndef _HAVE_MAIN_H -#include "main.h" -#endif -#include -#define LDAP_DEPRECATED 1 /* Set flag for enabling classic ldap functions */ -#include -#include - -/* compile options */ -#define USE_LDAP_INIT -#ifndef NETSCAPE_SSL -# define NETSCAPE_SSL -#endif - -/* define LDAP_AUTH_TLS */ -#ifdef NETSCAPE_SSL -# ifndef LDAP_AUTH_TLS -# define LDAP_AUTH_TLS ((ber_tag_t) 0xb3U) -# endif -#endif - -/* status flags */ -#define LDAP_INIT_S 0x0001 -#define LDAP_OPEN_S 0x0002 -#define LDAP_BIND_S 0x0004 -#define LDAP_SEARCH_S 0x0008 /* We got data */ -#define LDAP_VAL_S 0x0010 /* Data has been copied to l->val */ -#define LDAP_CLOSE_S 0x0020 -#define LDAP_SSL_S 0x0040 -#define LDAP_TLS_S 0x0080 -#define LDAP_IPV4_S 0x0100 /* Search IP is IPv4 */ -#define LDAP_IPV6_S 0x0200 /* Search IP is IPv6 */ - -/* ldap_t struct typedef */ -typedef struct { - LDAP *lp; - LDAPMessage *lm; - struct berval **val; - char basedn[MAXLEN]; - char host[MAXLEN]; - char dn[MAXLEN]; - char passwd[MAXLEN]; - char search_filter[MAXLEN]; /* search_group gets appended here by GroupLDAP */ - char search_ip[MAXLEN]; /* Could be IPv4 or IPv6, set by ConvertIP */ - char userid[MAXLEN]; /* Resulting userid */ - unsigned int status; - unsigned int port; - unsigned long type; /* Type of bind */ - int ver; - int scope; - int err; /* LDAP error code */ - time_t idle_time; - int num_ent; /* Number of entry's found via search */ - int num_val; /* Number of value's found via getval */ -} ldap_t; - -/* iplookup.c - Functions */ -void InitLDAP(ldap_t *); -int OpenLDAP(ldap_t *, char *, unsigned int); -int CloseLDAP(ldap_t *); -int SetVerLDAP(ldap_t *, int); -int BindLDAP(ldap_t *, char *, char *, unsigned int); -int ConvertIP(ldap_t *, char *); -int SearchFilterLDAP(ldap_t *, char *); -int SearchLDAP(ldap_t *, int, char *, char **); -int GetValLDAP(ldap_t *, char *); -int SearchIPLDAP(ldap_t *, char *); -#endif === removed file 'helpers/external_acl/eDirectory_userip/main.c' --- helpers/external_acl/eDirectory_userip/main.c 2010-08-30 00:05:19 +0000 +++ helpers/external_acl/eDirectory_userip/main.c 1970-01-01 00:00:00 +0000 @@ -1,676 +0,0 @@ -/* squid_edir_iplookup - Copyright (C) 2009, 2010 Chad E. Naugle - * - ******************************************************************************** - * - * This file is part of squid_edir_iplookup. - * - * squid_edir_iplookup 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. - * - * squid_edir_iplookup 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 squid_edir_iplookup. If not, see . - * - ******************************************************************************** - * - * main.c -- - * - * Main program functions. - * - */ - -#include "main.h" -#include "edui_util.h" -#include "iplookup.h" - -char *search_attrib[] = { "cn", "uid", "networkAddress", "groupMembership", NULL }; -conf_t conf; -ldap_t ldap; -time_t now; -time_t elap; - -/* Displays version information */ -void DisplayVersion() -{ - printfx("Squid eDirectory IP Lookup Helper v1.5. Copyright (C) 2009, 2010 Chad E. Naugle\n"); -} - -/* Displays program usage information */ -void DisplayUsage() -{ - DisplayVersion(); - printfx("\n"); - printfx("Usage: %s\n", conf.program); - printfx(" -H -p [-Z] [-P] [-v 3] -b -s \n"); - printfx(" -D -W -F [-G] \n\n"); - printfx(" -d : Debug Mode.\n"); - printfx(" -4 : Address is IPv4 (127.0.0.1 format).\n"); - printfx(" -6 : Address is IPv6 (::1 format).\n"); - printfx(" -46 : Address is IPv4-in-IPv6 (::ffff:127.0.0.1 format).\n"); - printfx(" -H : Specify hostname/ip of server.\n"); - printfx(" -p : Specify port number. (Range 1-65535)\n"); - printfx(" -Z : Enable TLS security.\n"); - printfx(" -P : Use persistent connections.\n"); - printfx(" -t : Timeout factor for persistent connections. (Default is 60 sec, set to 0 for never timeout)\n"); - printfx(" -v <1,2,3> : Set LDAP version to 1, 2, or 3.\n"); - printfx(" -b : Specify Base DN. (ie. \"o=ORG\")\n"); - printfx(" -s : Specify LDAP Search Scope (base, one, sub; defaults to 'base').\n"); - printfx(" -D : Specify Binding DN. (ie. cn=squid,o=ORG)\n"); - printfx(" -W : Specify Binding password.\n"); - printfx(" -u : Set userid attribute (Defaults to \"cn\").\n"); - printfx(" -F : Specify LDAP search filter. (ie. \"(objectClass=User)\")\n"); - printfx(" -G : Specify if LDAP search group is required. (ie. \"groupMembership=\")\n"); - printfx(" -V : Display version & exit.\n"); - printfx(" -h : This screen & exit.\n"); - printfx("\n"); -} - -/* Initalizes program's configuration paremeters */ -void InitConf() -{ - memset(conf.program, '\0', sizeof(conf.program)); - memset(conf.basedn, '\0', sizeof(conf.basedn)); - memset(conf.host, '\0', sizeof(conf.host)); - memset(conf.attrib, '\0', sizeof(conf.attrib)); - memset(conf.dn, '\0', sizeof(conf.dn)); - memset(conf.passwd, '\0', sizeof(conf.passwd)); - memset(conf.search_filter, '\0', sizeof(conf.search_filter)); - conf.scope = -1; - conf.ver = -1; - conf.port = -1; - conf.persist_timeout = -1; - conf.mode = 0; - conf.mode |= MODE_INIT; - - /* Set defaults from edui_config.h */ -#ifdef DEFAULT_BASE_DN - strcpy(conf.basedn, DEFAULT_BASE_DN); -#endif -#ifdef DEFAULT_HOST - strcpy(conf.host, DEFAULT_HOST); -#endif -#ifdef DEFAULT_BIND_DN - strcpy(conf.dn, DEFAULT_BIND_DN); -#endif -#ifdef DEFAULT_BIND_PASS - strcpy(conf.passwd, DEFAULT_BIND_PASS); -#endif -#ifdef DEFAULT_USER_ATTRIB - strcpy(conf.attrib, DEFAULT_USER_ATTRIB); -#endif -#ifdef DEFAULT_SEARCH_FILTER - strcpy(conf.search_filter, DEFAULT_SEARCH_FILTER); -#endif -#ifdef DEFAULT_SEARCH_SCOPE - if (!strcmp(DEFAULT_SEARCH_SCOPE, "base")) - conf.scope = 0; - else if (!strcmp(DEFAULT_SEARCH_SCOPE, "one")) - conf.scope = 1; - else if (!strcmp(DEFAULT_SEARCH_SCOPE, "sub")) - conf.scope = 2; - else - conf.scope = 0; -#endif -#ifdef DEFAULT_LDAP_VERSION - conf.ver = DEFAULT_LDAP_VERSION; -#endif -#ifdef DEFAULT_PORT - conf.port = DEFAULT_PORT; -#endif -#ifdef DEFAULT_USE_IPV4 - conf.mode |= MODE_IPV4; -#endif -#ifdef DEFAULT_USE_IPV6 - conf.mode |= MODE_IPV6; -#endif -#ifdef DEFAULT_USE_TLS - conf.mode |= MODE_TLS; -#endif -#ifdef DEFAULT_USE_PERSIST - conf.mode |= MODE_PERSIST; -#endif -#ifdef DEFAULT_PERSIST_TIMEOUT - conf.persist_timeout = DEFAULT_PERSIST_TIMEOUT; -#endif -#ifdef DEFAULT_GROUP_REQUIRED - conf.mode |= MODE_GROUP; -#endif -#ifdef DEFAULT_DEBUG - conf.mode |= MODE_DEBUG; -#endif -} - -/* Displays running configuration */ -void DisplayConf() -{ - if (!(conf.mode & MODE_DEBUG)) - return; - DisplayVersion(); - printfx("\n"); - printfx("Configuration:\n"); - if (conf.mode & MODE_DEBUG) - printfx(" Debug mode: ON\n"); - else - printfx(" Debug mode: OFF\n"); - if ((conf.mode & MODE_IPV4) && (conf.mode & MODE_IPV6)) - printfx(" Address format: IPv4-in-IPv6 (::ffff:127.0.0.1)\n"); - else if (conf.mode & MODE_IPV6) - printfx(" Address format: IPv6 (::1)\n"); - else - printfx(" Address format: IPv4 (127.0.0.1)\n"); - if (conf.host[0] != '\0') - printfx(" Hostname: %s\n", conf.host); - else - printfx(" Hostname: 127.0.0.1\n"); - if (conf.port > 0) - printfx(" Port: %d\n", conf.port); - else - printfx(" Port: %d\n", LDAP_PORT); - if (conf.mode & MODE_TLS) - printfx(" TLS mode: ON\n"); - else - printfx(" TLS mode: OFF\n"); - if (conf.mode & MODE_PERSIST) { - printfx(" Persistent mode: ON\n"); - if (conf.persist_timeout > 0) - printfx(" Persistent mode idle timeout: %d\n", conf.persist_timeout); - else - printfx(" Persistent mode idle timeout: OFF\n"); - } else - printfx(" Persistent mode: OFF\n"); - printfx(" LDAP Version: %d\n", conf.ver); - if (conf.basedn[0] != '\0') - printfx(" Base DN: %s\n", conf.basedn); - else - printfx(" Base DN: None\n"); - if (conf.dn[0] != '\0') - printfx(" Binding DN: %s\n", conf.dn); - else - printfx(" Binding DN: Anonymous\n"); - if (conf.passwd[0] != '\0') - printfx(" Binding Password: %s\n", conf.passwd); - else - printfx(" Binding Password: None\n"); - switch (conf.scope) { - case 0: - printfx(" Search Scope: base\n"); - break; - case 1: - printfx(" Search Scope: one level\n"); - break; - case 2: - printfx(" Search Scope: subtree\n"); - break; - default: - printfx(" Search Scope: base\n"); - break; - } - if (conf.search_filter[0] != '\0') - printfx(" Search Filter: %s\n", conf.search_filter); - else - printfx(" Search Filter: (&(objectClass=User)(networkAddress=*))\n"); - if (conf.mode & MODE_GROUP) - printfx(" Search Group Required: Yes\n"); - else - printfx(" Search Group Required: No\n"); - printfx("\n"); -} - -/* Signal Trap routine */ -static void SigTrap(int s) -{ - if (!(conf.mode & MODE_KILL)) - conf.mode |= MODE_KILL; - - /* Clean Up */ - if (ldap.status & LDAP_OPEN_S) - CloseLDAP(&ldap); - - debug("SigTrap", "Terminating, Signal: %d\n", s); - exit(0); -} - -/* main() - function */ -int main(int argc, char **argv) -{ - char bufa[MAXLEN], bufb[MAXLEN], *p = NULL; - char bufc[MAXLEN]; - char sfmod[MAXLEN]; - int x; - size_t i, j, s, k; - time_t t; - struct sigaction sv; - - /* Init */ - k = (size_t) argc; - memset(bufa, '\0', sizeof(bufa)); - memset(bufb, '\0', sizeof(bufb)); - memset(bufc, '\0', sizeof(bufc)); - memset(sfmod, '\0', sizeof(sfmod)); - InitConf(&conf); - strncpy(conf.program, argv[0], sizeof(conf.program)); - now = -1; - t = -1; - debug("main", "InitConf() done.\n"); - - /* Scan args */ - if (k > 1) { - for (i = 1; i < k; i++) { - /* Classic / novelty usage schemes */ - if (!strcmp(argv[i], "--help")) { - DisplayUsage(); - return 1; - } else if (!strcmp(argv[i], "--usage")) { - DisplayUsage(); - return 1; - } else if (!strcmp(argv[i], "--version")) { - DisplayVersion(); - return 1; - } else if (argv[i][0] == '-') { - s = strlen(argv[i]); - for (j = 1; j < s; j++) { - switch (argv[i][j]) { - case 'h': - DisplayUsage(); - return 1; - case 'V': - DisplayVersion(); - return 1; - case 'd': - if (!(conf.mode & MODE_DEBUG)) - conf.mode |= MODE_DEBUG; /* Don't set mode more than once */ - break; - case '4': - if (!(conf.mode & MODE_IPV4)) - conf.mode |= MODE_IPV4; /* Don't set mode more than once */ - break; - case '6': - if (!(conf.mode & MODE_IPV6)) - conf.mode |= MODE_IPV6; /* Don't set mode more than once */ - break; - case 'Z': - if (!(conf.mode & MODE_TLS)) - conf.mode |= MODE_TLS; /* Don't set mode more than once */ - break; - case 'P': - if (!(conf.mode & MODE_PERSIST)) - conf.mode |= MODE_PERSIST; /* Don't set mode more than once */ - break; - case 'v': - i++; - if (argv[i] != NULL) { - conf.ver = atoi(argv[i]); - if (conf.ver < 1) - conf.ver = 1; - else if (conf.ver > 3) - conf.ver = 3; - } else { - printfx("No parameters given for 'v'.\n"); - DisplayUsage(); - return 1; - } - break; - case 't': - i++; - if (argv[i] != NULL) { - conf.persist_timeout = atoi(argv[i]); - if (conf.persist_timeout < 0) - conf.persist_timeout = 0; - } else { - printfx("No parameters given for 't'.\n"); - DisplayUsage(); - return 1; - } - break; - case 'b': - i++; /* Set Base DN */ - if (argv[i] != NULL) - strncpy(conf.basedn, argv[i], sizeof(conf.basedn)); - else { - printfx("No parameters given for 'b'.\n"); - DisplayUsage(); - return 1; - } - break; - case 'H': - i++; /* Set Hostname */ - if (argv[i] != NULL) - strncpy(conf.host, argv[i], sizeof(conf.host)); - else { - printfx("No parameters given for 'H'.\n"); - DisplayUsage(); - return 1; - } - break; - case 'p': - i++; /* Set port */ - if (argv[i] != NULL) - conf.port = atoi(argv[i]); - else { - printfx("No parameters given for 'p'.\n"); - DisplayUsage(); - return 1; - } - break; - case 'D': - i++; /* Set Bind DN */ - if (argv[i] != NULL) - strncpy(conf.dn, argv[i], sizeof(conf.dn)); - else { - printfx("No parameters given for 'D'.\n"); - DisplayUsage(); - return 1; - } - break; - case 'W': - i++; /* Set Bind PWD */ - if (argv[i] != NULL) - strncpy(conf.passwd, argv[i], sizeof(conf.passwd)); - else { - printfx("No parameters given for 'W'.\n"); - DisplayUsage(); - return 1; - } - break; - case 'F': - i++; /* Set Search Filter */ - if (argv[i] != NULL) - strncpy(conf.search_filter, argv[i], sizeof(conf.search_filter)); - else { - printfx("No parameters given for 'F'.\n"); - DisplayUsage(); - return 1; - } - break; - case 'G': - if (!(conf.mode & MODE_GROUP)) - conf.mode |= MODE_GROUP; /* Don't set mode more than once */ - break; - case 's': - i++; /* Set Scope Level */ - if (argv[i] != NULL) { - if (!strncmp(argv[i], "base", 4)) - conf.scope = 0; - else if (!strncmp(argv[i], "one", 4)) - conf.scope = 1; - else if (!strncmp(argv[i], "sub", 4)) - conf.scope = 2; - else - conf.scope = 0; /* Default is 'base' */ - } else { - printfx("No parameters given for 's'.\n"); - DisplayUsage(); - return 1; - } - break; - case '-': /* We got a second '-' ... ignore */ - break; - default: - printfx("Invalid parameter - '%c'.\n", argv[i][j]); - break; - } - } - } else { - /* Incorrect parameter, display usage */ - DisplayUsage(); - return 1; - } - } - } - - /* Set predefined required paremeters if none are given, localhost:LDAP_PORT, etc */ - if (conf.host[0] == '\0') /* Default to 127.0.0.1 */ - strcpy(conf.host, "127.0.0.1"); - if (conf.port < 0) - conf.port = LDAP_PORT; /* Default: LDAP_PORT */ - if (!(conf.mode & MODE_IPV4) && !(conf.mode & MODE_IPV6)) - conf.mode |= MODE_IPV4; /* Default to IPv4 */ - if (conf.ver < 0) - conf.ver = 2; - if ((conf.mode & MODE_TLS) && (conf.ver < 3)) - conf.ver = 3; /* TLS requires version 3 */ - if (conf.persist_timeout < 0) - conf.persist_timeout = 600; /* Default: 600 seconds (10 minutes) */ - if (conf.scope < 0) - conf.scope = 0; /* Default: base */ - if (conf.search_filter[0] == '\0') - strcpy(conf.search_filter, "(&(objectclass=User)(networkAddress=*))"); - debug("main", "Configuration done.\n"); - - DisplayConf(); - /* Done with arguments */ - - /* Trap the following signals */ - sigemptyset(&sv.sa_mask); - sv.sa_handler = SigTrap; - sigaction(SIGTERM, &sv, NULL); - sv.sa_handler = SigTrap; - sigaction(SIGHUP, &sv, NULL); - sv.sa_handler = SigTrap; - sigaction(SIGABRT, &sv, NULL); - sv.sa_handler = SigTrap; - sigaction(SIGINT, &sv, NULL); - sv.sa_handler = SigTrap; - sigaction(SIGSEGV, &sv, NULL); - debug("main", "Signals trapped.\n"); - - /* Set elap timer */ - time(&now); - t = now; - - /* Main loop -- Waits for stdin input before action */ - while (fgets(bufa, sizeof(bufa), stdin) != NULL) { - if (conf.mode & MODE_KILL) - break; - time(&now); - if (t < now) { - /* Elapse seconds */ - elap = now - t; -// debug("main", "while() -> %d seconds elapsed.\n", elap); - t = now; - } else - elap = 0; - k = strlen(bufa); - /* - debug("main", "while() -> bufa[%zd]: %s", k, bufa); - debug("main", "while() -> bufa[%zd]: "); - for (i = 0; i < k; i++) - debugx("%.2X", bufa[i]); - debugx("\n"); - */ - /* Check for CRLF */ - p = strchr(bufa, '\n'); - if (p != NULL) - *p = '\0'; - p = strchr(bufa, '\r'); - if (p != NULL) - *p = '\0'; - p = strchr(bufa, ' '); - - /* No space given, but group string is required --> ERR */ - if ((conf.mode & MODE_GROUP) && (p == NULL)) { - debug("main", "while() -> Search group is required.\n"); - printfx("ERR\n"); - continue; - } - x = 0; - - /* Open LDAP connection */ - if (!(ldap.status & LDAP_INIT_S)) { - InitLDAP(&ldap); - debug("main", "InitLDAP() -> %s\n", ErrLDAP(LDAP_ERR_SUCCESS)); - if (conf.mode & MODE_PERSIST) /* Setup persistant mode */ - ldap.status |= LDAP_PERSIST_S; - } - if ((ldap.status & LDAP_IDLE_S) && (elap > 0)) { - ldap.idle_time = ldap.idle_time + elap; - } - if ((ldap.status & LDAP_PERSIST_S) && (ldap.status & LDAP_IDLE_S) && (ldap.idle_time > conf.persist_timeout)) { - debug("main", "while() -> Connection timed out after %u seconds\n", ldap.idle_time); - x = CloseLDAP(&ldap); - debug("main", "CloseLDAP(-) -> %s\n", ErrLDAP(x)); - } - ldap.err = -1; - if (!(ldap.status & LDAP_OPEN_S)) { - x = OpenLDAP(&ldap, conf.host, conf.port); - if (x != LDAP_ERR_SUCCESS) { - /* Failed to connect */ - debug("main", "OpenLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err)); - } else { - debug("main", "OpenLDAP(-, %s, %d) -> %s\n", conf.host, conf.port, ErrLDAP(x)); - x = SetVerLDAP(&ldap, conf.ver); - if (x != LDAP_ERR_SUCCESS) { - /* Failed to set version */ - debug("main", "SetVerLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err)); - } else - debug("main", "SetVerLDAP(-, %d) -> %s\n", conf.ver, ErrLDAP(x)); - } - } - ldap.err = -1; - if (!(ldap.status & LDAP_BIND_S) && (conf.mode & MODE_TLS)) { - /* TLS binding */ - x = BindLDAP(&ldap, conf.dn, conf.passwd, LDAP_AUTH_TLS); - if (x != LDAP_ERR_SUCCESS) { - /* Unable to bind */ - debug("main", "BindLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err)); - } else - debug("main", "BindLDAP(-, %s, %s, %ul) -> %s\n", conf.dn, conf.passwd, LDAP_AUTH_TLS, ErrLDAP(x)); - } else if (!(ldap.status & LDAP_BIND_S)) { - if (conf.dn[0] != '\0') { - /* Simple binding - using dn / passwd for authorization */ - x = BindLDAP(&ldap, conf.dn, conf.passwd, LDAP_AUTH_SIMPLE); - if (x != LDAP_ERR_SUCCESS) { - /* Unable to bind */ - debug("main", "BindLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err)); - } else - debug("main", "BindLDAP(-, %s, %s, %ul) -> %s\n", conf.dn, conf.passwd, LDAP_AUTH_SIMPLE, ErrLDAP(x)); - } else { - /* Anonymous binding */ - x = BindLDAP(&ldap, conf.dn, conf.passwd, LDAP_AUTH_NONE); - if (x != LDAP_ERR_SUCCESS) { - /* Unable to bind */ - debug("main", "BindLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err)); - } else - debug("main", "BindLDAP(-, -, -, %ul) -> %s\n", LDAP_AUTH_NONE, ErrLDAP(x)); - } - } - ldap.err = -1; - if (ldap.status & LDAP_PERSIST_S) { - x = ResetLDAP(&ldap); - if (x != LDAP_ERR_SUCCESS) { - /* Unable to reset */ - debug("main", "ResetLDAP() -> %s\n", ErrLDAP(x)); - } else - debug("main", "ResetLDAP() -> %s\n", ErrLDAP(x)); - } - if (x != LDAP_ERR_SUCCESS) { - /* Everything failed --> ERR */ - debug("main", "while() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err)); - CloseLDAP(&ldap); - printfx("ERR\n"); - continue; - } - ldap.err = -1; - /* If we got a group string, split it */ - if (p != NULL) { - /* Split string */ - debug("main", "SplitString(%s, %zd, ' ', %s, %zd)\n", bufa, strlen(bufa), bufb, sizeof(bufb)); - i = SplitString(bufa, strlen(bufa), ' ', bufb, sizeof(bufb)); - if (i > 0) { - debug("main", "SplitString(%s, %s) done. Result: %zd\n", bufa, bufb, i); - /* Got a group to match against */ - x = ConvertIP(&ldap, bufb); - if (x < 0) { - debug("main", "ConvertIP() -> %s\n", ErrLDAP(x)); - printfx("ERR\n"); - } else { - ldap.err = -1; - debug("main", "ConvertIP(-, %s) -> Result[%zd]: %s\n", bufb, x, ldap.search_ip); - x = SearchFilterLDAP(&ldap, bufa); - if (x < 0) { - debug("main", "SearchFilterLDAP() -> %s\n", ErrLDAP(x)); - printfx("ERR\n"); - } else { - /* Do Search */ - ldap.err = -1; - debug("main", "SearchFilterLDAP(-, %s) -> Length: %u\n", bufa, x); - x = SearchLDAP(&ldap, ldap.scope, ldap.search_filter, search_attrib); - if (x != LDAP_ERR_SUCCESS) { - debug("main", "SearchLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err)); - printfx("ERR\n"); - } else { - ldap.err = -1; - debug("main", "SearchLDAP(-, %d, %s, -) -> %s\n", conf.scope, ldap.search_filter, ErrLDAP(x)); - x = SearchIPLDAP(&ldap, bufc); - if (x != LDAP_ERR_SUCCESS) { - debug("main", "SearchIPLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err)); - printfx("ERR\n"); - } else { - debug("main", "SearchIPLDAP(-, %s) -> %s\n", bufc, ErrLDAP(x)); - printfx("OK user=%s\n", bufc); /* Got userid --> OK user= */ - } - } - /* Clear for next query */ - memset(bufc, '\0', strlen(bufc)); - } - } - } else { - debug("main", "SplitString() -> Error: %d\n", i); - printfx("ERR\n"); - } - } else { - /* No group to match against, only an IP */ - x = ConvertIP(&ldap, bufa); - if (x < 0) { - debug("main", "ConvertIP() -> %s\n", ErrLDAP(x)); - printfx("ERR\n"); - } else { - debug("main", "ConvertIP(-, %s) -> Result[%zd]: %s\n", bufa, x, ldap.search_ip); - /* Do search */ - x = SearchFilterLDAP(&ldap, NULL); - if (x < 0) { - debug("main", "SearchFilterLDAP() -> %s\n", ErrLDAP(x)); - printfx("ERR\n"); - } else { - ldap.err = -1; - debug("main", "SearchFilterLDAP(-, NULL) -> Length: %u\n", x); - x = SearchLDAP(&ldap, ldap.scope, ldap.search_filter, search_attrib); - if (x != LDAP_ERR_SUCCESS) { - debug("main", "SearchLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(x)); - printfx("ERR\n"); - } else { - ldap.err = -1; - debug("main", "SearchLDAP(-, %d, %s, -) -> %s\n", conf.scope, ldap.search_filter, ErrLDAP(x)); - x = SearchIPLDAP(&ldap, bufc); - if (x != LDAP_ERR_SUCCESS) { - debug("main", "SearchIPLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err)); - printfx("ERR\n"); - } else { - debug("main", "SearchIPLDAP(-, %s) -> %s\n", bufc, ErrLDAP(x)); - printfx("OK user=%s\n", bufc); /* Got a userid --> OK user= */ - } - } - } - /* Clear for next query */ - memset(bufc, '\0', strlen(bufc)); - } - } - - /* Clear buffer and close for next data, if not persistent */ - ldap.err = -1; - memset(bufa, '\0', strlen(bufa)); - if (!(ldap.status & LDAP_PERSIST_S)) { - x = CloseLDAP(&ldap); - debug("main", "CloseLDAP(-) -> %s\n", ErrLDAP(x)); - } - } - - debug("main", "Terminating.\n"); - exit(1); -} === removed file 'helpers/external_acl/eDirectory_userip/main.h' --- helpers/external_acl/eDirectory_userip/main.h 2010-08-30 00:05:19 +0000 +++ helpers/external_acl/eDirectory_userip/main.h 1970-01-01 00:00:00 +0000 @@ -1,82 +0,0 @@ -/* squid_edir_iplookup - Copyright (C) 2009, 2010 Chad E. Naugle - * - ******************************************************************************** - * - * This file is part of squid_edir_iplookup. - * - * squid_edir_iplookup 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. - * - * squid_edir_iplookup 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 squid_edir_iplookup. If not, see . - * - ******************************************************************************** - * - * main.h -- - * - * Main program includes & conf_t struct typedef for program configuration. - * - */ - -#ifndef _HAVE_MAIN_H -#define _HAVE_MAIN_H - -#include "config.h" -#include "edui_config.h" - -#ifndef DEFAULT_PROGRAM_NAME -#define DEFAULT_PROGRAM_NAME "ext_edirectory_iuserp_acl" -#endif - -/* Must ... include ... these ... */ -#include -#define _GNU_SOURCE -#define __USE_GNU -#include -#include -#include -#include -#include - -#ifdef DEFAULT_MAXLEN -#define MAXLEN DEFAULT_MAXLEN -#else -#define MAXLEN 1024 -#endif -#define MODE_INIT 0x01 -#define MODE_DEBUG 0x02 -#define MODE_TLS 0x04 -#define MODE_IPV4 0x08 -#define MODE_IPV6 0x10 -#define MODE_GROUP 0x20 /* Group is REQUIRED */ -#define MODE_PERSIST 0x40 /* Persistent LDAP connections */ -#define MODE_KILL 0x80 - -/* conf_t - Program configuration struct typedef */ -typedef struct { - char program[MAXLEN]; - char basedn[MAXLEN]; - char host[MAXLEN]; - char attrib[MAXLEN]; - char dn[MAXLEN]; - char passwd[MAXLEN]; - char search_filter[MAXLEN]; /* Base search_filter that gets copied to ldap_t */ - int ver; - int scope; - int port; - time_t persist_timeout; - unsigned int mode; -} conf_t; - -/* extern the struct */ -extern conf_t conf; /* Main configuration struct */ -extern time_t now; /* Now's time, according to time() */ -extern time_t elap; /* Time elapsed since 'now' */ -#endif