ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/core/m_nick.c
Revision: 3178
Committed: Wed Mar 19 18:27:44 2014 UTC (11 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 26851 byte(s)
Log Message:
- Get rid of kill_client_serv_butone()

File Contents

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

Properties

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