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