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

Comparing:
ircd-hybrid/trunk/src/s_auth.c (file contents), Revision 3250 by michael, Sun Mar 30 20:47:30 2014 UTC vs.
ircd-hybrid/trunk/src/auth.c (file contents), Revision 6313 by michael, Sat Aug 1 18:03:39 2015 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (c) 1997-2014 ircd-hybrid development team
4 > *  Copyright (c) 1997-2015 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 15 | Line 15
15   *
16   *  You should have received a copy of the GNU General Public License
17   *  along with this program; if not, write to the Free Software
18 < *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18 > *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19   *  USA
20   */
21  
22 < /*! \file s_auth.c
22 > /*! \file auth.c
23   * \brief Functions for querying a users ident.
24   * \version $Id$
25   */
# Line 39 | Line 39
39   #include "list.h"
40   #include "ircd_defs.h"
41   #include "fdlist.h"
42 < #include "s_auth.h"
42 > #include "auth.h"
43   #include "conf.h"
44   #include "client.h"
45   #include "event.h"
46 #include "hook.h"
46   #include "irc_string.h"
47   #include "ircd.h"
48   #include "packet.h"
49 < #include "irc_res.h"
49 > #include "res.h"
50   #include "s_bsd.h"
51   #include "log.h"
52   #include "send.h"
53   #include "mempool.h"
54  
55  
57 static const char *HeaderMessages[] =
58 {
59  ":*** Looking up your hostname...",
60  ":*** Found your hostname",
61  ":*** Couldn't look up your hostname",
62  ":*** Checking Ident",
63  ":*** Got Ident response",
64  ":*** No Ident response",
65  ":*** Your forward and reverse DNS do not match, ignoring hostname.",
66  ":*** Your hostname is too long, ignoring hostname"
67 };
68
56   enum
57   {
58    REPORT_DO_DNS,
# Line 78 | Line 65 | enum
65    REPORT_HOST_TOOLONG
66   };
67  
68 < #define sendheader(c, i) sendto_one_notice((c), &me, HeaderMessages[(i)])
68 > static const char *const HeaderMessages[] =
69 > {
70 >  [REPORT_DO_DNS] = ":*** Looking up your hostname",
71 >  [REPORT_FIN_DNS] = ":*** Found your hostname",
72 >  [REPORT_FAIL_DNS] = ":*** Couldn't look up your hostname",
73 >  [REPORT_DO_ID] = ":*** Checking Ident",
74 >  [REPORT_FIN_ID] = ":*** Got Ident response",
75 >  [REPORT_FAIL_ID] = ":*** No Ident response",
76 >  [REPORT_IP_MISMATCH] = ":*** Your forward and reverse DNS do not match, ignoring hostname",
77 >  [REPORT_HOST_TOOLONG] = ":*** Your hostname is too long, ignoring hostname"
78 > };
79  
80 < static dlink_list auth_doing_list = { NULL, NULL, 0 };
80 > #define sendheader(c, i) sendto_one_notice((c), &me, "%s", HeaderMessages[(i)])
81  
82 < static EVH timeout_auth_queries_event;
82 > static dlink_list auth_pending_list;
83 > static void read_auth_reply(fde_t *, void *);
84 > static void auth_connect_callback(fde_t *, int, void *);
85  
87 static PF read_auth_reply;
88 static CNCB auth_connect_callback;
89
90 /* auth_init
91 *
92 * Initialise the auth code
93 */
94 void
95 auth_init(void)
96 {
97  eventAddIsh("timeout_auth_queries_event", timeout_auth_queries_event, NULL, 1);
98 }
86  
87   /*
88   * make_auth_request - allocate a new auth request
# Line 103 | Line 90 | auth_init(void)
90   static struct AuthRequest *
91   make_auth_request(struct Client *client)
92   {
93 <  struct AuthRequest *request = &client->localClient->auth;
93 >  struct AuthRequest *const request = &client->connection->auth;
94  
95    memset(request, 0, sizeof(*request));
96  
# Line 121 | Line 108 | make_auth_request(struct Client *client)
108   void
109   release_auth_client(struct AuthRequest *auth)
110   {
111 <  struct Client *client = auth->client;
111 >  struct Client *const client = auth->client;
112  
113    if (IsDoingAuth(auth) || IsDNSPending(auth))
114      return;
115  
116    if (IsInAuth(auth))
117    {
118 <    dlinkDelete(&auth->node, &auth_doing_list);
118 >    dlinkDelete(&auth->node, &auth_pending_list);
119      ClearInAuth(auth);
120    }
121  
# Line 137 | Line 124 | release_auth_client(struct AuthRequest *
124     * us. This is what read_packet() does.
125     *     -- adrian
126     */
127 <  client->localClient->allow_read = MAX_FLOOD;
128 <  comm_setflush(&client->localClient->fd, 1000, flood_recalc, client);
142 <
143 <  dlinkAdd(client, &client->node, &global_client_list);
127 >  client->connection->allow_read = MAX_FLOOD;
128 >  comm_setflush(&client->connection->fd, 1000, flood_recalc, client);
129  
130 <  client->localClient->since     = CurrentTime;
131 <  client->localClient->lasttime  = CurrentTime;
132 <  client->localClient->firsttime = CurrentTime;
130 >  client->connection->since     = CurrentTime;
131 >  client->connection->lasttime  = CurrentTime;
132 >  client->connection->firsttime = CurrentTime;
133    client->flags |= FLAGS_FINISHED_AUTH;
134  
135 <  read_packet(&client->localClient->fd, client);
135 >  read_packet(&client->connection->fd, client);
136   }
137  
138   /*
# Line 158 | Line 143 | release_auth_client(struct AuthRequest *
143   * of success of failure
144   */
145   static void
146 < auth_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name)
146 > auth_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name, size_t namelength)
147   {
148 <  struct AuthRequest *auth = vptr;
148 >  struct AuthRequest *const auth = vptr;
149  
150    ClearDNSPending(auth);
151  
152 <  if (name)
152 >  if (!EmptyString(name))
153    {
154 <    const struct sockaddr_in *v4, *v4dns;
170 < #ifdef IPV6
171 <    const struct sockaddr_in6 *v6, *v6dns;
172 < #endif
173 <    int good = 1;
174 <
175 < #ifdef IPV6
176 <    if (auth->client->localClient->ip.ss.ss_family == AF_INET6)
154 >    if (auth->client->connection->ip.ss.ss_family == AF_INET6)
155      {
156 <      v6 = (const struct sockaddr_in6 *)&auth->client->localClient->ip;
157 <      v6dns = (const struct sockaddr_in6 *)addr;
156 >      const struct sockaddr_in6 *const v6 = (const struct sockaddr_in6 *)&auth->client->connection->ip;
157 >      const struct sockaddr_in6 *const v6dns = (const struct sockaddr_in6 *)addr;
158  
159 <      if (memcmp(&v6->sin6_addr, &v6dns->sin6_addr, sizeof(struct in6_addr)) != 0)
159 >      if (memcmp(&v6->sin6_addr, &v6dns->sin6_addr, sizeof(struct in6_addr)))
160        {
161          sendheader(auth->client, REPORT_IP_MISMATCH);
162 <        good = 0;
162 >        release_auth_client(auth);
163 >        return;
164        }
165      }
166      else
188 #endif
167      {
168 <      v4 = (const struct sockaddr_in *)&auth->client->localClient->ip;
169 <      v4dns = (const struct sockaddr_in *)addr;
168 >      const struct sockaddr_in *const v4 = (const struct sockaddr_in *)&auth->client->connection->ip;
169 >      const struct sockaddr_in *const v4dns = (const struct sockaddr_in *)addr;
170  
171        if (v4->sin_addr.s_addr != v4dns->sin_addr.s_addr)
172        {
173          sendheader(auth->client, REPORT_IP_MISMATCH);
174 <        good = 0;
174 >        release_auth_client(auth);
175 >        return;
176        }
177      }
178  
179 <    if (good && strlen(name) <= HOSTLEN)
179 >    if (namelength > HOSTLEN)
180 >      sendheader(auth->client, REPORT_HOST_TOOLONG);
181 >    else
182      {
183 <      strlcpy(auth->client->host, name,
203 <              sizeof(auth->client->host));
183 >      strlcpy(auth->client->host, name, sizeof(auth->client->host));
184        sendheader(auth->client, REPORT_FIN_DNS);
185      }
206    else if (strlen(name) > HOSTLEN)
207      sendheader(auth->client, REPORT_HOST_TOOLONG);
186    }
187    else
188      sendheader(auth->client, REPORT_FAIL_DNS);
# Line 242 | Line 220 | start_auth_query(struct AuthRequest *aut
220   {
221    struct irc_ssaddr localaddr;
222    socklen_t locallen = sizeof(struct irc_ssaddr);
245 #ifdef IPV6
223    struct sockaddr_in6 *v6;
247 #else
248  struct sockaddr_in *v4;
249 #endif
224  
225    /* open a socket of the same type as the client socket */
226 <  if (comm_open(&auth->fd, auth->client->localClient->ip.ss.ss_family,
226 >  if (comm_open(&auth->fd, auth->client->connection->ip.ss.ss_family,
227                  SOCK_STREAM, 0, "ident") == -1)
228    {
229      report_error(L_ALL, "creating auth stream socket %s:%s",
230                   get_client_name(auth->client, SHOW_IP), errno);
257    ilog(LOG_TYPE_IRCD, "Unable to create auth socket for %s",
258        get_client_name(auth->client, SHOW_IP));
231      ++ServerStats.is_abad;
232      return 0;
233    }
# Line 263 | Line 235 | start_auth_query(struct AuthRequest *aut
235    sendheader(auth->client, REPORT_DO_ID);
236  
237    /*
238 <   * get the local address of the client and bind to that to
239 <   * make the auth request.  This used to be done only for
268 <   * ifdef VIRTUAL_HOST, but needs to be done for all clients
269 <   * since the ident request must originate from that same address--
270 <   * and machines with multiple IP addresses are common now
238 >   * Get the local address of the client and bind to that to
239 >   * make the auth request.
240     */
241    memset(&localaddr, 0, locallen);
242 <  getsockname(auth->client->localClient->fd.fd, (struct sockaddr*)&localaddr,
242 >  getsockname(auth->client->connection->fd.fd, (struct sockaddr*)&localaddr,
243        &locallen);
244  
276 #ifdef IPV6
245    remove_ipv6_mapping(&localaddr);
246    v6 = (struct sockaddr_in6 *)&localaddr;
247    v6->sin6_port = htons(0);
280 #else
281  localaddr.ss_len = locallen;
282  v4 = (struct sockaddr_in *)&localaddr;
283  v4->sin_port = htons(0);
284 #endif
248    localaddr.ss_port = htons(0);
249  
250 <  comm_connect_tcp(&auth->fd, auth->client->sockhost, 113,
250 >  comm_connect_tcp(&auth->fd, auth->client->sockhost, RFC1413_PORT,
251        (struct sockaddr *)&localaddr, localaddr.ss_len, auth_connect_callback,
252 <      auth, auth->client->localClient->ip.ss.ss_family,
252 >      auth, auth->client->connection->ip.ss.ss_family,
253        GlobalSetOptions.ident_timeout);
254    return 1; /* We suceed here for now */
255   }
256  
257   /*
295 * GetValidIdent - parse ident query reply from identd server
296 *
297 * Inputs        - pointer to ident buf
298 * Output        - NULL if no valid ident found, otherwise pointer to name
299 * Side effects  -
300 */
301 /*
302 * A few questions have been asked about this mess, obviously
303 * it should have been commented better the first time.
304 * The original idea was to remove all references to libc from ircd-hybrid.
305 * Instead of having to write a replacement for sscanf(), I did a
306 * rather gruseome parser here so we could remove this function call.
307 * Note, that I had also removed a few floating point printfs as well (though
308 * now we are still stuck with a few...)
309 * Remember, we have a replacement ircd sprintf, we have bleeps fputs lib
310 * it would have been nice to remove some unneeded code.
311 * Oh well. If we don't remove libc stuff totally, then it would be
312 * far cleaner to use sscanf()
313 *
314 * - Dianora
315 */
316 static char *
317 GetValidIdent(char *buf)
318 {
319  int   remp = 0;
320  int   locp = 0;
321  char* colon1Ptr;
322  char* colon2Ptr;
323  char* colon3Ptr;
324  char* commaPtr;
325  char* remotePortString;
326
327  /* All this to get rid of a sscanf() fun. */
328  remotePortString = buf;
329
330  if ((colon1Ptr = strchr(remotePortString,':')) == NULL)
331    return 0;
332  *colon1Ptr = '\0';
333  colon1Ptr++;
334
335  if ((colon2Ptr = strchr(colon1Ptr,':')) == NULL)
336    return 0;
337  *colon2Ptr = '\0';
338  colon2Ptr++;
339
340  if ((commaPtr = strchr(remotePortString, ',')) == NULL)
341    return 0;
342  *commaPtr = '\0';
343  commaPtr++;
344
345  if ((remp = atoi(remotePortString)) == 0)
346    return 0;
347
348  if ((locp = atoi(commaPtr)) == 0)
349    return 0;
350
351  /* look for USERID bordered by first pair of colons */
352  if (strstr(colon1Ptr, "USERID") == NULL)
353    return 0;
354
355  if ((colon3Ptr = strchr(colon2Ptr,':')) == NULL)
356    return 0;
357  *colon3Ptr = '\0';
358  colon3Ptr++;
359  return (colon3Ptr);
360 }
361
362 /*
258   * start_auth
259   *
260   * inputs       - pointer to client to auth
# Line 369 | Line 264 | GetValidIdent(char *buf)
264   void
265   start_auth(struct Client *client_p)
266   {
267 <  struct AuthRequest *auth = NULL;
267 >  struct AuthRequest *const auth = make_auth_request(client_p);
268  
374  assert(client_p);
375
376  auth = make_auth_request(client_p);
269    SetInAuth(auth);
270 <  dlinkAddTail(auth, &auth->node, &auth_doing_list);
270 >  dlinkAddTail(auth, &auth->node, &auth_pending_list);
271  
272    sendheader(client_p, REPORT_DO_DNS);
273  
274    SetDNSPending(auth);
275  
276 <  if (ConfigFileEntry.disable_auth == 0)
276 >  if (ConfigGeneral.disable_auth == 0)
277    {
278      SetDoingAuth(auth);
279      start_auth_query(auth);
280    }
281  
282 <  gethost_byaddr(auth_dns_callback, auth, &client_p->localClient->ip);
282 >  gethost_byaddr(auth_dns_callback, auth, &client_p->connection->ip);
283   }
284  
285   /*
# Line 397 | Line 289 | start_auth(struct Client *client_p)
289   static void
290   timeout_auth_queries_event(void *notused)
291   {
292 <  dlink_node *ptr = NULL, *ptr_next = NULL;
292 >  dlink_node *node = NULL, *node_next = NULL;
293  
294 <  DLINK_FOREACH_SAFE(ptr, ptr_next, auth_doing_list.head)
294 >  DLINK_FOREACH_SAFE(node, node_next, auth_pending_list.head)
295    {
296 <    struct AuthRequest *auth = ptr->data;
296 >    struct AuthRequest *auth = node->data;
297  
298      if (auth->timeout > CurrentTime)
299        break;
# Line 421 | Line 313 | timeout_auth_queries_event(void *notused
313        sendheader(auth->client, REPORT_FAIL_DNS);
314      }
315  
424    ilog(LOG_TYPE_IRCD, "DNS/AUTH timeout %s",
425         get_client_name(auth->client, SHOW_IP));
316      release_auth_client(auth);
317    }
318   }
# Line 441 | Line 331 | timeout_auth_queries_event(void *notused
331   static void
332   auth_connect_callback(fde_t *fd, int error, void *data)
333   {
334 <  struct AuthRequest *auth = data;
334 >  struct AuthRequest *const auth = data;
335    struct irc_ssaddr us;
336    struct irc_ssaddr them;
337 <  char authbuf[32];
337 >  char authbuf[16];
338 >  ssize_t len = 0;
339    socklen_t ulen = sizeof(struct irc_ssaddr);
340    socklen_t tlen = sizeof(struct irc_ssaddr);
341    uint16_t uport, tport;
451 #ifdef IPV6
342    struct sockaddr_in6 *v6;
453 #else
454  struct sockaddr_in *v4;
455 #endif
343  
344    if (error != COMM_OK)
345    {
# Line 460 | Line 347 | auth_connect_callback(fde_t *fd, int err
347      return;
348    }
349  
350 <  if (getsockname(auth->client->localClient->fd.fd, (struct sockaddr *)&us, &ulen) ||
351 <      getpeername(auth->client->localClient->fd.fd, (struct sockaddr *)&them, &tlen))
350 >  if (getsockname(auth->client->connection->fd.fd, (struct sockaddr *)&us, &ulen) ||
351 >      getpeername(auth->client->connection->fd.fd, (struct sockaddr *)&them, &tlen))
352    {
353 <    ilog(LOG_TYPE_IRCD, "auth get{sock,peer}name error for %s",
354 <         get_client_name(auth->client, SHOW_IP));
353 >    report_error(L_ALL, "auth get{sock,peer}name error %s:%s",
354 >                 get_client_name(auth->client, SHOW_IP), errno);
355      auth_error(auth);
356      return;
357    }
358  
472 #ifdef IPV6
359    v6 = (struct sockaddr_in6 *)&us;
360    uport = ntohs(v6->sin6_port);
361    v6 = (struct sockaddr_in6 *)&them;
362    tport = ntohs(v6->sin6_port);
363    remove_ipv6_mapping(&us);
364    remove_ipv6_mapping(&them);
479 #else
480  v4 = (struct sockaddr_in *)&us;
481  uport = ntohs(v4->sin_port);
482  v4 = (struct sockaddr_in *)&them;
483  tport = ntohs(v4->sin_port);
484  us.ss_len = ulen;
485  them.ss_len = tlen;
486 #endif
365  
366 <  snprintf(authbuf, sizeof(authbuf), "%u , %u\r\n", tport, uport);
366 >  len = snprintf(authbuf, sizeof(authbuf), "%u, %u\r\n", tport, uport);
367  
368 <  if (send(fd->fd, authbuf, strlen(authbuf), 0) == -1)
368 >  if (send(fd->fd, authbuf, len, 0) != len)
369    {
370      auth_error(auth);
371      return;
372    }
373  
374 <  read_auth_reply(&auth->fd, auth);
374 >  comm_setselect(fd, COMM_SELECT_READ, read_auth_reply, auth, 0);
375 > }
376 >
377 > /** Enum used to index ident reply fields in a human-readable way. */
378 > enum IdentReplyFields
379 > {
380 >  IDENT_PORT_NUMBERS,
381 >  IDENT_REPLY_TYPE,
382 >  IDENT_OS_TYPE,
383 >  IDENT_INFO,
384 >  USERID_TOKEN_COUNT
385 > };
386 >
387 > /** Parse an ident reply line and extract the userid from it.
388 > * \param reply The ident reply line.
389 > * \return The userid, or NULL on parse failure.
390 > */
391 > static const char *
392 > check_ident_reply(char *const reply)
393 > {
394 >  char *token = NULL, *end = NULL;
395 >  char *vector[USERID_TOKEN_COUNT];
396 >  const int count = token_vector(reply, ':', vector, USERID_TOKEN_COUNT);
397 >
398 >  if (USERID_TOKEN_COUNT != count)
399 >    return NULL;
400 >
401 >  /*
402 >   * Second token is the reply type
403 >   */
404 >  token = vector[IDENT_REPLY_TYPE];
405 >
406 >  if (EmptyString(token))
407 >    return NULL;
408 >
409 >  while (IsSpace(*token))
410 >    ++token;
411 >
412 >  if (strncmp(token, "USERID", 6))
413 >    return NULL;
414 >
415 >  /*
416 >   * Third token is the os type
417 >   */
418 >  token = vector[IDENT_OS_TYPE];
419 >
420 >  if (EmptyString(token))
421 >    return NULL;
422 >
423 >  while (IsSpace(*token))
424 >   ++token;
425 >
426 >  /*
427 >   * Unless "OTHER" is specified as the operating system type, the server
428 >   * is expected to return the "normal" user identification of the owner
429 >   * of this connection. "Normal" in this context may be taken to mean a
430 >   * string of characters which uniquely identifies the connection owner
431 >   * such as a user identifier assigned by the system administrator and
432 >   * used by such user as a mail identifier, or as the "user" part of a
433 >   * user/password pair used to gain access to system resources. When an
434 >   * operating system is specified (e.g., anything but "OTHER"), the user
435 >   * identifier is expected to be in a more or less immediately useful
436 >   * form - e.g., something that could be used as an argument to "finger"
437 >   * or as a mail address.
438 >   */
439 >  if (!strncmp(token, "OTHER", 5))
440 >    return NULL;
441 >
442 >  /*
443 >   * Fourth token is the username
444 >   */
445 >  token = vector[IDENT_INFO];
446 >
447 >  if (EmptyString(token))
448 >    return NULL;
449 >
450 >  while (IsSpace(*token))
451 >    ++token;
452 >
453 >  while (*token == '~' || *token == '^')
454 >    ++token;
455 >
456 >  /*
457 >   * Look for the end of the username, terminators are '\0, @, <SPACE>, :'
458 >   */
459 >  for (end = token; *end; ++end)
460 >    if (IsSpace(*end) || '@' == *end || ':' == *end)
461 >      break;
462 >  *end = '\0';
463 >
464 >  return token;
465   }
466  
467   /*
# Line 502 | Line 470 | auth_connect_callback(fde_t *fd, int err
470   * We only give it one shot, if the reply isn't good the first time
471   * fail the authentication entirely. --Bleep
472   */
505 #define AUTH_BUFSIZ 128
506
473   static void
474   read_auth_reply(fde_t *fd, void *data)
475   {
476 <  struct AuthRequest *auth = data;
477 <  char *s = NULL;
478 <  char *t = NULL;
479 <  int len;
514 <  int count;
515 <  char buf[AUTH_BUFSIZ + 1]; /* buffer to read auth reply into */
516 <
517 <  /* Why?
518 <   * Well, recv() on many POSIX systems is a per-packet operation,
519 <   * and we do not necessarily want this, because on lowspec machines,
520 <   * the ident response may come back fragmented, thus resulting in an
521 <   * invalid ident response, even if the ident response was really OK.
522 <   *
523 <   * So PLEASE do not change this code to recv without being aware of the
524 <   * consequences.
525 <   *
526 <   *    --nenolod
527 <   */
528 <  len = read(fd->fd, buf, AUTH_BUFSIZ);
476 >  struct AuthRequest *const auth = data;
477 >  const char *username = NULL;
478 >  ssize_t len = 0;
479 >  char buf[RFC1413_BUFSIZ + 1];
480  
481 <  if (len < 0)
531 <  {
532 <    if (ignoreErrno(errno))
533 <      comm_setselect(fd, COMM_SELECT_READ, read_auth_reply, auth, 0);
534 <    else
535 <      auth_error(auth);
536 <    return;
537 <  }
538 <
539 <  if (len > 0)
481 >  if ((len = recv(fd->fd, buf, RFC1413_BUFSIZ, 0)) > 0)
482    {
483      buf[len] = '\0';
484 <
543 <    if ((s = GetValidIdent(buf)))
544 <    {
545 <      t = auth->client->username;
546 <
547 <      while (*s == '~' || *s == '^')
548 <        s++;
549 <
550 <      for (count = USERLEN; *s && count; s++)
551 <      {
552 <        if (*s == '@')
553 <          break;
554 <        if (!IsSpace(*s) && *s != ':' && *s != '[')
555 <        {
556 <          *t++ = *s;
557 <          count--;
558 <        }
559 <      }
560 <
561 <      *t = '\0';
562 <    }
484 >    username = check_ident_reply(buf);
485    }
486  
487    fd_close(fd);
488  
489    ClearAuth(auth);
490  
491 <  if (s == NULL)
491 >  if (EmptyString(username))
492    {
493      sendheader(auth->client, REPORT_FAIL_ID);
494      ++ServerStats.is_abad;
495    }
496    else
497    {
498 +    strlcpy(auth->client->username, username, sizeof(auth->client->username));
499      sendheader(auth->client, REPORT_FIN_ID);
500      ++ServerStats.is_asuc;
501 <    SetGotId(auth->client);
501 >    AddFlag(auth->client, FLAGS_GOTID);
502    }
503  
504    release_auth_client(auth);
# Line 595 | Line 518 | delete_auth(struct AuthRequest *auth)
518  
519    if (IsInAuth(auth))
520    {
521 <    dlinkDelete(&auth->node, &auth_doing_list);
521 >    dlinkDelete(&auth->node, &auth_pending_list);
522      ClearInAuth(auth);
523    }
524   }
525 +
526 + /* auth_init
527 + *
528 + * Initialise the auth code
529 + */
530 + void
531 + auth_init(void)
532 + {
533 +  static struct event timeout_auth_queries =
534 +  {
535 +    .name = "timeout_auth_queries_event",
536 +    .handler = timeout_auth_queries_event,
537 +    .when = 1
538 +  };
539 +
540 +  event_add(&timeout_auth_queries, NULL);
541 + }

Diff Legend

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