ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/core/m_nick.c
Revision: 2686
Committed: Mon Dec 16 17:37:20 2013 UTC (12 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 30072 byte(s)
Log Message:
- m_nick.c, m_join.c: Tweaked channel/nickname rejection notices

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_nick.c: Sets a users nick.
4     *
5     * Copyright (C) 2002 by the past and present ircd coders, and others.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22 knight 31 * $Id$
23 adx 30 */
24    
25     #include "stdinc.h"
26 michael 1011 #include "list.h"
27 adx 30 #include "client.h"
28     #include "hash.h"
29     #include "fdlist.h"
30     #include "irc_string.h"
31     #include "ircd.h"
32     #include "numeric.h"
33 michael 1309 #include "conf.h"
34 adx 30 #include "s_user.h"
35     #include "whowas.h"
36     #include "s_serv.h"
37     #include "send.h"
38     #include "channel.h"
39 michael 1192 #include "channel_mode.h"
40 michael 1309 #include "log.h"
41 adx 30 #include "resv.h"
42     #include "parse.h"
43     #include "modules.h"
44     #include "packet.h"
45 michael 876 #include "watch.h"
46 michael 1751 #include "s_misc.h"
47 adx 30
48    
49 michael 1997 /* check_clean_nick()
50     *
51     * input - pointer to source
52     * -
53     * - nickname
54     * - truncated nickname
55     * - origin of client
56     * - pointer to server nick is coming from
57     * output - none
58     * side effects - if nickname is erroneous, or a different length to
59     * truncated nickname, return 1
60     */
61     static int
62     check_clean_nick(struct Client *client_p, struct Client *source_p,
63     char *nick, struct Client *server_p)
64     {
65     /* the old code did some wacky stuff here, if the nick is invalid, kill it
66     * and dont bother messing at all
67     */
68     if (!valid_nickname(nick, 0))
69     {
70     ++ServerStats.is_kill;
71     sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
72     "Bad/long Nick: %s From: %s(via %s)",
73     nick, server_p->name, client_p->name);
74    
75     sendto_one(client_p, ":%s KILL %s :%s (Bad Nickname)",
76     me.name, nick, me.name);
77    
78     /* bad nick change */
79     if (source_p != client_p)
80     {
81 michael 2565 kill_client_serv_butone(client_p, source_p,
82     "%s (Bad Nickname)",
83     me.name);
84 michael 1997 AddFlag(source_p, FLAGS_KILLED);
85     exit_client(source_p, &me, "Bad Nickname");
86     }
87    
88     return 1;
89     }
90    
91     return 0;
92     }
93    
94     /* check_clean_user()
95     *
96     * input - pointer to client sending data
97     * - nickname
98     * - username to check
99     * - origin of NICK
100     * output - none
101     * side effects - if username is erroneous, return 1
102     */
103     static int
104     check_clean_user(struct Client *client_p, char *nick,
105     char *user, struct Client *server_p)
106     {
107 michael 2070 if (!valid_username(user, 0))
108 michael 1997 {
109     ++ServerStats.is_kill;
110     sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
111     "Bad/Long Username: %s Nickname: %s From: %s(via %s)",
112     user, nick, server_p->name, client_p->name);
113     sendto_one(client_p, ":%s KILL %s :%s (Bad Username)",
114     me.name, nick, me.name);
115     return 1;
116     }
117    
118     return 0;
119     }
120    
121     /* check_clean_host()
122     *
123     * input - pointer to client sending us data
124     * - nickname
125     * - hostname to check
126     * - source name
127     * output - none
128     * side effects - if hostname is erroneous, return 1
129     */
130     static int
131     check_clean_host(struct Client *client_p, char *nick,
132     char *host, struct Client *server_p)
133     {
134     if (!valid_hostname(host))
135     {
136     ++ServerStats.is_kill;
137     sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
138     "Bad/Long Hostname: %s Nickname: %s From: %s(via %s)",
139     host, nick, server_p->name, client_p->name);
140     sendto_one(client_p, ":%s KILL %s :%s (Bad Hostname)",
141     me.name, nick, me.name);
142     return 1;
143     }
144    
145     return 0;
146     }
147    
148 michael 1002 /* set_initial_nick()
149     *
150     * inputs
151     * output
152     * side effects -
153     *
154     * This function is only called to set up an initially registering
155     * client.
156     */
157     static void
158 michael 1003 set_initial_nick(struct Client *source_p, const char *nick)
159 michael 1002 {
160     /* Client setting NICK the first time */
161    
162     /* This had to be copied here to avoid problems.. */
163     source_p->tsinfo = CurrentTime;
164     source_p->localClient->registration &= ~REG_NEED_NICK;
165    
166     if (source_p->name[0])
167     hash_del_client(source_p);
168    
169     strlcpy(source_p->name, nick, sizeof(source_p->name));
170     hash_add_client(source_p);
171    
172     /* fd_desc is long enough */
173 michael 1003 fd_note(&source_p->localClient->fd, "Nick: %s", nick);
174 michael 1002
175     if (!source_p->localClient->registration)
176 michael 1080 register_local_user(source_p);
177 michael 1002 }
178    
179 michael 1192 /* change_local_nick()
180     *
181     * inputs - pointer to server
182     * - pointer to client
183     * - nick
184     * output -
185     * side effects - changes nick of a LOCAL user
186     */
187     static void
188 michael 1193 change_local_nick(struct Client *source_p, const char *nick)
189 michael 1192 {
190 michael 2368 int samenick = 0;
191    
192 michael 1192 assert(source_p->name[0] && !EmptyString(nick));
193 michael 1193 assert(MyConnect(source_p));
194 michael 1192
195     /*
196     * Client just changing his/her nick. If he/she is
197     * on a channel, send note of change to all clients
198     * on that channel. Propagate notice to other servers.
199     */
200     if ((source_p->localClient->last_nick_change +
201     ConfigFileEntry.max_nick_time) < CurrentTime)
202     source_p->localClient->number_of_nick_changes = 0;
203 michael 2368
204     if (ConfigFileEntry.anti_nick_flood &&
205     !HasUMode(source_p, UMODE_OPER) &&
206     source_p->localClient->number_of_nick_changes >
207     ConfigFileEntry.max_nick_changes)
208     {
209     sendto_one(source_p, form_str(ERR_NICKTOOFAST), me.name,
210     source_p->name, source_p->name, nick,
211     ConfigFileEntry.max_nick_time);
212     return;
213     }
214    
215 michael 1192 source_p->localClient->last_nick_change = CurrentTime;
216     source_p->localClient->number_of_nick_changes++;
217    
218 michael 2368 samenick = !irccmp(source_p->name, nick);
219    
220     if (!samenick)
221 michael 1192 {
222 michael 2368 source_p->tsinfo = CurrentTime;
223     clear_ban_cache_client(source_p);
224     watch_check_hash(source_p, RPL_LOGOFF);
225 michael 1192
226 michael 2368 if (HasUMode(source_p, UMODE_REGISTERED))
227 michael 1192 {
228 michael 2368 unsigned int oldmodes = source_p->umodes;
229     char modebuf[IRCD_BUFSIZE] = { '\0' };
230 michael 1192
231 michael 2368 DelUMode(source_p, UMODE_REGISTERED);
232     send_umode(source_p, source_p, oldmodes, 0xffffffff, modebuf);
233 michael 1192 }
234 michael 2368 }
235 michael 1192
236 michael 2368 sendto_realops_flags(UMODE_NCHANGE, L_ALL, SEND_NOTICE,
237     "Nick change: From %s to %s [%s@%s]",
238     source_p->name, nick, source_p->username, source_p->host);
239     sendto_common_channels_local(source_p, 1, 0, ":%s!%s@%s NICK :%s",
240     source_p->name, source_p->username,
241     source_p->host, nick);
242     whowas_add_history(source_p, 1);
243 michael 1192
244 michael 2368 sendto_server(source_p, CAP_TS6, NOCAPS,
245     ":%s NICK %s :%lu",
246     ID(source_p), nick, (unsigned long)source_p->tsinfo);
247     sendto_server(source_p, NOCAPS, CAP_TS6,
248     ":%s NICK %s :%lu",
249     source_p->name, nick, (unsigned long)source_p->tsinfo);
250 michael 1192
251 michael 2368 hash_del_client(source_p);
252     strlcpy(source_p->name, nick, sizeof(source_p->name));
253     hash_add_client(source_p);
254 michael 1192
255 michael 2368 if (!samenick)
256     watch_check_hash(source_p, RPL_LOGON);
257 michael 1192
258 michael 2368 /* fd_desc is long enough */
259     fd_note(&source_p->localClient->fd, "Nick: %s", nick);
260 michael 1192 }
261    
262 michael 1997 /*
263     * nick_from_server()
264     */
265     static void
266     nick_from_server(struct Client *client_p, struct Client *source_p, int parc,
267     char *parv[], time_t newts, const char *svsid, char *nick, char *ngecos)
268     {
269     int samenick = 0;
270    
271     if (IsServer(source_p))
272     {
273     /* A server introducing a new client, change source */
274     source_p = make_client(client_p);
275     dlinkAdd(source_p, &source_p->node, &global_client_list);
276    
277     if (parc > 2)
278     source_p->hopcount = atoi(parv[2]);
279     if (newts)
280     source_p->tsinfo = newts;
281     else
282     {
283     newts = source_p->tsinfo = CurrentTime;
284     ts_warn("Remote nick %s (%s) introduced without a TS", nick, parv[0]);
285     }
286    
287     strlcpy(source_p->svid, svsid, sizeof(source_p->svid));
288     strlcpy(source_p->info, ngecos, sizeof(source_p->info));
289     /* copy the nick in place */
290     strlcpy(source_p->name, nick, sizeof(source_p->name));
291     hash_add_client(source_p);
292    
293     if (parc > 8)
294     {
295     const char *m;
296    
297     /* parse usermodes */
298     for (m = &parv[4][1]; *m; ++m)
299     {
300     unsigned int flag = user_modes[(unsigned char)*m];
301    
302     if ((flag & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE))
303     ++Count.invisi;
304     if ((flag & UMODE_OPER) && !HasUMode(source_p, UMODE_OPER))
305     ++Count.oper;
306    
307     source_p->umodes |= flag & SEND_UMODES;
308     }
309    
310     register_remote_user(source_p, parv[5], parv[6],
311     parv[7], ngecos);
312     return;
313     }
314     }
315     else if (source_p->name[0])
316     {
317     samenick = !irccmp(source_p->name, nick);
318    
319 michael 2004 /* Client changing their nick */
320 michael 1997 if (!samenick)
321     {
322     DelUMode(source_p, UMODE_REGISTERED);
323     watch_check_hash(source_p, RPL_LOGOFF);
324     source_p->tsinfo = newts ? newts : CurrentTime;
325     }
326    
327     sendto_common_channels_local(source_p, 1, 0, ":%s!%s@%s NICK :%s",
328     source_p->name,source_p->username,
329     source_p->host, nick);
330    
331 michael 2300 whowas_add_history(source_p, 1);
332 michael 1997 sendto_server(client_p, CAP_TS6, NOCAPS,
333     ":%s NICK %s :%lu",
334     ID(source_p), nick, (unsigned long)source_p->tsinfo);
335     sendto_server(client_p, NOCAPS, CAP_TS6,
336     ":%s NICK %s :%lu",
337     source_p->name, nick, (unsigned long)source_p->tsinfo);
338     }
339    
340     /* set the new nick name */
341     if (source_p->name[0])
342     hash_del_client(source_p);
343    
344     strlcpy(source_p->name, nick, sizeof(source_p->name));
345     hash_add_client(source_p);
346    
347     if (!samenick)
348     watch_check_hash(source_p, RPL_LOGON);
349     }
350    
351     /*
352     * client_from_server()
353     */
354     static void
355     uid_from_server(struct Client *client_p, struct Client *source_p, int parc,
356     char *parv[], time_t newts, const char *svsid, char *nick, char *ugecos)
357     {
358     const char *m = NULL;
359     const char *servername = source_p->name;
360    
361     source_p = make_client(client_p);
362     dlinkAdd(source_p, &source_p->node, &global_client_list);
363    
364     source_p->hopcount = atoi(parv[2]);
365     source_p->tsinfo = newts;
366     strlcpy(source_p->svid, svsid, sizeof(source_p->svid));
367    
368     /* copy the nick in place */
369 michael 2046 strlcpy(source_p->name, nick, sizeof(source_p->name));
370 michael 1997 strlcpy(source_p->id, parv[8], sizeof(source_p->id));
371     strlcpy(source_p->sockhost, parv[7], sizeof(source_p->sockhost));
372     strlcpy(source_p->info, ugecos, sizeof(source_p->info));
373    
374     hash_add_client(source_p);
375     hash_add_id(source_p);
376    
377     /* parse usermodes */
378     for (m = &parv[4][1]; *m; ++m)
379     {
380     unsigned int flag = user_modes[(unsigned char)*m];
381    
382     if ((flag & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE))
383     ++Count.invisi;
384     if ((flag & UMODE_OPER) && !HasUMode(source_p, UMODE_OPER))
385     ++Count.oper;
386    
387     source_p->umodes |= flag & SEND_UMODES;
388     }
389    
390     register_remote_user(source_p, parv[5], parv[6],
391     servername, ugecos);
392     }
393    
394     static void
395     perform_nick_collides(struct Client *source_p, struct Client *client_p,
396     struct Client *target_p, int parc, char *parv[],
397     time_t newts, const char *svsid, char *nick, char *gecos, char *uid)
398     {
399 michael 2004 int sameuser = 0;
400 michael 1997
401 michael 2004 /* Server introducing new nick */
402 michael 1997 if (IsServer(source_p))
403     {
404 michael 2004 /* If we don't have a TS, or their TS's are the same, kill both */
405 michael 1997 if (!newts || !target_p->tsinfo || (newts == target_p->tsinfo))
406     {
407     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
408     "Nick collision on %s(%s <- %s)(both killed)",
409 michael 2004 target_p->name, target_p->from->name,
410     client_p->name);
411 michael 1997
412     /* if we have a UID, issue a kill for it */
413     if (uid)
414     sendto_one(client_p, ":%s KILL %s :%s (Nick collision (new))",
415     me.id, uid, me.name);
416    
417 michael 2565 kill_client_serv_butone(NULL, target_p,
418     "%s (Nick collision (new))", me.name);
419 michael 1997 ++ServerStats.is_kill;
420     sendto_one(target_p, form_str(ERR_NICKCOLLISION),
421     me.name, target_p->name, target_p->name);
422    
423     AddFlag(target_p, FLAGS_KILLED);
424     exit_client(target_p, &me, "Nick collision (new)");
425     return;
426     }
427     /* the timestamps are different */
428     else
429     {
430     sameuser = !irccmp(target_p->username, parv[5]) &&
431     !irccmp(target_p->host, parv[6]);
432    
433 michael 2004 /*
434     * If the users are the same (loaded a client on a different server)
435 michael 1997 * and the new users ts is older, or the users are different and the
436     * new users ts is newer, ignore the new client and let it do the kill
437     */
438     if ((sameuser && newts < target_p->tsinfo) ||
439     (!sameuser && newts > target_p->tsinfo))
440     {
441     if (uid)
442     sendto_one(client_p, ":%s KILL %s :%s (Nick collision (new))",
443     me.id, uid, me.name);
444 michael 2004 return;
445 michael 1997 }
446     else
447     {
448     if (sameuser)
449 michael 2004 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
450     "Nick collision on %s(%s <- %s)(older killed)",
451     target_p->name, target_p->from->name,
452     client_p->name);
453 michael 1997 else
454 michael 2004 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
455     "Nick collision on %s(%s <- %s)(newer killed)",
456     target_p->name, target_p->from->name,
457     client_p->name);
458 michael 1997
459     ++ServerStats.is_kill;
460 michael 2004 sendto_one(target_p, form_str(ERR_NICKCOLLISION),
461     me.name, target_p->name, target_p->name);
462 michael 1997
463     /* if it came from a LL server, itd have been source_p,
464 michael 2004 * so we dont need to mark target_p as known
465     */
466 michael 2565 kill_client_serv_butone(source_p, target_p,
467     "%s (Nick collision (new))", me.name);
468 michael 1997
469     AddFlag(target_p, FLAGS_KILLED);
470 michael 2004 exit_client(target_p, &me, "Nick collision");
471    
472     if (!uid && (parc == 9 || parc == 10))
473     nick_from_server(client_p, source_p, parc, parv, newts, svsid, nick, gecos);
474     else if (uid && (parc == 10 || parc == 11))
475     uid_from_server(client_p, source_p, parc, parv, newts, svsid, nick, gecos);
476     return;
477 michael 1997 }
478     }
479     }
480    
481     /* its a client changing nick and causing a collide */
482     if (!newts || !target_p->tsinfo || (newts == target_p->tsinfo))
483     {
484     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
485     "Nick change collision from %s to %s(%s <- %s)(both killed)",
486 michael 2004 source_p->name, target_p->name, target_p->from->name,
487     client_p->name);
488 michael 1997
489     sendto_one(target_p, form_str(ERR_NICKCOLLISION), me.name,
490     target_p->name, target_p->name);
491    
492     ++ServerStats.is_kill;
493 michael 2565 kill_client_serv_butone(NULL, source_p, "%s (Nick change collision)",
494     me.name);
495 michael 1997
496     ++ServerStats.is_kill;
497 michael 2565 kill_client_serv_butone(NULL, target_p, "%s (Nick change collision)",
498     me.name);
499 michael 1997
500     AddFlag(target_p, FLAGS_KILLED);
501     exit_client(target_p, &me, "Nick collision (new)");
502    
503     AddFlag(source_p, FLAGS_KILLED);
504     exit_client(source_p, &me, "Nick collision (old)");
505     return;
506 michael 2004 }
507     else
508     {
509     sameuser = !irccmp(target_p->username, source_p->username) &&
510     !irccmp(target_p->host, source_p->host);
511    
512     if ((sameuser && newts < target_p->tsinfo) ||
513     (!sameuser && newts > target_p->tsinfo))
514     {
515     if (sameuser)
516     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
517     "Nick change collision from %s to %s(%s <- %s)(older killed)",
518     source_p->name, target_p->name, target_p->from->name,
519     client_p->name);
520     else
521     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
522     "Nick change collision from %s to %s(%s <- %s)(newer killed)",
523     source_p->name, target_p->name, target_p->from->name,
524     client_p->name);
525    
526     ++ServerStats.is_kill;
527 michael 2565 kill_client_serv_butone(client_p, source_p,
528     "%s (Nick change collision)", me.name);
529 michael 2004 AddFlag(source_p, FLAGS_KILLED);
530    
531     if (sameuser)
532     exit_client(source_p, &me, "Nick collision (old)");
533     else
534     exit_client(source_p, &me, "Nick collision (new)");
535     return;
536 michael 1997 }
537     else
538     {
539 michael 2004 if (sameuser)
540     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
541     "Nick collision on %s(%s <- %s)(older killed)",
542     target_p->name, target_p->from->name,
543     client_p->name);
544     else
545     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
546     "Nick collision on %s(%s <- %s)(newer killed)",
547     target_p->name, target_p->from->name,
548     client_p->name);
549 michael 1997
550 michael 2565 kill_client_serv_butone(source_p, target_p,
551     "%s (Nick collision)", me.name);
552 michael 1997
553 michael 2004 ++ServerStats.is_kill;
554     sendto_one(target_p, form_str(ERR_NICKCOLLISION),
555     me.name, target_p->name, target_p->name);
556 michael 1997
557 michael 2004 AddFlag(target_p, FLAGS_KILLED);
558     exit_client(target_p, &me, "Nick collision");
559     }
560     }
561 michael 1997
562 michael 2004 /*
563     * we should only ever call nick_from_server() here, as
564 michael 1997 * this is a client changing nick, not a new client
565     */
566     nick_from_server(client_p, source_p, parc, parv, newts, svsid, nick, gecos);
567     }
568    
569 michael 981 /*! \brief NICK command handler (called by unregistered,
570     * locally connected clients)
571 adx 30 *
572 michael 981 * \param client_p Pointer to allocated Client struct with physical connection
573     * to this server, i.e. with an open socket connected.
574     * \param source_p Pointer to allocated Client struct from which the message
575     * originally comes from. This can be a local or remote client.
576     * \param parc Integer holding the number of supplied arguments.
577     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
578     * pointers.
579     * \note Valid arguments for this command are:
580     * - parv[0] = sender prefix
581     * - parv[1] = nickname
582 adx 30 */
583     static void
584     mr_nick(struct Client *client_p, struct Client *source_p,
585     int parc, char *parv[])
586     {
587 michael 2004 char nick[NICKLEN + 1] = { '\0' };
588 michael 885 struct Client *target_p = NULL;
589 michael 1687 struct MaskItem *conf = NULL;
590 michael 885
591 adx 30 if (parc < 2 || EmptyString(parv[1]))
592     {
593 michael 1834 sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name,
594 michael 1234 source_p->name[0] ? source_p->name : "*");
595 adx 30 return;
596     }
597    
598 michael 2004 /* Copy the nick and terminate it */
599 michael 1751 strlcpy(nick, parv[1], IRCD_MIN(sizeof(nick), ServerInfo.max_nick_length + 1));
600 adx 30
601 michael 2004 /* Check the nickname is ok */
602 michael 1165 if (!valid_nickname(nick, 1))
603 adx 30 {
604 michael 1834 sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name,
605 michael 1838 source_p->name[0] ? source_p->name : "*", parv[1],
606     "Erroneous Nickname");
607 adx 30 return;
608     }
609    
610 michael 2004 /* Check if the nick is resv'd */
611 michael 1688 if ((conf = find_matching_name_conf(CONF_NRESV, nick, NULL, NULL, 0)))
612 adx 30 {
613 michael 1687 ++conf->count;
614 michael 1834 sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name,
615 michael 1838 source_p->name[0] ? source_p->name : "*", nick, conf->reason);
616 michael 1698 sendto_realops_flags(UMODE_REJ, L_ALL, SEND_NOTICE,
617 michael 2686 "Forbidding reserved nick %s from user %s",
618 michael 1442 nick, get_client_name(client_p, HIDE_IP));
619 adx 30 return;
620     }
621    
622 michael 1169 if ((target_p = hash_find_client(nick)) == NULL)
623 michael 1003 set_initial_nick(source_p, nick);
624 adx 30 else if (source_p == target_p)
625 michael 1080 strlcpy(source_p->name, nick, sizeof(source_p->name));
626 adx 30 else
627 michael 1834 sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, "*", nick);
628 adx 30 }
629    
630 michael 981 /*! \brief NICK command handler (called by already registered,
631     * locally connected clients)
632 adx 30 *
633 michael 981 * \param client_p Pointer to allocated Client struct with physical connection
634     * to this server, i.e. with an open socket connected.
635     * \param source_p Pointer to allocated Client struct from which the message
636     * originally comes from. This can be a local or remote client.
637     * \param parc Integer holding the number of supplied arguments.
638     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
639     * pointers.
640     * \note Valid arguments for this command are:
641     * - parv[0] = sender prefix
642     * - parv[1] = nickname
643 adx 30 */
644     static void
645     m_nick(struct Client *client_p, struct Client *source_p,
646     int parc, char *parv[])
647     {
648 michael 2004 char nick[NICKLEN + 1] = { '\0' };
649 michael 885 struct Client *target_p = NULL;
650 michael 1687 struct MaskItem *conf = NULL;
651 adx 30
652 michael 1193 assert(source_p == client_p);
653    
654 adx 30 if (parc < 2 || EmptyString(parv[1]))
655     {
656 michael 1834 sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN),
657 michael 981 me.name, source_p->name);
658 adx 30 return;
659     }
660    
661     /* mark end of grace period, to prevent nickflooding */
662     if (!IsFloodDone(source_p))
663     flood_endgrace(source_p);
664    
665     /* terminate nick to NICKLEN */
666 michael 1751 strlcpy(nick, parv[1], IRCD_MIN(sizeof(nick), ServerInfo.max_nick_length + 1));
667 adx 30
668     /* check the nickname is ok */
669 michael 1165 if (!valid_nickname(nick, 1))
670 adx 30 {
671 michael 1838 sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name,
672     source_p->name, nick, "Erroneous Nickname");
673 adx 30 return;
674     }
675    
676 michael 1687 if (!IsExemptResv(source_p) &&
677     !(HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.oper_pass_resv) &&
678     (conf = find_matching_name_conf(CONF_NRESV, nick, NULL, NULL, 0)))
679 adx 30 {
680 michael 1687 ++conf->count;
681 michael 1834 sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME),
682 michael 1838 me.name, source_p->name, nick, conf->reason);
683 michael 1698 sendto_realops_flags(UMODE_REJ, L_ALL, SEND_NOTICE,
684 michael 2686 "Forbidding reserved nick %s from user %s",
685 michael 1442 nick, get_client_name(client_p, HIDE_IP));
686 adx 30 return;
687     }
688    
689 michael 1169 if ((target_p = hash_find_client(nick)) == NULL)
690 michael 1193 change_local_nick(source_p, nick);
691 michael 981 else if (target_p == source_p)
692 adx 30 {
693 michael 981 /*
694     * If (target_p == source_p) the client is changing nicks between
695 adx 30 * equivalent nicknames ie: [nick] -> {nick}
696     */
697    
698 michael 2004 /* Check the nick isn't exactly the same */
699 michael 981 if (strcmp(target_p->name, nick))
700 michael 1193 change_local_nick(source_p, nick);
701 michael 981 }
702     else if (IsUnknown(target_p))
703     {
704     /*
705 michael 2004 * If the client that has the nick isn't registered yet (nick but no
706 adx 30 * user) then drop the unregged client
707     */
708 michael 981 exit_client(target_p, &me, "Overridden");
709 michael 1193 change_local_nick(source_p, nick);
710 adx 30 }
711     else
712 michael 1834 sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name,
713 michael 981 source_p->name, nick);
714 adx 30 }
715    
716 michael 981 /*! \brief NICK command handler (called by servers and remotely
717     * connected clients)
718     *
719     * \param client_p Pointer to allocated Client struct with physical connection
720     * to this server, i.e. with an open socket connected.
721     * \param source_p Pointer to allocated Client struct from which the message
722     * originally comes from. This can be a local or remote client.
723     * \param parc Integer holding the number of supplied arguments.
724     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
725     * pointers.
726     * \note Valid arguments for this command are:
727     *
728 adx 30 * server -> server nick change
729 michael 981 * - parv[0] = sender prefix
730     * - parv[1] = nickname
731     * - parv[2] = TS when nick change
732 adx 30 *
733 michael 1196 * server introducing new nick (without services support)
734 michael 981 * - parv[0] = sender prefix
735     * - parv[1] = nickname
736     * - parv[2] = hop count
737     * - parv[3] = TS
738     * - parv[4] = umode
739     * - parv[5] = username
740     * - parv[6] = hostname
741     * - parv[7] = server
742     * - parv[8] = ircname
743 michael 1196 *
744     * server introducing new nick (with services support)
745     * - parv[0] = sender prefix
746     * - parv[1] = nickname
747     * - parv[2] = hop count
748     * - parv[3] = TS
749     * - parv[4] = umode
750     * - parv[5] = username
751     * - parv[6] = hostname
752     * - parv[7] = server
753     * - parv[8] = services id (timestamp)
754     * - parv[9] = ircname
755 adx 30 */
756     static void
757     ms_nick(struct Client *client_p, struct Client *source_p,
758     int parc, char *parv[])
759     {
760 michael 981 struct Client *target_p = NULL;
761 adx 30 time_t newts = 0;
762 michael 1559 const char *svsid = "0";
763 adx 30
764 michael 1531 if (parc < 3 || EmptyString(parv[parc - 1]))
765 adx 30 return;
766    
767 michael 1196 if (parc >= 9)
768 adx 30 {
769 michael 1169 struct Client *server_p = hash_find_server(parv[7]);
770 adx 30
771     if (server_p == NULL)
772     {
773 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
774 michael 1997 "Invalid server %s from %s for NICK %s",
775     parv[7], source_p->name, parv[1]);
776 adx 30 sendto_one(client_p, ":%s KILL %s :%s (Server doesn't exist!)",
777 michael 981 me.name, parv[1], me.name);
778 adx 30 return;
779     }
780    
781 michael 981 if (check_clean_nick(client_p, source_p, parv[1], server_p) ||
782     check_clean_user(client_p, parv[1], parv[5], server_p) ||
783 michael 1997 check_clean_host(client_p, parv[1], parv[6], server_p))
784 adx 30 return;
785    
786     if (IsServer(source_p))
787 michael 981 newts = atol(parv[3]);
788 michael 1196 if (IsServer(source_p) && parc == 10)
789 michael 1559 svsid = parv[8];
790 adx 30 }
791     else if (parc == 3)
792     {
793     if (IsServer(source_p))
794 michael 981 /* Servers can't change nicks.. */
795 adx 30 return;
796    
797 michael 981 if (check_clean_nick(client_p, source_p, parv[1],
798 michael 1997 source_p->servptr))
799 adx 30 return;
800 michael 981
801 michael 1997 newts = atol(parv[2]);
802 adx 30 }
803    
804 michael 2004 /* If the nick doesnt exist, allow it and process like normal */
805 michael 1169 if ((target_p = hash_find_client(parv[1])) == NULL)
806 michael 1196 nick_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]);
807 michael 981 else if (IsUnknown(target_p))
808 adx 30 {
809 michael 2004 /* We're not living in the past anymore, an unknown client is local only. */
810 adx 30 exit_client(target_p, &me, "Overridden");
811 michael 1196 nick_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]);
812 adx 30 }
813 michael 981 else if (target_p == source_p)
814 adx 30 {
815 michael 981 if (strcmp(target_p->name, parv[1]))
816 michael 1196 nick_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]);
817 adx 30 }
818 michael 981 else
819     perform_nick_collides(source_p, client_p, target_p, parc, parv,
820 michael 1196 newts, svsid, parv[1], parv[parc-1], NULL);
821 adx 30 }
822    
823 michael 981 /*! \brief UID command handler (called by servers)
824 adx 30 *
825 michael 981 * \param client_p Pointer to allocated Client struct with physical connection
826     * to this server, i.e. with an open socket connected.
827     * \param source_p Pointer to allocated Client struct from which the message
828     * originally comes from. This can be a local or remote client.
829     * \param parc Integer holding the number of supplied arguments.
830     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
831     * pointers.
832     * \note Valid arguments for this command are:
833     *
834 michael 1196 * server introducing new nick (without services support)
835 michael 981 * - parv[0] = sender prefix
836     * - parv[1] = nickname
837     * - parv[2] = hop count
838     * - parv[3] = TS
839     * - parv[4] = umode
840     * - parv[5] = username
841     * - parv[6] = hostname
842     * - parv[7] = ip
843     * - parv[8] = uid
844     * - parv[9] = ircname (gecos)
845 michael 1196 *
846     * server introducing new nick (with services support)
847     * - parv[ 0] = sender prefix
848     * - parv[ 1] = nickname
849     * - parv[ 2] = hop count
850     * - parv[ 3] = TS
851     * - parv[ 4] = umode
852     * - parv[ 5] = username
853     * - parv[ 6] = hostname
854     * - parv[ 7] = ip
855     * - parv[ 8] = uid
856     * - parv[ 9] = services id (timestamp)
857     * - parv[10] = ircname (gecos)
858 adx 30 */
859     static void
860     ms_uid(struct Client *client_p, struct Client *source_p,
861     int parc, char *parv[])
862     {
863 michael 981 struct Client *target_p = NULL;
864 adx 30 time_t newts = 0;
865 michael 1559 const char *svsid = "0";
866 adx 30
867 michael 1196 if (parc < 10 || EmptyString(parv[parc-1]))
868 adx 30 return;
869    
870 michael 981 if (check_clean_nick(client_p, source_p, parv[1], source_p) ||
871     check_clean_user(client_p, parv[1], parv[5], source_p) ||
872     check_clean_host(client_p, parv[1], parv[6], source_p))
873 adx 30 return;
874    
875 michael 981 newts = atol(parv[3]);
876 michael 1559 svsid = parc == 11 ? parv[9] : "0";
877 adx 30
878 michael 981 /*
879 michael 2004 * If there is an ID collision, kill our client, and kill theirs.
880     * This may generate 401's, but it ensures that both clients always
881 adx 30 * go, even if the other server refuses to do the right thing.
882     */
883 michael 981 if ((target_p = hash_find_id(parv[8])) != NULL)
884 adx 30 {
885 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
886 michael 1997 "ID collision on %s(%s <- %s)(both killed)",
887     target_p->name, target_p->from->name,
888     client_p->name);
889 michael 2565 kill_client_serv_butone(NULL, target_p, "%s (ID collision)",
890     me.name);
891 adx 30
892 michael 896 ++ServerStats.is_kill;
893 michael 1219 AddFlag(target_p, FLAGS_KILLED);
894 adx 30 exit_client(target_p, &me, "ID Collision");
895     return;
896     }
897 michael 1997
898 michael 1169 if ((target_p = hash_find_client(parv[1])) == NULL)
899 michael 1196 uid_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]);
900 adx 30 else if (IsUnknown(target_p))
901     {
902     exit_client(target_p, &me, "Overridden");
903 michael 1196 uid_from_server(client_p, source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]);
904 adx 30 }
905     else
906 michael 1196 perform_nick_collides(source_p, client_p, target_p, parc, parv, newts, svsid, parv[1],
907     parv[parc-1], parv[8]);
908 adx 30 }
909    
910 michael 1230 static struct Message nick_msgtab = {
911     "NICK", 0, 0, 0, MAXPARA, MFLG_SLOW, 0,
912     {mr_nick, m_nick, ms_nick, m_ignore, m_nick, m_ignore}
913     };
914    
915     static struct Message uid_msgtab = {
916     "UID", 0, 0, 10, MAXPARA, MFLG_SLOW, 0,
917     {m_ignore, m_ignore, ms_uid, m_ignore, m_ignore, m_ignore}
918     };
919    
920     static void
921     module_init(void)
922     {
923     mod_add_cmd(&uid_msgtab);
924     mod_add_cmd(&nick_msgtab);
925     }
926    
927     static void
928     module_exit(void)
929     {
930     mod_del_cmd(&uid_msgtab);
931     mod_del_cmd(&nick_msgtab);
932     }
933    
934     struct module module_entry = {
935     .node = { NULL, NULL, NULL },
936     .name = NULL,
937     .version = "$Revision$",
938     .handle = NULL,
939     .modinit = module_init,
940     .modexit = module_exit,
941     .flags = MODULE_FLAG_CORE
942     };

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision