ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/src/auth.c
(Generate patch)

Comparing:
ircd-hybrid-7.2/src/s_auth.c (file contents), Revision 650 by michael, Thu Jun 8 07:00:17 2006 UTC vs.
ircd-hybrid/branches/8.2.x/src/auth.c (file contents), Revision 4188 by michael, Mon Jul 7 18:29:35 2014 UTC

# Line 1 | Line 1
1   /*
2 < *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  s_auth.c: Functions for querying a users ident.
2 > *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (C) 2002 by the past and present ircd coders, and others.
4 > *  Copyright (c) 1997-2014 ircd-hybrid development team
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 18 | Line 17
17   *  along with this program; if not, write to the Free Software
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
19   *  USA
20 < *
21 < *  $Id$
20 > */
21 >
22 > /*! \file auth.c
23 > * \brief Functions for querying a users ident.
24 > * \version $Id$
25   */
26  
27   /*
# Line 32 | Line 34
34   *     any messages from it.
35   *     --Bleep  Thomas Helvey <tomh@inxpress.net>
36   */
37 +
38   #include "stdinc.h"
36 #include "tools.h"
39   #include "list.h"
40 < #include "s_auth.h"
41 < #include "s_conf.h"
40 > #include "ircd_defs.h"
41 > #include "fdlist.h"
42 > #include "auth.h"
43 > #include "conf.h"
44   #include "client.h"
41 #include "common.h"
45   #include "event.h"
43 #include "fdlist.h"              /* fdlist_add */
44 #include "hook.h"
46   #include "irc_string.h"
46 #include "sprintf_irc.h"
47   #include "ircd.h"
48 #include "numeric.h"
48   #include "packet.h"
49 < #include "irc_res.h"
49 > #include "res.h"
50   #include "s_bsd.h"
51 < #include "s_log.h"
53 < #include "s_stats.h"
51 > #include "log.h"
52   #include "send.h"
53 < #include "memory.h"
53 > #include "mempool.h"
54 >
55  
56 < static const char *HeaderMessages[] = {
57 <  ":%s NOTICE AUTH :*** Looking up your hostname...",
58 <  ":%s NOTICE AUTH :*** Found your hostname",
59 <  ":%s NOTICE AUTH :*** Couldn't look up your hostname",
60 <  ":%s NOTICE AUTH :*** Checking Ident",
61 <  ":%s NOTICE AUTH :*** Got Ident response",
62 <  ":%s NOTICE AUTH :*** No Ident response",
63 <  ":%s NOTICE AUTH :*** Your forward and reverse DNS do not match, ignoring hostname.",
64 <  ":%s NOTICE AUTH :*** Your hostname is too long, ignoring hostname"
56 > static const char *const HeaderMessages[] =
57 > {
58 >  ":*** Looking up your hostname...",
59 >  ":*** Found your hostname",
60 >  ":*** Couldn't look up your hostname",
61 >  ":*** Checking Ident",
62 >  ":*** Got Ident response",
63 >  ":*** No Ident response",
64 >  ":*** Your forward and reverse DNS do not match, ignoring hostname.",
65 >  ":*** Your hostname is too long, ignoring hostname"
66   };
67  
68 < enum {
68 > enum
69 > {
70    REPORT_DO_DNS,
71    REPORT_FIN_DNS,
72    REPORT_FAIL_DNS,
# Line 76 | Line 77 | enum {
77    REPORT_HOST_TOOLONG
78   };
79  
80 < #define sendheader(c, i) sendto_one((c), HeaderMessages[(i)], me.name)
80 > #define sendheader(c, i) sendto_one_notice((c), &me, HeaderMessages[(i)])
81  
82 < /*
82 < * Ok, the original was confusing.
83 < * Now there are two lists, an auth request can be on both at the same time
84 < * or only on one or the other.
85 < * - Dianora
86 < */
87 < static dlink_list auth_doing_dns_list   = { NULL, NULL, 0 };
88 < static dlink_list auth_doing_ident_list = { NULL, NULL, 0 };
82 > static dlink_list auth_doing_list = { NULL, NULL, 0 };
83  
84 < static EVH timeout_auth_queries_event;
84 > static void timeout_auth_queries_event(void *);
85  
86   static PF read_auth_reply;
87   static CNCB auth_connect_callback;
94 static CBFUNC start_auth;
95
96 struct Callback *auth_cb = NULL;
88  
89 < /* init_auth()
89 > /* auth_init
90   *
91   * Initialise the auth code
92   */
93   void
94 < init_auth(void)
94 > auth_init(void)
95   {
96 <  auth_cb = register_callback("start_auth", start_auth);
97 <  eventAddIsh("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1);
96 >  static struct event timeout_auth_queries =
97 >  {
98 >    .name = "timeout_auth_queries_event",
99 >    .handler = timeout_auth_queries_event,
100 >    .when = 1
101 >  };
102 >
103 >  event_add(&timeout_auth_queries, NULL);
104   }
105  
106   /*
# Line 112 | Line 109 | init_auth(void)
109   static struct AuthRequest *
110   make_auth_request(struct Client *client)
111   {
112 <  struct AuthRequest *request = MyMalloc(sizeof(struct AuthRequest));
112 >  struct AuthRequest *request = &client->localClient->auth;
113 >
114 >  memset(request, 0, sizeof(*request));
115  
116    request->client  = client;
117    request->timeout = CurrentTime + CONNECTTIMEOUT;
# Line 126 | Line 125 | make_auth_request(struct Client *client)
125   * the main io processing loop
126   */
127   void
128 < release_auth_client(struct Client *client)
128 > release_auth_client(struct AuthRequest *auth)
129   {
130 +  struct Client *client = auth->client;
131 +
132 +  if (IsDoingAuth(auth) || IsDNSPending(auth))
133 +    return;
134 +
135 +  if (IsInAuth(auth))
136 +  {
137 +    dlinkDelete(&auth->node, &auth_doing_list);
138 +    ClearInAuth(auth);
139 +  }
140 +
141    /*
142     * When a client has auth'ed, we want to start reading what it sends
143     * us. This is what read_packet() does.
# Line 136 | Line 146 | release_auth_client(struct Client *clien
146    client->localClient->allow_read = MAX_FLOOD;
147    comm_setflush(&client->localClient->fd, 1000, flood_recalc, client);
148  
149 <  if ((client->node.prev != NULL) || (client->node.next != NULL))
150 <  {
151 <    sendto_realops_flags(UMODE_ALL, L_OPER,
152 <                         "already linked %s at %s:%d", client->name,
143 <                         __FILE__, __LINE__);
144 <    ilog(L_ERROR, "already linked %s at %s:%d", client->name,
145 <         __FILE__, __LINE__);
146 <    assert(0==5);
147 <  }
148 <  else
149 <    dlinkAdd(client, &client->node, &global_client_list);
150 <
151 <  client_p->since  = client_p->lasttime = client_p->firsttime = CurrentTime;
152 <  client_p->flags |= FLAGS_FINISHED_AUTH;
149 >  client->localClient->since     = CurrentTime;
150 >  client->localClient->lasttime  = CurrentTime;
151 >  client->localClient->firsttime = CurrentTime;
152 >  client->flags |= FLAGS_FINISHED_AUTH;
153  
154    read_packet(&client->localClient->fd, client);
155   }
156 <
156 >
157   /*
158   * auth_dns_callback - called when resolver query finishes
159 < * if the query resulted in a successful search, hp will contain
160 < * a non-null pointer, otherwise hp will be null.
159 > * if the query resulted in a successful search, name will contain
160 > * a non-NULL pointer, otherwise name will be NULL.
161   * set the client on it's way to a connection completion, regardless
162   * of success of failure
163   */
164   static void
165 < auth_dns_callback(void *vptr, struct DNSReply *reply)
165 > auth_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name)
166   {
167 <  struct AuthRequest *auth = (struct AuthRequest *)vptr;
167 >  struct AuthRequest *auth = vptr;
168  
169  dlinkDelete(&auth->dns_node, &auth_doing_dns_list);
169    ClearDNSPending(auth);
170  
171 <  if (reply != NULL)
171 >  if (name)
172    {
173 <    struct sockaddr_in *v4, *v4dns;
173 >    const struct sockaddr_in *v4, *v4dns;
174   #ifdef IPV6
175 <    struct sockaddr_in6 *v6, *v6dns;
175 >    const struct sockaddr_in6 *v6, *v6dns;
176   #endif
177      int good = 1;
178  
179   #ifdef IPV6
180      if (auth->client->localClient->ip.ss.ss_family == AF_INET6)
181      {
182 <      v6 = (struct sockaddr_in6 *)&auth->client->localClient->ip;
183 <      v6dns = (struct sockaddr_in6 *)&reply->addr;
182 >      v6 = (const struct sockaddr_in6 *)&auth->client->localClient->ip;
183 >      v6dns = (const struct sockaddr_in6 *)addr;
184 >
185        if (memcmp(&v6->sin6_addr, &v6dns->sin6_addr, sizeof(struct in6_addr)) != 0)
186        {
187          sendheader(auth->client, REPORT_IP_MISMATCH);
# Line 191 | Line 191 | auth_dns_callback(void *vptr, struct DNS
191      else
192   #endif
193      {
194 <      v4 = (struct sockaddr_in *)&auth->client->localClient->ip;
195 <      v4dns = (struct sockaddr_in *)&reply->addr;
196 <      if(v4->sin_addr.s_addr != v4dns->sin_addr.s_addr)
194 >      v4 = (const struct sockaddr_in *)&auth->client->localClient->ip;
195 >      v4dns = (const struct sockaddr_in *)addr;
196 >
197 >      if (v4->sin_addr.s_addr != v4dns->sin_addr.s_addr)
198        {
199          sendheader(auth->client, REPORT_IP_MISMATCH);
200          good = 0;
201        }
202      }
203 <    if (good && strlen(reply->h_name) <= HOSTLEN)
203 >
204 >    if (good && strlen(name) <= HOSTLEN)
205      {
206 <      strlcpy(auth->client->host, reply->h_name,
207 <              sizeof(auth->client->host));
206 >      strlcpy(auth->client->host, name,
207 >              sizeof(auth->client->host));
208        sendheader(auth->client, REPORT_FIN_DNS);
209      }
210 <    else if (strlen(reply->h_name) > HOSTLEN)
210 >    else if (strlen(name) > HOSTLEN)
211        sendheader(auth->client, REPORT_HOST_TOOLONG);
212    }
213    else
214 <      sendheader(auth->client, REPORT_FAIL_DNS);
213 <
214 <  MyFree(auth->client->localClient->dns_query);
215 <  auth->client->localClient->dns_query = NULL;
214 >    sendheader(auth->client, REPORT_FAIL_DNS);
215  
216 <  if (!IsDoingAuth(auth))
218 <  {
219 <    struct Client *client_p = auth->client;
220 <    MyFree(auth);
221 <    release_auth_client(client_p);
222 <  }
216 >  release_auth_client(auth);
217   }
218  
219   /*
# Line 228 | Line 222 | auth_dns_callback(void *vptr, struct DNS
222   static void
223   auth_error(struct AuthRequest *auth)
224   {
225 <  ++ServerStats->is_abad;
225 >  ++ServerStats.is_abad;
226  
227    fd_close(&auth->fd);
228  
235  dlinkDelete(&auth->ident_node, &auth_doing_ident_list);
229    ClearAuth(auth);
230  
231    sendheader(auth->client, REPORT_FAIL_ID);
232  
233 <  if (!IsDNSPending(auth) && !IsCrit(auth))
241 <  {
242 <    release_auth_client(auth->client);
243 <    MyFree(auth);
244 <  }
233 >  release_auth_client(auth);
234   }
235  
236   /*
237 < * start_auth_query - Flag the client to show that an attempt to
237 > * start_auth_query - Flag the client to show that an attempt to
238   * contact the ident server on
239   * the client's host.  The connect and subsequently the socket are all put
240   * into 'non-blocking' mode.  Should the connect or any later phase of the
# Line 267 | Line 256 | start_auth_query(struct AuthRequest *aut
256    if (comm_open(&auth->fd, auth->client->localClient->ip.ss.ss_family,
257                  SOCK_STREAM, 0, "ident") == -1)
258    {
259 <    report_error(L_ALL, "creating auth stream socket %s:%s",
260 <        get_client_name(auth->client, SHOW_IP), errno);
261 <    ilog(L_ERROR, "Unable to create auth socket for %s",
259 >    report_error(L_ALL, "creating auth stream socket %s:%s",
260 >                 get_client_name(auth->client, SHOW_IP), errno);
261 >    ilog(LOG_TYPE_IRCD, "Unable to create auth socket for %s",
262          get_client_name(auth->client, SHOW_IP));
263 <    ++ServerStats->is_abad;
263 >    ++ServerStats.is_abad;
264      return 0;
265    }
266  
267    sendheader(auth->client, REPORT_DO_ID);
268  
269 <  /*
269 >  /*
270     * get the local address of the client and bind to that to
271     * make the auth request.  This used to be done only for
272     * ifdef VIRTUAL_HOST, but needs to be done for all clients
# Line 299 | Line 288 | start_auth_query(struct AuthRequest *aut
288   #endif
289    localaddr.ss_port = htons(0);
290  
291 <  SetDoingAuth(auth);
292 <  dlinkAdd(auth, &auth->ident_node, &auth_doing_ident_list);
293 <
305 <  comm_connect_tcp(&auth->fd, auth->client->sockhost, 113,
306 <      (struct sockaddr *)&localaddr, localaddr.ss_len, auth_connect_callback,
307 <      auth, auth->client->localClient->ip.ss.ss_family,
291 >  comm_connect_tcp(&auth->fd, auth->client->sockhost, 113,
292 >      (struct sockaddr *)&localaddr, localaddr.ss_len, auth_connect_callback,
293 >      auth, auth->client->localClient->ip.ss.ss_family,
294        GlobalSetOptions.ident_timeout);
295    return 1; /* We suceed here for now */
296   }
297  
298   /*
299   * GetValidIdent - parse ident query reply from identd server
300 < *
300 > *
301   * Inputs        - pointer to ident buf
302   * Output        - NULL if no valid ident found, otherwise pointer to name
303   * Side effects  -
# Line 344 | Line 330 | GetValidIdent(char *buf)
330  
331    /* All this to get rid of a sscanf() fun. */
332    remotePortString = buf;
333 <  
333 >
334    if ((colon1Ptr = strchr(remotePortString,':')) == NULL)
335      return 0;
336    *colon1Ptr = '\0';
# Line 354 | Line 340 | GetValidIdent(char *buf)
340      return 0;
341    *colon2Ptr = '\0';
342    colon2Ptr++;
343 <  
343 >
344    if ((commaPtr = strchr(remotePortString, ',')) == NULL)
345      return 0;
346    *commaPtr = '\0';
# Line 362 | Line 348 | GetValidIdent(char *buf)
348  
349    if ((remp = atoi(remotePortString)) == 0)
350      return 0;
351 <              
351 >
352    if ((locp = atoi(commaPtr)) == 0)
353      return 0;
354  
# Line 378 | Line 364 | GetValidIdent(char *buf)
364   }
365  
366   /*
367 < * start_auth
367 > * start_auth
368   *
369   * inputs       - pointer to client to auth
370   * output       - NONE
371   * side effects - starts auth (identd) and dns queries for a client
372   */
373 < static void *
374 < start_auth(va_list args)
373 > void
374 > start_auth(struct Client *client_p)
375   {
390  struct Client *client = va_arg(args, struct Client *);
376    struct AuthRequest *auth = NULL;
377  
378 <  assert(client != NULL);
378 >  assert(client_p);
379  
380 <  auth = make_auth_request(client);
381 <  SetCrit(auth);
380 >  auth = make_auth_request(client_p);
381 >  SetInAuth(auth);
382 >  dlinkAddTail(auth, &auth->node, &auth_doing_list);
383  
384 <  client->localClient->dns_query = MyMalloc(sizeof(struct DNSQuery));
399 <  client->localClient->dns_query->ptr = auth;
400 <  client->localClient->dns_query->callback = auth_dns_callback;
384 >  sendheader(client_p, REPORT_DO_DNS);
385  
386 <  sendheader(client, REPORT_DO_DNS);
386 >  SetDNSPending(auth);
387  
388    if (ConfigFileEntry.disable_auth == 0)
389 +  {
390 +    SetDoingAuth(auth);
391      start_auth_query(auth);
392 +  }
393  
394 <  /* auth order changed, before gethost_byaddr can immediately call
408 <   * dns callback under win32 when the lookup cannot be started.
409 <   * And that would do MyFree(auth) etc -adx */
410 <  SetDNSPending(auth);
411 <  dlinkAdd(auth, &auth->dns_node, &auth_doing_dns_list);
412 <  ClearCrit(auth);
413 <  gethost_byaddr(&client->localClient->ip, client->localClient->dns_query);
414 <
415 <  return NULL;
394 >  gethost_byaddr(auth_dns_callback, auth, &client_p->localClient->ip);
395   }
396  
397   /*
# Line 422 | Line 401 | start_auth(va_list args)
401   static void
402   timeout_auth_queries_event(void *notused)
403   {
404 <  dlink_node *ptr;
426 <  dlink_node *next_ptr;
427 <  struct AuthRequest* auth;
404 >  dlink_node *ptr = NULL, *ptr_next = NULL;
405  
406 <  DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_ident_list.head)
406 >  DLINK_FOREACH_SAFE(ptr, ptr_next, auth_doing_list.head)
407    {
408 <    auth = ptr->data;
408 >    struct AuthRequest *auth = ptr->data;
409 >
410 >    if (auth->timeout > CurrentTime)
411 >      break;
412  
413 <    if (auth->timeout <= CurrentTime)
413 >    if (IsDoingAuth(auth))
414      {
415 +      ++ServerStats.is_abad;
416        fd_close(&auth->fd);
417 <
437 <      ++ServerStats->is_abad;
417 >      ClearAuth(auth);
418        sendheader(auth->client, REPORT_FAIL_ID);
419 +    }
420  
421 <      if (IsDNSPending(auth))
422 <      {
423 <        struct Client *client_p = auth->client;
424 <
425 <        dlinkDelete(&auth->dns_node, &auth_doing_dns_list);
445 <        if (client_p->localClient->dns_query != NULL)
446 <        {
447 <          delete_resolver_queries(client_p->localClient->dns_query);
448 <          MyFree(client_p->localClient->dns_query);
449 <        }
450 <        auth->client->localClient->dns_query = NULL;
451 <        sendheader(client_p, REPORT_FAIL_DNS);
452 <      }
453 <
454 <      ilog(L_INFO, "DNS/AUTH timeout %s",
455 <           get_client_name(auth->client, SHOW_IP));
456 <
457 <      dlinkDelete(&auth->ident_node, &auth_doing_ident_list);
458 <      release_auth_client(auth->client);
459 <      MyFree(auth);
421 >    if (IsDNSPending(auth))
422 >    {
423 >      delete_resolver_queries(auth);
424 >      ClearDNSPending(auth);
425 >      sendheader(auth->client, REPORT_FAIL_DNS);
426      }
427 +
428 +    ilog(LOG_TYPE_IRCD, "DNS/AUTH timeout %s",
429 +         get_client_name(auth->client, SHOW_IP));
430 +    release_auth_client(auth);
431    }
432   }
433  
# Line 481 | Line 451 | auth_connect_callback(fde_t *fd, int err
451    char authbuf[32];
452    socklen_t ulen = sizeof(struct irc_ssaddr);
453    socklen_t tlen = sizeof(struct irc_ssaddr);
454 <  u_int16_t uport, tport;
454 >  uint16_t uport, tport;
455   #ifdef IPV6
456    struct sockaddr_in6 *v6;
457   #else
# Line 494 | Line 464 | auth_connect_callback(fde_t *fd, int err
464      return;
465    }
466  
467 <  if (getsockname(auth->client->localClient->fd.fd, (struct sockaddr *) &us,
468 <      (socklen_t *) &ulen) ||
499 <      getpeername(auth->client->localClient->fd.fd, (struct sockaddr *) &them,
500 <      (socklen_t *) &tlen))
467 >  if (getsockname(auth->client->localClient->fd.fd, (struct sockaddr *)&us, &ulen) ||
468 >      getpeername(auth->client->localClient->fd.fd, (struct sockaddr *)&them, &tlen))
469    {
470 <    ilog(L_INFO, "auth get{sock,peer}name error for %s",
471 <        get_client_name(auth->client, SHOW_IP));
470 >    ilog(LOG_TYPE_IRCD, "auth get{sock,peer}name error for %s",
471 >         get_client_name(auth->client, SHOW_IP));
472      auth_error(auth);
473      return;
474    }
# Line 520 | Line 488 | auth_connect_callback(fde_t *fd, int err
488    us.ss_len = ulen;
489    them.ss_len = tlen;
490   #endif
491 <  
492 <  ircsprintf(authbuf, "%u , %u\r\n", tport, uport);
491 >
492 >  snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n", tport, uport);
493  
494    if (send(fd->fd, authbuf, strlen(authbuf), 0) == -1)
495    {
496      auth_error(auth);
497      return;
498    }
499 +
500    read_auth_reply(&auth->fd, auth);
501   }
502  
503   /*
504 < * read_auth_reply - read the reply (if any) from the ident server
504 > * read_auth_reply - read the reply (if any) from the ident server
505   * we connected to.
506   * We only give it one shot, if the reply isn't good the first time
507   * fail the authentication entirely. --Bleep
# Line 560 | Line 529 | read_auth_reply(fde_t *fd, void *data)
529     *
530     *    --nenolod
531     */
563 #ifndef _WIN32
532    len = read(fd->fd, buf, AUTH_BUFSIZ);
533 < #else
566 <  len = recv(fd->fd, buf, AUTH_BUFSIZ, 0);
567 < #endif
568 <  
533 >
534    if (len < 0)
535    {
571 #ifdef _WIN32
572    errno = WSAGetLastError();
573 #endif
536      if (ignoreErrno(errno))
537        comm_setselect(fd, COMM_SELECT_READ, read_auth_reply, auth, 0);
538      else
# Line 593 | Line 555 | read_auth_reply(fde_t *fd, void *data)
555        {
556          if (*s == '@')
557            break;
558 <        if (!IsSpace(*s) && *s != ':' && *s != '[')
558 >        if (!IsSpace(*s) && *s != ':')
559          {
560            *t++ = *s;
561            count--;
# Line 606 | Line 568 | read_auth_reply(fde_t *fd, void *data)
568  
569    fd_close(fd);
570  
609  dlinkDelete(&auth->ident_node, &auth_doing_ident_list);  
571    ClearAuth(auth);
572  
573    if (s == NULL)
574    {
575      sendheader(auth->client, REPORT_FAIL_ID);
576 <    ++ServerStats->is_abad;
576 >    ++ServerStats.is_abad;
577    }
578    else
579    {
580      sendheader(auth->client, REPORT_FIN_ID);
581 <    ++ServerStats->is_asuc;
581 >    ++ServerStats.is_asuc;
582      SetGotId(auth->client);
583    }
584  
585 <  if (!IsDNSPending(auth) && !IsCrit(auth))
625 <  {
626 <    release_auth_client(auth->client);
627 <    MyFree(auth);
628 <  }
585 >  release_auth_client(auth);
586   }
587  
588   /*
589   * delete_auth()
590   */
591 < void
592 < delete_auth(struct Client *target_p)
591 > void
592 > delete_auth(struct AuthRequest *auth)
593   {
594 <  dlink_node *ptr;
595 <  dlink_node *next_ptr;
639 <  struct AuthRequest *auth;
594 >  if (IsDNSPending(auth))
595 >    delete_resolver_queries(auth);
596  
597 <  if (!IsUnknown(target_p))
598 <    return;
643 <
644 <  if (target_p->localClient->dns_query != NULL)
645 <    DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_dns_list.head)
646 <    {
647 <      auth = ptr->data;
648 <
649 <      if (auth->client == target_p)
650 <      {
651 <        delete_resolver_queries(target_p->localClient->dns_query);
597 >  if (IsDoingAuth(auth))
598 >    fd_close(&auth->fd);
599  
600 <        dlinkDelete(&auth->dns_node, &auth_doing_dns_list);
654 <        if (!IsDoingAuth(auth))
655 <        {
656 <          MyFree(auth);
657 <          return;
658 <        }
659 <      }
660 <    }
661 <
662 <  DLINK_FOREACH_SAFE(ptr, next_ptr, auth_doing_ident_list.head)
600 >  if (IsInAuth(auth))
601    {
602 <    auth = ptr->data;
603 <
666 <    if (auth->client == target_p)
667 <    {
668 <      fd_close(&auth->fd);
669 <
670 <      dlinkDelete(&auth->ident_node, &auth_doing_ident_list);
671 <      MyFree(auth);
672 <    }
602 >    dlinkDelete(&auth->node, &auth_doing_list);
603 >    ClearInAuth(auth);
604    }
605   }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)