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: 4021
Committed: Fri Jun 20 16:19:28 2014 UTC (9 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 26640 byte(s)
Log Message:
- Got rid of SEND_UMODES. We now propagate all modes.

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 michael 3347 #include "user.h"
37 adx 30 #include "whowas.h"
38 michael 3347 #include "server.h"
39 adx 30 #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 3347 #include "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 michael 3680 char modebuf[IRCD_BUFSIZE] = "";
229 michael 1192
230 michael 2368 DelUMode(source_p, UMODE_REGISTERED);
231 michael 4021 send_umode(source_p, source_p, oldmodes, 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 3186 source_p->id, 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     /* parse usermodes */
292 michael 3283 for (const char *m = &parv[4][1]; *m; ++m)
293 michael 1997 {
294     unsigned int flag = user_modes[(unsigned char)*m];
295    
296     if ((flag & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE))
297     ++Count.invisi;
298     if ((flag & UMODE_OPER) && !HasUMode(source_p, UMODE_OPER))
299     ++Count.oper;
300    
301 michael 4021 AddUMode(source_p, flag);
302 michael 1997 }
303    
304 michael 2955 register_remote_user(source_p, parv[5], parv[6], parv[7]);
305 michael 1997 return;
306     }
307     }
308     else if (source_p->name[0])
309     {
310     samenick = !irccmp(source_p->name, nick);
311    
312 michael 2004 /* Client changing their nick */
313 michael 1997 if (!samenick)
314     {
315     DelUMode(source_p, UMODE_REGISTERED);
316     watch_check_hash(source_p, RPL_LOGOFF);
317     source_p->tsinfo = newts ? newts : CurrentTime;
318     }
319    
320     sendto_common_channels_local(source_p, 1, 0, ":%s!%s@%s NICK :%s",
321 michael 3079 source_p->name, source_p->username,
322 michael 1997 source_p->host, nick);
323    
324 michael 2300 whowas_add_history(source_p, 1);
325 michael 3156 sendto_server(source_p, NOCAPS, NOCAPS, ":%s NICK %s :%lu",
326 michael 3186 source_p->id, nick, (unsigned long)source_p->tsinfo);
327 michael 1997 }
328    
329     /* set the new nick name */
330     if (source_p->name[0])
331     hash_del_client(source_p);
332    
333     strlcpy(source_p->name, nick, sizeof(source_p->name));
334     hash_add_client(source_p);
335    
336     if (!samenick)
337     watch_check_hash(source_p, RPL_LOGON);
338     }
339    
340     /*
341     * client_from_server()
342     */
343     static void
344 michael 3156 uid_from_server(struct Client *source_p, int parc,
345 michael 1997 char *parv[], time_t newts, const char *svsid, char *nick, char *ugecos)
346     {
347     const char *servername = source_p->name;
348    
349 michael 3156 source_p = make_client(source_p->from);
350 michael 1997 dlinkAdd(source_p, &source_p->node, &global_client_list);
351    
352     source_p->hopcount = atoi(parv[2]);
353     source_p->tsinfo = newts;
354     strlcpy(source_p->svid, svsid, sizeof(source_p->svid));
355    
356     /* copy the nick in place */
357 michael 2046 strlcpy(source_p->name, nick, sizeof(source_p->name));
358 michael 1997 strlcpy(source_p->id, parv[8], sizeof(source_p->id));
359     strlcpy(source_p->sockhost, parv[7], sizeof(source_p->sockhost));
360     strlcpy(source_p->info, ugecos, sizeof(source_p->info));
361    
362     hash_add_client(source_p);
363     hash_add_id(source_p);
364    
365     /* parse usermodes */
366 michael 3283 for (const char *m = &parv[4][1]; *m; ++m)
367 michael 1997 {
368     unsigned int flag = user_modes[(unsigned char)*m];
369    
370     if ((flag & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE))
371     ++Count.invisi;
372     if ((flag & UMODE_OPER) && !HasUMode(source_p, UMODE_OPER))
373     ++Count.oper;
374    
375 michael 4021 AddUMode(source_p, flag);
376 michael 1997 }
377    
378 michael 2955 register_remote_user(source_p, parv[5], parv[6], servername);
379 michael 1997 }
380    
381     static void
382 michael 3156 perform_nick_collides(struct Client *source_p,
383 michael 2820 struct Client *target_p, int parc, char *parv[],
384 michael 1997 time_t newts, const char *svsid, char *nick, char *gecos, char *uid)
385     {
386 michael 2004 int sameuser = 0;
387 michael 2820
388 michael 2004 /* Server introducing new nick */
389 michael 1997 if (IsServer(source_p))
390     {
391 michael 2004 /* If we don't have a TS, or their TS's are the same, kill both */
392 michael 1997 if (!newts || !target_p->tsinfo || (newts == target_p->tsinfo))
393     {
394     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
395     "Nick collision on %s(%s <- %s)(both killed)",
396 michael 2004 target_p->name, target_p->from->name,
397 michael 3156 source_p->from->name);
398 michael 2820
399 michael 1997 /* if we have a UID, issue a kill for it */
400     if (uid)
401 michael 3156 sendto_one(source_p, ":%s KILL %s :%s (Nick collision (new))",
402 michael 1997 me.id, uid, me.name);
403    
404 michael 3178 sendto_server(NULL, NOCAPS, NOCAPS, ":%s KILL %s :%s (Nick collision (new))",
405     me.id, target_p->id, me.name);
406    
407 michael 1997 ++ServerStats.is_kill;
408 michael 3109 sendto_one_numeric(target_p, &me, ERR_NICKCOLLISION, target_p->name);
409 michael 1997
410     AddFlag(target_p, FLAGS_KILLED);
411 michael 3171 exit_client(target_p, "Nick collision (new)");
412 michael 1997 return;
413     }
414     /* the timestamps are different */
415     else
416     {
417     sameuser = !irccmp(target_p->username, parv[5]) &&
418     !irccmp(target_p->host, parv[6]);
419 michael 2820
420 michael 2004 /*
421     * If the users are the same (loaded a client on a different server)
422 michael 1997 * and the new users ts is older, or the users are different and the
423     * new users ts is newer, ignore the new client and let it do the kill
424     */
425     if ((sameuser && newts < target_p->tsinfo) ||
426     (!sameuser && newts > target_p->tsinfo))
427     {
428     if (uid)
429 michael 3156 sendto_one(source_p, ":%s KILL %s :%s (Nick collision (new))",
430 michael 1997 me.id, uid, me.name);
431 michael 2004 return;
432 michael 1997 }
433     else
434     {
435     if (sameuser)
436 michael 2004 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
437     "Nick collision on %s(%s <- %s)(older killed)",
438     target_p->name, target_p->from->name,
439 michael 3156 source_p->from->name);
440 michael 1997 else
441 michael 2004 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
442     "Nick collision on %s(%s <- %s)(newer killed)",
443     target_p->name, target_p->from->name,
444 michael 3156 source_p->from->name);
445 michael 1997
446     ++ServerStats.is_kill;
447 michael 3109 sendto_one_numeric(target_p, &me, ERR_NICKCOLLISION, target_p->name);
448 michael 1997
449 michael 3178 sendto_server(NULL, NOCAPS, NOCAPS, ":%s KILL %s :%s (Nick collision (new))",
450     me.id, target_p->id, me.name);
451 michael 1997
452     AddFlag(target_p, FLAGS_KILLED);
453 michael 3171 exit_client(target_p, "Nick collision");
454 michael 2004
455     if (!uid && (parc == 9 || parc == 10))
456 michael 3156 nick_from_server(source_p, parc, parv, newts, svsid, nick, gecos);
457 michael 2004 else if (uid && (parc == 10 || parc == 11))
458 michael 3156 uid_from_server(source_p, parc, parv, newts, svsid, nick, gecos);
459 michael 2004 return;
460 michael 1997 }
461     }
462     }
463    
464     /* its a client changing nick and causing a collide */
465     if (!newts || !target_p->tsinfo || (newts == target_p->tsinfo))
466     {
467     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
468     "Nick change collision from %s to %s(%s <- %s)(both killed)",
469 michael 2004 source_p->name, target_p->name, target_p->from->name,
470 michael 3156 source_p->from->name);
471 michael 2820
472 michael 3109 sendto_one_numeric(target_p, &me, ERR_NICKCOLLISION, target_p->name);
473     ++ServerStats.is_kill;
474 michael 1997
475    
476 michael 3178 sendto_server(NULL, NOCAPS, NOCAPS, ":%s KILL %s :%s (Nick change collision)",
477     me.id, source_p->id, me.name);
478    
479 michael 1997 ++ServerStats.is_kill;
480    
481 michael 3178 sendto_server(NULL, NOCAPS, NOCAPS, ":%s KILL %s :%s (Nick change collision)",
482     me.id, target_p->id, me.name);
483    
484 michael 1997 AddFlag(target_p, FLAGS_KILLED);
485 michael 3171 exit_client(target_p, "Nick collision (new)");
486 michael 1997
487     AddFlag(source_p, FLAGS_KILLED);
488 michael 3171 exit_client(source_p, "Nick collision (old)");
489 michael 1997 return;
490 michael 2004 }
491     else
492     {
493     sameuser = !irccmp(target_p->username, source_p->username) &&
494     !irccmp(target_p->host, source_p->host);
495    
496     if ((sameuser && newts < target_p->tsinfo) ||
497     (!sameuser && newts > target_p->tsinfo))
498     {
499     if (sameuser)
500     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
501     "Nick change collision from %s to %s(%s <- %s)(older killed)",
502     source_p->name, target_p->name, target_p->from->name,
503 michael 3156 source_p->from->name);
504 michael 2004 else
505     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
506     "Nick change collision from %s to %s(%s <- %s)(newer killed)",
507     source_p->name, target_p->name, target_p->from->name,
508 michael 3156 source_p->from->name);
509 michael 2004
510     ++ServerStats.is_kill;
511 michael 3178
512     sendto_server(NULL, NOCAPS, NOCAPS, ":%s KILL %s :%s (Nick change collision)",
513     me.id, source_p->id, me.name);
514 michael 2004 AddFlag(source_p, FLAGS_KILLED);
515    
516     if (sameuser)
517 michael 3171 exit_client(source_p, "Nick collision (old)");
518 michael 2004 else
519 michael 3171 exit_client(source_p, "Nick collision (new)");
520 michael 2004 return;
521 michael 1997 }
522     else
523     {
524 michael 2004 if (sameuser)
525     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
526     "Nick collision on %s(%s <- %s)(older killed)",
527     target_p->name, target_p->from->name,
528 michael 3156 source_p->from->name);
529 michael 2004 else
530     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
531     "Nick collision on %s(%s <- %s)(newer killed)",
532     target_p->name, target_p->from->name,
533 michael 3156 source_p->from->name);
534 michael 1997
535 michael 3178 sendto_server(NULL, NOCAPS, NOCAPS, ":%s KILL %s :%s (Nick collision)",
536     me.id, target_p->id, me.name);
537 michael 1997
538 michael 2004 ++ServerStats.is_kill;
539 michael 3109 sendto_one_numeric(target_p, &me, ERR_NICKCOLLISION, target_p->name);
540 michael 1997
541 michael 2004 AddFlag(target_p, FLAGS_KILLED);
542 michael 3171 exit_client(target_p, "Nick collision");
543 michael 2004 }
544     }
545 michael 1997
546 michael 2004 /*
547     * we should only ever call nick_from_server() here, as
548 michael 1997 * this is a client changing nick, not a new client
549     */
550 michael 3156 nick_from_server(source_p, parc, parv, newts, svsid, nick, gecos);
551 michael 1997 }
552    
553 michael 3300 /*! \brief NICK command handler
554 adx 30 *
555 michael 981 * \param source_p Pointer to allocated Client struct from which the message
556     * originally comes from. This can be a local or remote client.
557     * \param parc Integer holding the number of supplied arguments.
558     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
559     * pointers.
560     * \note Valid arguments for this command are:
561 michael 3096 * - parv[0] = command
562 michael 981 * - parv[1] = nickname
563 adx 30 */
564 michael 2820 static int
565 michael 3156 mr_nick(struct Client *source_p, int parc, char *parv[])
566 adx 30 {
567 michael 3680 char nick[NICKLEN + 1] = "";
568 michael 885 struct Client *target_p = NULL;
569 michael 1687 struct MaskItem *conf = NULL;
570 michael 885
571 adx 30 if (parc < 2 || EmptyString(parv[1]))
572     {
573 michael 3109 sendto_one_numeric(source_p, &me, ERR_NONICKNAMEGIVEN);
574 michael 2820 return 0;
575 adx 30 }
576    
577 michael 2004 /* Copy the nick and terminate it */
578 michael 1751 strlcpy(nick, parv[1], IRCD_MIN(sizeof(nick), ServerInfo.max_nick_length + 1));
579 adx 30
580 michael 2004 /* Check the nickname is ok */
581 michael 1165 if (!valid_nickname(nick, 1))
582 adx 30 {
583 michael 3109 sendto_one_numeric(source_p, &me, ERR_ERRONEUSNICKNAME, parv[1], "Erroneous Nickname");
584 michael 2820 return 0;
585 adx 30 }
586    
587 michael 2004 /* Check if the nick is resv'd */
588 michael 1688 if ((conf = find_matching_name_conf(CONF_NRESV, nick, NULL, NULL, 0)))
589 adx 30 {
590 michael 1687 ++conf->count;
591 michael 3109 sendto_one_numeric(source_p, &me, ERR_ERRONEUSNICKNAME, nick, conf->reason);
592 michael 1698 sendto_realops_flags(UMODE_REJ, L_ALL, SEND_NOTICE,
593 michael 2686 "Forbidding reserved nick %s from user %s",
594 michael 3156 nick, get_client_name(source_p, HIDE_IP));
595 michael 2820 return 0;
596 adx 30 }
597    
598 michael 1169 if ((target_p = hash_find_client(nick)) == NULL)
599 michael 1003 set_initial_nick(source_p, nick);
600 adx 30 else if (source_p == target_p)
601 michael 1080 strlcpy(source_p->name, nick, sizeof(source_p->name));
602 adx 30 else
603 michael 3109 sendto_one_numeric(source_p, &me, ERR_NICKNAMEINUSE, nick);
604    
605 michael 2820 return 0;
606 adx 30 }
607    
608 michael 3300 /*! \brief NICK command handler
609 adx 30 *
610 michael 981 * \param source_p Pointer to allocated Client struct from which the message
611     * originally comes from. This can be a local or remote client.
612     * \param parc Integer holding the number of supplied arguments.
613     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
614     * pointers.
615     * \note Valid arguments for this command are:
616 michael 3096 * - parv[0] = command
617 michael 981 * - parv[1] = nickname
618 adx 30 */
619 michael 2820 static int
620 michael 3156 m_nick(struct Client *source_p, int parc, char *parv[])
621 adx 30 {
622 michael 3680 char nick[NICKLEN + 1] = "";
623 michael 885 struct Client *target_p = NULL;
624 michael 1687 struct MaskItem *conf = NULL;
625 adx 30
626 michael 3156 assert(MyClient(source_p));
627 michael 1193
628 adx 30 if (parc < 2 || EmptyString(parv[1]))
629     {
630 michael 3109 sendto_one_numeric(source_p, &me, ERR_NONICKNAMEGIVEN);
631 michael 2820 return 0;
632 adx 30 }
633    
634     /* mark end of grace period, to prevent nickflooding */
635     if (!IsFloodDone(source_p))
636     flood_endgrace(source_p);
637    
638     /* terminate nick to NICKLEN */
639 michael 1751 strlcpy(nick, parv[1], IRCD_MIN(sizeof(nick), ServerInfo.max_nick_length + 1));
640 adx 30
641     /* check the nickname is ok */
642 michael 1165 if (!valid_nickname(nick, 1))
643 adx 30 {
644 michael 3109 sendto_one_numeric(source_p, &me, ERR_ERRONEUSNICKNAME, nick, "Erroneous Nickname");
645 michael 2820 return 0;
646 adx 30 }
647    
648 michael 1687 if (!IsExemptResv(source_p) &&
649     !(HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.oper_pass_resv) &&
650     (conf = find_matching_name_conf(CONF_NRESV, nick, NULL, NULL, 0)))
651 adx 30 {
652 michael 1687 ++conf->count;
653 michael 3109 sendto_one_numeric(source_p, &me, ERR_ERRONEUSNICKNAME, nick, conf->reason);
654 michael 1698 sendto_realops_flags(UMODE_REJ, L_ALL, SEND_NOTICE,
655 michael 2686 "Forbidding reserved nick %s from user %s",
656 michael 3156 nick, get_client_name(source_p, HIDE_IP));
657 michael 2820 return 0;
658 adx 30 }
659    
660 michael 1169 if ((target_p = hash_find_client(nick)) == NULL)
661 michael 1193 change_local_nick(source_p, nick);
662 michael 981 else if (target_p == source_p)
663 adx 30 {
664 michael 981 /*
665     * If (target_p == source_p) the client is changing nicks between
666 adx 30 * equivalent nicknames ie: [nick] -> {nick}
667     */
668    
669 michael 2004 /* Check the nick isn't exactly the same */
670 michael 981 if (strcmp(target_p->name, nick))
671 michael 1193 change_local_nick(source_p, nick);
672 michael 981 }
673     else if (IsUnknown(target_p))
674     {
675     /*
676 michael 2004 * If the client that has the nick isn't registered yet (nick but no
677 adx 30 * user) then drop the unregged client
678     */
679 michael 3171 exit_client(target_p, "Overridden");
680 michael 1193 change_local_nick(source_p, nick);
681 adx 30 }
682     else
683 michael 3109 sendto_one_numeric(source_p, &me, ERR_NICKNAMEINUSE, nick);
684    
685 michael 2820 return 0;
686 adx 30 }
687    
688 michael 3300 /*! \brief NICK command handler
689 michael 981 *
690     * \param source_p Pointer to allocated Client struct from which the message
691     * originally comes from. This can be a local or remote client.
692     * \param parc Integer holding the number of supplied arguments.
693     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
694     * pointers.
695     * \note Valid arguments for this command are:
696     *
697 adx 30 * server -> server nick change
698 michael 3300 * - parv[0] = command
699     * - parv[1] = nickname
700     * - parv[2] = TS when nick change
701 adx 30 */
702 michael 2820 static int
703 michael 3156 ms_nick(struct Client *source_p, int parc, char *parv[])
704 adx 30 {
705 michael 981 struct Client *target_p = NULL;
706 adx 30 time_t newts = 0;
707    
708 michael 1531 if (parc < 3 || EmptyString(parv[parc - 1]))
709 michael 2820 return 0;
710 adx 30
711 michael 3135 if (IsServer(source_p))
712 michael 3680 return 0; /* Servers can't change nicks.. */
713 adx 30
714 michael 3156 if (check_clean_nick(source_p, parv[1], source_p->servptr))
715 michael 3135 return 0;
716 adx 30
717 michael 3135 newts = atol(parv[2]);
718 adx 30
719 michael 2004 /* If the nick doesnt exist, allow it and process like normal */
720 michael 1169 if ((target_p = hash_find_client(parv[1])) == NULL)
721 michael 3156 nick_from_server(source_p, parc, parv, newts, NULL, parv[1], parv[parc-1]);
722 michael 981 else if (IsUnknown(target_p))
723 adx 30 {
724 michael 2004 /* We're not living in the past anymore, an unknown client is local only. */
725 michael 3171 exit_client(target_p, "Overridden");
726 michael 3156 nick_from_server(source_p, parc, parv, newts, NULL, parv[1], parv[parc-1]);
727 adx 30 }
728 michael 981 else if (target_p == source_p)
729 adx 30 {
730 michael 981 if (strcmp(target_p->name, parv[1]))
731 michael 3156 nick_from_server(source_p, parc, parv, newts, NULL, parv[1], parv[parc-1]);
732 adx 30 }
733 michael 981 else
734 michael 3156 perform_nick_collides(source_p, target_p, parc, parv,
735 michael 3135 newts, NULL, parv[1], parv[parc-1], NULL);
736 michael 2820 return 0;
737 adx 30 }
738    
739 michael 3300 /*! \brief UID command handler
740 adx 30 *
741 michael 981 * \param source_p Pointer to allocated Client struct from which the message
742     * originally comes from. This can be a local or remote client.
743     * \param parc Integer holding the number of supplied arguments.
744     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
745     * pointers.
746     * \note Valid arguments for this command are:
747     *
748 michael 1196 * server introducing new nick (without services support)
749 michael 3300 * - parv[0] = command
750     * - parv[1] = nickname
751     * - parv[2] = hop count
752     * - parv[3] = TS
753     * - parv[4] = umode
754     * - parv[5] = username
755     * - parv[6] = hostname
756     * - parv[7] = ip
757     * - parv[8] = uid
758     * - parv[9] = ircname (gecos)
759 michael 1196 *
760     * server introducing new nick (with services support)
761 michael 3300 * - parv[ 0] = command
762     * - parv[ 1] = nickname
763     * - parv[ 2] = hop count
764     * - parv[ 3] = TS
765     * - parv[ 4] = umode
766     * - parv[ 5] = username
767     * - parv[ 6] = hostname
768     * - parv[ 7] = ip
769     * - parv[ 8] = uid
770 michael 3677 * - parv[ 9] = services id (account name)
771 michael 3300 * - parv[10] = ircname (gecos)
772 adx 30 */
773 michael 2820 static int
774 michael 3156 ms_uid(struct Client *source_p, int parc, char *parv[])
775 adx 30 {
776 michael 981 struct Client *target_p = NULL;
777 adx 30 time_t newts = 0;
778 michael 1559 const char *svsid = "0";
779 adx 30
780 michael 3680 if (parc < 10 || EmptyString(parv[parc - 1]))
781 michael 2820 return 0;
782 adx 30
783 michael 3156 if (check_clean_nick(source_p, parv[1], source_p) ||
784     check_clean_user(source_p, parv[1], parv[5], source_p) ||
785     check_clean_host(source_p, parv[1], parv[6], source_p))
786 michael 2820 return 0;
787 adx 30
788 michael 981 newts = atol(parv[3]);
789 michael 1559 svsid = parc == 11 ? parv[9] : "0";
790 adx 30
791 michael 981 /*
792 michael 2004 * If there is an ID collision, kill our client, and kill theirs.
793     * This may generate 401's, but it ensures that both clients always
794 adx 30 * go, even if the other server refuses to do the right thing.
795     */
796 michael 3680 if ((target_p = hash_find_id(parv[8])))
797 adx 30 {
798 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
799 michael 1997 "ID collision on %s(%s <- %s)(both killed)",
800     target_p->name, target_p->from->name,
801 michael 3156 source_p->from->name);
802 adx 30
803 michael 3178 sendto_server(NULL, NOCAPS, NOCAPS, ":%s KILL %s :%s (ID collision)",
804     me.id, target_p->id, me.name);
805    
806 michael 896 ++ServerStats.is_kill;
807 michael 1219 AddFlag(target_p, FLAGS_KILLED);
808 michael 3171 exit_client(target_p, "ID Collision");
809 michael 2820 return 0;
810 adx 30 }
811 michael 1997
812 michael 1169 if ((target_p = hash_find_client(parv[1])) == NULL)
813 michael 3156 uid_from_server(source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]);
814 adx 30 else if (IsUnknown(target_p))
815     {
816 michael 3171 exit_client(target_p, "Overridden");
817 michael 3156 uid_from_server(source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]);
818 adx 30 }
819     else
820 michael 3156 perform_nick_collides(source_p, target_p, parc, parv, newts, svsid, parv[1],
821 michael 1196 parv[parc-1], parv[8]);
822 michael 2820 return 0;
823 adx 30 }
824    
825 michael 2820 static struct Message nick_msgtab =
826     {
827 michael 1230 "NICK", 0, 0, 0, MAXPARA, MFLG_SLOW, 0,
828 michael 2820 { mr_nick, m_nick, ms_nick, m_ignore, m_nick, m_ignore }
829 michael 1230 };
830    
831 michael 2820 static struct Message uid_msgtab =
832     {
833 michael 1230 "UID", 0, 0, 10, MAXPARA, MFLG_SLOW, 0,
834 michael 2820 { m_ignore, m_ignore, ms_uid, m_ignore, m_ignore, m_ignore }
835 michael 1230 };
836    
837     static void
838     module_init(void)
839     {
840     mod_add_cmd(&uid_msgtab);
841     mod_add_cmd(&nick_msgtab);
842     }
843    
844     static void
845     module_exit(void)
846     {
847     mod_del_cmd(&uid_msgtab);
848     mod_del_cmd(&nick_msgtab);
849     }
850    
851 michael 2820 struct module module_entry =
852     {
853 michael 1230 .node = { NULL, NULL, NULL },
854     .name = NULL,
855     .version = "$Revision$",
856     .handle = NULL,
857     .modinit = module_init,
858     .modexit = module_exit,
859     .flags = MODULE_FLAG_CORE
860     };

Properties

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