X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/907468c485f837cb8442c32509c8efec8f3f43b1..8097430a810ac1535fe5304f74991b16ff58b064:/modules/core/m_nick.c diff --git a/modules/core/m_nick.c b/modules/core/m_nick.c index dd827b8..eec78fa 100644 --- a/modules/core/m_nick.c +++ b/modules/core/m_nick.c @@ -27,7 +27,7 @@ #include "stdinc.h" #include "client.h" #include "hash.h" -#include "irc_string.h" +#include "match.h" #include "ircd.h" #include "numeric.h" #include "s_conf.h" @@ -68,7 +68,7 @@ static void bad_nickname(struct Client *, const char *); struct Message nick_msgtab = { "NICK", 0, 0, 0, MFLG_SLOW, - {{mr_nick, 0}, {m_nick, 0}, {mc_nick, 3}, {ms_nick, 8}, mg_ignore, {m_nick, 0}} + {{mr_nick, 0}, {m_nick, 0}, {mc_nick, 3}, {ms_nick, 0}, mg_ignore, {m_nick, 0}} }; struct Message uid_msgtab = { "UID", 0, 0, 0, MFLG_SLOW, @@ -108,7 +108,6 @@ static int perform_nickchange_collides(struct Client *, struct Client *, struct Client *, int, const char **, time_t, const char *); /* mr_nick() - * parv[0] = sender prefix * parv[1] = nickname */ static int @@ -145,7 +144,7 @@ mr_nick(struct Client *client_p, struct Client *source_p, int parc, const char * if(!clean_nick(nick, 1)) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), - me.name, EmptyString(parv[0]) ? "*" : parv[0], parv[1]); + me.name, EmptyString(source_p->name) ? "*" : source_p->name, parv[1]); return 0; } @@ -175,7 +174,6 @@ mr_nick(struct Client *client_p, struct Client *source_p, int parc, const char * } /* m_nick() - * parv[0] = sender prefix * parv[1] = nickname */ static int @@ -208,7 +206,7 @@ m_nick(struct Client *client_p, struct Client *source_p, int parc, const char *p /* check the nickname is ok */ if(!clean_nick(nick, 1)) { - sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, parv[0], nick); + sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, source_p->name, nick); return 0; } @@ -245,7 +243,7 @@ m_nick(struct Client *client_p, struct Client *source_p, int parc, const char *p change_local_nick(client_p, source_p, nick, 1); } else - sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, parv[0], nick); + sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, source_p->name, nick); return 0; } @@ -255,23 +253,11 @@ m_nick(struct Client *client_p, struct Client *source_p, int parc, const char *p return 0; } -/* ms_nick() +/* mc_nick() * * server -> server nick change - * parv[0] = sender prefix * parv[1] = nickname * parv[2] = TS when nick change - * - * server introducing new nick - * parv[0] = sender prefix - * parv[1] = nickname - * parv[2] = hop count - * parv[3] = TS - * parv[4] = umode - * parv[5] = username - * parv[6] = hostname - * parv[7] = server - * parv[8] = ircname */ static int mc_nick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) @@ -316,74 +302,21 @@ mc_nick(struct Client *client_p, struct Client *source_p, int parc, const char * static int ms_nick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { - struct Client *target_p; - time_t newts = 0; - - if(parc != 9) - { - sendto_realops_snomask(SNO_GENERAL, L_ALL, - "Dropping server %s due to (invalid) command 'NICK' " - "with %d arguments (expecting 9)", client_p->name, parc); - ilog(L_SERVER, "Excess parameters (%d) for command 'NICK' from %s.", - parc, client_p->name); - exit_client(client_p, client_p, client_p, "Excess parameters to NICK command"); - return 0; - } - - /* if nicks empty, erroneous, or too long, kill */ - if(!clean_nick(parv[1], 0)) - { - bad_nickname(client_p, parv[1]); - return 0; - } - - /* invalid username or host? */ - if(!clean_username(parv[5]) || !clean_host(parv[6])) - { - ServerStats.is_kill++; - sendto_realops_snomask(SNO_DEBUG, L_ALL, - "Bad user@host: %s@%s From: %s(via %s)", - parv[5], parv[6], parv[7], client_p->name); - sendto_one(client_p, ":%s KILL %s :%s (Bad user@host)", me.name, parv[1], me.name); - return 0; - } + const char *nick, *server; - /* check the length of the clients gecos */ - if(strlen(parv[8]) > REALLEN) - { - char *s = LOCAL_COPY(parv[8]); - /* why exactly do we care? --fl */ - sendto_realops_snomask(SNO_GENERAL, L_ALL, - "Long realname from server %s for %s", parv[7], parv[1]); + nick = parc > 1 ? parv[1] : "?"; + server = parc > 7 ? parv[7] : "?"; - s[REALLEN] = '\0'; - parv[8] = s; - } - - newts = atol(parv[3]); + sendto_wallops_flags(UMODE_WALLOP, &me, + "Link %s cancelled, TS5 nickname %s on %s introduced (old server?)", + client_p->name, nick, server); + sendto_server(NULL, NULL, CAP_TS6, NOCAPS, + ":%s WALLOPS :Link %s cancelled, TS5 nickname %s on %s introduced (old server?)", + me.id, client_p->name, nick, server); + ilog(L_SERVER, "Link %s cancelled, TS5 nickname %s on %s introduced (old server?)", + client_p->name, nick, server); - target_p = find_named_client(parv[1]); - - /* if the nick doesnt exist, allow it and process like normal */ - if(target_p == NULL) - { - register_client(client_p, NULL, parv[1], newts, parc, parv); - } - else if(IsUnknown(target_p)) - { - exit_client(NULL, target_p, &me, "Overridden"); - register_client(client_p, NULL, parv[1], newts, parc, parv); - } - else if(target_p == source_p) - { - /* client changing case of nick */ - if(strcmp(target_p->name, parv[1])) - register_client(client_p, NULL, parv[1], newts, parc, parv); - } - /* we've got a collision! */ - else - perform_nick_collides(source_p, client_p, target_p, parc, parv, - newts, parv[1], NULL); + exit_client(client_p, client_p, &me, "TS5 nickname introduced"); return 0; } @@ -404,6 +337,7 @@ ms_uid(struct Client *client_p, struct Client *source_p, int parc, const char *p { struct Client *target_p; time_t newts = 0; + char squitreason[120]; newts = atol(parv[3]); @@ -414,7 +348,10 @@ ms_uid(struct Client *client_p, struct Client *source_p, int parc, const char *p "with %d arguments (expecting 10)", client_p->name, parc); ilog(L_SERVER, "Excess parameters (%d) for command 'UID' from %s.", parc, client_p->name); - exit_client(client_p, client_p, client_p, "Excess parameters to UID command"); + rb_snprintf(squitreason, sizeof squitreason, + "Excess parameters (%d) to %s command, expecting %d", + parc, "UID", 10); + exit_client(client_p, client_p, client_p, squitreason); return 0; } @@ -425,23 +362,22 @@ ms_uid(struct Client *client_p, struct Client *source_p, int parc, const char *p return 0; } - if(!clean_username(parv[5]) || !clean_host(parv[6])) + if(!clean_uid(parv[8])) { - ServerStats.is_kill++; - sendto_realops_snomask(SNO_DEBUG, L_ALL, - "Bad user@host: %s@%s From: %s(via %s)", - parv[5], parv[6], source_p->name, client_p->name); - sendto_one(client_p, ":%s KILL %s :%s (Bad user@host)", me.id, parv[8], me.name); + rb_snprintf(squitreason, sizeof squitreason, + "Invalid UID %s for nick %s on %s", + parv[8], parv[1], source_p->name); + exit_client(client_p, client_p, client_p, squitreason); return 0; } - if(!clean_uid(parv[8])) + if(!clean_username(parv[5]) || !clean_host(parv[6])) { ServerStats.is_kill++; sendto_realops_snomask(SNO_DEBUG, L_ALL, - "Bad UID: %s From: %s(via %s)", - parv[8], source_p->name, client_p->name); - sendto_one(client_p, ":%s KILL %s :%s (Bad UID)", me.id, parv[8], me.name); + "Bad user@host: %s@%s From: %s(via %s)", + parv[5], parv[6], source_p->name, client_p->name); + sendto_one(client_p, ":%s KILL %s :%s (Bad user@host)", me.id, parv[8], me.name); return 0; } @@ -450,7 +386,7 @@ ms_uid(struct Client *client_p, struct Client *source_p, int parc, const char *p { char *s = LOCAL_COPY(parv[9]); sendto_realops_snomask(SNO_GENERAL, L_ALL, "Long realname from server %s for %s", - parv[0], parv[1]); + source_p->name, parv[1]); s[REALLEN] = '\0'; parv[9] = s; } @@ -492,6 +428,7 @@ ms_euid(struct Client *client_p, struct Client *source_p, int parc, const char * { struct Client *target_p; time_t newts = 0; + char squitreason[120]; newts = atol(parv[3]); @@ -502,7 +439,10 @@ ms_euid(struct Client *client_p, struct Client *source_p, int parc, const char * "with %d arguments (expecting 12)", client_p->name, parc); ilog(L_SERVER, "Excess parameters (%d) for command 'EUID' from %s.", parc, client_p->name); - exit_client(client_p, client_p, client_p, "Excess parameters to EUID command"); + rb_snprintf(squitreason, sizeof squitreason, + "Excess parameters (%d) to %s command, expecting %d", + parc, "EUID", 12); + exit_client(client_p, client_p, client_p, squitreason); return 0; } @@ -513,23 +453,22 @@ ms_euid(struct Client *client_p, struct Client *source_p, int parc, const char * return 0; } - if(!clean_username(parv[5]) || !clean_host(parv[6])) + if(!clean_uid(parv[8])) { - ServerStats.is_kill++; - sendto_realops_snomask(SNO_DEBUG, L_ALL, - "Bad user@host: %s@%s From: %s(via %s)", - parv[5], parv[6], source_p->name, client_p->name); - sendto_one(client_p, ":%s KILL %s :%s (Bad user@host)", me.id, parv[8], me.name); + rb_snprintf(squitreason, sizeof squitreason, + "Invalid UID %s for nick %s on %s", + parv[8], parv[1], source_p->name); + exit_client(client_p, client_p, client_p, squitreason); return 0; } - if(!clean_uid(parv[8])) + if(!clean_username(parv[5]) || !clean_host(parv[6])) { ServerStats.is_kill++; sendto_realops_snomask(SNO_DEBUG, L_ALL, - "Bad UID: %s From: %s(via %s)", - parv[8], source_p->name, client_p->name); - sendto_one(client_p, ":%s KILL %s :%s (Bad UID)", me.id, parv[8], me.name); + "Bad user@host: %s@%s From: %s(via %s)", + parv[5], parv[6], source_p->name, client_p->name); + sendto_one(client_p, ":%s KILL %s :%s (Bad user@host)", me.id, parv[8], me.name); return 0; } @@ -548,7 +487,7 @@ ms_euid(struct Client *client_p, struct Client *source_p, int parc, const char * { char *s = LOCAL_COPY(parv[11]); sendto_realops_snomask(SNO_GENERAL, L_ALL, "Long realname from server %s for %s", - parv[0], parv[1]); + source_p->name, parv[1]); s[REALLEN] = '\0'; parv[11] = s; } @@ -752,6 +691,16 @@ change_local_nick(struct Client *client_p, struct Client *source_p, nick, chptr->chname); return; } + + chptr = find_nonickchange_channel(source_p); + if (chptr != NULL) + { + sendto_one_numeric(source_p, ERR_NONICK, + form_str(ERR_NONICK), + chptr->chname); + return; + } + if((source_p->localClient->last_nick_change + ConfigFileEntry.max_nick_time) < rb_current_time()) source_p->localClient->number_of_nick_changes = 0; @@ -801,8 +750,6 @@ change_local_nick(struct Client *client_p, struct Client *source_p, { sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s NICK %s :%ld", use_id(source_p), nick, (long) source_p->tsinfo); - sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s NICK %s :%ld", - source_p->name, nick, (long) source_p->tsinfo); } } @@ -862,8 +809,6 @@ change_remote_nick(struct Client *client_p, struct Client *source_p, { sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s NICK %s :%ld", use_id(source_p), nick, (long) source_p->tsinfo); - sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s NICK %s :%ld", - source_p->name, nick, (long) source_p->tsinfo); } } @@ -901,7 +846,7 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p, /* if we dont have a ts, or their TS's are the same, kill both */ if(!newts || !target_p->tsinfo || (newts == target_p->tsinfo)) { - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_SKILL, L_ALL, "Nick collision on %s(%s <- %s)(both %s)", target_p->name, target_p->from->name, client_p->name, action); @@ -964,12 +909,12 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p, else { if(sameuser) - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_SKILL, L_ALL, "Nick collision on %s(%s <- %s)(older %s)", target_p->name, target_p->from->name, client_p->name, action); else - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_SKILL, L_ALL, "Nick collision on %s(%s <- %s)(newer %s)", target_p->name, target_p->from->name, client_p->name, action); @@ -993,7 +938,7 @@ perform_nick_collides(struct Client *source_p, struct Client *client_p, (void) exit_client(client_p, target_p, &me, "Nick collision"); } - register_client(client_p, parc >= 10 ? source_p : NULL, + register_client(client_p, source_p, nick, newts, parc, parv); return 0; @@ -1018,7 +963,7 @@ perform_nickchange_collides(struct Client *source_p, struct Client *client_p, /* its a client changing nick and causing a collide */ if(!newts || !target_p->tsinfo || (newts == target_p->tsinfo) || !source_p->user) { - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_SKILL, L_ALL, "Nick change collision from %s to %s(%s <- %s)(both %s)", source_p->name, target_p->name, target_p->from->name, client_p->name, action); @@ -1061,12 +1006,12 @@ perform_nickchange_collides(struct Client *source_p, struct Client *client_p, (!sameuser && newts > target_p->tsinfo)) { if(sameuser) - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_SKILL, L_ALL, "Nick change collision from %s to %s(%s <- %s)(older %s)", source_p->name, target_p->name, target_p->from->name, client_p->name, action); else - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_SKILL, L_ALL, "Nick change collision from %s to %s(%s <- %s)(newer %s)", source_p->name, target_p->name, target_p->from->name, client_p->name, action); @@ -1106,12 +1051,12 @@ perform_nickchange_collides(struct Client *source_p, struct Client *client_p, else { if(sameuser) - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_SKILL, L_ALL, "Nick collision on %s(%s <- %s)(older %s)", target_p->name, target_p->from->name, client_p->name, action); else - sendto_realops_snomask(SNO_GENERAL, L_ALL, + sendto_realops_snomask(SNO_SKILL, L_ALL, "Nick collision on %s(%s <- %s)(newer %s)", target_p->name, target_p->from->name, client_p->name, action); @@ -1152,19 +1097,6 @@ register_client(struct Client *client_p, struct Client *server, const char *m; int flag; - if(server == NULL) - { - if((server = find_server(NULL, parv[7])) == NULL) - { - sendto_realops_snomask(SNO_GENERAL, L_ALL, - "Ghost killed: %s on invalid server %s", - nick, parv[7]); - sendto_one(client_p, ":%s KILL %s :%s (Server doesn't exist)", - get_id(&me, client_p), nick, me.name); - return 0; - } - } - source_p = make_client(client_p); user = make_user(source_p); rb_dlinkAddTail(source_p, &source_p->node, &global_client_list); @@ -1201,7 +1133,7 @@ register_client(struct Client *client_p, struct Client *server, } else { - rb_strlcpy(source_p->info, parv[8], sizeof(source_p->info)); + s_assert(0); } /* remove any nd entries for this nick */ @@ -1262,23 +1194,6 @@ register_client(struct Client *client_p, struct Client *server, rb_dlinkAdd(source_p, &source_p->lnode, &source_p->servptr->serv->users); - /* fake direction */ - if(source_p->servptr->from != source_p->from) - { - struct Client *target_p = source_p->servptr->from; - - sendto_realops_snomask(SNO_DEBUG, L_ALL, - "Bad User [%s] :%s USER %s@%s %s, != %s[%s]", - client_p->name, source_p->name, - source_p->username, source_p->host, - server->name, target_p->name, target_p->from->name); - kill_client(client_p, source_p, - "%s (NICK from wrong direction (%s != %s))", - me.name, server->name, target_p->from->name); - source_p->flags |= FLAGS_KILLED; - return exit_client(source_p, source_p, &me, "USER server wrong direction"); - } - call_hook(h_new_remote_user, source_p); return (introduce_client(client_p, source_p, user, nick, parc == 12)); @@ -1327,8 +1242,6 @@ save_user(struct Client *client_p, struct Client *source_p, source_p->id, target_p->id, (long)target_p->tsinfo); sendto_server(client_p, NULL, CAP_TS6, CAP_SAVE, ":%s NICK %s :%ld", target_p->id, target_p->id, (long)SAVE_NICKTS); - sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s NICK %s :%ld", - target_p->name, target_p->id, (long)SAVE_NICKTS); if (!IsMe(client_p)) sendto_realops_snomask(SNO_SKILL, L_ALL, "Received SAVE message for %s from %s", @@ -1354,9 +1267,8 @@ static void bad_nickname(struct Client *client_p, const char *nick) sendto_server(NULL, NULL, CAP_TS6, NOCAPS, ":%s WALLOPS :Squitting %s because of bad nickname %s (NICKLEN mismatch?)", me.id, client_p->name, nick); - sendto_server(NULL, NULL, NOCAPS, CAP_TS6, - ":%s WALLOPS :Squitting %s because of bad nickname %s (NICKLEN mismatch?)", - me.name, client_p->name, nick); + ilog(L_SERVER, "Link %s cancelled, bad nickname %s sent (NICKLEN mismatch?)", + client_p->name, nick); rb_snprintf(squitreason, sizeof squitreason, "Bad nickname introduced [%s]", nick);