--------------------- PatchSet 6134 Date: 2004/02/04 13:56:11 Author: hno Branch: ntlmcleanup Tag: (none) Log: Import of ntlm cleanup patch Members: src/authenticate.c:1.23.2.8->1.23.2.8.10.1 src/enums.h:1.29.2.9->1.29.2.9.4.1 src/helper.c:1.16.2.10->1.16.2.10.6.1 src/protos.h:1.41.6.17->1.41.6.17.4.1 src/structs.h:1.48.2.20->1.48.2.20.4.1 src/typedefs.h:1.25.6.3->1.25.6.3.4.1 src/auth/ntlm/auth_ntlm.c:1.18.2.4->1.18.2.4.12.1 Index: squid/src/authenticate.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/authenticate.c,v retrieving revision 1.23.2.8 retrieving revision 1.23.2.8.10.1 diff -u -r1.23.2.8 -r1.23.2.8.10.1 --- squid/src/authenticate.c 19 May 2003 02:14:39 -0000 1.23.2.8 +++ squid/src/authenticate.c 4 Feb 2004 13:56:11 -0000 1.23.2.8.10.1 @@ -1,6 +1,6 @@ /* - * $Id: authenticate.c,v 1.23.2.8 2003/05/19 02:14:39 squidadm Exp $ + * $Id: authenticate.c,v 1.23.2.8.10.1 2004/02/04 13:56:11 hno Exp $ * * DEBUG: section 29 Authenticator * AUTHOR: Duane Wessels @@ -463,6 +463,7 @@ } return AUTH_ACL_CHALLENGE; } +#if 0 /* * Is this an already authenticated connection with a new auth header? * No check for function required in the if: its compulsory for conn based @@ -487,6 +488,7 @@ /* Set the connection auth type */ conn->auth_type = AUTH_UNKNOWN; } +#endif /* we have a proxy auth header and as far as we know this connection has * not had bungled connection oriented authentication happen on it. */ debug(28, 9) ("authenticateAuthenticate: header %s.\n", proxy_auth ? proxy_auth : NULL); Index: squid/src/enums.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/enums.h,v retrieving revision 1.29.2.9 retrieving revision 1.29.2.9.4.1 diff -u -r1.29.2.9 -r1.29.2.9.4.1 --- squid/src/enums.h 20 Dec 2003 03:13:43 -0000 1.29.2.9 +++ squid/src/enums.h 4 Feb 2004 13:56:11 -0000 1.29.2.9.4.1 @@ -1,6 +1,6 @@ /* - * $Id: enums.h,v 1.29.2.9 2003/12/20 03:13:43 squidadm Exp $ + * $Id: enums.h,v 1.29.2.9.4.1 2004/02/04 13:56:11 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -529,14 +529,6 @@ AUTH_BROKEN /* known type, but broken data */ } auth_type_t; -/* stateful helper callback response codes */ -typedef enum { - S_HELPER_UNKNOWN, - S_HELPER_RESERVE, - S_HELPER_RELEASE, - S_HELPER_DEFER -} stateful_helper_callback_t; - /* stateful helper reservation info */ typedef enum { S_HELPER_FREE, /* available for requests */ Index: squid/src/helper.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/helper.c,v retrieving revision 1.16.2.10 retrieving revision 1.16.2.10.6.1 diff -u -r1.16.2.10 -r1.16.2.10.6.1 --- squid/src/helper.c 13 Sep 2003 02:14:23 -0000 1.16.2.10 +++ squid/src/helper.c 4 Feb 2004 13:56:12 -0000 1.16.2.10.6.1 @@ -1,6 +1,6 @@ /* - * $Id: helper.c,v 1.16.2.10 2003/09/13 02:14:23 squidadm Exp $ + * $Id: helper.c,v 1.16.2.10.6.1 2004/02/04 13:56:12 hno Exp $ * * DEBUG: section 84 Helper process maintenance * AUTHOR: Harvest Derived? @@ -53,9 +53,6 @@ static void helperRequestFree(helper_request * r); static void helperStatefulRequestFree(helper_stateful_request * r); static void StatefulEnqueue(statefulhelper * hlp, helper_stateful_request * r); -static helper_stateful_request *StatefulServerDequeue(helper_stateful_server * srv); -static void StatefulServerEnqueue(helper_stateful_server * srv, helper_stateful_request * r); -static void helperStatefulServerKickQueue(helper_stateful_server * srv); void helperOpenServers(helper * hlp) @@ -184,12 +181,8 @@ srv = cbdataAlloc(helper_stateful_server); srv->pid = x; srv->flags.alive = 1; - srv->flags.reserved = S_HELPER_FREE; - srv->deferred_requests = 0; - srv->stats.deferbyfunc = 0; - srv->stats.deferbycb = 0; + srv->flags.reserved = 0; srv->stats.submits = 0; - srv->stats.releases = 0; srv->index = k; srv->rfd = rfd; srv->wfd = wfd; @@ -243,14 +236,10 @@ debug(84, 9) ("helperSubmit: %s\n", buf); } -/* lastserver = "server last used as part of a deferred or reserved - * request sequence" - */ void -helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPSCB * callback, void *data, helper_stateful_server * lastserver) +helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPSCB * callback, void *data, helper_stateful_server * srv) { helper_stateful_request *r = memAllocate(MEM_HELPER_STATEFUL_REQUEST); - helper_stateful_server *srv; if (hlp == NULL) { debug(84, 3) ("helperStatefulSubmit: hlp == NULL\n"); callback(data, 0, NULL); @@ -258,109 +247,49 @@ } r->callback = callback; r->data = data; - if (buf != NULL) { - r->buf = xstrdup(buf); - r->placeholder = 0; - } else { - r->buf = NULL; - r->placeholder = 1; - } + r->buf = xstrdup(buf); cbdataLock(r->data); - if ((buf != NULL) && lastserver) { - debug(84, 5) ("StatefulSubmit with lastserver %p\n", lastserver); - /* the queue doesn't count for this assert because queued requests - * have already gone through here and been tested. - * It's legal to have deferred_requests == 0 and queue entries - * and status of S_HELPEER_DEFERRED. - * BUT: It's not legal to submit a new request w/lastserver in - * that state. - */ - assert(!(lastserver->deferred_requests == 0 && - lastserver->flags.reserved == S_HELPER_DEFERRED)); - if (lastserver->flags.reserved != S_HELPER_RESERVED) { - lastserver->stats.submits++; - lastserver->deferred_requests--; - } - if (!(lastserver->request)) { - debug(84, 5) ("StatefulSubmit dispatching\n"); - helperStatefulDispatch(lastserver, r); - } else { - debug(84, 5) ("StatefulSubmit queuing\n"); - StatefulServerEnqueue(lastserver, r); - } + if (!srv) + srv = helperStatefulGetServer(hlp); + if (srv) { + assert(buf != NULL); + debug(84, 5) ("helperStatefulSubmit: sever %p, buf '%s'.\n", srv, buf); + assert(!srv->request); + helperStatefulDispatch(srv, r); } else { - if ((srv = StatefulGetFirstAvailable(hlp))) { - helperStatefulDispatch(srv, r); - } else - StatefulEnqueue(hlp, r); + debug(84, 9) ("helperStatefulSubmit: enqueued, buf '%s'.\n", buf); + StatefulEnqueue(hlp, r); } - debug(84, 9) ("helperStatefulSubmit: placeholder: '%d', buf '%s'.\n", r->placeholder, buf); } helper_stateful_server * -helperStatefulDefer(statefulhelper * hlp) -/* find and add a deferred request to a server */ +helperStatefulGetServer(statefulhelper * hlp) +/* find a server for this request */ { - dlink_node *n; - helper_stateful_server *srv = NULL, *rv = NULL; + helper_stateful_server *srv = NULL; if (hlp == NULL) { - debug(84, 3) ("helperStatefulDefer: hlp == NULL\n"); + debug(84, 3) ("helperStatefulGetServer: hlp == NULL\n"); return NULL; } - debug(84, 5) ("helperStatefulDefer: Running servers %d.\n", hlp->n_running); + debug(84, 5) ("helperStatefulGetServer: Running servers %d.\n", hlp->n_running); if (hlp->n_running == 0) { - debug(84, 1) ("helperStatefulDefer: No running servers!. \n"); + debug(84, 1) ("helperStatefulGetServer: No running servers!. \n"); return NULL; } - rv = srv = StatefulGetFirstAvailable(hlp); - if (rv == NULL) { - /* - * all currently busy; loop through servers and find server - * with the shortest queue - */ - for (n = hlp->servers.head; n != NULL; n = n->next) { - srv = n->data; - if (srv->flags.reserved == S_HELPER_RESERVED) - continue; - if (!srv->flags.alive) - continue; - if ((hlp->IsAvailable != NULL) && (srv->data != NULL) && - !(hlp->IsAvailable(srv->data))) - continue; - if ((rv != NULL) && (rv->deferred_requests < srv->deferred_requests)) - continue; - rv = srv; - } - } - if (rv == NULL) { - debug(84, 1) ("helperStatefulDefer: None available.\n"); - return NULL; - } - /* consistency check: - * when the deferred count is 0, - * submits + releases == deferbyfunc + deferbycb - * Or in english, when there are no deferred requests, the amount - * we have submitted to the queue or cancelled must equal the amount - * we have said we wanted to be able to submit or cancel - */ - if (rv->deferred_requests == 0) - assert(rv->stats.submits + rv->stats.releases == - rv->stats.deferbyfunc + rv->stats.deferbycb); - - rv->flags.reserved = S_HELPER_DEFERRED; - rv->deferred_requests++; - rv->stats.deferbyfunc++; - return rv; + srv = StatefulGetFirstAvailable(hlp); + if (srv) + srv->flags.reserved = 1; + debug(84, 5) ("helperStatefulGetServer: Returning %p\n", srv); + return srv; } +/* puts this helper forcibly back in the queue. */ void helperStatefulReset(helper_stateful_server * srv) -/* puts this helper back in the queue. the calling app is required to - * manage the state in the helper. - */ { statefulhelper *hlp = srv->parent; helper_stateful_request *r; + debug(84, 5) ("helperStatefulReset: %p\n", srv); r = srv->request; if (r != NULL) { /* reset attempt DURING an outstaning request */ @@ -372,31 +301,26 @@ srv->request = NULL; } srv->flags.busy = 0; - if (srv->queue.head) { - srv->flags.reserved = S_HELPER_DEFERRED; - helperStatefulServerKickQueue(srv); + srv->flags.reserved = 0; + if ((srv->parent->Reset != NULL) && (srv->data)) + srv->parent->Reset(srv->data); + if (srv->flags.shutdown) { + int wfd = srv->wfd; + srv->wfd = -1; + comm_close(wfd); } else { - srv->flags.reserved = S_HELPER_FREE; - if ((srv->parent->OnEmptyQueue != NULL) && (srv->data)) - srv->parent->OnEmptyQueue(srv->data); helperStatefulKickQueue(hlp); } } +/* puts this helper back in the queue. */ void helperStatefulReleaseServer(helper_stateful_server * srv) -/*decrease the number of 'waiting' clients that set the helper to be DEFERRED */ { - srv->stats.releases++; - if (srv->flags.reserved == S_HELPER_DEFERRED) { - assert(srv->deferred_requests); - srv->deferred_requests--; - } - if (!(srv->deferred_requests) && (srv->flags.reserved == S_HELPER_DEFERRED) && !(srv->queue.head)) { - srv->flags.reserved = S_HELPER_FREE; - if ((srv->parent->OnEmptyQueue != NULL) && (srv->data)) - srv->parent->OnEmptyQueue(srv->data); - } + debug(84, 5) ("helperStatefulReleaseServer: %p\n", srv); + assert(!srv->request); + assert(srv->flags.reserved); + helperStatefulReset(srv); } void * @@ -475,12 +399,11 @@ storeAppendPrintf(sentry, "avg service time: %d msec\n", hlp->stats.avg_svc_time); storeAppendPrintf(sentry, "\n"); - storeAppendPrintf(sentry, "%7s\t%7s\t%7s\t%11s\t%20s\t%s\t%7s\t%7s\t%7s\n", + storeAppendPrintf(sentry, "%7s\t%7s\t%7s\t%11s\t%s\t%7s\t%7s\t%7s\n", "#", "FD", "PID", "# Requests", - "# Deferred Requests", "Flags", "Time", "Offset", @@ -488,18 +411,16 @@ for (link = hlp->servers.head; link; link = link->next) { srv = link->data; tt = 0.001 * tvSubMsec(srv->dispatch_time, current_time); - storeAppendPrintf(sentry, "%7d\t%7d\t%7d\t%11d\t%20d\t%c%c%c%c%c%c\t%7.3f\t%7d\t%s\n", + storeAppendPrintf(sentry, "%7d\t%7d\t%7d\t%11d\t%c%c%c%c%c\t%7.3f\t%7d\t%s\n", srv->index + 1, srv->rfd, srv->pid, srv->stats.uses, - (int) srv->deferred_requests, srv->flags.alive ? 'A' : ' ', srv->flags.busy ? 'B' : ' ', srv->flags.closing ? 'C' : ' ', - srv->flags.reserved != S_HELPER_FREE ? 'R' : ' ', + srv->flags.reserved ? 'R' : ' ', srv->flags.shutdown ? 'S' : ' ', - srv->request ? (srv->request->placeholder ? 'P' : ' ') : ' ', tt < 0.0 ? 0.0 : tt, (int) srv->offset, srv->request ? log_quote(srv->request->buf) : "(none)"); @@ -570,16 +491,11 @@ hlp->id_name, srv->index + 1); continue; } - if (srv->flags.reserved != S_HELPER_FREE) { + if (srv->flags.reserved) { debug(84, 3) ("helperStatefulShutdown: %s #%d is RESERVED.\n", hlp->id_name, srv->index + 1); continue; } - if (srv->deferred_requests) { - debug(84, 3) ("helperStatefulShutdown: %s #%d has DEFERRED requests.\n", - hlp->id_name, srv->index + 1); - continue; - } srv->flags.closing = 1; wfd = srv->wfd; srv->wfd = -1; @@ -747,11 +663,8 @@ /* end of reply found */ debug(84, 3) ("helperHandleRead: end of reply found\n"); *t = '\0'; - if (cbdataValid(r->data)) - r->callback(r->data, srv->buf); srv->flags.busy = 0; srv->offset = 0; - helperRequestFree(r); srv->request = NULL; hlp->stats.replies++; srv->answer_time = current_time; @@ -759,11 +672,10 @@ intAverage(hlp->stats.avg_svc_time, tvSubUsec(srv->dispatch_time, current_time), hlp->stats.replies, REDIRECT_AV_FACTOR); - if (srv->flags.shutdown) { - int wfd = srv->wfd; - srv->wfd = -1; - comm_close(wfd); - } else + if (cbdataValid(r->data)) + r->callback(r->data, srv->buf); + helperRequestFree(r); + if (!srv->flags.shutdown) helperKickQueue(hlp); } else { commSetSelect(srv->rfd, COMM_SELECT_READ, helperHandleRead, srv, 0); @@ -803,68 +715,20 @@ /* end of reply found */ debug(84, 3) ("helperStatefulHandleRead: end of reply found\n"); *t = '\0'; - if (cbdataValid(r->data)) { - switch ((r->callback(r->data, srv, srv->buf))) { /*if non-zero reserve helper */ - case S_HELPER_UNKNOWN: - fatal("helperStatefulHandleRead: either a non-state aware callback was give to the stateful helper routines, or an uninitialised callback response was recieved.\n"); - break; - case S_HELPER_RELEASE: /* helper finished with */ - if (!srv->deferred_requests && !srv->queue.head) { - srv->flags.reserved = S_HELPER_FREE; - if ((srv->parent->OnEmptyQueue != NULL) && (srv->data)) - srv->parent->OnEmptyQueue(srv->data); - debug(84, 5) ("StatefulHandleRead: releasing %s #%d\n", hlp->id_name, srv->index + 1); - } else { - srv->flags.reserved = S_HELPER_DEFERRED; - debug(84, 5) ("StatefulHandleRead: outstanding deferred requests on %s #%d. reserving for deferred requests.\n", hlp->id_name, srv->index + 1); - } - break; - case S_HELPER_RESERVE: /* 'pin' this helper for the caller */ - if (!srv->queue.head) { - assert(srv->deferred_requests == 0); - srv->flags.reserved = S_HELPER_RESERVED; - debug(84, 5) ("StatefulHandleRead: reserving %s #%d\n", hlp->id_name, srv->index + 1); - } else { - fatal("StatefulHandleRead: Callback routine attempted to reserve a stateful helper with deferred requests. This can lead to deadlock.\n"); - } - break; - case S_HELPER_DEFER: - /* the helper is still needed, but can - * be used for other requests in the meantime. - */ - srv->flags.reserved = S_HELPER_DEFERRED; - srv->deferred_requests++; - srv->stats.deferbycb++; - debug(84, 5) ("StatefulHandleRead: reserving %s #%d for deferred requests.\n", hlp->id_name, srv->index + 1); - break; - default: - fatal("helperStatefulHandleRead: unknown stateful helper callback result.\n"); - } - - } else { - debug(84, 1) ("StatefulHandleRead: no callback data registered\n"); - } srv->flags.busy = 0; srv->offset = 0; - helperStatefulRequestFree(r); srv->request = NULL; hlp->stats.replies++; hlp->stats.avg_svc_time = intAverage(hlp->stats.avg_svc_time, tvSubMsec(srv->dispatch_time, current_time), hlp->stats.replies, REDIRECT_AV_FACTOR); - if (srv->flags.shutdown - && srv->flags.reserved == S_HELPER_FREE - && !srv->deferred_requests) { - int wfd = srv->wfd; - srv->wfd = -1; - comm_close(wfd); + if (cbdataValid(r->data)) { + r->callback(r->data, srv, srv->buf); } else { - if (srv->queue.head) - helperStatefulServerKickQueue(srv); - else - helperStatefulKickQueue(hlp); + debug(84, 1) ("StatefulHandleRead: no callback data registered\n"); } + helperStatefulRequestFree(r); } else { commSetSelect(srv->rfd, COMM_SELECT_READ, helperStatefulHandleRead, srv, 0); } @@ -878,16 +742,19 @@ hlp->stats.queue_size++; if (hlp->stats.queue_size < hlp->n_running) return; + if (hlp->stats.queue_size < hlp->n_running) + return; if (squid_curtime - hlp->last_queue_warn < 600) return; if (shutting_down || reconfiguring) return; hlp->last_queue_warn = squid_curtime; debug(84, 0) ("WARNING: All %s processes are busy.\n", hlp->id_name); - debug(84, 0) ("WARNING: %d pending requests queued\n", hlp->stats.queue_size); + debug(84, 0) ("WARNING: %d to %d pending requests queued\n", hlp->stats.queue_size, hlp->stats.max_queue_size); if (hlp->stats.queue_size > hlp->n_running * 2) - fatalf("Too many queued %s requests", hlp->id_name); + fatalf("Too many queued %s requests (%d/%d)", hlp->id_name, hlp->stats.queue_size, hlp->n_running); debug(84, 1) ("Consider increasing the number of %s processes in your config file.\n", hlp->id_name); + hlp->stats.max_queue_size = hlp->stats.queue_size; } static void @@ -898,43 +765,21 @@ hlp->stats.queue_size++; if (hlp->stats.queue_size < hlp->n_running) return; - if (hlp->stats.queue_size > hlp->n_running * 2) - fatalf("Too many queued %s requests", hlp->id_name); + if (hlp->stats.queue_size > hlp->stats.max_queue_size) + hlp->stats.max_queue_size = hlp->stats.queue_size; + if (hlp->stats.queue_size > hlp->n_running * 5) + fatalf("Too many queued %s requests (%d/%d)", hlp->id_name, hlp->stats.queue_size, hlp->n_running); if (squid_curtime - hlp->last_queue_warn < 600) return; if (shutting_down || reconfiguring) return; hlp->last_queue_warn = squid_curtime; debug(84, 0) ("WARNING: All %s processes are busy.\n", hlp->id_name); - debug(84, 0) ("WARNING: %d pending requests queued\n", hlp->stats.queue_size); + debug(84, 0) ("WARNING: %d to %d pending requests queued\n", hlp->stats.queue_size, hlp->stats.max_queue_size); debug(84, 1) ("Consider increasing the number of %s processes in your config file.\n", hlp->id_name); + hlp->stats.max_queue_size = hlp->stats.queue_size; } -static void -StatefulServerEnqueue(helper_stateful_server * srv, helper_stateful_request * r) -{ - dlink_node *link = memAllocate(MEM_DLINK_NODE); - dlinkAddTail(r, link, &srv->queue); -/* TODO: warning if the queue on this server is more than X - * We don't check the queue size at the moment, because - * requests hitting here are deferrable - */ -/* hlp->stats.queue_size++; - * if (hlp->stats.queue_size < hlp->n_running) - * return; - * if (squid_curtime - hlp->last_queue_warn < 600) - * return; - * if (shutting_down || reconfiguring) - * return; - * hlp->last_queue_warn = squid_curtime; - * debug(84, 0) ("WARNING: All %s processes are busy.\n", hlp->id_name); - * debug(84, 0) ("WARNING: %d pending requests queued\n", hlp->stats.queue_size); - * if (hlp->stats.queue_size > hlp->n_running * 2) - * fatalf("Too many queued %s requests", hlp->id_name); - * debug(84, 1) ("Consider increasing the number of %s processes in your config file.\n", hlp->id_name); */ -} - - static helper_request * Dequeue(helper * hlp) { @@ -950,19 +795,6 @@ } static helper_stateful_request * -StatefulServerDequeue(helper_stateful_server * srv) -{ - dlink_node *link; - helper_stateful_request *r = NULL; - if ((link = srv->queue.head)) { - r = link->data; - dlinkDelete(link, &srv->queue); - memFree(link, MEM_DLINK_NODE); - } - return r; -} - -static helper_stateful_request * StatefulDequeue(statefulhelper * hlp) { dlink_node *link; @@ -1006,7 +838,7 @@ srv = n->data; if (srv->flags.busy) continue; - if (srv->flags.reserved == S_HELPER_RESERVED) + if (srv->flags.reserved) continue; if (!srv->flags.alive) continue; @@ -1058,31 +890,6 @@ return; } debug(84, 9) ("helperStatefulDispatch busying helper %s #%d\n", hlp->id_name, srv->index + 1); - if (r->placeholder == 1) { - /* a callback is needed before this request can _use_ a helper. */ - /* we don't care about releasing/deferring this helper. The request NEVER - * gets to the helper. So we throw away the return code */ - r->callback(r->data, srv, NULL); - /* throw away the placeholder */ - helperStatefulRequestFree(r); - /* and push the queue. Note that the callback may have submitted a new - * request to the helper which is why we test for the request*/ - if (srv->request == NULL) { - if (srv->flags.shutdown - && srv->flags.reserved == S_HELPER_FREE - && !srv->deferred_requests) { - int wfd = srv->wfd; - srv->wfd = -1; - comm_close(wfd); - } else { - if (srv->queue.head) - helperStatefulServerKickQueue(srv); - else - helperStatefulKickQueue(hlp); - } - } - return; - } srv->flags.busy = 1; srv->request = r; srv->dispatch_time = current_time; @@ -1117,16 +924,10 @@ { helper_stateful_request *r; helper_stateful_server *srv; - while ((srv = StatefulGetFirstAvailable(hlp)) && (r = StatefulDequeue(hlp))) - helperStatefulDispatch(srv, r); -} - -static void -helperStatefulServerKickQueue(helper_stateful_server * srv) -{ - helper_stateful_request *r; - if ((r = StatefulServerDequeue(srv))) + while ((srv = StatefulGetFirstAvailable(hlp)) && (r = StatefulDequeue(hlp))) { + srv->flags.reserved = 1; helperStatefulDispatch(srv, r); + } } static void Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.41.6.17 retrieving revision 1.41.6.17.4.1 diff -u -r1.41.6.17 -r1.41.6.17.4.1 --- squid/src/protos.h 15 Dec 2003 03:13:47 -0000 1.41.6.17 +++ squid/src/protos.h 4 Feb 2004 13:56:12 -0000 1.41.6.17.4.1 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.41.6.17 2003/12/15 03:13:47 squidadm Exp $ + * $Id: protos.h,v 1.41.6.17.4.1 2004/02/04 13:56:12 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1274,7 +1274,7 @@ extern void helperStatefulReset(helper_stateful_server * srv); extern void helperStatefulReleaseServer(helper_stateful_server * srv); extern void *helperStatefulServerGetData(helper_stateful_server * srv); -extern helper_stateful_server *helperStatefulDefer(statefulhelper *); +extern helper_stateful_server *helperStatefulGetServer(statefulhelper *); Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.48.2.20 retrieving revision 1.48.2.20.4.1 diff -u -r1.48.2.20 -r1.48.2.20.4.1 --- squid/src/structs.h 15 Jan 2004 03:13:54 -0000 1.48.2.20 +++ squid/src/structs.h 4 Feb 2004 13:56:12 -0000 1.48.2.20.4.1 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.48.2.20 2004/01/15 03:13:54 squidadm Exp $ + * $Id: structs.h,v 1.48.2.20.4.1 2004/02/04 13:56:12 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -2000,8 +2000,6 @@ struct _helper_stateful_request { char *buf; HLPSCB *callback; - int placeholder; /* if 1, this is a dummy request waiting for a stateful helper - * to become available for deferred requests.*/ void *data; }; @@ -2019,6 +2017,7 @@ int requests; int replies; int queue_size; + int max_queue_size; int avg_svc_time; } stats; time_t last_restart; @@ -2034,12 +2033,13 @@ int ipc_type; MemPool *datapool; HLPSAVAIL *IsAvailable; - HLPSONEQ *OnEmptyQueue; + HLPSRESET *Reset; time_t last_queue_warn; struct { int requests; int replies; int queue_size; + int max_queue_size; int avg_svc_time; } stats; time_t last_restart; @@ -2081,7 +2081,6 @@ struct timeval dispatch_time; struct timeval answer_time; dlink_node link; - dlink_list queue; statefulhelper *parent; helper_stateful_request *request; struct _helper_stateful_flags { @@ -2089,16 +2088,13 @@ unsigned int busy:1; unsigned int closing:1; unsigned int shutdown:1; - stateful_helper_reserve_t reserved; + unsigned int reserved:1; } flags; struct { int uses; int submits; int releases; - int deferbyfunc; - int deferbycb; } stats; - int deferred_requests; /* current number of deferred requests */ void *data; /* State data used by the calling routines */ }; Index: squid/src/typedefs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v retrieving revision 1.25.6.3 retrieving revision 1.25.6.3.4.1 diff -u -r1.25.6.3 -r1.25.6.3.4.1 --- squid/src/typedefs.h 7 Dec 2003 03:14:44 -0000 1.25.6.3 +++ squid/src/typedefs.h 4 Feb 2004 13:56:12 -0000 1.25.6.3.4.1 @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.25.6.3 2003/12/07 03:14:44 squidadm Exp $ + * $Id: typedefs.h,v 1.25.6.3.4.1 2004/02/04 13:56:12 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -249,9 +249,9 @@ typedef void SIGHDLR(int sig); typedef void STVLDCB(void *, int, int); typedef void HLPCB(void *, char *buf); -typedef stateful_helper_callback_t HLPSCB(void *, void *lastserver, char *buf); +typedef void HLPSCB(void *, void *lastserver, char *buf); typedef int HLPSAVAIL(void *); -typedef void HLPSONEQ(void *); +typedef void HLPSRESET(void *); typedef void HLPCMDOPTS(int *argc, char **argv); typedef void IDNSCB(void *, rfc1035_rr *, int, const char *); Index: squid/src/auth/ntlm/auth_ntlm.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/auth/ntlm/auth_ntlm.c,v retrieving revision 1.18.2.4 retrieving revision 1.18.2.4.12.1 diff -u -r1.18.2.4 -r1.18.2.4.12.1 --- squid/src/auth/ntlm/auth_ntlm.c 5 Feb 2003 03:20:35 -0000 1.18.2.4 +++ squid/src/auth/ntlm/auth_ntlm.c 4 Feb 2004 13:56:12 -0000 1.18.2.4.12.1 @@ -74,7 +74,7 @@ /* helper callbacks to handle per server state data */ static HLPSAVAIL authenticateNTLMHelperServerAvailable; -static HLPSONEQ authenticateNTLMHelperServerOnEmpty; +static HLPSRESET authenticateNTLMHelperServerReset; static statefulhelper *ntlmauthenticators = NULL; @@ -245,7 +245,7 @@ ntlmauthenticators->ipc_type = IPC_TCP_SOCKET; ntlmauthenticators->datapool = ntlm_helper_state_pool; ntlmauthenticators->IsAvailable = authenticateNTLMHelperServerAvailable; - ntlmauthenticators->OnEmptyQueue = authenticateNTLMHelperServerOnEmpty; + ntlmauthenticators->Reset = authenticateNTLMHelperServerReset; helperStatefulOpenServers(ntlmauthenticators); /* * TODO: In here send the initial YR to preinitialise the @@ -364,7 +364,7 @@ xfree(ntlm_request->authchallenge); if (ntlm_request->ntlmauthenticate) xfree(ntlm_request->ntlmauthenticate); - if (ntlm_request->authserver != NULL && ntlm_request->authserver_deferred) { + if (ntlm_request->authserver != NULL) { debug(29, 9) ("authenticateNTLMRequestFree: releasing server '%p'\n", ntlm_request->authserver); helperStatefulReleaseServer(ntlm_request->authserver); ntlm_request->authserver = NULL; @@ -407,11 +407,32 @@ auth_user->scheme_data = NULL; } -static stateful_helper_callback_t -authenticateNTLMHandleplaceholder(void *data, void *lastserver, char *reply) +/* clear the NTLM helper of being reserved for future requests */ +static void +authenticateNTLMReleaseServer(ntlm_request_t * ntlm_request) +{ + helper_stateful_server *server = ntlm_request->authserver; + debug(29, 9) ("authenticateNTLMReleaseServer: releasing server '%p'\n", server); + ntlm_request->authserver = NULL; + helperStatefulReleaseServer(server); +} + +/* clear the NTLM helper of being reserved for future requests */ +static void +authenticateNTLMResetServer(ntlm_request_t * ntlm_request) +{ + helper_stateful_server *server = ntlm_request->authserver; + ntlm_helper_state_t *helperstate = helperStatefulServerGetData(server); + debug(29, 9) ("authenticateNTLMReleaseServer: releasing server '%p'\n", server); + ntlm_request->authserver = NULL; + helperstate->starve = 1; + helperStatefulReleaseServer(server); +} + +static void +authenticateNTLMHandleplaceholder(void *data, void *srv, char *reply) { authenticateStateData *r = data; - stateful_helper_callback_t result = S_HELPER_UNKNOWN; int valid; /* we should only be called for placeholder requests - which have no reply string */ assert(reply == NULL); @@ -420,36 +441,35 @@ valid = cbdataValid(r->data); if (!valid) { debug(29, 1) ("AuthenticateNTLMHandlePlacheholder: invalid callback data.\n"); - return result; + helperStatefulReleaseServer(srv); + return; } /* call authenticateNTLMStart to retry this request */ debug(29, 9) ("authenticateNTLMHandleplaceholder: calling authenticateNTLMStart\n"); + helperStatefulReleaseServer(srv); authenticateNTLMStart(r->auth_user_request, r->handler, r->data); cbdataUnlock(r->data); authenticateStateFree(r); - return result; } -static stateful_helper_callback_t -authenticateNTLMHandleReply(void *data, void *lastserver, char *reply) +static void +authenticateNTLMHandleReply(void *data, void *srv, char *reply) { authenticateStateData *r = data; ntlm_helper_state_t *helperstate; int valid; - stateful_helper_callback_t result = S_HELPER_UNKNOWN; - char *t = NULL; auth_user_request_t *auth_user_request; auth_user_t *auth_user; ntlm_user_t *ntlm_user; ntlm_request_t *ntlm_request; - debug(29, 9) ("authenticateNTLMHandleReply: Helper: '%p' {%s}\n", lastserver, reply ? reply : ""); + debug(29, 9) ("authenticateNTLMHandleReply: Helper: '%p' {%s}\n", srv, reply ? reply : ""); valid = cbdataValid(r->data); if (!valid) { - debug(29, 1) ("AuthenticateNTLMHandleReply: invalid callback data. Releasing helper '%p'.\n", lastserver); + debug(29, 1) ("AuthenticateNTLMHandleReply: invalid callback data. Releasing helper '%p'.\n", srv); cbdataUnlock(r->data); authenticateStateFree(r); - debug(29, 9) ("NTLM HandleReply, telling stateful helper : %d\n", S_HELPER_RELEASE); - return S_HELPER_RELEASE; + helperStatefulReleaseServer(srv); + return; } if (!reply) { /* @@ -458,48 +478,41 @@ */ fatal("authenticateNTLMHandleReply: called with no result string\n"); } + + assert(r->auth_user_request != NULL); + assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM); + auth_user_request = r->auth_user_request; + ntlm_request = auth_user_request->scheme_data; + assert(ntlm_request != NULL); + /* seperate out the useful data */ if (strncasecmp(reply, "TT ", 3) == 0) { reply += 3; /* we have been given a Challenge */ /* we should check we weren't given an empty challenge */ /* copy the challenge to the state data */ - helperstate = helperStatefulServerGetData(lastserver); + helperstate = helperStatefulServerGetData(srv); if (helperstate == NULL) fatal("lost NTLM helper state! quitting\n"); helperstate->challenge = xstrndup(reply, NTLM_CHALLENGE_SZ + 5); - helperstate->challengeuses = 0; helperstate->renewed = squid_curtime; /* and we satisfy the request that happended on the refresh boundary */ /* note this code is now in two places FIXME */ - assert(r->auth_user_request != NULL); - assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM); - auth_user_request = r->auth_user_request; - ntlm_request = auth_user_request->scheme_data; - assert(ntlm_request != NULL); - result = S_HELPER_DEFER; - /* reserve the server for future authentication */ - ntlm_request->authserver_deferred = 1; - debug(29, 9) ("authenticateNTLMHandleReply: helper '%p'\n", lastserver); assert(ntlm_request->auth_state == AUTHENTICATE_STATE_NEGOTIATE); - ntlm_request->authserver = lastserver; + ntlm_request->authserver = srv; ntlm_request->authchallenge = xstrndup(reply, NTLM_CHALLENGE_SZ + 5); + helperstate->challengeuses = 1; } else if (strncasecmp(reply, "AF ", 3) == 0) { /* we're finished, release the helper */ reply += 3; - assert(r->auth_user_request != NULL); - assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM); - auth_user_request = r->auth_user_request; - assert(auth_user_request->scheme_data != NULL); - ntlm_request = auth_user_request->scheme_data; auth_user = auth_user_request->auth_user; ntlm_user = auth_user_request->auth_user->scheme_data; assert(ntlm_user != NULL); - result = S_HELPER_RELEASE; /* we only expect OK when finishing the handshake */ assert(ntlm_request->auth_state == AUTHENTICATE_STATE_RESPONSE); ntlm_user->username = xstrndup(reply, MAX_LOGIN_SZ); ntlm_request->authserver = NULL; + helperStatefulReleaseServer(srv); #ifdef NTLM_FAIL_OPEN } else if (strncasecmp(reply, "LD ", 3) == 0) { /* This is a variant of BH, which rather than deny access @@ -512,44 +525,22 @@ * case */ /* AF code: mark user as authenticated */ reply += 3; - assert(r->auth_user_request != NULL); - assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM); - auth_user_request = r->auth_user_request; - assert(auth_user_request->scheme_data != NULL); - ntlm_request = auth_user_request->scheme_data; auth_user = auth_user_request->auth_user; ntlm_user = auth_user_request->auth_user->scheme_data; assert(ntlm_user != NULL); - result = S_HELPER_RELEASE; /* we only expect LD when finishing the handshake */ assert(ntlm_request->auth_state == AUTHENTICATE_STATE_RESPONSE); ntlm_user->username = xstrndup(reply, MAX_LOGIN_SZ); helperstate = helperStatefulServerGetData(ntlm_request->authserver); - ntlm_request->authserver = NULL; /* BH code: mark helper as broken */ - /* mark it for starving */ - helperstate->starve = 1; + authenticateNTLMResetServer(ntlm_request); + debug(29, 4) ("authenticateNTLMHandleReply: Error validating user via NTLM. Error returned '%s'\n", reply); #endif } else if (strncasecmp(reply, "NA ", 3) == 0) { - /* TODO: only work with auth_user here if it exists */ - assert(r->auth_user_request != NULL); - assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM); - auth_user_request = r->auth_user_request; - auth_user = auth_user_request->auth_user; - assert(auth_user != NULL); - ntlm_user = auth_user->scheme_data; - ntlm_request = auth_user_request->scheme_data; - assert((ntlm_user != NULL) && (ntlm_request != NULL)); /* todo: action of Negotiate state on error */ - result = S_HELPER_RELEASE; /*some error has occured. no more requests */ - ntlm_request->authserver = NULL; - debug(29, 4) ("authenticateNTLMHandleReply: Error validating user via NTLM. Error returned '%s'\n", reply); ntlm_request->auth_state = AUTHENTICATE_STATE_FAILED; - if ((t = strchr(reply, ' '))) /* strip after a space */ - *t = '\0'; - } else if (strncasecmp(reply, "NA", 2) == 0) { - /* NTLM Helper protocol violation! */ - fatal("NTLM Helper returned invalid response \"NA\" - a error message MUST be attached\n"); + authenticateNTLMResetServer(ntlm_request); + debug(29, 4) ("authenticateNTLMHandleReply: Error validating user via NTLM. Error returned '%s'\n", reply); } else if (strncasecmp(reply, "BH ", 3) == 0) { /* TODO kick off a refresh process. This can occur after a YR or after * a KK. If after a YR release the helper and resubmit the request via @@ -564,57 +555,31 @@ ntlm_user = auth_user->scheme_data; ntlm_request = auth_user_request->scheme_data; assert((ntlm_user != NULL) && (ntlm_request != NULL)); - result = S_HELPER_RELEASE; /*some error has occured. no more requests for - * this helper */ - assert(ntlm_request->authserver ? ntlm_request->authserver == lastserver : 1); + assert(!ntlm_request->authserver || ntlm_request->authserver == srv); helperstate = helperStatefulServerGetData(ntlm_request->authserver); - ntlm_request->authserver = NULL; + authenticateNTLMResetServer(ntlm_request); if (ntlm_request->auth_state == AUTHENTICATE_STATE_NEGOTIATE) { /* The helper broke on YR. It automatically * resets */ - debug(29, 1) ("authenticateNTLMHandleReply: Error obtaining challenge from helper: %p. Error returned '%s'\n", lastserver, reply); - /* mark it for starving */ - helperstate->starve = 1; + debug(29, 1) ("authenticateNTLMHandleReply: Error obtaining challenge from helper: %p. Error returned '%s'\n", srv, reply); /* resubmit the request. This helper is currently busy, so we will get * a different one. Our auth state stays the same */ authenticateNTLMStart(auth_user_request, r->handler, r->data); /* don't call the callback */ cbdataUnlock(r->data); authenticateStateFree(r); - debug(29, 9) ("NTLM HandleReply, telling stateful helper : %d\n", result); - return result; + return; + } else { + /* the helper broke on a KK */ + debug(29, 1) ("authenticateNTLMHandleReply: Error validating user via NTLM. Error returned '%s'\n", reply); + ntlm_request->auth_state = AUTHENTICATE_STATE_FAILED; } - /* the helper broke on a KK */ - /* first the standard KK stuff */ - debug(29, 4) ("authenticateNTLMHandleReply: Error validating user via NTLM. Error returned '%s'\n", reply); - if ((t = strchr(reply, ' '))) /* strip after a space */ - *t = '\0'; - /* now we mark the helper for resetting. */ - helperstate->starve = 1; - ntlm_request->auth_state = AUTHENTICATE_STATE_FAILED; } else { - /* TODO: only work with auth_user here if it exists */ - /* TODO: take the request state into consideration */ - assert(r->auth_user_request != NULL); - assert(r->auth_user_request->auth_user->auth_type == AUTH_NTLM); - auth_user_request = r->auth_user_request; - auth_user = auth_user_request->auth_user; - assert(auth_user != NULL); - ntlm_user = auth_user->scheme_data; - ntlm_request = auth_user_request->scheme_data; - assert((ntlm_user != NULL) && (ntlm_request != NULL)); - debug(29, 1) ("authenticateNTLMHandleReply: *** Unsupported helper response ***, '%s'\n", reply); - /* **** NOTE THIS CODE IS EFFECTIVELY UNTESTED **** */ - /* restart the authentication process */ - ntlm_request->auth_state = AUTHENTICATE_STATE_NONE; - assert(ntlm_request->authserver ? ntlm_request->authserver == lastserver : 1); - ntlm_request->authserver = NULL; + fatalf("authenticateNTLMHandleReply: *** Unsupported helper response ***, '%s'\n", reply); } r->handler(r->data, NULL); cbdataUnlock(r->data); authenticateStateFree(r); - debug(29, 9) ("NTLM HandleReply, telling stateful helper : %d\n", result); - return result; } static void @@ -717,32 +682,33 @@ * 2: does it have a challenge? * 3: tell it to get a challenge, or give ntlmauthdone the challenge */ - server = helperStatefulDefer(ntlmauthenticators); + server = helperStatefulGetServer(ntlmauthenticators); helperstate = server ? helperStatefulServerGetData(server) : NULL; - while ((server != NULL) && authenticateNTLMChangeChallenge_p(helperstate)) { - /* flag this helper for challenge changing */ - helperstate->starve = 1; - /* and release the deferred request */ - helperStatefulReleaseServer(server); - /* Get another deferrable server */ - server = helperStatefulDefer(ntlmauthenticators); - helperstate = server ? helperStatefulServerGetData(server) : NULL; + if (ntlmConfig->challengeuses) { + while ((server != NULL) && authenticateNTLMChangeChallenge_p(helperstate)) { + /* flag this helper for challenge changing */ + helperstate->starve = 1; + helperStatefulReset(server); + /* Get another server */ + server = helperStatefulGetServer(ntlmauthenticators); + helperstate = server ? helperStatefulServerGetData(server) : NULL; + } } - if (server == NULL) - debug(29, 9) ("unable to get a deferred ntlm helper... all helpers are refreshing challenges. Queuing as a placeholder request.\n"); - ntlm_request->authserver = server; /* tell the log what helper we have been given */ - debug(29, 9) ("authenticateNTLMStart: helper '%p' assigned\n", server); + if (server == NULL) + debug(29, 9) ("authenticateNTLMStart: unable to get a ntlm helper... Queuing as a placeholder request.\n"); + else + debug(29, 9) ("authenticateNTLMStart: helper '%p' assigned\n", server); /* server and valid challenge? */ - if ((server == NULL) || !authenticateNTLMValidChallenge(helperstate)) { + if ((server == NULL) || ntlmConfig->challengeuses == 0 || !authenticateNTLMValidChallenge(helperstate)) { /* No server, or server with invalid challenge */ r = cbdataAlloc(authenticateStateData); r->handler = handler; cbdataLock(data); r->data = data; r->auth_user_request = auth_user_request; - if (server == NULL) { + if (server == NULL && ntlmConfig->challengeuses) { helperStatefulSubmit(ntlmauthenticators, NULL, authenticateNTLMHandleplaceholder, r, NULL); } else { /* Server with invalid challenge */ @@ -756,10 +722,6 @@ helperstate->challengeuses++; /* assign the challenge */ ntlm_request->authchallenge = xstrndup(helperstate->challenge, NTLM_CHALLENGE_SZ + 5); - /* we're not actually submitting a request, so we need to release the helper - * should the connection close unexpectedly - */ - ntlm_request->authserver_deferred = 1; handler(data, NULL); } @@ -771,8 +733,6 @@ r->data = data; r->auth_user_request = auth_user_request; snprintf(buf, 8192, "KK %s\n", sent_string); - /* getting rid of deferred request status */ - ntlm_request->authserver_deferred = 0; helperStatefulSubmit(ntlmauthenticators, buf, authenticateNTLMHandleReply, r, ntlm_request->authserver); debug(29, 9) ("authenticateNTLMstart: finished\n"); break; @@ -800,14 +760,14 @@ } static void -authenticateNTLMHelperServerOnEmpty(void *data) +authenticateNTLMHelperServerReset(void *data) { ntlm_helper_state_t *statedata = data; if (statedata == NULL) return; if (statedata->starve) { /* we have been starving the helper */ - debug(29, 9) ("authenticateNTLMHelperServerOnEmpty: resetting challenge details\n"); + debug(29, 9) ("authenticateNTLMHelperServerReset: resetting challenge details\n"); statedata->starve = 0; statedata->challengeuses = 0; statedata->renewed = 0; @@ -816,20 +776,6 @@ } } - -/* clear the NTLM helper of being reserved for future requests */ -static void -authenticateNTLMReleaseServer(auth_user_request_t * auth_user_request) -{ - ntlm_request_t *ntlm_request; - assert(auth_user_request->auth_user->auth_type == AUTH_NTLM); - assert(auth_user_request->scheme_data != NULL); - ntlm_request = auth_user_request->scheme_data; - debug(29, 9) ("authenticateNTLMReleaseServer: releasing server '%p'\n", ntlm_request->authserver); - helperStatefulReleaseServer(ntlm_request->authserver); - ntlm_request->authserver = NULL; -} - /* clear any connection related authentication details */ static void authenticateNTLMOnCloseConnection(ConnStateData * conn) @@ -840,8 +786,8 @@ assert(conn->auth_user_request->scheme_data != NULL); ntlm_request = conn->auth_user_request->scheme_data; assert(ntlm_request->conn == conn); - if (ntlm_request->authserver != NULL && ntlm_request->authserver_deferred) - authenticateNTLMReleaseServer(conn->auth_user_request); + if (ntlm_request->authserver != NULL) + authenticateNTLMReleaseServer(ntlm_request); /* unlock the connection based lock */ debug(29, 9) ("authenticateNTLMOnCloseConnection: Unlocking auth_user from the connection.\n"); /* minor abstraction break here: FIXME */ @@ -1021,7 +967,7 @@ debug(29, 4) ("authenticateNTLMAuthenticateUser: ntlm proxy-auth cache hit\n"); /* throw away the temporary entry */ ntlm_request->authserver_deferred = 0; - authenticateNTLMReleaseServer(auth_user_request); + authenticateNTLMReleaseServer(ntlm_request); authenticateAuthUserMerge(auth_user, proxy_auth_hash->auth_user); auth_user = proxy_auth_hash->auth_user; auth_user_request->auth_user = auth_user; @@ -1053,22 +999,23 @@ ntlm_request->authchallenge); /* see if this is an existing user with a different proxy_auth * string */ - if ((usernamehash = hash_lookup(proxy_auth_username_cache, ntlm_user->username))) { - while ((usernamehash->auth_user->auth_type != auth_user->auth_type) && (usernamehash->next) && !authenticateNTLMcmpUsername(usernamehash->auth_user->scheme_data, ntlm_user)) + usernamehash = hash_lookup(proxy_auth_username_cache, ntlm_user->username); + if (usernamehash) { + while (usernamehash && (usernamehash->auth_user->auth_type != auth_user->auth_type || authenticateNTLMcmpUsername(usernamehash->auth_user->scheme_data, ntlm_user) != 0)) usernamehash = usernamehash->next; - if (usernamehash->auth_user->auth_type == auth_user->auth_type) { - /* - * add another link from the new proxy_auth to the - * auth_user structure and update the information */ - assert(proxy_auth_hash == NULL); - authenticateProxyAuthCacheAddLink(ntlmhash, usernamehash->auth_user); - /* we can't seamlessly recheck the username due to the - * challenge nature of the protocol. Just free the - * temporary auth_user */ - authenticateAuthUserMerge(auth_user, usernamehash->auth_user); - auth_user = usernamehash->auth_user; - auth_user_request->auth_user = auth_user; - } + } + if (usernamehash) { + /* + * add another link from the new proxy_auth to the + * auth_user structure and update the information */ + assert(proxy_auth_hash == NULL); + authenticateProxyAuthCacheAddLink(ntlmhash, usernamehash->auth_user); + /* we can't seamlessly recheck the username due to the + * challenge nature of the protocol. Just free the + * temporary auth_user */ + authenticateAuthUserMerge(auth_user, usernamehash->auth_user); + auth_user = usernamehash->auth_user; + auth_user_request->auth_user = auth_user; } else { /* store user in hash's */ authenticateUserNameCacheAdd(auth_user);