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

Comparing ircd-hybrid/trunk/src/user.c (file contents):
Revision 6764 by michael, Fri Nov 13 18:38:18 2015 UTC vs.
Revision 9877 by michael, Sat Jan 9 14:20:00 2021 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (c) 1997-2015 ircd-hybrid development team
4 > *  Copyright (c) 1997-2021 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 38 | Line 38
38   #include "motd.h"
39   #include "numeric.h"
40   #include "conf.h"
41 + #include "conf_gecos.h"
42   #include "log.h"
43   #include "server.h"
44   #include "send.h"
45   #include "memory.h"
46   #include "packet.h"
47   #include "rng_mt.h"
47 – #include "userhost.h"
48   #include "misc.h"
49   #include "parse.h"
50 < #include "watch.h"
50 > #include "monitor.h"
51   #include "isupport.h"
52 + #include "tls.h"
53 + #include "patchlevel.h"
54  
55 < static char umode_buffer[IRCD_BUFSIZE];
55 > static char umode_buffer[UMODE_MAX_STR];
56  
57   const struct user_modes *umode_map[256];
58   const struct user_modes  umode_tab[] =
59   {
60 +  { 'B', UMODE_BOT          },
61    { 'D', UMODE_DEAF         },
62    { 'F', UMODE_FARCONNECT   },
63    { 'G', UMODE_SOFTCALLERID },
64    { 'H', UMODE_HIDDEN       },
65 +  { 'X', UMODE_EXPIRATION   },
66    { 'R', UMODE_REGONLY      },
67 <  { 'S', UMODE_SSL          },
67 >  { 'S', UMODE_SECURE       },
68    { 'W', UMODE_WEBIRC       },
69    { 'a', UMODE_ADMIN        },
66 –  { 'b', UMODE_BOTS         },
70    { 'c', UMODE_CCONN        },
71    { 'd', UMODE_DEBUG        },
72    { 'e', UMODE_EXTERNAL     },
73 <  { 'f', UMODE_FULL         },
73 >  { 'f', UMODE_FLOOD        },
74    { 'g', UMODE_CALLERID     },
75    { 'i', UMODE_INVISIBLE    },
76    { 'j', UMODE_REJ          },
# Line 79 | Line 82 | const struct user_modes  umode_tab[] =
82    { 'q', UMODE_HIDEIDLE     },
83    { 'r', UMODE_REGISTERED   },
84    { 's', UMODE_SERVNOTICE   },
82 –  { 'u', UMODE_UNAUTH       },
85    { 'w', UMODE_WALLOP       },
84 –  { 'x', UMODE_HIDDENHOST   },
86    { 'y', UMODE_SPY          },
87    { '\0', 0 }
88   };
# Line 107 | Line 108 | user_modes_init(void)
108   * side effects - display to client user counts etc.
109   */
110   void
111 < show_lusers(struct Client *source_p)
111 > show_lusers(struct Client *client)
112   {
113 <  if (!ConfigServerHide.hide_servers || HasUMode(source_p, UMODE_OPER))
114 <    sendto_one_numeric(source_p, &me, RPL_LUSERCLIENT, (Count.total - Count.invisi),
113 >  if (ConfigServerHide.hide_servers == 0 || HasUMode(client, UMODE_OPER))
114 >    sendto_one_numeric(client, &me, RPL_LUSERCLIENT, (dlink_list_length(&global_client_list) - Count.invisi),
115                         Count.invisi, dlink_list_length(&global_server_list));
116    else
117 <    sendto_one_numeric(source_p, &me, RPL_LUSERCLIENT, (Count.total - Count.invisi),
117 >    sendto_one_numeric(client, &me, RPL_LUSERCLIENT, (dlink_list_length(&global_client_list) - Count.invisi),
118                         Count.invisi, 1);
119  
120    if (Count.oper)
121 <    sendto_one_numeric(source_p, &me, RPL_LUSEROP, Count.oper);
121 >    sendto_one_numeric(client, &me, RPL_LUSEROP, Count.oper);
122  
123    if (dlink_list_length(&unknown_list))
124 <    sendto_one_numeric(source_p, &me, RPL_LUSERUNKNOWN, dlink_list_length(&unknown_list));
124 >    sendto_one_numeric(client, &me, RPL_LUSERUNKNOWN, dlink_list_length(&unknown_list));
125  
126 <  if (dlink_list_length(&channel_list))
127 <    sendto_one_numeric(source_p, &me, RPL_LUSERCHANNELS, dlink_list_length(&channel_list));
126 >  if (dlink_list_length(channel_get_list()))
127 >    sendto_one_numeric(client, &me, RPL_LUSERCHANNELS, dlink_list_length(channel_get_list()));
128  
129 <  if (!ConfigServerHide.hide_servers || HasUMode(source_p, UMODE_OPER))
129 >  if (ConfigServerHide.hide_servers == 0 || HasUMode(client, UMODE_OPER))
130    {
131 <    sendto_one_numeric(source_p, &me, RPL_LUSERME, Count.local, Count.myserver);
132 <    sendto_one_numeric(source_p, &me, RPL_LOCALUSERS, Count.local, Count.max_loc);
131 >    sendto_one_numeric(client, &me, RPL_LUSERME, dlink_list_length(&local_client_list), dlink_list_length(&local_server_list));
132 >    sendto_one_numeric(client, &me, RPL_LOCALUSERS, dlink_list_length(&local_client_list), Count.max_loc);
133 >    sendto_one_numeric(client, &me, RPL_GLOBALUSERS, dlink_list_length(&global_client_list), Count.max_tot);
134 >    sendto_one_numeric(client, &me, RPL_STATSCONN, Count.max_loc_con, Count.max_loc, Count.totalrestartcount);
135    }
136    else
137    {
138 <    sendto_one_numeric(source_p, &me, RPL_LUSERME, Count.total, 0);
139 <    sendto_one_numeric(source_p, &me, RPL_LOCALUSERS, Count.total, Count.max_tot);
138 >    sendto_one_numeric(client, &me, RPL_LUSERME, dlink_list_length(&global_client_list), 0);
139 >    sendto_one_numeric(client, &me, RPL_LOCALUSERS, dlink_list_length(&global_client_list), Count.max_tot);
140 >    sendto_one_numeric(client, &me, RPL_GLOBALUSERS, dlink_list_length(&global_client_list), Count.max_tot);
141    }
138 –
139 –  sendto_one_numeric(source_p, &me, RPL_GLOBALUSERS, Count.total, Count.max_tot);
140 –
141 –  if (!ConfigServerHide.hide_servers || HasUMode(source_p, UMODE_OPER))
142 –    sendto_one_numeric(source_p, &me, RPL_STATSCONN, Count.max_loc_con,
143 –                       Count.max_loc_cli, Count.totalrestartcount);
144 –
145 –  if (Count.local > Count.max_loc_cli)
146 –    Count.max_loc_cli = Count.local;
147 –
148 –  if ((Count.local + Count.myserver) > Count.max_loc_con)
149 –    Count.max_loc_con = Count.local + Count.myserver;
142   }
143  
144   /* report_and_set_user_flags()
145   *
146 < * inputs       - pointer to source_p
146 > * inputs       - pointer to client
147   *              - pointer to conf for this user
148   * output       - NONE
149   * side effects - Report to user any special flags
150   *                they are getting, and set them.
151   */
152   static void
153 < report_and_set_user_flags(struct Client *source_p, const struct MaskItem *conf)
153 > report_and_set_user_flags(struct Client *client, const struct MaskItem *conf)
154   {
155    /* If this user is being spoofed, tell them so */
156    if (IsConfDoSpoofIp(conf))
157 <    sendto_one_notice(source_p, &me, ":*** Spoofing your IP. Congrats.");
157 >    sendto_one_notice(client, &me, ":*** Spoofing your IP");
158  
159    /* If this user is in the exception class, set it "E lined" */
160    if (IsConfExemptKline(conf))
161    {
162 <    AddFlag(source_p, FLAGS_EXEMPTKLINE);
163 <    sendto_one_notice(source_p, &me, ":*** You are exempt from K/D lines. Congrats.");
162 >    AddFlag(client, FLAGS_EXEMPTKLINE);
163 >    sendto_one_notice(client, &me, ":*** You are exempt from K/D lines");
164    }
165  
166    if (IsConfExemptXline(conf))
167    {
168 <    AddFlag(source_p, FLAGS_EXEMPTXLINE);
169 <    sendto_one_notice(source_p, &me, ":*** You are exempt from X lines. Congrats.");
168 >    AddFlag(client, FLAGS_EXEMPTXLINE);
169 >    sendto_one_notice(client, &me, ":*** You are exempt from X lines");
170    }
171  
172    if (IsConfExemptResv(conf))
173    {
174 <    AddFlag(source_p, FLAGS_EXEMPTRESV);
175 <    sendto_one_notice(source_p, &me, ":*** You are exempt from resvs. Congrats.");
174 >    AddFlag(client, FLAGS_EXEMPTRESV);
175 >    sendto_one_notice(client, &me, ":*** You are exempt from resvs");
176    }
177  
178    /* If this user is exempt from user limits set it "F lined" */
179    if (IsConfExemptLimits(conf))
180    {
181 <    AddFlag(source_p, FLAGS_NOLIMIT);
182 <    sendto_one_notice(source_p, &me, ":*** You are exempt from user limits. Congrats.");
181 >    AddFlag(client, FLAGS_NOLIMIT);
182 >    sendto_one_notice(client, &me, ":*** You are exempt from user limits");
183    }
184  
185    if (IsConfCanFlood(conf))
186    {
187 <    AddFlag(source_p, FLAGS_CANFLOOD);
188 <    sendto_one_notice(source_p, &me, ":*** You are exempt from flood "
197 <                      "protection, aren't you fearsome.");
187 >    AddFlag(client, FLAGS_CANFLOOD);
188 >    sendto_one_notice(client, &me, ":*** You are exempt from flood protection");
189    }
190   }
191  
192   /* introduce_client()
193   *
194 < * inputs       - source_p
194 > * inputs       - client
195   * output       - NONE
196   * side effects - This common function introduces a client to the rest
197   *                of the net, either from a local client connect or
198   *                from a remote connect.
199   */
200   static void
201 < introduce_client(struct Client *source_p)
201 > introduce_client(struct Client *client)
202   {
203 <  dlink_node *node = NULL;
213 <  char ubuf[IRCD_BUFSIZE] = "";
214 <
215 <  if (MyClient(source_p))
216 <    send_umode(source_p, source_p, 0, ubuf);
217 <  else
218 <    send_umode(NULL, source_p, 0, ubuf);
203 >  char buf[UMODE_MAX_STR] = "";
204  
205 <  watch_check_hash(source_p, RPL_LOGON);
205 >  send_umode(client, MyConnect(client), 0, buf);
206 >  monitor_signon(client);
207  
208 <  if (ubuf[0] == '\0')
208 >  if (buf[0] == '\0')
209    {
210 <    ubuf[0] = '+';
211 <    ubuf[1] = '\0';
210 >    buf[0] = '+';
211 >    buf[1] = '\0';
212    }
213  
214 <  DLINK_FOREACH(node, local_server_list.head)
215 <  {
216 <    struct Client *server = node->data;
217 <
218 <    if (server == source_p->from)
233 <      continue;
234 <
235 <    if (IsCapable(server, CAPAB_SVS))
236 <      sendto_one(server, ":%s UID %s %u %lu %s %s %s %s %s %s :%s",
237 <                 source_p->servptr->id,
238 <                 source_p->name, source_p->hopcount+1,
239 <                 (unsigned long)source_p->tsinfo,
240 <                 ubuf, source_p->username, source_p->host,
241 <                 source_p->sockhost, source_p->id,
242 <                 source_p->account,
243 <                 source_p->info);
244 <    else
245 <      sendto_one(server, ":%s UID %s %u %lu %s %s %s %s %s :%s",
246 <                 source_p->servptr->id,
247 <                 source_p->name, source_p->hopcount+1,
248 <                 (unsigned long)source_p->tsinfo,
249 <                 ubuf, source_p->username, source_p->host,
250 <                 source_p->sockhost, source_p->id, source_p->info);
214 >  sendto_server(client, 0, 0, ":%s UID %s %u %ju %s %s %s %s %s %s %s :%s",
215 >                client->servptr->id, client->name, client->hopcount + 1,
216 >                client->tsinfo, buf, client->username, client->host,
217 >                client->realhost, client->sockhost, client->id,
218 >                client->account, client->info);
219  
220 <    if (!EmptyString(source_p->certfp))
221 <      sendto_one(server, ":%s CERTFP %s", source_p->id, source_p->certfp);
254 <  }
220 >  if (!EmptyString(client->tls_certfp))
221 >    sendto_server(client, 0, 0, ":%s CERTFP %s", client->id, client->tls_certfp);
222   }
223  
224   /* user_welcome()
# Line 261 | Line 228 | introduce_client(struct Client *source_p
228   * side effects -
229   */
230   static void
231 < user_welcome(struct Client *source_p)
231 > user_welcome(struct Client *client)
232   {
233    static const char built_date[] = __DATE__ " at " __TIME__;
234  
235 < #ifdef HAVE_LIBCRYPTO
269 <  if (HasFlag(source_p, FLAGS_SSL))
235 >  if (HasFlag(client, FLAGS_TLS))
236    {
237 <    AddUMode(source_p, UMODE_SSL);
272 <    sendto_one_notice(source_p, &me, ":*** Connected securely via %s",
273 <                      ssl_get_cipher(source_p->connection->fd.ssl));
274 <  }
275 < #endif
276 <
277 <  sendto_one_numeric(source_p, &me, RPL_WELCOME, ConfigServerInfo.network_name,
278 <                     source_p->name);
279 <  sendto_one_numeric(source_p, &me, RPL_YOURHOST,
280 <                     listener_get_name(source_p->connection->listener), ircd_version);
281 <  sendto_one_numeric(source_p, &me, RPL_CREATED, built_date);
282 <  sendto_one_numeric(source_p, &me, RPL_MYINFO, me.name, ircd_version, umode_buffer);
283 <
284 <  isupport_show(source_p);
285 <  show_lusers(source_p);
286 <  motd_signon(source_p);
287 < }
237 >    AddUMode(client, UMODE_SECURE);
238  
239 < /* check_xline()
240 < *
241 < * inputs       - pointer to client to test
292 < * outupt       - 1 if exiting 0 if ok
293 < * side effects -
294 < */
295 < static int
296 < check_xline(struct Client *source_p)
297 < {
298 <  struct MaskItem *conf = NULL;
299 <
300 <  if (HasFlag(source_p, FLAGS_EXEMPTXLINE))
301 <    return 0;
302 <
303 <  if ((conf = find_matching_name_conf(CONF_XLINE, source_p->info, NULL, NULL, 0)))
304 <  {
305 <    ++conf->count;
306 <    sendto_realops_flags(UMODE_REJ, L_ALL, SEND_NOTICE,
307 <                         "X-line Rejecting [%s] [%s], user %s [%s]",
308 <                         source_p->info, conf->reason,
309 <                         get_client_name(source_p, HIDE_IP),
310 <                         source_p->sockhost);
311 <
312 <    ++ServerStats.is_ref;
313 <    exit_client(source_p, "Bad user info");
314 <    return 1;
239 >    client->tls_cipher = xstrdup(tls_get_cipher(&client->connection->fd->tls));
240 >    sendto_one_notice(client, &me, ":*** Connected securely via %s",
241 >                      client->tls_cipher);
242    }
243  
244 <  return 0;
244 >  sendto_one_numeric(client, &me, RPL_WELCOME, ConfigServerInfo.network_name,
245 >                     client->name, client->username, client->realhost);
246 >  sendto_one_numeric(client, &me, RPL_YOURHOST,
247 >                     listener_get_name(client->connection->listener), PATCHLEVEL);
248 >  sendto_one_numeric(client, &me, RPL_CREATED, built_date);
249 >  sendto_one_numeric(client, &me, RPL_MYINFO, me.name, PATCHLEVEL, umode_buffer);
250 >
251 >  isupport_show(client);
252 >  show_lusers(client);
253 >  motd_signon(client);
254   }
255  
256   /*! \brief This function is called when both NICK and USER messages
257   *      have been accepted for the client, in whatever order. Only
258   *      after this, is the UID message propagated.
259 < * \param source_p Pointer to given client to introduce
259 > * \param client Pointer to given client to introduce
260   */
261   void
262 < register_local_user(struct Client *source_p)
262 > register_local_user(struct Client *client)
263   {
328 –  const char *id = NULL;
264    const struct MaskItem *conf = NULL;
265  
266 <  assert(source_p == source_p->from);
267 <  assert(MyConnect(source_p));
268 <  assert(IsUnknown(source_p));
269 <  assert(!source_p->connection->registration);
266 >  assert(client == client->from);
267 >  assert(client->connection->registration == 0);
268 >  assert(MyConnect(client));
269 >  assert(IsUnknown(client));
270  
271    if (ConfigGeneral.ping_cookie)
272    {
273 <    if (!HasFlag(source_p, FLAGS_PINGSENT) && !source_p->connection->random_ping)
273 >    if (!HasFlag(client, FLAGS_PINGSENT) && client->connection->random_ping == 0)
274      {
275        do
276 <        source_p->connection->random_ping = genrand_int32();
277 <      while (!source_p->connection->random_ping);
276 >        client->connection->random_ping = genrand_int32();
277 >      while (client->connection->random_ping == 0);
278  
279 <      sendto_one(source_p, "PING :%u", source_p->connection->random_ping);
280 <      AddFlag(source_p, FLAGS_PINGSENT);
279 >      sendto_one(client, "PING :%u", client->connection->random_ping);
280 >      AddFlag(client, FLAGS_PINGSENT);
281        return;
282      }
283  
284 <    if (!HasFlag(source_p, FLAGS_PING_COOKIE))
284 >    if (!HasFlag(client, FLAGS_PING_COOKIE))
285        return;
286    }
287  
288 <  source_p->connection->last_privmsg = CurrentTime;
354 <  /* Straight up the maximum rate of flooding... */
355 <  source_p->connection->allow_read = MAX_FLOOD_BURST;
356 <
357 <  if (!check_client(source_p))
288 >  if (conf_check_client(client) == false)
289      return;
290  
291 <  if (!valid_hostname(source_p->host))
361 <  {
362 <    sendto_one_notice(source_p, &me, ":*** Notice -- You have an illegal "
363 <                      "character in your hostname");
364 <    strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host));
365 <  }
291 >  conf = client->connection->confs.head->data;
292  
293 <  conf = source_p->connection->confs.head->data;
368 <
369 <  if (!HasFlag(source_p, FLAGS_GOTID))
293 >  if (!HasFlag(client, FLAGS_GOTID))
294    {
295 <    char username[USERLEN + 1] = "";
295 >    char username[USERLEN + 1];
296      unsigned int i = 0;
297  
298      if (IsNeedIdentd(conf))
299      {
300        ++ServerStats.is_ref;
301 <      sendto_one_notice(source_p, &me, ":*** Notice -- You need to install "
301 >      sendto_one_notice(client, &me, ":*** Notice -- You need to install "
302                          "identd to use this server");
303 <      exit_client(source_p, "Install identd");
303 >      exit_client(client, "Install identd");
304        return;
305      }
306  
307 <    strlcpy(username, source_p->username, sizeof(username));
307 >    strlcpy(username, client->username, sizeof(username));
308  
309      if (!IsNoTilde(conf))
310 <      source_p->username[i++] = '~';
310 >      client->username[i++] = '~';
311  
312      for (const char *p = username; *p && i < USERLEN; ++p)
313 <      source_p->username[i++] = *p;
313 >      client->username[i++] = *p;
314  
315 <    source_p->username[i] = '\0';
315 >    client->username[i] = '\0';
316    }
317  
318    /* Password check */
319    if (!EmptyString(conf->passwd))
320    {
321 <    if (!match_conf_password(source_p->connection->password, conf))
321 >    if (match_conf_password(client->connection->password, conf) == false)
322      {
323        ++ServerStats.is_ref;
324  
325 <      sendto_one_numeric(source_p, &me, ERR_PASSWDMISMATCH);
326 <      exit_client(source_p, "Bad Password");
325 >      sendto_one_numeric(client, &me, ERR_PASSWDMISMATCH);
326 >      exit_client(client, "Bad Password");
327        return;
328      }
329    }
330  
331 <  /*
332 <   * Don't free source_p->connection->password here - it can be required
409 <   * by masked /stats I if there are auth {} blocks with need_password = no;
410 <   * --adx
411 <   */
331 >  xfree(client->connection->password);
332 >  client->connection->password = NULL;
333  
334    /*
335 <   * Report if user has &^>= etc. and set flags as needed in source_p
335 >   * Report if user has &^>= etc. and set flags as needed in client
336     */
337 <  report_and_set_user_flags(source_p, conf);
337 >  report_and_set_user_flags(client, conf);
338  
339 <  if (IsDead(source_p))
339 >  if (IsDead(client))
340      return;
341  
342    /*
# Line 426 | Line 347 | register_local_user(struct Client *sourc
347     * probably be just a percentage of the MAXCLIENTS...
348     *   -Taner
349     */
350 <  if ((Count.local >= GlobalSetOptions.maxclients + MAX_BUFFER) ||
351 <      (Count.local >= GlobalSetOptions.maxclients && !HasFlag(source_p, FLAGS_NOLIMIT)))
350 >  if ((dlink_list_length(&local_client_list) >= GlobalSetOptions.maxclients + MAX_BUFFER) ||
351 >      (dlink_list_length(&local_client_list) >= GlobalSetOptions.maxclients && !HasFlag(client, FLAGS_NOLIMIT)))
352    {
353 <    sendto_realops_flags(UMODE_FULL, L_ALL, SEND_NOTICE,
353 >    sendto_realops_flags(UMODE_REJ, L_ALL, SEND_NOTICE,
354                           "Too many clients, rejecting %s[%s].",
355 <                         source_p->name, source_p->host);
355 >                         client->name, client->host);
356      ++ServerStats.is_ref;
357 <    exit_client(source_p, "Sorry, server is full - try later");
357 >    exit_client(client, "Sorry, server is full - try later");
358      return;
359    }
360  
361 <  if (!valid_username(source_p->username, 1))
361 >  if (valid_username(client->username, true) == false)
362    {
363 <    char buf[IRCD_BUFSIZE] = "";
363 >    char buf[sizeof("Invalid username []") + sizeof(client->username)];
364  
365      sendto_realops_flags(UMODE_REJ, L_ALL, SEND_NOTICE,
366                           "Invalid username: %s (%s@%s)",
367 <                         source_p->name, source_p->username, source_p->host);
367 >                         client->name, client->username, client->host);
368      ++ServerStats.is_ref;
369 <    snprintf(buf, sizeof(buf), "Invalid username [%s]", source_p->username);
370 <    exit_client(source_p, buf);
369 >    snprintf(buf, sizeof(buf), "Invalid username [%s]", client->username);
370 >    exit_client(client, buf);
371      return;
372    }
373  
374 <  if (check_xline(source_p))
375 <    return;
374 >  if (!HasFlag(client, FLAGS_EXEMPTXLINE))
375 >  {
376 >    const struct GecosItem *gecos = gecos_find(client->info, match);
377 >    if (gecos)
378 >    {
379 >      sendto_realops_flags(UMODE_REJ, L_ALL, SEND_NOTICE,
380 >                           "X-line Rejecting [%s] [%s], user %s [%s]",
381 >                           client->info, gecos->reason,
382 >                           client_get_name(client, HIDE_IP),
383 >                           client->sockhost);
384 >      ++ServerStats.is_ref;
385 >      exit_client(client, "Bad user info");
386 >      return;
387 >    }
388 >  }
389  
390 +  const char *id;
391    while (hash_find_id((id = uid_get())))
392      ;
393  
394 <  strlcpy(source_p->id, id, sizeof(source_p->id));
395 <  hash_add_id(source_p);
394 >  strlcpy(client->id, id, sizeof(client->id));
395 >  hash_add_id(client);
396  
397    sendto_realops_flags(UMODE_CCONN, L_ALL, SEND_NOTICE,
398                         "Client connecting: %s (%s@%s) [%s] {%s} [%s] <%s>",
399 <                       source_p->name, source_p->username, source_p->host,
400 <                       source_p->sockhost,
401 <                       get_client_class(&source_p->connection->confs),
402 <                       source_p->info, source_p->id);
399 >                       client->name, client->username, client->realhost,
400 >                       client->sockhost,
401 >                       get_client_class(&client->connection->confs),
402 >                       client->info, client->id);
403  
404    if (ConfigGeneral.invisible_on_connect)
405    {
406 <    AddUMode(source_p, UMODE_INVISIBLE);
406 >    AddUMode(client, UMODE_INVISIBLE);
407      ++Count.invisi;
408    }
409  
410 <  if (++Count.local > Count.max_loc)
410 >  SetClient(client);
411 >
412 >  client->servptr = &me;
413 >  client->connection->last_privmsg = event_base->time.sec_monotonic;
414 >
415 >  dlinkAdd(client, &client->lnode, &client->servptr->serv->client_list);
416 >  dlinkAdd(client, &client->node, &global_client_list);
417 >
418 >  assert(dlinkFind(&unknown_list, client));
419 >
420 >  dlink_move_node(&client->connection->lclient_node,
421 >                  &unknown_list, &local_client_list);
422 >
423 >  if (dlink_list_length(&local_client_list) > Count.max_loc)
424    {
425 <    Count.max_loc = Count.local;
425 >    Count.max_loc = dlink_list_length(&local_client_list);
426  
427      if (!(Count.max_loc % 10))
428        sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
# Line 482 | Line 430 | register_local_user(struct Client *sourc
430                             Count.max_loc);
431    }
432  
433 <  if (++Count.total > Count.max_tot)
434 <    Count.max_tot = Count.total;
435 <  ++Count.totalrestartcount;
436 <
489 <  assert(source_p->servptr == &me);
490 <  SetClient(source_p);
491 <  dlinkAdd(source_p, &source_p->lnode, &source_p->servptr->serv->client_list);
492 <  dlinkAdd(source_p, &source_p->node, &global_client_list);
493 <
494 <  assert(dlinkFind(&unknown_list, source_p));
433 >  if ((dlink_list_length(&local_client_list) +
434 >       dlink_list_length(&local_server_list)) > Count.max_loc_con)
435 >    Count.max_loc_con = dlink_list_length(&local_client_list) +
436 >                        dlink_list_length(&local_server_list);
437  
438 <  dlink_move_node(&source_p->connection->lclient_node,
439 <                  &unknown_list, &local_client_list);
438 >  if (dlink_list_length(&global_client_list) > Count.max_tot)
439 >    Count.max_tot = dlink_list_length(&global_client_list);
440 >  ++Count.totalrestartcount;
441  
442 <  user_welcome(source_p);
500 <  userhost_add(source_p->username, source_p->host, 0);
501 <  AddFlag(source_p, FLAGS_USERHOST);
442 >  user_welcome(client);
443  
444 <  introduce_client(source_p);
444 >  introduce_client(client);
445   }
446  
447   /* register_remote_user()
448   *
449 < * inputs       - source_p remote or directly connected client
449 > * inputs       - client remote or directly connected client
450   *              - username to register as
451   *              - host name to register as
452   *              - server name
# Line 514 | Line 455 | register_local_user(struct Client *sourc
455   *                is introduced by a server.
456   */
457   void
458 < register_remote_user(struct Client *source_p)
458 > register_remote_user(struct Client *client)
459   {
460 <  const struct Client *target_p = NULL;
520 <
521 <  if ((target_p = source_p->servptr) && target_p->from != source_p->from)
522 <  {
523 <    sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
524 <                         "Bad User [%s] :%s USER %s@%s %s, != %s[%s]",
525 <                         source_p->from->name, source_p->name, source_p->username,
526 <                         source_p->host, source_p->servptr->name,
527 <                         target_p->name, target_p->from->name);
528 <    sendto_one(source_p->from,
529 <               ":%s KILL %s :%s (UID from wrong direction (%s != %s))",
530 <               me.id, source_p->id, me.name, source_p->servptr->name,
531 <               target_p->from->name);
532 <
533 <    AddFlag(source_p, FLAGS_KILLED);
534 <    exit_client(source_p, "UID server wrong direction");
535 <    return;
536 <  }
460 >  assert(client->servptr->from == client->from);
461  
462    /*
463     * If the nick has been introduced by a services server,
464     * make it a service as well.
465     */
466 <  if (HasFlag(source_p->servptr, FLAGS_SERVICE))
467 <    AddFlag(source_p, FLAGS_SERVICE);
466 >  if (HasFlag(client->servptr, FLAGS_SERVICE))
467 >    AddFlag(client, FLAGS_SERVICE);
468  
469 <  if (++Count.total > Count.max_tot)
470 <    Count.max_tot = Count.total;
469 >  SetClient(client);
470 >  dlinkAdd(client, &client->lnode, &client->servptr->serv->client_list);
471 >  dlinkAdd(client, &client->node, &global_client_list);
472  
473 <  SetClient(source_p);
474 <  dlinkAdd(source_p, &source_p->lnode, &source_p->servptr->serv->client_list);
550 <  dlinkAdd(source_p, &source_p->node, &global_client_list);
551 <  userhost_add(source_p->username, source_p->host, 1);
552 <  AddFlag(source_p, FLAGS_USERHOST);
473 >  if (dlink_list_length(&global_client_list) > Count.max_tot)
474 >    Count.max_tot = dlink_list_length(&global_client_list);
475  
476 <  if (HasFlag(source_p->servptr, FLAGS_EOB))
476 >  if (HasFlag(client->servptr, FLAGS_EOB))
477      sendto_realops_flags(UMODE_FARCONNECT, L_ALL, SEND_NOTICE,
478                           "Client connecting at %s: %s (%s@%s) [%s] [%s] <%s>",
479 <                         source_p->servptr->name,
480 <                         source_p->name, source_p->username, source_p->host,
481 <                         source_p->sockhost, source_p->info, source_p->id);
479 >                         client->servptr->name,
480 >                         client->name, client->username, client->realhost,
481 >                         client->sockhost, client->info, client->id);
482  
483 <  introduce_client(source_p);
483 >  introduce_client(client);
484   }
485  
486   /* valid_hostname()
# Line 570 | Line 492 | register_remote_user(struct Client *sour
492   * NOTE: this doesn't allow a hostname to begin with a dot and
493   * will not allow more dots than chars.
494   */
495 < int
495 > bool
496   valid_hostname(const char *hostname)
497   {
498    const char *p = hostname;
# Line 578 | Line 500 | valid_hostname(const char *hostname)
500    assert(p);
501  
502    if (EmptyString(p) || *p == '.' || *p == ':')
503 <    return 0;
503 >    return false;
504  
505    for (; *p; ++p)
506      if (!IsHostChar(*p))
507 <      return 0;
507 >      return false;
508  
509    return p - hostname <= HOSTLEN;
510   }
# Line 598 | Line 520 | valid_hostname(const char *hostname)
520   * Allow '.' in username to allow for "first.last"
521   * style of username
522   */
523 < int
524 < valid_username(const char *username, const int local)
523 > bool
524 > valid_username(const char *username, bool local)
525   {
526    const char *p = username;
527  
# Line 614 | Line 536 | valid_username(const char *username, con
536     * or "-hi-@somehost", "h-----@somehost" would still be accepted.
537     */
538    if (!IsAlNum(*p))
539 <    return 0;
539 >    return false;
540  
541    if (local)
542    {
543      unsigned int dots = 0;
544  
545 <    while (*++p)
545 >    while (*p)
546      {
547        if (*p == '.' && ConfigGeneral.dots_in_ident)
548        {
549          if (++dots > ConfigGeneral.dots_in_ident)
550 <          return 0;
551 <        if (!IsUserChar(*(p + 1)))
552 <          return 0;
550 >          return false;
551 >        if (!IsUser2Char(*(p + 1)))
552 >          return false;
553        }
554 <      else if (!IsUserChar(*p))
555 <        return 0;
554 >      else if (!IsUser2Char(*p))
555 >        return false;
556      }
557    }
558    else
559    {
560      while (*++p)
561        if (!IsUserChar(*p))
562 <        return 0;
562 >        return false;
563    }
564  
565    return p - username <= USERLEN;
# Line 650 | Line 572 | valid_username(const char *username, con
572   * output       - none
573   * side effects - walks through the nickname, returning 0 if erroneous
574   */
575 < int
576 < valid_nickname(const char *nickname, const int local)
575 > bool
576 > valid_nickname(const char *nickname, bool local)
577   {
578    const char *p = nickname;
579  
# Line 661 | Line 583 | valid_nickname(const char *nickname, con
583     * Nicks can't start with a digit or - or be 0 length.
584     */
585    if (EmptyString(p) || *p == '-' || (IsDigit(*p) && local))
586 <    return 0;
586 >    return false;
587  
588    for (; *p; ++p)
589      if (!IsNickChar(*p))
590 <      return 0;
590 >      return false;
591  
592    return p - nickname <= NICKLEN;
593   }
594  
595 < /* send_umode()
596 < * send the MODE string for user (user) to connection client_p
597 < * -avalon
598 < *
599 < * inputs       - client_p
678 < *              - source_p
679 < *              - int old
680 < *              - suplied umode_buf
681 < * output       - NONE
595 > /*! \brief Builds a mode change string to buffer pointed by \a buf
596 > * \param client   Pointer to client
597 > * \param dispatch Whether to send a MODE message to client
598 > * \param old      Old user mode to compare against when building new mode buffer
599 > * \param buf      Pointer to buffer to build string in
600   */
601   void
602 < send_umode(struct Client *client_p, struct Client *source_p,
685 <           unsigned int old, char *umode_buf)
602 > send_umode(struct Client *client, bool dispatch, unsigned int old, char *buf)
603   {
604 <  char *m = umode_buf;
604 >  char *m = buf;
605    int what = 0;
606  
607    /*
608     * Build a string in umode_buf to represent the change in the user's
609 <   * mode between the new (source_p->umodes) and 'old'.
609 >   * mode between the new (client->umodes) and 'old'.
610     */
611    for (const struct user_modes *tab = umode_tab; tab->c; ++tab)
612    {
613 <    if ((tab->flag & old) && !HasUMode(source_p, tab->flag))
613 >    if ((tab->flag & old) && !HasUMode(client, tab->flag))
614      {
615        if (what == MODE_DEL)
616          *m++ = tab->c;
# Line 704 | Line 621 | send_umode(struct Client *client_p, stru
621          *m++ = tab->c;
622        }
623      }
624 <    else if (!(tab->flag & old) && HasUMode(source_p, tab->flag))
624 >    else if (!(tab->flag & old) && HasUMode(client, tab->flag))
625      {
626        if (what == MODE_ADD)
627          *m++ = tab->c;
# Line 719 | Line 636 | send_umode(struct Client *client_p, stru
636  
637    *m = '\0';
638  
639 <  if (*umode_buf && client_p)
640 <    sendto_one(client_p, ":%s!%s@%s MODE %s :%s",
641 <               client_p->name, client_p->username,
642 <               client_p->host, client_p->name, umode_buf);
639 >  if (dispatch == true && *buf)
640 >    sendto_one(client, ":%s!%s@%s MODE %s :%s",
641 >               client->name, client->username,
642 >               client->host, client->name, buf);
643   }
644  
645   /* send_umode_out()
# Line 732 | Line 649 | send_umode(struct Client *client_p, stru
649   * side effects - Only send ubuf out to servers that know about this client
650   */
651   void
652 < send_umode_out(struct Client *source_p, unsigned int old)
652 > send_umode_out(struct Client *client, unsigned int old)
653   {
654 <  char buf[IRCD_BUFSIZE] = "";
654 >  char buf[UMODE_MAX_STR] = "";
655  
656 <  send_umode(MyClient(source_p) ? source_p : NULL, source_p, old, buf);
656 >  send_umode(client, MyConnect(client), old, buf);
657  
658    if (buf[0])
659 <    sendto_server(source_p, 0, 0, ":%s MODE %s :%s",
660 <                  source_p->id, source_p->id, buf);
659 >    sendto_server(client, 0, 0, ":%s MODE %s :%s",
660 >                  client->id, client->id, buf);
661   }
662  
663   void
664 < user_set_hostmask(struct Client *target_p, const char *hostname, const int what)
664 > user_set_hostmask(struct Client *client, const char *hostname)
665   {
666 <  dlink_node *node = NULL;
666 >  dlink_node *node;
667  
668 <  if (!strcmp(target_p->host, hostname))
668 >  if (strcmp(client->host, hostname) == 0)
669      return;
670  
754 –  switch (what)
755 –  {
756 –    case MODE_ADD:
757 –      AddUMode(target_p, UMODE_HIDDENHOST);
758 –      break;
759 –    case MODE_DEL:
760 –      DelUMode(target_p, UMODE_HIDDENHOST);
761 –      break;
762 –    default: return;
763 –  }
764 –
671    if (ConfigGeneral.cycle_on_host_change)
672 <    sendto_common_channels_local(target_p, 0, 0, ":%s!%s@%s QUIT :Changing hostname",
673 <                                 target_p->name, target_p->username, target_p->host);
672 >    sendto_common_channels_local(client, false, 0, CAP_CHGHOST, ":%s!%s@%s QUIT :Changing hostname",
673 >                                 client->name, client->username, client->host);
674  
675 <  if (HasFlag(target_p, FLAGS_USERHOST))
676 <    userhost_del(target_p->username, target_p->host, !MyConnect(target_p));
675 >  sendto_common_channels_local(client, true, CAP_CHGHOST, 0, ":%s!%s@%s CHGHOST %s %s",
676 >                               client->name, client->username,
677 >                               client->host, client->username, hostname);
678  
679 <  strlcpy(target_p->host, hostname, sizeof(target_p->host));
679 >  strlcpy(client->host, hostname, sizeof(client->host));
680  
681 <  userhost_add(target_p->username, target_p->host, !MyConnect(target_p));
775 <  AddFlag(target_p, FLAGS_USERHOST);
776 <
777 <  if (MyConnect(target_p))
681 >  if (MyConnect(client))
682    {
683 <    sendto_one_numeric(target_p, &me, RPL_VISIBLEHOST, target_p->host);
684 <    clear_ban_cache_client(target_p);
683 >    sendto_one_numeric(client, &me, RPL_VISIBLEHOST, client->host);
684 >    clear_ban_cache_list(&client->channel);
685    }
686  
687 <  if (!ConfigGeneral.cycle_on_host_change)
687 >  if (ConfigGeneral.cycle_on_host_change == 0)
688      return;
689  
690 <  DLINK_FOREACH(node, target_p->channel.head)
690 >  DLINK_FOREACH(node, client->channel.head)
691    {
692 <    char modebuf[4], nickbuf[NICKLEN * 3 + 3] = "";
692 >    char modebuf[CMEMBER_STATUS_FLAGS_LEN + 1];
693 >    char nickbuf[CMEMBER_STATUS_FLAGS_LEN * NICKLEN + CMEMBER_STATUS_FLAGS_LEN] = "";
694      char *p = modebuf;
695      int len = 0;
696 <    const struct Membership *member = node->data;
696 >    const struct ChannelMember *member = node->data;
697  
698 <    if (has_member_flags(member, CHFL_CHANOP))
698 >    if (member_has_flags(member, CHFL_CHANOP) == true)
699      {
700        *p++ = 'o';
701 <      len += snprintf(nickbuf + len, sizeof(nickbuf) - len, len ? " %s" : "%s", target_p->name);
701 >      len += snprintf(nickbuf + len, sizeof(nickbuf) - len, len ? " %s" : "%s", client->name);
702      }
703  
704 <    if (has_member_flags(member, CHFL_HALFOP))
704 >    if (member_has_flags(member, CHFL_HALFOP) == true)
705      {
706        *p++ = 'h';
707 <      len += snprintf(nickbuf + len, sizeof(nickbuf) - len, len ? " %s" : "%s", target_p->name);
707 >      len += snprintf(nickbuf + len, sizeof(nickbuf) - len, len ? " %s" : "%s", client->name);
708      }
709  
710 <    if (has_member_flags(member, CHFL_VOICE))
710 >    if (member_has_flags(member, CHFL_VOICE) == true)
711      {
712        *p++ = 'v';
713 <      len += snprintf(nickbuf + len, sizeof(nickbuf) - len, len ? " %s" : "%s", target_p->name);
713 >      len += snprintf(nickbuf + len, sizeof(nickbuf) - len, len ? " %s" : "%s", client->name);
714      }
715  
716      *p = '\0';
717  
718 <
719 <    sendto_channel_local(target_p, member->chptr, 0, CAP_EXTENDED_JOIN, 0, ":%s!%s@%s JOIN %s %s :%s",
720 <                         target_p->name, target_p->username,
721 <                         target_p->host, member->chptr->name,
722 <                         (!IsDigit(target_p->account[0]) && target_p->account[0] != '*') ? target_p->account : "*",
723 <                         target_p->info);
724 <    sendto_channel_local(target_p, member->chptr, 0, 0, CAP_EXTENDED_JOIN, ":%s!%s@%s JOIN :%s",
820 <                         target_p->name, target_p->username,
821 <                         target_p->host, member->chptr->name);
718 >    sendto_channel_local(client, member->channel, 0, CAP_EXTENDED_JOIN, CAP_CHGHOST, ":%s!%s@%s JOIN %s %s :%s",
719 >                         client->name, client->username,
720 >                         client->host, member->channel->name,
721 >                         client->account, client->info);
722 >    sendto_channel_local(client, member->channel, 0, 0, CAP_EXTENDED_JOIN | CAP_CHGHOST, ":%s!%s@%s JOIN :%s",
723 >                         client->name, client->username,
724 >                         client->host, member->channel->name);
725  
726      if (nickbuf[0])
727 <      sendto_channel_local(target_p, member->chptr, 0, 0, 0, ":%s MODE %s +%s %s",
728 <                           target_p->servptr->name, member->chptr->name,
727 >      sendto_channel_local(client, member->channel, 0, 0, CAP_CHGHOST, ":%s MODE %s +%s %s",
728 >                           client->servptr->name, member->channel->name,
729                             modebuf, nickbuf);
827 –    if (target_p->away[0])
828 –      sendto_channel_local(target_p, member->chptr, 0, CAP_AWAY_NOTIFY, 0,
829 –                           ":%s!%s@%s AWAY :%s",
830 –                           target_p->name, target_p->username,
831 –                           target_p->host, target_p->away);
730    }
731 +
732 +  if (client->away[0])
733 +    sendto_common_channels_local(client, false, CAP_AWAY_NOTIFY, CAP_CHGHOST,
734 +                                 ":%s!%s@%s AWAY :%s",
735 +                                 client->name, client->username,
736 +                                 client->host, client->away);
737   }

Comparing ircd-hybrid/trunk/src/user.c (property svn:keywords):
Revision 6764 by michael, Fri Nov 13 18:38:18 2015 UTC vs.
Revision 9877 by michael, Sat Jan 9 14:20:00 2021 UTC

# Line 1 | Line 1
1 < Id Revision
1 > Id

Diff Legend

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