Drop duplication definition of MODS_INCREMENT macro.
[seven-1.x.git] / src / s_user.c
blob932214f44edc251d6cd3e09d97e9b23cd8e94d6c
1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * s_user.c: User related functions.
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
24 * $Id: s_user.c 196 2006-12-19 01:20:05Z beu $
27 #include "stdinc.h"
28 #include "tools.h"
29 #include "s_user.h"
30 #include "channel.h"
31 #include "class.h"
32 #include "client.h"
33 #include "common.h"
34 #include "hash.h"
35 #include "irc_string.h"
36 #include "sprintf_irc.h"
37 #include "ircd.h"
38 #include "listener.h"
39 #include "msg.h"
40 #include "numeric.h"
41 #include "commio.h"
42 #include "s_conf.h"
43 #include "s_newconf.h"
44 #include "s_log.h"
45 #include "s_serv.h"
46 #include "s_stats.h"
47 #include "scache.h"
48 #include "send.h"
49 #include "supported.h"
50 #include "whowas.h"
51 #include "memory.h"
52 #include "packet.h"
53 #include "reject.h"
54 #include "cache.h"
55 #include "hook.h"
56 #include "monitor.h"
57 #include "snomask.h"
58 #include "blacklist.h"
60 static void report_and_set_user_flags(struct Client *, struct ConfItem *);
61 void user_welcome(struct Client *source_p);
63 extern char *crypt();
65 char umodebuf[128];
67 int user_modes[256] = {
68 /* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0F */
69 /* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1F */
70 /* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x2F */
71 /* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x3F */
72 0, /* @ */
73 0, /* A */
74 0, /* B */
75 0, /* C */
76 UMODE_DEAF, /* D */
77 0, /* E */
78 0, /* F */
79 0, /* G */
80 0, /* H */
81 0, /* I */
82 0, /* J */
83 0, /* K */
84 0, /* L */
85 0, /* M */
86 0, /* N */
87 0, /* O */
88 0, /* P */
89 UMODE_NOFORWARD, /* Q */
90 UMODE_REGONLYMSG, /* R */
91 UMODE_SERVICE, /* S */
92 UMODE_HELPER, /* T */
93 0, /* U */
94 0, /* V */
95 0, /* W */
96 0, /* X */
97 0, /* Y */
98 0, /* Z */
99 /* 0x5B */ 0, 0, 0, 0, 0, 0, /* 0x60 */
100 UMODE_ADMIN, /* a */
101 0, /* b */
102 0, /* c */
103 0, /* d */
104 0, /* e */
105 0, /* f */
106 UMODE_CALLERID, /* g */
107 0, /* h */
108 UMODE_INVISIBLE, /* i */
109 0, /* j */
110 0, /* k */
111 0, /* l */
112 0, /* m */
113 0, /* n */
114 UMODE_OPER, /* o */
115 UMODE_OVERRIDE, /* p */
116 0, /* q */
117 0, /* r */
118 UMODE_SERVNOTICE, /* s */
119 0, /* t */
120 0, /* u */
121 0, /* v */
122 UMODE_WALLOP, /* w */
123 0, /* x */
124 0, /* y */
125 UMODE_OPERWALL, /* z */
126 /* 0x7B */ 0, 0, 0, 0, 0, /* 0x7F */
127 /* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9F */
128 /* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x9F */
129 /* 0xA0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xAF */
130 /* 0xB0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xBF */
131 /* 0xC0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCF */
132 /* 0xD0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xDF */
133 /* 0xE0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xEF */
134 /* 0xF0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xFF */
136 /* *INDENT-ON* */
139 * show_lusers -
141 * inputs - pointer to client
142 * output -
143 * side effects - display to client user counts etc.
146 show_lusers(struct Client *source_p)
148 sendto_one_numeric(source_p, RPL_LUSERCLIENT, form_str(RPL_LUSERCLIENT),
149 (Count.total - Count.invisi),
150 Count.invisi, dlink_list_length(&global_serv_list));
152 if(dlink_list_length(&oper_list) > 0)
153 sendto_one_numeric(source_p, RPL_LUSEROP,
154 form_str(RPL_LUSEROP), dlink_list_length(&oper_list));
156 if(dlink_list_length(&unknown_list) > 0)
157 sendto_one_numeric(source_p, RPL_LUSERUNKNOWN,
158 form_str(RPL_LUSERUNKNOWN),
159 dlink_list_length(&unknown_list));
161 if(dlink_list_length(&global_channel_list) > 0)
162 sendto_one_numeric(source_p, RPL_LUSERCHANNELS,
163 form_str(RPL_LUSERCHANNELS),
164 dlink_list_length(&global_channel_list));
166 sendto_one_numeric(source_p, RPL_LUSERME, form_str(RPL_LUSERME),
167 dlink_list_length(&lclient_list),
168 dlink_list_length(&serv_list));
170 sendto_one_numeric(source_p, RPL_LOCALUSERS,
171 form_str(RPL_LOCALUSERS),
172 dlink_list_length(&lclient_list),
173 Count.max_loc,
174 dlink_list_length(&lclient_list),
175 Count.max_loc);
177 sendto_one_numeric(source_p, RPL_GLOBALUSERS, form_str(RPL_GLOBALUSERS),
178 Count.total, Count.max_tot,
179 Count.total, Count.max_tot);
181 sendto_one_numeric(source_p, RPL_STATSCONN,
182 form_str(RPL_STATSCONN),
183 MaxConnectionCount, MaxClientCount,
184 Count.totalrestartcount);
186 if(dlink_list_length(&lclient_list) > (unsigned long)MaxClientCount)
187 MaxClientCount = dlink_list_length(&lclient_list);
189 if((dlink_list_length(&lclient_list) + dlink_list_length(&serv_list)) >
190 (unsigned long)MaxConnectionCount)
191 MaxConnectionCount = dlink_list_length(&lclient_list) +
192 dlink_list_length(&serv_list);
194 return 0;
198 ** register_local_user
199 ** This function is called when both NICK and USER messages
200 ** have been accepted for the client, in whatever order. Only
201 ** after this, is the USER message propagated.
203 ** NICK's must be propagated at once when received, although
204 ** it would be better to delay them too until full info is
205 ** available. Doing it is not so simple though, would have
206 ** to implement the following:
208 ** (actually it has been implemented already for a while) -orabidoo
210 ** 1) user telnets in and gives only "NICK foobar" and waits
211 ** 2) another user far away logs in normally with the nick
212 ** "foobar" (quite legal, as this server didn't propagate
213 ** it).
214 ** 3) now this server gets nick "foobar" from outside, but
215 ** has alread the same defined locally. Current server
216 ** would just issue "KILL foobar" to clean out dups. But,
217 ** this is not fair. It should actually request another
218 ** nick from local user or kill him/her...
222 register_local_user(struct Client *client_p, struct Client *source_p, const char *username)
224 struct ConfItem *aconf;
225 struct User *user = source_p->user;
226 char tmpstr2[IRCD_BUFSIZE];
227 char ipaddr[HOSTIPLEN];
228 char myusername[USERLEN+1];
229 int status;
231 s_assert(NULL != source_p);
232 s_assert(MyConnect(source_p));
233 s_assert(source_p->username != username);
235 if(source_p == NULL)
236 return -1;
238 if(IsAnyDead(source_p))
239 return -1;
241 if(ConfigFileEntry.ping_cookie)
243 if(!(source_p->flags & FLAGS_PINGSENT) && source_p->localClient->random_ping == 0)
245 source_p->localClient->random_ping = (unsigned long) (rand() * rand()) << 1;
246 sendto_one(source_p, "PING :%08lX",
247 (unsigned long) source_p->localClient->random_ping);
248 source_p->flags |= FLAGS_PINGSENT;
249 return -1;
251 if(!(source_p->flags2 & FLAGS2_PING_COOKIE))
253 return -1;
257 /* hasnt finished client cap negotiation */
258 if(source_p->flags2 & FLAGS2_CLICAP)
259 return -1;
261 /* still has DNSbls to validate against */
262 if(dlink_list_length(&source_p->preClient->dnsbl_queries) > 0)
263 return -1;
265 client_p->localClient->last = CurrentTime;
266 /* Straight up the maximum rate of flooding... */
267 source_p->localClient->allow_read = MAX_FLOOD_BURST;
269 /* XXX - fixme. we shouldnt have to build a users buffer twice.. */
270 if(!IsGotId(source_p) && (strchr(username, '[') != NULL))
272 const char *p;
273 int i = 0;
275 p = username;
277 while(*p && i < USERLEN)
279 if(*p != '[')
280 myusername[i++] = *p;
281 p++;
284 myusername[i] = '\0';
285 username = myusername;
288 if((status = check_client(client_p, source_p, username)) < 0)
289 return (CLIENT_EXITED);
291 /* Apply nick override */
292 if(*source_p->preClient->spoofnick)
294 del_from_client_hash(source_p->name, source_p);
295 strlcpy(source_p->name, source_p->preClient->spoofnick, NICKLEN + 1);
296 add_to_client_hash(source_p->name, source_p);
297 comm_note(source_p->localClient->fd, "Nick: %s", source_p->name);
300 if(!valid_hostname(source_p->host))
302 sendto_one(source_p,
303 ":%s NOTICE %s :*** Notice -- You have an illegal character in your hostname",
304 me.name, source_p->name);
306 strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host));
308 #ifdef IPV6
309 if(ConfigFileEntry.dot_in_ip6_addr == 1)
310 strlcat(source_p->host, ".", sizeof(source_p->host));
311 #endif
315 aconf = source_p->localClient->att_conf;
317 if(aconf == NULL)
319 exit_client(client_p, source_p, &me, "*** Not Authorised");
320 return (CLIENT_EXITED);
323 if(!IsGotId(source_p))
325 const char *p;
326 int i = 0;
328 if(IsNeedIdentd(aconf))
330 ServerStats->is_ref++;
331 sendto_one(source_p,
332 ":%s NOTICE %s :*** Notice -- You need to install identd to use this server",
333 me.name, client_p->name);
334 exit_client(client_p, source_p, &me, "Install identd");
335 return (CLIENT_EXITED);
338 /* dont replace username if its supposed to be spoofed --fl */
339 if(!IsConfDoSpoofIp(aconf) || !strchr(aconf->name, '@'))
341 p = username;
343 if(!IsNoTilde(aconf))
344 source_p->username[i++] = '~';
346 while (*p && i < USERLEN)
348 if(*p != '[')
349 source_p->username[i++] = *p;
350 p++;
353 source_p->username[i] = '\0';
357 if(IsNeedSasl(aconf) && !*user->suser)
359 ServerStats->is_ref++;
360 sendto_one(source_p,
361 ":%s NOTICE %s :*** Notice -- You need to identify via SASL to use this server",
362 me.name, client_p->name);
363 exit_client(client_p, source_p, &me, "SASL access only");
364 return (CLIENT_EXITED);
367 /* password check */
368 if(!EmptyString(aconf->passwd))
370 const char *encr;
372 if(EmptyString(source_p->localClient->passwd))
373 encr = "";
374 else if(IsConfEncrypted(aconf))
375 encr = crypt(source_p->localClient->passwd, aconf->passwd);
376 else
377 encr = source_p->localClient->passwd;
379 if(strcmp(encr, aconf->passwd))
381 ServerStats->is_ref++;
382 sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name);
383 exit_client(client_p, source_p, &me, "Bad Password");
384 return (CLIENT_EXITED);
387 /* clear password only if used now, otherwise send it
388 * to services -- jilles */
389 if(source_p->localClient->passwd)
391 memset(source_p->localClient->passwd, 0, strlen(source_p->localClient->passwd));
392 MyFree(source_p->localClient->passwd);
393 source_p->localClient->passwd = NULL;
397 /* report if user has &^>= etc. and set flags as needed in source_p */
398 report_and_set_user_flags(source_p, aconf);
400 /* Limit clients */
402 * We want to be able to have servers and F-line clients
403 * connect, so save room for "buffer" connections.
404 * Smaller servers may want to decrease this, and it should
405 * probably be just a percentage of the MAXCLIENTS...
406 * -Taner
408 /* Except "F:" clients */
409 if(((dlink_list_length(&lclient_list) + 1) >=
410 ((unsigned long)GlobalSetOptions.maxclients + MAX_BUFFER) ||
411 (dlink_list_length(&lclient_list) + 1) >=
412 ((unsigned long)GlobalSetOptions.maxclients - 5)) && !(IsExemptLimits(source_p)))
414 sendto_realops_snomask(SNO_FULL, L_NETWIDE,
415 "Too many clients, rejecting %s[%s].", source_p->name, source_p->host);
417 ServerStats->is_ref++;
418 exit_client(client_p, source_p, &me, "Sorry, server is full - try later");
419 return (CLIENT_EXITED);
422 /* valid user name check */
424 if(!valid_username(source_p->username))
426 sendto_realops_snomask(SNO_REJ, L_NETWIDE,
427 "Invalid username: %s (%s@%s)",
428 source_p->name, source_p->username, source_p->host);
429 ServerStats->is_ref++;
430 ircsprintf(tmpstr2, "Invalid username [%s]", source_p->username);
431 exit_client(client_p, source_p, &me, tmpstr2);
432 return (CLIENT_EXITED);
435 /* end of valid user name check */
437 /* kline exemption extends to xline too */
438 if(!IsExemptKline(source_p) &&
439 find_xline(source_p->info, 1) != NULL)
441 ServerStats->is_ref++;
442 add_reject(source_p);
443 exit_client(client_p, source_p, &me, "Bad user info");
444 return CLIENT_EXITED;
447 /* dnsbl check */
448 if (source_p->preClient->dnsbl_listed != NULL)
450 if (IsExemptKline(source_p) || IsConfExemptDNSBL(aconf))
451 sendto_one_notice(source_p, ":*** Your IP address %s is listed in %s, but you are exempt",
452 source_p->sockhost, source_p->preClient->dnsbl_listed->host);
453 else
455 ServerStats->is_ref++;
456 sendto_one(source_p, form_str(ERR_YOUREBANNEDCREEP),
457 me.name, source_p->name,
458 source_p->preClient->dnsbl_listed->reject_reason);
459 sendto_one_notice(source_p, ":*** Your IP address %s is listed in %s",
460 source_p->sockhost, source_p->preClient->dnsbl_listed->host);
461 source_p->preClient->dnsbl_listed->hits++;
462 add_reject(source_p);
463 exit_client(client_p, source_p, &me, "*** Banned (DNS blacklist)");
464 return CLIENT_EXITED;
468 /* Store original hostname -- jilles */
469 strlcpy(source_p->orighost, source_p->host, HOSTLEN + 1);
471 /* Spoof user@host */
472 if(*source_p->preClient->spoofuser)
473 strlcpy(source_p->username, source_p->preClient->spoofuser, USERLEN + 1);
474 if(*source_p->preClient->spoofhost)
476 strlcpy(source_p->host, source_p->preClient->spoofhost, HOSTLEN + 1);
477 if (irccmp(source_p->host, source_p->orighost))
478 SetDynSpoof(source_p);
481 if(IsAnyDead(client_p))
482 return CLIENT_EXITED;
484 inetntop_sock((struct sockaddr *)&source_p->localClient->ip, ipaddr, sizeof(ipaddr));
486 sendto_realops_snomask(SNO_CCONN, L_ALL,
487 "Client connecting: %s (%s@%s) [%s] {%s} [%s]",
488 source_p->name, source_p->username, source_p->orighost,
489 show_ip(NULL, source_p) ? ipaddr : "255.255.255.255",
490 get_client_class(source_p), source_p->info);
492 sendto_realops_snomask(SNO_CCONNEXT, L_ALL,
493 "CLICONN %s %s %s %s %s %s 0 %s",
494 source_p->name, source_p->username, source_p->orighost,
495 show_ip(NULL, source_p) ? ipaddr : "255.255.255.255",
496 get_client_class(source_p),
497 /* mirc can sometimes send ips here */
498 show_ip(NULL, source_p) ? source_p->localClient->fullcaps : "<hidden> <hidden>",
499 source_p->info);
501 /* If they have died in send_* don't do anything. */
502 if(IsAnyDead(source_p))
503 return CLIENT_EXITED;
505 add_to_hostname_hash(source_p->orighost, source_p);
507 /* Allocate a UID if it was not previously allocated.
508 * If this already occured, it was probably during SASL auth...
510 if(!*source_p->id)
512 strcpy(source_p->id, generate_uid());
513 add_to_id_hash(source_p->id, source_p);
516 source_p->umodes |= ConfigFileEntry.default_umodes & ~ConfigFileEntry.oper_only_umodes;
518 if (source_p->umodes & UMODE_INVISIBLE)
519 Count.invisi++;
521 s_assert(!IsClient(source_p));
522 dlinkMoveNode(&source_p->localClient->tnode, &unknown_list, &lclient_list);
523 SetClient(source_p);
525 /* XXX source_p->servptr is &me, since local client */
526 source_p->servptr = find_server(NULL, user->server);
527 dlinkAdd(source_p, &source_p->lnode, &source_p->servptr->serv->users);
528 /* Increment our total user count here */
529 if(++Count.total > Count.max_tot)
530 Count.max_tot = Count.total;
531 source_p->localClient->allow_read = MAX_FLOOD_BURST;
533 Count.totalrestartcount++;
535 s_assert(source_p->localClient != NULL);
537 if(dlink_list_length(&lclient_list) > (unsigned long)Count.max_loc)
539 Count.max_loc = dlink_list_length(&lclient_list);
540 if(!(Count.max_loc % 10))
541 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
542 "New Max Local Clients: %d", Count.max_loc);
545 /* they get a reduced limit */
546 if(find_tgchange(source_p->sockhost))
547 USED_TARGETS(source_p) = 6;
549 call_hook(h_new_local_user, source_p);
551 monitor_signon(source_p);
552 user_welcome(source_p);
554 free_pre_client(source_p);
556 return (introduce_client(client_p, source_p, user, source_p->name, 1));
560 * introduce_clients
562 * inputs -
563 * output -
564 * side effects - This common function introduces a client to the rest
565 * of the net, either from a local client connect or
566 * from a remote connect.
569 introduce_client(struct Client *client_p, struct Client *source_p, struct User *user, const char *nick, int use_euid)
571 static char ubuf[12];
572 struct Client *identifyservice_p;
573 char *p;
574 hook_data_umode_changed hdata;
575 hook_data_client hdata2;
577 if(MyClient(source_p))
578 send_umode(source_p, source_p, 0, 0, ubuf);
579 else
580 send_umode(NULL, source_p, 0, 0, ubuf);
582 if(!*ubuf)
584 ubuf[0] = '+';
585 ubuf[1] = '\0';
588 /* if it has an ID, introduce it with its id to TS6 servers,
589 * otherwise introduce it normally to all.
591 if(has_id(source_p))
593 char sockhost[HOSTLEN];
594 if(source_p->sockhost[0] == ':')
596 sockhost[0] = '0';
597 sockhost[1] = '\0';
598 strlcat(sockhost, source_p->sockhost, sizeof(sockhost));
599 } else
600 strcpy(sockhost, source_p->sockhost);
602 if (use_euid)
603 sendto_server(client_p, NULL, CAP_EUID | CAP_TS6, NOCAPS,
604 ":%s EUID %s %d %ld %s %s %s %s %s %s %s :%s",
605 source_p->servptr->id, nick,
606 source_p->hopcount + 1,
607 (long) source_p->tsinfo, ubuf,
608 source_p->username, source_p->host,
609 IsIPSpoof(source_p) ? "0" : sockhost,
610 source_p->id,
611 IsDynSpoof(source_p) ? source_p->orighost : "*",
612 EmptyString(source_p->user->suser) ? "*" : source_p->user->suser,
613 source_p->info);
615 sendto_server(client_p, NULL, CAP_TS6, use_euid ? CAP_EUID : NOCAPS,
616 ":%s UID %s %d %ld %s %s %s %s %s :%s",
617 source_p->servptr->id, nick,
618 source_p->hopcount + 1,
619 (long) source_p->tsinfo, ubuf,
620 source_p->username, source_p->host,
621 IsIPSpoof(source_p) ? "0" : sockhost,
622 source_p->id, source_p->info);
624 sendto_server(client_p, NULL, NOCAPS, CAP_TS6,
625 "NICK %s %d %ld %s %s %s %s :%s",
626 nick, source_p->hopcount + 1,
627 (long) source_p->tsinfo,
628 ubuf, source_p->username, source_p->host,
629 user->server, source_p->info);
631 else
632 sendto_server(client_p, NULL, NOCAPS, NOCAPS,
633 "NICK %s %d %ld %s %s %s %s :%s",
634 nick, source_p->hopcount + 1,
635 (long) source_p->tsinfo,
636 ubuf, source_p->username, source_p->host,
637 user->server, source_p->info);
639 if (IsDynSpoof(source_p))
641 sendto_server(client_p, NULL, CAP_TS6, use_euid ? CAP_EUID : NOCAPS, ":%s ENCAP * REALHOST %s",
642 use_id(source_p), source_p->orighost);
643 sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s ENCAP * REALHOST %s",
644 source_p->name, source_p->orighost);
646 if (!EmptyString(source_p->user->suser))
648 sendto_server(client_p, NULL, CAP_TS6, use_euid ? CAP_EUID : NOCAPS, ":%s ENCAP * LOGIN %s",
649 use_id(source_p), source_p->user->suser);
650 sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s ENCAP * LOGIN %s",
651 source_p->name, source_p->user->suser);
654 if(MyConnect(source_p) && source_p->localClient->passwd)
656 if (ConfigFileEntry.identifyservice[0] != '\0' &&
657 ConfigFileEntry.identifycommand[0] != '\0')
659 /* use user@server */
660 p = strchr(ConfigFileEntry.identifyservice, '@');
661 if (p != NULL)
662 identifyservice_p = find_named_client(p + 1);
663 else
664 identifyservice_p = NULL;
665 if (identifyservice_p != NULL)
666 sendto_one(identifyservice_p, ":%s PRIVMSG %s :%s %s",
667 get_id(source_p, identifyservice_p),
668 ConfigFileEntry.identifyservice,
669 ConfigFileEntry.identifycommand,
670 source_p->localClient->passwd);
672 memset(source_p->localClient->passwd, 0, strlen(source_p->localClient->passwd));
673 MyFree(source_p->localClient->passwd);
674 source_p->localClient->passwd = NULL;
677 /* let modules providing usermodes know that we've got a new user,
678 * why is this here? -- well, some modules need to be able to send out new
679 * information about a client, so this was the best place to do it
680 * --nenolod
682 hdata.client = source_p;
683 hdata.oldumodes = 0;
684 hdata.oldsnomask = 0;
685 call_hook(h_umode_changed, &hdata);
687 /* On the other hand, some modules need to know when a client is
688 * being introduced, period.
689 * --gxti
691 hdata2.client = client_p;
692 hdata2.target = source_p;
693 call_hook(h_introduce_client, &hdata2);
695 return 0;
699 * valid_hostname - check hostname for validity
701 * Inputs - pointer to user
702 * Output - YES if valid, NO if not
703 * Side effects - NONE
705 * NOTE: this doesn't allow a hostname to begin with a dot and
706 * will not allow more dots than chars.
709 valid_hostname(const char *hostname)
711 const char *p = hostname;
712 int found_sep = 0;
714 s_assert(NULL != p);
716 if(hostname == NULL)
717 return NO;
719 if('.' == *p || ':' == *p || '/' == *p)
720 return NO;
722 while (*p)
724 if(!IsHostChar(*p))
725 return NO;
726 if(*p == '.' || *p == ':' || *p == '/')
727 found_sep++;
728 p++;
731 if(found_sep == 0)
732 return(NO);
734 return (YES);
738 * valid_username - check username for validity
740 * Inputs - pointer to user
741 * Output - YES if valid, NO if not
742 * Side effects - NONE
744 * Absolutely always reject any '*' '!' '?' '@' in an user name
745 * reject any odd control characters names.
746 * Allow '.' in username to allow for "first.last"
747 * style of username
750 valid_username(const char *username)
752 int dots = 0;
753 const char *p = username;
755 s_assert(NULL != p);
757 if(username == NULL)
758 return NO;
760 if('~' == *p)
761 ++p;
763 /* reject usernames that don't start with an alphanum
764 * i.e. reject jokers who have '-@somehost' or '.@somehost'
765 * or "-hi-@somehost", "h-----@somehost" would still be accepted.
767 if(!IsAlNum(*p))
768 return NO;
770 while (*++p)
772 if((*p == '.') && ConfigFileEntry.dots_in_ident)
774 dots++;
775 if(dots > ConfigFileEntry.dots_in_ident)
776 return NO;
777 if(!IsUserChar(p[1]))
778 return NO;
780 else if(!IsUserChar(*p))
781 return NO;
783 return YES;
786 /* report_and_set_user_flags
788 * Inputs - pointer to source_p
789 * - pointer to aconf for this user
790 * Output - NONE
791 * Side effects -
792 * Report to user any special flags they are getting, and set them.
795 static void
796 report_and_set_user_flags(struct Client *source_p, struct ConfItem *aconf)
798 /* If this user is being spoofed, tell them so */
799 if(IsConfDoSpoofIp(aconf))
801 sendto_one(source_p,
802 ":%s NOTICE %s :*** Spoofing your IP. congrats.",
803 me.name, source_p->name);
806 /* If this user is in the exception class, Set it "E lined" */
807 if(IsConfExemptKline(aconf))
809 SetExemptKline(source_p);
810 sendto_one(source_p,
811 ":%s NOTICE %s :*** You are exempt from K/D/G/X lines. congrats.",
812 me.name, source_p->name);
815 if(IsConfExemptDNSBL(aconf))
816 /* kline exempt implies this, don't send both */
817 if(!IsConfExemptKline(aconf))
818 sendto_one(source_p,
819 ":%s NOTICE %s :*** You are exempt from DNS blacklists.",
820 me.name, source_p->name);
822 /* If this user is exempt from user limits set it F lined" */
823 if(IsConfExemptLimits(aconf))
825 SetExemptLimits(source_p);
826 sendto_one(source_p,
827 ":%s NOTICE %s :*** You are exempt from user limits. congrats.",
828 me.name, source_p->name);
831 /* If this user is exempt from idle time outs */
832 if(IsConfIdlelined(aconf))
834 SetIdlelined(source_p);
835 sendto_one(source_p,
836 ":%s NOTICE %s :*** You are exempt from idle limits. congrats.",
837 me.name, source_p->name);
840 if(IsConfExemptFlood(aconf))
842 SetExemptFlood(source_p);
843 sendto_one(source_p,
844 ":%s NOTICE %s :*** You are exempt from flood limits.",
845 me.name, source_p->name);
848 if(IsConfExemptSpambot(aconf))
850 SetExemptSpambot(source_p);
851 sendto_one(source_p,
852 ":%s NOTICE %s :*** You are exempt from spambot checks.",
853 me.name, source_p->name);
856 if(IsConfExemptJupe(aconf))
858 SetExemptJupe(source_p);
859 sendto_one(source_p,
860 ":%s NOTICE %s :*** You are exempt from juped channel warnings.",
861 me.name, source_p->name);
864 if(IsConfExemptResv(aconf))
866 SetExemptResv(source_p);
867 sendto_one(source_p,
868 ":%s NOTICE %s :*** You are exempt from resvs.",
869 me.name, source_p->name);
872 if(IsConfExemptShide(aconf))
874 SetExemptShide(source_p);
875 sendto_one(source_p,
876 ":%s NOTICE %s :*** You are exempt from serverhiding.",
877 me.name, source_p->name);
882 * user_mode - set get current users mode
884 * m_umode() added 15/10/91 By Darren Reed.
885 * parv[0] - sender
886 * parv[1] - username to change mode for
887 * parv[2] - modes to change
890 user_mode(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
892 int flag;
893 int i;
894 char *m;
895 const char *pm;
896 struct Client *target_p;
897 int what, setflags;
898 int badflag = NO; /* Only send one bad flag notice */
899 int showsnomask = NO;
900 unsigned int setsnomask;
901 char buf[BUFSIZE];
902 hook_data_umode_changed hdata;
904 what = MODE_ADD;
906 if(parc < 2)
908 sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "MODE");
909 return 0;
912 if((target_p = MyClient(source_p) ? find_named_person(parv[1]) : find_person(parv[1])) == NULL)
914 if(MyConnect(source_p))
915 sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
916 form_str(ERR_NOSUCHCHANNEL), parv[1]);
917 return 0;
920 /* Dont know why these were commented out..
921 * put them back using new sendto() funcs
924 if(IsServer(source_p))
926 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
927 "*** Mode for User %s from %s", parv[1], source_p->name);
928 return 0;
931 if(source_p != target_p || target_p->from != source_p->from)
933 sendto_one(source_p, form_str(ERR_USERSDONTMATCH), me.name, source_p->name);
934 return 0;
937 if(parc < 3)
939 m = buf;
940 *m++ = '+';
942 for (i = 0; i < 128; i++) /* >= 127 is extended ascii */
943 if (source_p->umodes & user_modes[i])
944 *m++ = (char) i;
946 *m = '\0';
947 sendto_one(source_p, form_str(RPL_UMODEIS), me.name, source_p->name, buf);
948 if (source_p->snomask != 0)
949 sendto_one(source_p, form_str(RPL_SNOMASK), me.name, source_p->name,
950 construct_snobuf(source_p->snomask));
951 return 0;
954 /* find flags already set for user */
955 setflags = source_p->umodes;
956 setsnomask = source_p->snomask;
959 * parse mode change string(s)
961 for (pm = parv[2]; *pm; pm++)
962 switch (*pm)
964 case '+':
965 what = MODE_ADD;
966 break;
967 case '-':
968 what = MODE_DEL;
969 break;
971 case 'o':
972 if(what == MODE_ADD)
974 if(IsServer(client_p) && !IsOper(source_p))
976 ++Count.oper;
977 SetOper(source_p);
978 dlinkAddAlloc(source_p, &oper_list);
981 else
983 /* Only decrement the oper counts if an oper to begin with
984 * found by Pat Szuta, Perly , perly@xnet.com
987 if(!IsOper(source_p))
988 break;
990 ClearOper(source_p);
992 Count.oper--;
994 if(MyConnect(source_p))
996 source_p->umodes &= ~ConfigFileEntry.oper_only_umodes;
997 if (!(source_p->umodes & UMODE_SERVNOTICE) && source_p->snomask != 0)
999 source_p->snomask = 0;
1000 showsnomask = YES;
1002 source_p->operflags = 0;
1004 MyFree(source_p->localClient->opername);
1005 source_p->localClient->opername = NULL;
1007 dlinkFindDestroy(source_p, &local_oper_list);
1010 dlinkFindDestroy(source_p, &oper_list);
1012 break;
1014 /* we may not get these,
1015 * but they shouldnt be in default
1018 /* can only be set on burst */
1019 case 'S':
1020 case ' ':
1021 case '\n':
1022 case '\r':
1023 case '\t':
1024 break;
1026 case 's':
1027 if (MyConnect(source_p))
1029 if(!IsOper(source_p)
1030 && (ConfigFileEntry.oper_only_umodes & UMODE_SERVNOTICE))
1032 if (what == MODE_ADD || source_p->umodes & UMODE_SERVNOTICE)
1033 badflag = YES;
1034 continue;
1036 showsnomask = YES;
1037 if(what == MODE_ADD)
1039 if (parc > 3)
1040 source_p->snomask = parse_snobuf_to_mask(source_p->snomask, parv[3]);
1041 else
1042 source_p->snomask |= SNO_GENERAL;
1044 else
1045 source_p->snomask = 0;
1046 if (source_p->snomask != 0)
1047 source_p->umodes |= UMODE_SERVNOTICE;
1048 else
1049 source_p->umodes &= ~UMODE_SERVNOTICE;
1050 break;
1052 /* FALLTHROUGH */
1053 default:
1054 if((flag = user_modes[(unsigned char) *pm]))
1056 if(MyConnect(source_p)
1057 && !IsOper(source_p)
1058 && (ConfigFileEntry.oper_only_umodes & flag))
1060 if (what == MODE_ADD || source_p->umodes & flag)
1061 badflag = YES;
1063 else
1065 if(what == MODE_ADD)
1066 source_p->umodes |= flag;
1067 else
1068 source_p->umodes &= ~flag;
1071 else
1073 if(MyConnect(source_p))
1074 badflag = YES;
1076 break;
1079 if(badflag)
1080 sendto_one(source_p, form_str(ERR_UMODEUNKNOWNFLAG), me.name, source_p->name);
1082 if(MyClient(source_p) && (source_p->umodes & UMODE_OPERWALL) && !IsOperOperwall(source_p))
1084 if(IsOper(source_p))
1085 sendto_one(source_p,
1086 ":%s NOTICE %s :*** You need the operwall flag for +z", me.name, parv[0]);
1087 else
1088 sendto_one(source_p, form_str(ERR_UMODEUNKNOWNFLAG), me.name, source_p->name);
1089 source_p->umodes &= ~UMODE_OPERWALL;
1092 if(MyConnect(source_p) && (source_p->umodes & UMODE_ADMIN) &&
1093 (!IsOperAdmin(source_p) || IsOperHiddenAdmin(source_p)))
1095 if(IsOper(source_p))
1096 sendto_one(source_p,
1097 ":%s NOTICE %s :*** You need the A flag for +a", me.name, parv[0]);
1098 else
1099 sendto_one(source_p, form_str(ERR_UMODEUNKNOWNFLAG), me.name, source_p->name);
1100 source_p->umodes &= ~UMODE_ADMIN;
1103 if(MyClient(source_p) && (source_p->umodes & UMODE_HELPER) && !IsOperHelper(source_p))
1105 if(IsOper(source_p))
1106 sendto_one(source_p,
1107 ":%s NOTICE %s :*** You need the helper flag for +T", me.name, parv[0]);
1108 else
1109 sendto_one(source_p, form_str(ERR_UMODEUNKNOWNFLAG), me.name, source_p->name);
1111 source_p->umodes &= ~UMODE_HELPER;
1114 if(MyClient(source_p) && (source_p->umodes & UMODE_OVERRIDE) && !IsOperOverride(source_p))
1116 if(IsOper(source_p))
1117 sendto_one(source_p,
1118 ":%s NOTICE %s :*** You need the override flag for +p", me.name, parv[0]);
1119 else
1120 sendto_one(source_p, form_str(ERR_UMODEUNKNOWNFLAG), me.name, source_p->name);
1122 source_p->umodes &= ~UMODE_OVERRIDE;
1125 if(MyClient(source_p) &&
1126 ((source_p->snomask & source_p->allowed_snomask) != source_p->snomask))
1128 sendto_one(source_p,
1129 ":%s NOTICE %s :*** Server notices not granted: %s",
1130 me.name, source_p->name,
1131 construct_snobuf(source_p->snomask & ~source_p->allowed_snomask));
1132 source_p->snomask &= source_p->allowed_snomask;
1135 /* let modules providing usermodes know that we've changed our usermode --nenolod */
1136 hdata.client = source_p;
1137 hdata.oldumodes = setflags;
1138 hdata.oldsnomask = setsnomask;
1139 call_hook(h_umode_changed, &hdata);
1141 if(!(setflags & UMODE_INVISIBLE) && IsInvisible(source_p))
1142 ++Count.invisi;
1143 if((setflags & UMODE_INVISIBLE) && !IsInvisible(source_p))
1144 --Count.invisi;
1146 * compare new flags with old flags and send string which
1147 * will cause servers to update correctly.
1149 send_umode_out(client_p, source_p, setflags);
1150 if (showsnomask && MyConnect(source_p))
1151 sendto_one(source_p, form_str(RPL_SNOMASK), me.name, source_p->name,
1152 construct_snobuf(source_p->snomask));
1154 return (0);
1158 * send the MODE string for user (user) to connection client_p
1159 * -avalon
1161 void
1162 send_umode(struct Client *client_p, struct Client *source_p, int old, int sendmask, char *umode_buf)
1164 int i;
1165 int flag;
1166 char *m;
1167 int what = 0;
1170 * build a string in umode_buf to represent the change in the user's
1171 * mode between the new (source_p->flag) and 'old'.
1173 m = umode_buf;
1174 *m = '\0';
1176 for (i = 0; i < 128; i++)
1178 flag = user_modes[i];
1180 if((flag & old) && !(source_p->umodes & flag))
1182 if(what == MODE_DEL)
1183 *m++ = (char) i;
1184 else
1186 what = MODE_DEL;
1187 *m++ = '-';
1188 *m++ = (char) i;
1191 else if(!(flag & old) && (source_p->umodes & flag))
1193 if(what == MODE_ADD)
1194 *m++ = (char) i;
1195 else
1197 what = MODE_ADD;
1198 *m++ = '+';
1199 *m++ = (char) i;
1203 *m = '\0';
1205 if(*umode_buf && client_p)
1206 sendto_one(client_p, ":%s MODE %s :%s", source_p->name, source_p->name, umode_buf);
1210 * send_umode_out
1212 * inputs -
1213 * output - NONE
1214 * side effects -
1216 void
1217 send_umode_out(struct Client *client_p, struct Client *source_p, int old)
1219 struct Client *target_p;
1220 char buf[BUFSIZE];
1221 dlink_node *ptr;
1223 send_umode(NULL, source_p, old, 0, buf);
1225 DLINK_FOREACH(ptr, serv_list.head)
1227 target_p = ptr->data;
1229 if((target_p != client_p) && (target_p != source_p) && (*buf))
1231 sendto_one(target_p, ":%s MODE %s :%s",
1232 get_id(source_p, target_p),
1233 get_id(source_p, target_p), buf);
1237 if(client_p && MyClient(client_p))
1238 send_umode(client_p, source_p, old, 0, buf);
1242 * user_welcome
1244 * inputs - client pointer to client to welcome
1245 * output - NONE
1246 * side effects -
1248 void
1249 user_welcome(struct Client *source_p)
1251 sendto_one(source_p, form_str(RPL_WELCOME), me.name, source_p->name,
1252 ServerInfo.network_name, source_p->name);
1253 sendto_one(source_p, form_str(RPL_YOURHOST), me.name,
1254 source_p->name,
1255 get_listener_name(source_p->localClient->listener), ircd_version);
1257 sendto_one(source_p, form_str(RPL_CREATED), me.name, source_p->name, creation);
1258 sendto_one(source_p, form_str(RPL_MYINFO), me.name, source_p->name, me.name, ircd_version, umodebuf);
1260 show_isupport(source_p);
1262 show_lusers(source_p);
1264 if(ConfigFileEntry.short_motd)
1266 sendto_one(source_p,
1267 "NOTICE %s :*** Notice -- motd was last changed at %s",
1268 source_p->name, user_motd_changed);
1270 sendto_one(source_p,
1271 "NOTICE %s :*** Notice -- Please read the motd if you haven't read it",
1272 source_p->name);
1274 sendto_one(source_p, form_str(RPL_MOTDSTART),
1275 me.name, source_p->name, me.name);
1277 sendto_one(source_p, form_str(RPL_MOTD),
1278 me.name, source_p->name, "*** This is the short motd ***");
1280 sendto_one(source_p, form_str(RPL_ENDOFMOTD), me.name, source_p->name);
1282 else
1283 send_user_motd(source_p);
1286 /* oper_up()
1288 * inputs - pointer to given client to oper
1289 * - pointer to ConfItem to use
1290 * output - none
1291 * side effects - opers up source_p using aconf for reference
1294 oper_up(struct Client *source_p, struct oper_conf *oper_p)
1296 unsigned int old = source_p->umodes, oldsnomask = source_p->snomask;
1297 hook_data_umode_changed hdata;
1299 SetOper(source_p);
1301 if(oper_p->umodes)
1302 source_p->umodes |= oper_p->umodes;
1303 else if(ConfigFileEntry.oper_umodes)
1304 source_p->umodes |= ConfigFileEntry.oper_umodes;
1305 else
1306 source_p->umodes |= DEFAULT_OPER_UMODES;
1308 if (oper_p->snomask)
1310 source_p->snomask |= oper_p->snomask & oper_p->allowed_snomask;
1311 source_p->umodes |= UMODE_SERVNOTICE;
1313 else if (source_p->umodes & UMODE_SERVNOTICE)
1315 /* Only apply these if +s is already set -- jilles */
1316 if (ConfigFileEntry.oper_snomask)
1317 source_p->snomask |= ConfigFileEntry.oper_snomask;
1318 else
1319 source_p->snomask |= DEFAULT_OPER_SNOMASK;
1322 Count.oper++;
1324 SetExemptKline(source_p);
1326 source_p->allowed_snomask = oper_p->allowed_snomask;
1327 source_p->operflags = oper_p->flags;
1328 DupString(source_p->localClient->opername, oper_p->name);
1330 dlinkAddAlloc(source_p, &local_oper_list);
1331 dlinkAddAlloc(source_p, &oper_list);
1333 if(IsOperAdmin(source_p) && !IsOperHiddenAdmin(source_p))
1334 source_p->umodes |= UMODE_ADMIN;
1335 if(!IsOperOperwall(source_p))
1336 source_p->umodes &= ~UMODE_OPERWALL;
1337 hdata.client = source_p;
1338 hdata.oldumodes = old;
1339 hdata.oldsnomask = oldsnomask;
1340 call_hook(h_umode_changed, &hdata);
1342 sendto_realops_snomask(SNO_GENERAL, L_ALL,
1343 "%s (%s@%s) is now an operator", source_p->name,
1344 source_p->username, source_p->host);
1345 send_umode_out(source_p, source_p, old);
1346 sendto_one(source_p, form_str(RPL_SNOMASK), me.name, source_p->name,
1347 construct_snobuf(source_p->snomask));
1348 sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, source_p->name);
1349 sendto_one(source_p, ":%s NOTICE %s :*** Oper privs are %s", me.name,
1350 source_p->name, get_oper_privs(oper_p->flags));
1351 sendto_one(source_p, ":%s NOTICE %s :*** Allowed snomasks are %s", me.name,
1352 source_p->name, construct_snobuf(source_p->allowed_snomask));
1353 send_oper_motd(source_p);
1355 sendto_server(source_p, NULL, CAP_TS6, NOCAPS, ":%s ENCAP * OPER %s",
1356 use_id(source_p), get_oper_privs(oper_p->flags));
1358 sendto_server(source_p, NULL, NOCAPS, CAP_TS6, ":%s ENCAP * OPER %s",
1359 source_p->name, get_oper_privs(oper_p->flags));
1361 return (1);
1364 void
1365 construct_umodebuf(void)
1367 int i;
1368 char *ptr = umodebuf;
1370 *ptr = '\0';
1372 for (i = 0; i < 128; i++)
1373 if (user_modes[i])
1374 *ptr++ = (char) i;
1376 *ptr++ = '\0';
1379 void
1380 change_nick_user_host(struct Client *target_p, const char *nick, const char *user,
1381 const char *host, int newts, char *format, ...)
1383 dlink_node *ptr;
1384 struct Channel *chptr;
1385 struct membership *mscptr;
1386 int changed = irccmp(target_p->name, nick);
1387 int changed_case = strcmp(target_p->name, nick);
1388 int do_qjm = irccmp(target_p->username, user) || irccmp(target_p->host, host);
1389 char mode[10], modeval[NICKLEN * 2 + 2], reason[256], *mptr;
1390 va_list ap;
1392 modeval[0] = '\0';
1394 if(changed)
1396 target_p->tsinfo = newts;
1397 monitor_signoff(target_p);
1399 invalidate_bancache_user(target_p);
1401 if(do_qjm)
1403 va_start(ap, format);
1404 vsnprintf(reason, 255, format, ap);
1405 va_end(ap);
1407 sendto_common_channels_local_butone(target_p, ":%s!%s@%s QUIT :%s",
1408 target_p->name, target_p->username, target_p->host,
1409 reason);
1411 DLINK_FOREACH(ptr, target_p->user->channel.head)
1413 mscptr = ptr->data;
1414 chptr = mscptr->chptr;
1415 mptr = mode;
1417 if(is_real_chanop(mscptr))
1419 *mptr++ = 'o';
1420 strcat(modeval, nick);
1421 strcat(modeval, " ");
1424 if(is_voiced(mscptr))
1426 *mptr++ = 'v';
1427 strcat(modeval, nick);
1430 *mptr = '\0';
1432 sendto_channel_local_butone(target_p, ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
1433 nick, user, host, chptr->chname);
1434 if(*mode)
1435 sendto_channel_local_butone(target_p, ALL_MEMBERS, chptr,
1436 ":%s MODE %s +%s %s",
1437 target_p->servptr->name,
1438 chptr->chname, mode, modeval);
1440 *modeval = '\0';
1443 if(MyClient(target_p) && changed_case)
1444 sendto_one(target_p, ":%s!%s@%s NICK %s",
1445 target_p->name, target_p->username, target_p->host, nick);
1447 else if(changed_case)
1449 sendto_common_channels_local(target_p, ":%s!%s@%s NICK :%s",
1450 target_p->name, target_p->username,
1451 target_p->host, nick);
1454 strlcpy(target_p->username, user, USERLEN);
1455 strlcpy(target_p->host, host, HOSTLEN);
1457 if (changed)
1458 add_history(target_p, 1);
1460 del_from_client_hash(target_p->name, target_p);
1461 strlcpy(target_p->name, nick, NICKLEN);
1462 add_to_client_hash(target_p->name, target_p);
1464 if(changed)
1466 monitor_signon(target_p);
1467 del_all_accepts(target_p);