/* * me_forcenick * parv[1] = forcenick victim * parv[2] = new nickname */ static int me_forcenick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p, *exist_p; const char *user; const char *newnick; user = parv[1]; /* We're supposed to drop servers over protocol violations, but shit happens... */ if(EmptyString(parv[2])) return 0; else { char *s; s = LOCAL_COPY(parv[2]); if(strlen(s) > (size_t) NICKLEN) s[NICKLEN] = '\0'; newnick = s; } if(!clean_nick(newnick)) return 0; if((target_p = find_person(user)) == NULL) return 0; if(IsServer(target_p) || IsMe(target_p)) return 0; if(!MyClient(target_p) && !IsOperGlobalForce(source_p)) return 0; if((exist_p = find_person(newnick)) != NULL) { /* Could just be a case shift */ if(irccmp(target_p->name, newnick)) return 0; /* If it's the same nick, f**k it */ else if(!strcmp(target_p->name, newnick)) return 0; } ilog(L_MAIN, "FORCENICK called for [%s] by %s!%s@%s", target_p->name, source_p->name, source_p->username, source_p->host); if(!MyClient(target_p)) { struct Client *cptr = target_p->servptr; sendto_one(cptr, ":%s ENCAP %s FORCENICK %s :%s", get_id(source_p, cptr), cptr->name, get_id(target_p, cptr), newnick); return 0; } change_nick(target_p, newnick); return 0; }
static int ms_signon(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p; int newts, sameuser; char login[NICKLEN+1]; if(!clean_nick(parv[1])) { ServerStats.is_kill++; sendto_realops_snomask(SNO_DEBUG, L_ALL, "Bad Nick from SIGNON: %s From: %s(via %s)", parv[1], source_p->servptr->name, client_p->name); /* if source_p has an id, kill_client_serv_butone() will * send a kill to client_p, otherwise do it here */ if (!has_id(source_p)) sendto_one(client_p, ":%s KILL %s :%s (Bad nickname from SIGNON)", get_id(&me, client_p), parv[1], me.name); kill_client_serv_butone(client_p, source_p, "%s (Bad nickname from SIGNON)", me.name); source_p->flags |= FLAGS_KILLED; exit_client(NULL, source_p, &me, "Bad nickname from SIGNON"); return 0; } if(!clean_username(parv[2]) || !clean_host(parv[3])) { ServerStats.is_kill++; sendto_realops_snomask(SNO_DEBUG, L_ALL, "Bad user@host from SIGNON: %s@%s From: %s(via %s)", parv[2], parv[3], source_p->servptr->name, client_p->name); /* if source_p has an id, kill_client_serv_butone() will * send a kill to client_p, otherwise do it here */ if (!has_id(source_p)) sendto_one(client_p, ":%s KILL %s :%s (Bad user@host from SIGNON)", get_id(&me, client_p), parv[1], me.name); kill_client_serv_butone(client_p, source_p, "%s (Bad user@host from SIGNON)", me.name); source_p->flags |= FLAGS_KILLED; exit_client(NULL, source_p, &me, "Bad user@host from SIGNON"); return 0; } newts = atol(parv[4]); if(!strcmp(parv[5], "0")) login[0] = '\0'; else if(*parv[5] != '*') { if (clean_nick(parv[5])) rb_strlcpy(login, parv[5], NICKLEN + 1); else return 0; } target_p = find_named_client(parv[1]); if(target_p != NULL && target_p != source_p) { /* In case of collision, follow NICK rules. */ /* XXX this is duplicated code and does not do SAVE */ if(IsUnknown(target_p)) exit_client(NULL, target_p, &me, "Overridden"); else { if(!newts || !target_p->tsinfo || (newts == target_p->tsinfo) || !source_p->user) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "Nick change collision from SIGNON from %s to %s(%s <- %s)(both killed)", source_p->name, target_p->name, target_p->from->name, client_p->name); ServerStats.is_kill++; sendto_one_numeric(target_p, ERR_NICKCOLLISION, form_str(ERR_NICKCOLLISION), target_p->name); kill_client_serv_butone(NULL, source_p, "%s (Nick change collision)", me.name); ServerStats.is_kill++; kill_client_serv_butone(NULL, target_p, "%s (Nick change collision)", me.name); target_p->flags |= FLAGS_KILLED; exit_client(NULL, target_p, &me, "Nick collision(new)"); source_p->flags |= FLAGS_KILLED; exit_client(client_p, source_p, &me, "Nick collision(old)"); return 0; } else { sameuser = !irccmp(target_p->username, source_p->username) && !irccmp(target_p->host, source_p->host); if((sameuser && newts < target_p->tsinfo) || (!sameuser && newts > target_p->tsinfo)) { if(sameuser) sendto_realops_snomask(SNO_GENERAL, L_ALL, "Nick change collision from SIGNON from %s to %s(%s <- %s)(older killed)", source_p->name, target_p->name, target_p->from->name, client_p->name); else sendto_realops_snomask(SNO_GENERAL, L_ALL, "Nick change collision from SIGNON from %s to %s(%s <- %s)(newer killed)", source_p->name, target_p->name, target_p->from->name, client_p->name); ServerStats.is_kill++; sendto_one_numeric(target_p, ERR_NICKCOLLISION, form_str(ERR_NICKCOLLISION), target_p->name); /* kill the client issuing the nickchange */ kill_client_serv_butone(client_p, source_p, "%s (Nick change collision)", me.name); source_p->flags |= FLAGS_KILLED; if(sameuser) exit_client(client_p, source_p, &me, "Nick collision(old)"); else exit_client(client_p, source_p, &me, "Nick collision(new)"); return 0; } else { if(sameuser) sendto_realops_snomask(SNO_GENERAL, L_ALL, "Nick collision from SIGNON on %s(%s <- %s)(older killed)", target_p->name, target_p->from->name, client_p->name); else sendto_realops_snomask(SNO_GENERAL, L_ALL, "Nick collision from SIGNON on %s(%s <- %s)(newer killed)", target_p->name, target_p->from->name, client_p->name); sendto_one_numeric(target_p, ERR_NICKCOLLISION, form_str(ERR_NICKCOLLISION), target_p->name); /* kill the client who existed before hand */ kill_client_serv_butone(client_p, target_p, "%s (Nick collision)", me.name); ServerStats.is_kill++; target_p->flags |= FLAGS_KILLED; (void) exit_client(client_p, target_p, &me, "Nick collision"); } } } } send_signon(client_p, source_p, parv[1], parv[2], parv[3], newts, login); return 0; }
static int me_svslogin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p, *exist_p; char nick[NICKLEN+1], login[NICKLEN+1]; char user[USERLEN+1], host[HOSTLEN+1]; int valid = 0; if(!(source_p->flags & FLAGS_SERVICE)) return 0; if((target_p = find_client(parv[1])) == NULL) return 0; if(!MyClient(target_p) && !IsUnknown(target_p)) return 0; if(clean_nick(parv[2])) { rb_strlcpy(nick, parv[2], NICKLEN + 1); valid |= NICK_VALID; } else if(*target_p->name) rb_strlcpy(nick, target_p->name, NICKLEN + 1); else strcpy(nick, "*"); if(clean_username(parv[3])) { rb_strlcpy(user, parv[3], USERLEN + 1); valid |= USER_VALID; } else rb_strlcpy(user, target_p->username, USERLEN + 1); if(clean_host(parv[4])) { rb_strlcpy(host, parv[4], HOSTLEN + 1); valid |= HOST_VALID; } else rb_strlcpy(host, target_p->host, HOSTLEN + 1); if(*parv[5] == '*') { if(target_p->user) rb_strlcpy(login, target_p->user->suser, NICKLEN + 1); else login[0] = '\0'; } else if(!strcmp(parv[5], "0")) login[0] = '\0'; else rb_strlcpy(login, parv[5], NICKLEN + 1); /* Login (mostly) follows nick rules. */ if(*login && !clean_nick(login)) return 0; if((exist_p = find_person(nick)) && target_p != exist_p) { char buf[BUFSIZE]; if(MyClient(exist_p)) sendto_one(exist_p, ":%s KILL %s :(Nickname regained by services)", me.name, exist_p->name); exist_p->flags |= FLAGS_KILLED; kill_client_serv_butone(NULL, exist_p, "%s (Nickname regained by services)", me.name); rb_snprintf(buf, sizeof(buf), "Killed (%s (Nickname regained by services))", me.name); exit_client(NULL, exist_p, &me, buf); } else if((exist_p = find_client(nick)) && IsUnknown(exist_p) && exist_p != target_p) { exit_client(NULL, exist_p, &me, "Overridden"); } if(*login) { /* Strip leading digits, unless it's purely numeric. */ const char *p = login; while(IsDigit(*p)) p++; if(!*p) p = login; sendto_one(target_p, form_str(RPL_LOGGEDIN), me.name, EmptyString(target_p->name) ? "*" : target_p->name, nick, user, host, p, p); } else sendto_one(target_p, form_str(RPL_LOGGEDOUT), me.name, EmptyString(target_p->name) ? "*" : target_p->name, nick, user, host); if(IsUnknown(target_p)) { struct User *user_p = make_user(target_p); if(valid & NICK_VALID) strcpy(target_p->preClient->spoofnick, nick); if(valid & USER_VALID) strcpy(target_p->preClient->spoofuser, user); if(valid & HOST_VALID) strcpy(target_p->preClient->spoofhost, host); rb_strlcpy(user_p->suser, login, NICKLEN + 1); } else { char note[NICKLEN + 10]; send_signon(NULL, target_p, nick, user, host, rb_current_time(), login); rb_snprintf(note, NICKLEN + 10, "Nick: %s", target_p->name); rb_note(target_p->localClient->F, note); } return 0; }
/* ** mo_forcenick ** parv[1] = forcenick victim ** parv[2] = new nickname */ static int mo_forcenick(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p, *exist_p; const char *user; const char *newnick; user = parv[1]; /* You must be this tall to ride the ride */ if(!IsOperLocalForce(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "local_force"); return 0; } /* Truncate it so clean_nick doesn't spaz out */ if(!EmptyString(parv[2])) { char *s; s = LOCAL_COPY(parv[2]); if(strlen(s) > (size_t) NICKLEN) s[NICKLEN] = '\0'; newnick = s; } else { sendto_one_numeric(source_p, ERR_NONICKNAMEGIVEN, form_str(ERR_NONICKNAMEGIVEN), me.name, source_p->name); return 0; } /* Nick has to be clean or we'll have a protocol violation... */ if(!clean_nick(newnick)) { sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME), me.name, user, newnick); return 0; } /* Find the target... */ if((target_p = find_named_person(user)) == NULL) { sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "FORCENICK"); return 0; } /* If it's a server, sod it, changing its name is stupid... */ if(IsServer(target_p) || IsMe(target_p)) { sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), user); return 0; } /* Do we have permission to send it globally? */ if(!MyClient(target_p) && (!IsOperGlobalForce(source_p))) { sendto_one_notice(source_p, ":Nick %s is not on your server and you do not have the global_force flag", target_p->name); return 0; } /* Check to see if the new nick exists */ if((exist_p = find_named_person(newnick)) != NULL) { /* Could just be a case shift */ if(irccmp(target_p->name, newnick)) { sendto_one(source_p, form_str(ERR_NICKNAMEINUSE), me.name, user, newnick); return 0; } /* If it's the same nick, f**k it */ else if(!strcmp(target_p->name, newnick)) return 0; } sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Received FORCENICK message for %s!%s@%s. From %s (Newnick: %s)", target_p->name, target_p->username, target_p->orighost, source_p->name, newnick); ilog(L_MAIN, "FORCENICK called for [%s] by %s!%s@%s", target_p->name, source_p->name, source_p->username, source_p->host); sendto_one_notice(target_p, ":You have been forcenicked from %s to %s by %s", target_p->name, newnick, source_p->name); if(!MyClient(target_p)) { struct Client *cptr = target_p->servptr; sendto_one(cptr, ":%s ENCAP %s FORCENICK %s :%s", get_id(source_p, cptr), cptr->name, get_id(target_p, cptr), newnick); return 0; } change_nick(target_p, newnick); return 0; }