ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/modules/core/m_nick.c
Revision: 4229
Committed: Mon Jul 14 20:11:08 2014 UTC (9 years, 8 months ago) by michael
Content type: text/x-csrc
File size: 27413 byte(s)
Log Message:
- m_nick(), mr_nick(): use target_p->name when reporting ERR_NICKNAMEINUSE

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

Properties

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