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: 3156
Committed: Fri Mar 14 19:57:38 2014 UTC (10 years ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/trunk/modules/core/m_nick.c
File size: 26917 byte(s)
Log Message:
- Removed client_p pointers from everywhere

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 3156 kill_client_serv_butone(source_p, source_p,
83 michael 2565 "%s (Bad Nickname)",
84     me.name);
85 michael 1997 AddFlag(source_p, FLAGS_KILLED);
86     exit_client(source_p, &me, "Bad Nickname");
87     }
88    
89     return 1;
90     }
91    
92     return 0;
93     }
94    
95     /* check_clean_user()
96     *
97     * input - pointer to client sending data
98     * - nickname
99     * - username to check
100     * - origin of NICK
101     * output - none
102     * side effects - if username is erroneous, return 1
103     */
104     static int
105 michael 3156 check_clean_user(struct Client *source_p, char *nick,
106 michael 1997 char *user, struct Client *server_p)
107     {
108 michael 2070 if (!valid_username(user, 0))
109 michael 1997 {
110     ++ServerStats.is_kill;
111     sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
112     "Bad/Long Username: %s Nickname: %s From: %s(via %s)",
113 michael 3156 user, nick, server_p->name, source_p->from->name);
114     sendto_one(source_p, ":%s KILL %s :%s (Bad Username)",
115 michael 1997 me.name, nick, me.name);
116     return 1;
117     }
118    
119     return 0;
120     }
121    
122     /* check_clean_host()
123     *
124     * input - pointer to client sending us data
125     * - nickname
126     * - hostname to check
127     * - source name
128     * output - none
129     * side effects - if hostname is erroneous, return 1
130     */
131     static int
132 michael 3156 check_clean_host(struct Client *source_p, char *nick,
133 michael 1997 char *host, struct Client *server_p)
134     {
135     if (!valid_hostname(host))
136     {
137     ++ServerStats.is_kill;
138     sendto_realops_flags(UMODE_DEBUG, L_ALL, SEND_NOTICE,
139     "Bad/Long Hostname: %s Nickname: %s From: %s(via %s)",
140 michael 3156 host, nick, server_p->name, source_p->from->name);
141     sendto_one(source_p, ":%s KILL %s :%s (Bad Hostname)",
142 michael 1997 me.name, nick, me.name);
143     return 1;
144     }
145    
146     return 0;
147     }
148    
149 michael 1002 /* set_initial_nick()
150     *
151     * inputs
152     * output
153     * side effects -
154     *
155     * This function is only called to set up an initially registering
156     * client.
157     */
158     static void
159 michael 1003 set_initial_nick(struct Client *source_p, const char *nick)
160 michael 1002 {
161     /* Client setting NICK the first time */
162    
163     /* This had to be copied here to avoid problems.. */
164     source_p->tsinfo = CurrentTime;
165     source_p->localClient->registration &= ~REG_NEED_NICK;
166    
167     if (source_p->name[0])
168     hash_del_client(source_p);
169    
170     strlcpy(source_p->name, nick, sizeof(source_p->name));
171     hash_add_client(source_p);
172    
173     /* fd_desc is long enough */
174 michael 1003 fd_note(&source_p->localClient->fd, "Nick: %s", nick);
175 michael 1002
176     if (!source_p->localClient->registration)
177 michael 1080 register_local_user(source_p);
178 michael 1002 }
179    
180 michael 1192 /* change_local_nick()
181     *
182     * inputs - pointer to server
183     * - pointer to client
184     * - nick
185 michael 2820 * output -
186 michael 1192 * side effects - changes nick of a LOCAL user
187     */
188     static void
189 michael 1193 change_local_nick(struct Client *source_p, const char *nick)
190 michael 1192 {
191 michael 2368 int samenick = 0;
192    
193 michael 1192 assert(source_p->name[0] && !EmptyString(nick));
194 michael 1193 assert(MyConnect(source_p));
195 michael 1192
196     /*
197     * Client just changing his/her nick. If he/she is
198     * on a channel, send note of change to all clients
199     * on that channel. Propagate notice to other servers.
200     */
201     if ((source_p->localClient->last_nick_change +
202     ConfigFileEntry.max_nick_time) < CurrentTime)
203     source_p->localClient->number_of_nick_changes = 0;
204 michael 2368
205     if (ConfigFileEntry.anti_nick_flood &&
206     !HasUMode(source_p, UMODE_OPER) &&
207     source_p->localClient->number_of_nick_changes >
208     ConfigFileEntry.max_nick_changes)
209     {
210 michael 3109 sendto_one_numeric(source_p, &me, ERR_NICKTOOFAST, source_p->name, nick,
211     ConfigFileEntry.max_nick_time);
212 michael 2368 return;
213     }
214    
215 michael 1192 source_p->localClient->last_nick_change = CurrentTime;
216     source_p->localClient->number_of_nick_changes++;
217    
218 michael 2368 samenick = !irccmp(source_p->name, nick);
219    
220     if (!samenick)
221 michael 1192 {
222 michael 2368 source_p->tsinfo = CurrentTime;
223     clear_ban_cache_client(source_p);
224     watch_check_hash(source_p, RPL_LOGOFF);
225 michael 1192
226 michael 2368 if (HasUMode(source_p, UMODE_REGISTERED))
227 michael 1192 {
228 michael 2368 unsigned int oldmodes = source_p->umodes;
229     char modebuf[IRCD_BUFSIZE] = { '\0' };
230 michael 1192
231 michael 2368 DelUMode(source_p, UMODE_REGISTERED);
232     send_umode(source_p, source_p, oldmodes, 0xffffffff, modebuf);
233 michael 1192 }
234 michael 2368 }
235 michael 1192
236 michael 2368 sendto_realops_flags(UMODE_NCHANGE, L_ALL, SEND_NOTICE,
237     "Nick change: From %s to %s [%s@%s]",
238     source_p->name, nick, source_p->username, source_p->host);
239     sendto_common_channels_local(source_p, 1, 0, ":%s!%s@%s NICK :%s",
240     source_p->name, source_p->username,
241     source_p->host, nick);
242     whowas_add_history(source_p, 1);
243 michael 1192
244 michael 3135 sendto_server(source_p, NOCAPS, NOCAPS, ":%s NICK %s :%lu",
245 michael 2368 ID(source_p), nick, (unsigned long)source_p->tsinfo);
246 michael 1192
247 michael 2368 hash_del_client(source_p);
248     strlcpy(source_p->name, nick, sizeof(source_p->name));
249     hash_add_client(source_p);
250 michael 1192
251 michael 2368 if (!samenick)
252     watch_check_hash(source_p, RPL_LOGON);
253 michael 1192
254 michael 2368 /* fd_desc is long enough */
255     fd_note(&source_p->localClient->fd, "Nick: %s", nick);
256 michael 1192 }
257    
258 michael 1997 /*
259     * nick_from_server()
260     */
261     static void
262 michael 3156 nick_from_server(struct Client *source_p, int parc,
263 michael 1997 char *parv[], time_t newts, const char *svsid, char *nick, char *ngecos)
264     {
265     int samenick = 0;
266    
267     if (IsServer(source_p))
268     {
269 michael 3096 const char *server = source_p->name;
270 michael 1997 /* A server introducing a new client, change source */
271 michael 3156 source_p = make_client(source_p->from);
272 michael 1997 dlinkAdd(source_p, &source_p->node, &global_client_list);
273    
274     if (parc > 2)
275     source_p->hopcount = atoi(parv[2]);
276     if (newts)
277     source_p->tsinfo = newts;
278     else
279     {
280     newts = source_p->tsinfo = CurrentTime;
281 michael 3096 sendto_realops_flags_ratelimited("Remote nick %s (%s) introduced without a TS", nick, server);
282 michael 1997 }
283    
284     strlcpy(source_p->svid, svsid, sizeof(source_p->svid));
285     strlcpy(source_p->info, ngecos, sizeof(source_p->info));
286     /* copy the nick in place */
287     strlcpy(source_p->name, nick, sizeof(source_p->name));
288     hash_add_client(source_p);
289    
290     if (parc > 8)
291     {
292     const char *m;
293    
294     /* parse usermodes */
295     for (m = &parv[4][1]; *m; ++m)
296     {
297     unsigned int flag = user_modes[(unsigned char)*m];
298    
299     if ((flag & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE))
300     ++Count.invisi;
301     if ((flag & UMODE_OPER) && !HasUMode(source_p, UMODE_OPER))
302     ++Count.oper;
303    
304     source_p->umodes |= flag & SEND_UMODES;
305     }
306    
307 michael 2955 register_remote_user(source_p, parv[5], parv[6], parv[7]);
308 michael 1997 return;
309     }
310     }
311     else if (source_p->name[0])
312     {
313     samenick = !irccmp(source_p->name, nick);
314    
315 michael 2004 /* Client changing their nick */
316 michael 1997 if (!samenick)
317     {
318     DelUMode(source_p, UMODE_REGISTERED);
319     watch_check_hash(source_p, RPL_LOGOFF);
320     source_p->tsinfo = newts ? newts : CurrentTime;
321     }
322    
323     sendto_common_channels_local(source_p, 1, 0, ":%s!%s@%s NICK :%s",
324 michael 3079 source_p->name, source_p->username,
325 michael 1997 source_p->host, nick);
326    
327 michael 2300 whowas_add_history(source_p, 1);
328 michael 3156 sendto_server(source_p, NOCAPS, NOCAPS, ":%s NICK %s :%lu",
329 michael 1997 ID(source_p), nick, (unsigned long)source_p->tsinfo);
330     }
331    
332     /* set the new nick name */
333     if (source_p->name[0])
334     hash_del_client(source_p);
335    
336     strlcpy(source_p->name, nick, sizeof(source_p->name));
337     hash_add_client(source_p);
338    
339     if (!samenick)
340     watch_check_hash(source_p, RPL_LOGON);
341     }
342    
343     /*
344     * client_from_server()
345     */
346     static void
347 michael 3156 uid_from_server(struct Client *source_p, int parc,
348 michael 1997 char *parv[], time_t newts, const char *svsid, char *nick, char *ugecos)
349     {
350     const char *m = NULL;
351     const char *servername = source_p->name;
352    
353 michael 3156 source_p = make_client(source_p->from);
354 michael 1997 dlinkAdd(source_p, &source_p->node, &global_client_list);
355    
356     source_p->hopcount = atoi(parv[2]);
357     source_p->tsinfo = newts;
358     strlcpy(source_p->svid, svsid, sizeof(source_p->svid));
359    
360     /* copy the nick in place */
361 michael 2046 strlcpy(source_p->name, nick, sizeof(source_p->name));
362 michael 1997 strlcpy(source_p->id, parv[8], sizeof(source_p->id));
363     strlcpy(source_p->sockhost, parv[7], sizeof(source_p->sockhost));
364     strlcpy(source_p->info, ugecos, sizeof(source_p->info));
365    
366     hash_add_client(source_p);
367     hash_add_id(source_p);
368    
369     /* parse usermodes */
370     for (m = &parv[4][1]; *m; ++m)
371     {
372     unsigned int flag = user_modes[(unsigned char)*m];
373    
374     if ((flag & UMODE_INVISIBLE) && !HasUMode(source_p, UMODE_INVISIBLE))
375     ++Count.invisi;
376     if ((flag & UMODE_OPER) && !HasUMode(source_p, UMODE_OPER))
377     ++Count.oper;
378    
379     source_p->umodes |= flag & SEND_UMODES;
380     }
381    
382 michael 2955 register_remote_user(source_p, parv[5], parv[6], servername);
383 michael 1997 }
384    
385     static void
386 michael 3156 perform_nick_collides(struct Client *source_p,
387 michael 2820 struct Client *target_p, int parc, char *parv[],
388 michael 1997 time_t newts, const char *svsid, char *nick, char *gecos, char *uid)
389     {
390 michael 2004 int sameuser = 0;
391 michael 2820
392 michael 2004 /* Server introducing new nick */
393 michael 1997 if (IsServer(source_p))
394     {
395 michael 2004 /* If we don't have a TS, or their TS's are the same, kill both */
396 michael 1997 if (!newts || !target_p->tsinfo || (newts == target_p->tsinfo))
397     {
398     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
399     "Nick collision on %s(%s <- %s)(both killed)",
400 michael 2004 target_p->name, target_p->from->name,
401 michael 3156 source_p->from->name);
402 michael 2820
403 michael 1997 /* if we have a UID, issue a kill for it */
404     if (uid)
405 michael 3156 sendto_one(source_p, ":%s KILL %s :%s (Nick collision (new))",
406 michael 1997 me.id, uid, me.name);
407    
408 michael 2565 kill_client_serv_butone(NULL, target_p,
409     "%s (Nick collision (new))", me.name);
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     exit_client(target_p, &me, "Nick collision (new)");
415     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     /* if it came from a LL server, itd have been source_p,
453 michael 2004 * so we dont need to mark target_p as known
454     */
455 michael 2565 kill_client_serv_butone(source_p, target_p,
456     "%s (Nick collision (new))", me.name);
457 michael 1997
458     AddFlag(target_p, FLAGS_KILLED);
459 michael 2004 exit_client(target_p, &me, "Nick collision");
460    
461     if (!uid && (parc == 9 || parc == 10))
462 michael 3156 nick_from_server(source_p, parc, parv, newts, svsid, nick, gecos);
463 michael 2004 else if (uid && (parc == 10 || parc == 11))
464 michael 3156 uid_from_server(source_p, parc, parv, newts, svsid, nick, gecos);
465 michael 2004 return;
466 michael 1997 }
467     }
468     }
469    
470     /* its a client changing nick and causing a collide */
471     if (!newts || !target_p->tsinfo || (newts == target_p->tsinfo))
472     {
473     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
474     "Nick change collision from %s to %s(%s <- %s)(both killed)",
475 michael 2004 source_p->name, target_p->name, target_p->from->name,
476 michael 3156 source_p->from->name);
477 michael 2820
478 michael 3109 sendto_one_numeric(target_p, &me, ERR_NICKCOLLISION, target_p->name);
479     ++ServerStats.is_kill;
480 michael 1997
481 michael 2565 kill_client_serv_butone(NULL, source_p, "%s (Nick change collision)",
482     me.name);
483 michael 1997
484     ++ServerStats.is_kill;
485 michael 2565 kill_client_serv_butone(NULL, target_p, "%s (Nick change collision)",
486     me.name);
487 michael 1997
488     AddFlag(target_p, FLAGS_KILLED);
489     exit_client(target_p, &me, "Nick collision (new)");
490    
491     AddFlag(source_p, FLAGS_KILLED);
492     exit_client(source_p, &me, "Nick collision (old)");
493     return;
494 michael 2004 }
495     else
496     {
497     sameuser = !irccmp(target_p->username, source_p->username) &&
498     !irccmp(target_p->host, source_p->host);
499    
500     if ((sameuser && newts < target_p->tsinfo) ||
501     (!sameuser && newts > target_p->tsinfo))
502     {
503     if (sameuser)
504     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
505     "Nick change collision from %s to %s(%s <- %s)(older killed)",
506     source_p->name, target_p->name, target_p->from->name,
507 michael 3156 source_p->from->name);
508 michael 2004 else
509     sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
510     "Nick change collision from %s to %s(%s <- %s)(newer killed)",
511     source_p->name, target_p->name, target_p->from->name,
512 michael 3156 source_p->from->name);
513 michael 2004
514     ++ServerStats.is_kill;
515 michael 3156 kill_client_serv_butone(source_p, source_p,
516 michael 2565 "%s (Nick change collision)", me.name);
517 michael 2004 AddFlag(source_p, FLAGS_KILLED);
518    
519     if (sameuser)
520     exit_client(source_p, &me, "Nick collision (old)");
521     else
522     exit_client(source_p, &me, "Nick collision (new)");
523     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 2565 kill_client_serv_butone(source_p, target_p,
539     "%s (Nick collision)", 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     exit_client(target_p, &me, "Nick collision");
546     }
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 981 exit_client(target_p, &me, "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 adx 30 exit_client(target_p, &me, "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 michael 2565 kill_client_serv_butone(NULL, target_p, "%s (ID collision)",
811     me.name);
812 adx 30
813 michael 896 ++ServerStats.is_kill;
814 michael 1219 AddFlag(target_p, FLAGS_KILLED);
815 adx 30 exit_client(target_p, &me, "ID Collision");
816 michael 2820 return 0;
817 adx 30 }
818 michael 1997
819 michael 1169 if ((target_p = hash_find_client(parv[1])) == NULL)
820 michael 3156 uid_from_server(source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]);
821 adx 30 else if (IsUnknown(target_p))
822     {
823     exit_client(target_p, &me, "Overridden");
824 michael 3156 uid_from_server(source_p, parc, parv, newts, svsid, parv[1], parv[parc-1]);
825 adx 30 }
826     else
827 michael 3156 perform_nick_collides(source_p, target_p, parc, parv, newts, svsid, parv[1],
828 michael 1196 parv[parc-1], parv[8]);
829 michael 2820 return 0;
830 adx 30 }
831    
832 michael 2820 static struct Message nick_msgtab =
833     {
834 michael 1230 "NICK", 0, 0, 0, MAXPARA, MFLG_SLOW, 0,
835 michael 2820 { mr_nick, m_nick, ms_nick, m_ignore, m_nick, m_ignore }
836 michael 1230 };
837    
838 michael 2820 static struct Message uid_msgtab =
839     {
840 michael 1230 "UID", 0, 0, 10, MAXPARA, MFLG_SLOW, 0,
841 michael 2820 { m_ignore, m_ignore, ms_uid, m_ignore, m_ignore, m_ignore }
842 michael 1230 };
843    
844     static void
845     module_init(void)
846     {
847     mod_add_cmd(&uid_msgtab);
848     mod_add_cmd(&nick_msgtab);
849     }
850    
851     static void
852     module_exit(void)
853     {
854     mod_del_cmd(&uid_msgtab);
855     mod_del_cmd(&nick_msgtab);
856     }
857    
858 michael 2820 struct module module_entry =
859     {
860 michael 1230 .node = { NULL, NULL, NULL },
861     .name = NULL,
862     .version = "$Revision$",
863     .handle = NULL,
864     .modinit = module_init,
865     .modexit = module_exit,
866     .flags = MODULE_FLAG_CORE
867     };

Properties

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