This patch is generated from the splay_userauth-20010107 branch of HEAD in squid Thu Sep 11 11:56:59 2003 GMT See http://devel.squid-cache.org/ Index: squid/include/splay.h diff -u squid/include/splay.h:1.3 squid/include/splay.h:1.3.2.1 --- squid/include/splay.h:1.3 Mon Oct 23 08:04:18 2000 +++ squid/include/splay.h Tue Oct 24 03:16:45 2000 @@ -2,6 +2,8 @@ * $Id: squid-splay_userauth-20010107-HEAD,v 1.1 2004/08/17 20:55:13 hno Exp $ */ +#ifndef _SPLAY_H +#define _SPLAY_H typedef struct _splay_node { void *data; @@ -19,3 +21,5 @@ extern splayNode *splay_splay(const void *, splayNode *, SPLAYCMP *); extern void splay_destroy(splayNode *, SPLAYFREE *); extern void splay_walk(splayNode *, SPLAYWALKEE *, void *); + +#endif /* _SPLAY_H */ Index: squid/src/acl.c diff -u squid/src/acl.c:1.8 squid/src/acl.c:1.3.2.5 --- squid/src/acl.c:1.8 Fri Jan 5 12:46:58 2001 +++ squid/src/acl.c Sun Jan 7 06:26:32 2001 @@ -41,6 +41,7 @@ static hash_table *proxy_auth_cache = NULL; static void aclParseDomainList(void *curlist); +static void aclParseProxyAuthList(void **current); static void aclParseIpList(void *curlist); static void aclParseIntlist(void *curlist); static void aclParseWordList(void *curlist); @@ -57,7 +58,7 @@ static int aclMatchAcl(struct _acl *, aclCheck_t *); static int aclMatchIntegerRange(intrange * data, int i); static int aclMatchTime(acl_time_data * data, time_t when); -static int aclMatchUser(wordlist * data, const char *ident); +static int aclMatchUser(void *proxyauth_acl, char *user); static int aclMatchIp(void *dataptr, struct in_addr c); static int aclMatchDomainList(void *dataptr, const char *); static int aclMatchIntegerRange(intrange * data, int i); @@ -634,6 +635,48 @@ wordlistAdd(curlist, t); } +static void +aclParseProxyAuthList(void **current) +{ + char *t = NULL; + acl_proxy_auth_data *data; + splayNode *Top = NULL; + + debug(28, 2) ("aclParseProxyAuthList: parsing authlist\n"); + if (*current == NULL) { + debug(28, 3) ("aclParseProxyAuthList: current is null. Creating\n"); + *current = memAllocate(MEM_ACL_PROXY_AUTH_DATA); /*we rely on mA. zeroing */ + } + data = *current; + if ((t = strtokFile())) { + debug(28, 5) ("aclParseProxyAuthList: First token is %s\n", t); + if (strcmp("-i", t) == 0) { + debug(28, 5) ("aclParseProxyAuthList: Going case-insensitive\n"); + data->flags.case_insensitive = 1; + } else if (strcmp("REQUIRED", t) == 0) { + debug(28, 5) ("aclParseProxyAuthList: REQUIRED-type enabled\n"); + data->flags.required = 1; + } else { + if (data->flags.case_insensitive) + Tolower(t); + Top = splay_insert(xstrdup(t), Top, (SPLAYCMP *) strcmp); + } + } + debug(28, 3) ("aclParseProxyAuthList: Case-insensitive-switch is %d\n", + data->flags.case_insensitive); + /* we might inherit from a previous declaration */ + + debug(28, 4) ("aclParseProxyAuthList: parsing proxy-auth list\n"); + while ((t = strtokFile())) { + debug(28, 6) ("aclParseProxyAuthList: Got token: %s\n", t); + if (data->flags.case_insensitive) + Tolower(t); + Top = splay_insert(xstrdup(t), Top, (SPLAYCMP *) strcmp); + } + data->names = Top; +} + + /**********************/ /* aclParseDomainList */ /**********************/ @@ -745,7 +788,7 @@ aclParseMethodList(&A->data); break; case ACL_PROXY_AUTH: - aclParseWordList(&A->data); + aclParseProxyAuthList(&A->data); if (!proxy_auth_cache) { /* First time around, 7921 should be big enough */ proxy_auth_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string); @@ -1009,20 +1052,33 @@ } static int -aclMatchUser(wordlist * data, const char *user) +aclMatchUser(void *proxyauth_acl, char *user) { + acl_proxy_auth_data *data = (acl_proxy_auth_data *) proxyauth_acl; + splayNode *Top = data->names; + + debug(28, 7) ("aclMatchUser: user is %s, case_insensitive is %d\n", + user, data->flags.case_insensitive); + debug(28, 8) ("Top is %p, Top->data is %s\n", Top, + (Top != NULL ? (Top)->data : "Unavailable")); + if (user == NULL) return 0; - debug(28, 3) ("aclMatchUser: checking '%s'\n", user); - while (data) { - debug(28, 3) ("aclMatchUser: looking for '%s'\n", data->key); - if (strcmp(data->key, "REQUIRED") == 0 && *user != '\0' && strcmp(user, "-") != 0) - return 1; - if (strcmp(data->key, user) == 0) - return 1; - data = data->next; - } - return 0; + + if (data->flags.case_insensitive) + Tolower(user); + + if (data->flags.required) { + debug(28, 7) ("aclMatchUser: user REQUIRED and auth-info present.\n"); + return 1; + } + Top = splay_splay(user, Top, (SPLAYCMP *) strcmp); + /* Top=splay_splay(user,Top,(SPLAYCMP *)dumping_strcmp); */ + debug(28, 7) ("aclMatchUser: returning %d,Top is %p, Top->data is %s\n", + !splayLastResult, + Top, (Top ? Top->data : "Unavailable")); + data->names = Top; + return !splayLastResult; } static int @@ -1892,6 +1948,15 @@ memFree(p, MEM_ACL_IP_DATA); } +static void +aclFreeProxyAuthData(void *data) +{ + acl_proxy_auth_data *d = data; + splay_destroy(d->names, xfree); + memFree(d, MEM_ACL_PROXY_AUTH_DATA); +} + + void aclDestroyAcls(acl ** head) { @@ -1913,12 +1978,16 @@ break; #if SQUID_SNMP case ACL_SNMP_COMMUNITY: + wordlistDestroy((wordlist **) & a->data); + break; #endif #if USE_IDENT case ACL_IDENT: + wordlistDestroy((wordlist **) & a->data); + break; #endif case ACL_PROXY_AUTH: - wordlistDestroy((wordlist **) & a->data); + aclFreeProxyAuthData(a->data); break; case ACL_TIME: aclDestroyTimeList(a->data); @@ -2095,6 +2164,27 @@ } static void +aclDumpProxyAuthListWalkee(void *node_data, void *outlist) +{ + /* outlist is really a wordlist ** */ + wordlistAdd(outlist, node_data); +} + +wordlist * +aclDumpProxyAuthList(acl_proxy_auth_data * data) +{ + wordlist *wl = NULL; + if ((data->flags.case_insensitive) != 0) + wordlistAdd(&wl, "-i"); + /* damn this is VERY inefficient for long ACL lists... filling + * a wordlist this way costs Sum(1,N) iterations. For instance + * a 1000-elements list will be filled in 499500 iterations. + */ + splay_walk(data->names, aclDumpProxyAuthListWalkee, &wl); + return wl; +} + +static void aclDumpIpListWalkee(void *node, void *state) { acl_ip_data *ip = node; @@ -2235,6 +2325,8 @@ break; #if SQUID_SNMP case ACL_SNMP_COMMUNITY: + return wordlistDup(a->data); + break; #endif #if USE_IDENT case ACL_IDENT: @@ -2245,7 +2337,7 @@ break; #endif case ACL_PROXY_AUTH: - return wordlistDup(a->data); + return aclDumpProxyAuthList(a->data); break; case ACL_TIME: return aclDumpTimeSpecList(a->data); Index: squid/src/enums.h diff -u squid/src/enums.h:1.8 squid/src/enums.h:1.3.2.3 --- squid/src/enums.h:1.8 Sat Jan 6 03:59:55 2001 +++ squid/src/enums.h Sun Jan 7 04:24:45 2001 @@ -517,6 +517,7 @@ MEM_ACL_IP_DATA, MEM_ACL_LIST, MEM_ACL_NAME_LIST, + MEM_ACL_PROXY_AUTH_DATA, MEM_ACL_PROXY_AUTH_USER, MEM_ACL_TIME_DATA, MEM_CACHEMGR_PASSWD, Index: squid/src/mem.c diff -u squid/src/mem.c:1.3 squid/src/mem.c:1.3.2.2 --- squid/src/mem.c:1.3 Mon Oct 23 08:04:21 2000 +++ squid/src/mem.c Sun Jan 7 04:24:45 2001 @@ -204,6 +204,8 @@ memDataInit(MEM_ACL_LIST, "acl_list", sizeof(acl_list), 0); memDataInit(MEM_ACL_NAME_LIST, "acl_name_list", sizeof(acl_name_list), 0); memDataInit(MEM_ACL_TIME_DATA, "acl_time_data", sizeof(acl_time_data), 0); + memDataInit(MEM_ACL_PROXY_AUTH_DATA, "acl_proxy_auth_data", + sizeof(acl_proxy_auth_data), 0); memDataInit(MEM_ACL_PROXY_AUTH_USER, "acl_proxy_auth_user", sizeof(acl_proxy_auth_user), 0); memDataInit(MEM_CACHEMGR_PASSWD, "cachemgr_passwd", Index: squid/src/structs.h diff -u squid/src/structs.h:1.15 squid/src/structs.h:1.3.2.4 --- squid/src/structs.h:1.15 Thu Jan 4 22:38:08 2001 +++ squid/src/structs.h Sun Jan 7 06:26:33 2001 @@ -31,6 +31,9 @@ * */ +#include "config.h" +#include "splay.h" + struct _dlink_node { void *data; dlink_node *prev; @@ -41,6 +44,15 @@ dlink_node *head; dlink_node *tail; }; + +struct _acl_proxy_auth_data { + splayNode *names; + struct { + unsigned int case_insensitive:1; + unsigned int required:1; + } flags; +}; + struct _acl_ip_data { struct in_addr addr1; /* if addr2 non-zero then its a range */ Index: squid/src/typedefs.h diff -u squid/src/typedefs.h:1.6 squid/src/typedefs.h:1.3.2.2 --- squid/src/typedefs.h:1.6 Fri Jan 5 12:46:59 2001 +++ squid/src/typedefs.h Sun Jan 7 04:18:36 2001 @@ -62,6 +62,7 @@ typedef struct _acl_name_list acl_name_list; typedef struct _acl_deny_info_list acl_deny_info_list; typedef struct _acl_proxy_auth acl_proxy_auth; +typedef struct _acl_proxy_auth_data acl_proxy_auth_data; typedef struct _acl_proxy_auth_user acl_proxy_auth_user; typedef struct _acl_arp_data acl_arp_data; typedef struct _acl acl; squid-splay_userauth-20010107-HEAD.new squid-splay_userauth-20010107-HEAD differ: char 83, line 2