static void mo_chgident(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { struct Client *target_p = NULL; if (MyClient(source_p) && !IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "CHGIDENT"); return; } if (EmptyString(parv[2])) { parv[2] = parv[1]; target_p = source_p; if (!IsClient(target_p)) return; } else { target_p = find_client(parv[1]); if (target_p == NULL || !IsClient(target_p)) { sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, parv[1]); return; } } if (strlen(parv[2]) > USERLEN || !*parv[2] || !valid_username(parv[2])) { sendto_one(source_p, ":%s NOTICE %s :Invalid username", me.name, source_p->name); return; } if (IsUserHostIp(target_p)) delete_user_host(target_p->username, target_p->host, !MyConnect(target_p)); strlcpy(target_p->username, parv[2], sizeof(target_p->username)); add_user_host(target_p->username, target_p->host, !MyConnect(target_p)); SetUserHost(target_p); if (MyClient(source_p)) { sendto_server(client_p, NULL, NOCAPS, NOCAPS, ":%s ENCAP * CHGIDENT %s %s", source_p->name, target_p->name, parv[2]); sendto_one(source_p, ":%s NOTICE %s :%s changed to %s@%s", me.name, source_p->name, target_p->name, target_p->username, target_p->host); } if (MyConnect(target_p) && IsClient(source_p)) sendto_one(target_p, ":%s NOTICE %s :You are now %s@%s", me.name, target_p->name, target_p->username, target_p->host); }
/* Disable this because of the abuse potential -- jilles * No, make it toggleable via ./configure. --nenolod */ static int mo_chghost(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p; if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin"); return 0; } if (!(target_p = find_named_person(parv[1]))) { sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), parv[1]); return 0; } if (!clean_host(parv[2])) { sendto_one_notice(source_p, ":Hostname %s is invalid", parv[2]); return 0; } do_chghost(source_p, target_p, parv[2], 0); sendto_server(NULL, NULL, CAP_EUID | CAP_TS6, NOCAPS, ":%s CHGHOST %s %s", use_id(source_p), use_id(target_p), parv[2]); sendto_server(NULL, NULL, CAP_TS6, CAP_EUID, ":%s ENCAP * CHGHOST %s :%s", use_id(source_p), use_id(target_p), parv[2]); return 0; }
static int mo_privs(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p; if (parc < 2 || EmptyString(parv[1])) target_p = source_p; else if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin"); return 0; } else { target_p = find_named_person(parv[1]); if (target_p == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), parv[1]); return 0; } } if (MyClient(target_p)) show_privs(source_p, target_p); else sendto_one(target_p, ":%s ENCAP %s PRIVS %s", get_id(source_p, target_p), target_p->servptr->name, use_id(target_p)); return 0; }
static int whowas_do(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { struct Whowas *temp; int cur = 0; int max = -1, found = 0; char *p, *nick; if(parc < 2 || BadPtr(parv[1])) { sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]); return 0; } if(parc > 2) max = atoi(parv[2]); if(parc > 3) if(hunt_server(client_p, source_p, ":%s WHOWAS %s %s :%s", 3, parc, parv)) return 0; if((p = strchr(parv[1], ','))) *p = '\0'; nick = parv[1]; temp = WHOWASHASH[hash_whowas_name(nick)]; found = 0; for (; temp; temp = temp->next) { if(!irccmp(nick, temp->name)) { sendto_one(source_p, form_str(RPL_WHOWASUSER), me.name, parv[0], temp->name, temp->username, (IsOperAdmin(source_p))? temp->hostname : temp->rhostname, temp->realname); if(ConfigServerHide.hide_servers && !IsOper(source_p)) sendto_one(source_p, form_str(RPL_WHOISSERVER), me.name, parv[0], temp->name, ServerInfo.network_name, myctime(temp->logoff)); else sendto_one(source_p, form_str(RPL_WHOISSERVER), me.name, parv[0], temp->name, temp->servername, myctime(temp->logoff)); cur++; found++; } if(max > 0 && cur >= max) break; } if(!found) sendto_one(source_p, form_str(ERR_WASNOSUCHNICK), me.name, parv[0], nick); sendto_one(source_p, form_str(RPL_ENDOFWHOWAS), me.name, parv[0], parv[1]); return 0; }
static int mo_forcepart(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p; struct Channel *chptr; struct membership *msptr; if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "forcepart"); return 0; } if((hunt_server(client_p, source_p, ":%s FORCEPART %s %s", 1, parc, parv)) != HUNTED_ISME) return 0; /* if target_p == NULL then let the oper know */ if((target_p = find_client(parv[1])) == NULL) { sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, parv[1]); return 0; } if(!IsClient(target_p)) return 0; if((chptr = find_channel(parv[2])) == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), parv[1]); return 0; } if((msptr = find_channel_membership(chptr, target_p)) == NULL) { sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL), me.name, source_p->name, parv[1], parv[2]); return 0; } sendto_server(target_p, chptr, NOCAPS, NOCAPS, ":%s PART %s :%s", target_p->name, chptr->chname, target_p->name); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s", target_p->name, target_p->username, target_p->host, chptr->chname, target_p->name); remove_user_from_channel(msptr); return 0; }
static void mo_chgname(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { struct Client *target_p = NULL; if (MyClient(source_p) && !IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "CHGNAME"); return; } if (EmptyString(parv[2])) { parv[2] = parv[1]; target_p = source_p; } else if ((target_p = find_client(parv[1])) == NULL) { sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, parv[1]); return; } if (strlen(parv[2]) > REALLEN || !*parv[2]) { sendto_one(source_p, ":%s NOTICE %s :Invalid realname", me.name, source_p->name); return; } if (parc > 3 && MyClient(source_p)) sendto_one(source_p, ":%s NOTICE %s :Warning -- too many parameters " "for CHGNAME. You are probably missing a : before the new " "IRC name.", me.name, source_p->name); strlcpy(target_p->info, parv[2], sizeof(target_p->info)); if (MyClient(source_p)) { sendto_server(client_p, NULL, NOCAPS, NOCAPS, ":%s ENCAP * CHGNAME %s :%s", source_p->name, target_p->name, parv[2]); sendto_one(source_p, ":%s NOTICE %s :%s realname changed to [%s]", me.name, source_p->name, target_p->name, target_p->info); } if (MyClient(target_p) && IsClient(source_p)) sendto_one(target_p, ":%s NOTICE %s :Your realname is now [%s]", me.name, target_p->name, target_p->info); }
/* * show_ports - send port listing to a client * inputs - pointer to client to show ports to * output - none * side effects - show ports */ void show_ports(struct Client *source_p) { struct Listener *listener = 0; for (listener = ListenerPollList; listener; listener = listener->next) { sendto_one_numeric(source_p, RPL_STATSPLINE, form_str(RPL_STATSPLINE), 'P', get_listener_port(listener), IsOperAdmin(source_p) ? listener->name : me.name, listener->ref_count, (listener->active) ? "active" : "disabled", listener->ssl ? " ssl" : ""); } }
/* * show_ports - send port listing to a client * inputs - pointer to client to show ports to * output - none * side effects - show ports */ void show_ports(struct Client* source_p) { struct Listener* listener = 0; for (listener = ListenerPollList; listener; listener = listener->next) { sendto_one(source_p, form_str(RPL_STATSPLINE), me.name, source_p->name, 'P', listener->port, IsOperAdmin(source_p) ? listener->name : me.name, listener->ref_count, (listener->active)?"active":"disabled"); } }
/* SET IDENTTIMEOUT */ static void quote_identtimeout(struct Client *source_p, const char *arg, int newval) { if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin"); return; } if(newval > 0) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s has changed IDENTTIMEOUT to %d", get_oper_name(source_p), newval); GlobalSetOptions.ident_timeout = newval; } else sendto_one_notice(source_p, ":IDENTTIMEOUT is currently %d", GlobalSetOptions.ident_timeout); }
/* * show_ports - send port listing to a client * inputs - pointer to client to show ports to * output - none * side effects - show ports */ void show_ports(struct Client *source_p) { struct Listener *listener = 0; for (listener = ListenerPollList; listener; listener = listener->next) { sendto_one_numeric(source_p, RPL_STATSPLINE, form_str(RPL_STATSPLINE), 'P', #ifdef RB_IPV6 ntohs(listener->addr.ss_family == AF_INET ? ((struct sockaddr_in *)&listener->addr)->sin_port : ((struct sockaddr_in6 *)&listener->addr)->sin6_port), #else ntohs(((struct sockaddr_in *)&listener->addr)->sin_port), #endif IsOperAdmin(source_p) ? listener->name : me.name, listener->ref_count, (listener->active) ? "active" : "disabled", listener->ssl ? " ssl" : ""); } }
/* SET IDENTTIMEOUT */ static void quote_identtimeout(struct Client *source_p, int newval) { if(!IsOperAdmin(source_p)) { sendto_one(source_p, ":%s NOTICE %s :You have no A flag", me.name, source_p->name); return; } if(newval > 0) { sendto_realops_flags(UMODE_ALL, L_ALL, "%s has changed IDENTTIMEOUT to %d", get_oper_name(source_p), newval); GlobalSetOptions.ident_timeout = newval; } else sendto_one(source_p, ":%s NOTICE %s :IDENTTIMEOUT is currently %d", me.name, source_p->name, GlobalSetOptions.ident_timeout); }
/* load a module .. */ static void mo_modload(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char **parv) { if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin"); return; } if(parc > 2) { sendto_match_servs(source_p, parv[2], CAP_ENCAP, NOCAPS, "ENCAP %s MODLOAD %s", parv[2], parv[1]); if(match(parv[2], me.name) == 0) return; } do_modload(source_p, parv[1]); }
static int mo_dehelper(struct Client *client_p, struct Client *source_p, int parc, const char **parv) { struct Client *target_p; if (!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin"); return 0; } if(!(target_p = find_named_person(parv[1]))) { sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), me.name, parv[1]); return 0; } if(MyClient(target_p)) do_dehelper(source_p, target_p); else sendto_one(target_p, ":%s ENCAP %s DEHELPER %s", use_id(source_p), target_p->servptr->name, use_id(target_p)); return 0; }
/* Now, our job is a bit harder. I will scan through the SPOOF_FILE * and read all auths{} (assuming they are written in our line formatting..), * then rewrite them skipping the one to delete. --adx */ static void mo_delspoof(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { #ifdef SPOOF_FILE FBFILE *f, *fout; int ignore_it = 1, spoof_found = 0; char buffer[1024], *tmp; #endif const char *user = NULL; char *host = NULL; if (MyConnect(source_p) && !IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, parv[0], "DELSPOOF"); return; } if (parv[1] == NULL || !*parv[1]) { if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :Syntax: /DELSPOOF <user@host>", me.name, source_p->name); return; } /* check user@host mask */ (void) collapse(parv[1]); host = strchr(parv[1], '@'); if (host != NULL) { user = parv[1]; *host = '\0'; host++; } else { user = "******"; host = parv[1]; } #ifdef PROPAGATE_SPOOF sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, LL_ICLIENT, ":%s DELSPOOF %s@%s", source_p->name, user, host); #endif #ifdef SPOOF_FILE if ((f = fbopen(SPOOF_FILE, "r")) == NULL) { sendto_realops_flags(UMODE_ALL, L_ALL, "Could not open %s file, auth for %s@%s not deleted " "(requested by %s)", SPOOF_FILE, user, host, source_p->name); return; } if ((fout = fbopen(SPOOF_FILE ".new", "w")) == NULL) { sendto_realops_flags(UMODE_ALL, L_ALL, "Could not create %s.new file, auth for %s@%s not " "deleted (requested by %s)", SPOOF_FILE, user, host, source_p->name); return; } while (fbgets(buffer, 1024, f)) { if (!ircncmp(buffer, "auth {", 6)) { /* don't process it yet.. we have to check whether the user="******"; field * matches the user@host mask which is being deleted */ ignore_it = 1; continue; } /* a simple parser substitute... */ for (tmp = buffer; *tmp == '\t' || *tmp == ' '; tmp++) ; if (!ircncmp(tmp, "user", 4)) { for (tmp += 4; *tmp == '\t' || *tmp == ' '; tmp++) ; if (*tmp == '=') { for (++tmp; *tmp == '\t' || *tmp == ' '; tmp++) ; if (*tmp == '\"') { /* yuppi, we've just reached the user="******"; field */ int matches; char *tmp2 = strchr(++tmp, '\"'); if (tmp2 != NULL) *tmp2 = '\0'; tmp2 = strchr(tmp, '@'); /* is it matching our mask? */ if (tmp2 == NULL) matches = !irccmp(user, "*") && !irccmp(host, tmp); else { *tmp2++ = '\0'; matches = !irccmp(user, tmp) && !irccmp(host, tmp2); } if (!matches) { /* no.. so leave it unchanged */ if (ignore_it) { ignore_it = 0; fbputs("auth {\n", fout, 7); /* user="******" should be the first field in the auth {}; block, * otherwise we could have problems... */ } fbputs("\tuser = \"", fout, 9); if (tmp2 == NULL) fbputs("*", fout, 1); else fbputs(tmp, fout, strlen(tmp)); fbputs("@", fout, 1); fbputs(tmp2, fout, strlen(tmp2)); fbputs("\";\n", fout, 3); } else { /* we've got it! - omit and continue working */ spoof_found = 1; } continue; } } } if (!ignore_it) fbputs(buffer, fout, strlen(buffer)); } fbclose(f); fbclose(fout); if (!spoof_found) { if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :No auth for %s@%s found", me.name, source_p->name, user, host); unlink(SPOOF_FILE ".new"); return; } unlink(SPOOF_FILE); rename(SPOOF_FILE ".new", SPOOF_FILE); rehash(0); #endif #ifdef LOG_SPOOF sendto_realops_flags(UMODE_ALL, L_ALL, "%s deleted auth for %s@%s", source_p->name, user, host); #endif }
static void mo_spoof(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { char *host, *spoof, *password; const char *tmp = NULL; const char *user = NULL; const char *flags = NULL; int i = 0; #ifdef SPOOF_FILE int class_opers; FBFILE *f; char buffer[1024]; struct AddressRec *arec; #endif if (MyConnect(source_p) && !IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "SPOOF"); return; } /* check the user@host mask */ if (strchr(parv[1], '!') != NULL) { syntax: if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :Syntax: SPOOF <umask@hmask> " "<spoof/-> [flags/- [password]]", me.name, source_p->name); return; } (void) collapse(parv[1]); for (tmp = parv[1]; *tmp; tmp++) if (!IsKWildChar(*tmp)) if (++i >= ConfigFileEntry.min_nonwildcard) break; if (i < ConfigFileEntry.min_nonwildcard) { if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :Not enough non-wildcard characters " "in user@host mask", me.name, source_p->name); return; } host = strchr(parv[1], '@'); if (host) { user = parv[1]; *host = '\0'; host++; } else { user = "******"; host = parv[1]; } /* check the spoof field */ spoof = parv[2]; if (spoof == NULL || !*spoof) goto syntax; if (spoof[0] != '-' || spoof[1] != '\0') { for (tmp = spoof; *tmp; tmp++) if (!IsHostChar(*tmp)) { if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :The spoof [%s] is invalid", me.name, source_p->name, spoof); return; } if (strlen(spoof) >= HOSTLEN) { if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :Spoofs must be less than %d.." "ignoring it", me.name, source_p->name, HOSTLEN); return; } } flags = (parc > 3) ? parv[3] : "-"; password = (parc > 4 && parv[4][0]) ? parv[4] : NULL; #ifdef PROPAGATE_SPOOF sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, LL_ICLIENT, ":%s SPOOF %s@%s %s %s :%s", source_p->name, user, host, spoof, flags, password ? password : ""); #endif #ifdef SPOOF_FILE /* Walk through auth {} items and check if we have another auth block * for this hostname */ for (i = 0; i < ATABLE_SIZE; i++) for (arec = atable[i]; arec; arec = arec->next) if (arec->type == CONF_CLIENT && !irccmp(arec->aconf->host, host) && !irccmp(arec->aconf->user, user)) { /* auth entry already exists */ if (MyConnect(source_p)) sendto_one(source_p, ":%s NOTICE %s :auth for %s@%s already exists, you need " "to use /DELSPOOF first", me.name, source_p->name, user, host); #ifdef LOG_SPOOF sendto_realops_flags(UMODE_ALL, L_ALL, "%s attemped to re-add auth for %s@%s " "[spoof: %s, flags: %s]", source_p->name, user, host, spoof, flags); #endif return; } /* Add the spoof to the the spoof file */ if ((f = fbopen(SPOOF_FILE, "a")) == NULL) { sendto_realops_flags(UMODE_ALL, L_ALL, "Could not open %s file, auth for %s@%s " "[spoof: %s, flags: %s, requested by %s] not added", SPOOF_FILE, user, host, spoof, flags, source_p->name); return; } /* write the auth {} block */ fbputs("auth {\n", f, 7); i = ircsprintf(buffer, "\tuser = \"%s@%s\";\n", user, host); fbputs(buffer, f, i); if (spoof[0] != '-' || spoof[1] != '\0') { i = ircsprintf(buffer, "\tspoof = \"%s\";\n", spoof); fbputs(buffer, f, i); } if (password) { i = ircsprintf(buffer, "\tpassword = \"%s\";\n", password); fbputs(buffer, f, i); } /* process given flags */ i = class_opers = 0; for (tmp = flags; *tmp; ++tmp) switch (*tmp) { case 't': i |= CONF_FLAGS_NO_TILDE; /* no_tilde = yes; */ break; case 'i': i |= CONF_FLAGS_NEED_IDENTD; /* need_ident = yes; */ break; case 'k': i |= CONF_FLAGS_EXEMPTKLINE; /* kline_exempt = yes; */ break; case 'g': i |= CONF_FLAGS_EXEMPTGLINE; /* gline_exempt = yes; */ break; case 'l': i |= CONF_FLAGS_NOLIMIT; /* exceed_limit = yes; */ break; case 'o': class_opers = 1; /* class = "opers"; */ break; case 'f': i |= CONF_FLAGS_CAN_FLOOD; /* can_flood = yes; */ break; case 'p': i|= CONF_FLAGS_NEED_PASSWORD; /* need_password = yes; */ } if (i) { fbputs("\tflags = ", f, 9); try_flag(f, &i, CONF_FLAGS_NO_TILDE, "no_tilde"); try_flag(f, &i, CONF_FLAGS_NEED_IDENTD, "need_ident"); try_flag(f, &i, CONF_FLAGS_EXEMPTKLINE, "kline_exempt"); try_flag(f, &i, CONF_FLAGS_EXEMPTGLINE, "gline_exempt"); try_flag(f, &i, CONF_FLAGS_NOLIMIT, "exceed_limit"); try_flag(f, &i, CONF_FLAGS_CAN_FLOOD, "can_flood"); try_flag(f, &i, CONF_FLAGS_NEED_PASSWORD, "need_password"); } if (class_opers) fbputs("\tclass = \"opers\";\n", f, 18); else fbputs("\tclass = \"users\";\n", f, 18); fbputs("};\n\n", f, 4); fbclose(f); rehash(0); #endif #ifdef LOG_SPOOF sendto_realops_flags(UMODE_ALL, L_ALL, "%s added auth for %s@%s [spoof: %s, flags: %s]", source_p->name, user, host, spoof, flags); ilog(L_TRACE, "%s added auth for %s@%s [spoof: %s, flags: %s]", source_p->name, user, host, spoof, flags); #endif }
/* ** mo_ojoin ** parv[1] = channel */ static int mo_ojoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Channel *chptr; int move_me = 0; /* admins only */ if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin"); return 0; } if(*parv[1] == '@' || *parv[1] == '%' || *parv[1] == '+' || *parv[1] == '!' || *parv[1] == '~') { parv[1]++; move_me = 1; } else { sendto_one_notice(source_p, ":Unrecognized op prefix '%c'", *parv[1]); return 0; } if((chptr = find_channel(parv[1])) == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), parv[1]); return 0; } if(IsMember(source_p, chptr)) { sendto_one_notice(source_p, ":Please part %s before using OJOIN", parv[1]); return 0; } if(move_me == 1) parv[1]--; /* only sends stuff for #channels remotely */ if(*parv[1] == '!') { if(!ConfigChannel.use_admin) { sendto_one_notice(source_p, ":This server's configuration file does not support admin prefix"); return 0; } add_user_to_channel(chptr, source_p, CHFL_ADMIN); sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s SJOIN %ld %s + :!%s", me.id, (long) chptr->channelts, chptr->chname, source_p->id); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s", source_p->name, source_p->username, source_p->host, chptr->chname); sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +a %s", me.name, chptr->chname, source_p->name); } else if(*parv[1] == '@') { add_user_to_channel(chptr, source_p, CHFL_CHANOP); sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s SJOIN %ld %s + :@%s", me.id, (long) chptr->channelts, chptr->chname, source_p->id); send_channel_join(chptr, source_p); sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s", me.name, chptr->chname, source_p->name); } else if(*parv[1] == '%') { if(!ConfigChannel.use_halfop) { sendto_one_notice(source_p, ":This server's configuration file does not support halfop prefix"); return 0; } add_user_to_channel(chptr, source_p, CHFL_HALFOP); sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s SJOIN %ld %s + :%s%s", me.id, (long) chptr->channelts, chptr->chname, "%", source_p->id); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s", source_p->name, source_p->username, source_p->host, chptr->chname); sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +h %s", me.name, chptr->chname, source_p->name); } else if(*parv[1] == '+') { add_user_to_channel(chptr, source_p, CHFL_VOICE); sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s SJOIN %ld %s + :+%s", me.id, (long) chptr->channelts, chptr->chname, source_p->id); send_channel_join(chptr, source_p); sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +v %s", me.name, chptr->chname, source_p->name); } else if(*parv[1] == '~') { if(!ConfigChannel.use_founder) { sendto_one_notice(source_p, ":This server's configuration file does not support founder prefix"); return 0; } add_user_to_channel(chptr, source_p, CHFL_FOUNDER); sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s SJOIN %ld %s + :~%s", me.id, (long) chptr->channelts, chptr->chname, source_p->id); send_channel_join(chptr, source_p); sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +u %s", me.name, chptr->chname, source_p->name); } else { add_user_to_channel(chptr, source_p, CHFL_PEON); sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s JOIN %ld %s +", source_p->id, (long) chptr->channelts, chptr->chname); send_channel_join(chptr, source_p); } /* send the topic... */ if(chptr->topic != NULL) { sendto_one(source_p, form_str(RPL_TOPIC), me.name, source_p->name, chptr->chname, chptr->topic); sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name, source_p->name, chptr->chname, chptr->topic_info, chptr->topic_time); } source_p->localClient->last_join_time = rb_current_time(); channel_member_names(chptr, source_p, 1); sendto_realops_snomask(SNO_GENERAL, L_ALL, "OJOIN called for %s by %s!%s@%s", parv[1], source_p->name, source_p->username, source_p->host); ilog(L_MAIN, "OJOIN called for %s by %s", parv[1], get_oper_name(source_p)); return 0; }
/* ** mo_ojoin ** parv[1] = channel */ static void mo_ojoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Channel *chptr; int move_me = 0; /* admins only */ if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin"); return; } if(*parv[1] == '@' || *parv[1] == '+') { parv[1]++; move_me = 1; } if((chptr = find_channel(parv[1])) == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), parv[1]); return; } if(IsMember(source_p, chptr)) { sendto_one_notice(source_p, ":Please part %s before using OJOIN", parv[1]); return; } if(move_me == 1) parv[1]--; sendto_wallops_flags(UMODE_WALLOP, &me, "OJOIN called for %s by %s!%s@%s", parv[1], source_p->name, source_p->username, source_p->host); ilog(L_MAIN, "OJOIN called for %s by %s", parv[1], get_oper_name(source_p)); /* only sends stuff for #channels remotely */ sendto_server(NULL, chptr, NOCAPS, NOCAPS, ":%s WALLOPS :OJOIN called for %s by %s!%s@%s", me.name, parv[1], source_p->name, source_p->username, source_p->host); if(*parv[1] == '@') { add_user_to_channel(chptr, source_p, CHFL_CHANOP); sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s SJOIN %ld %s + :@%s", me.id, (long) chptr->channelts, chptr->chname, source_p->id); send_channel_join(chptr, source_p); sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s", me.name, chptr->chname, source_p->name); } else if(*parv[1] == '+') { add_user_to_channel(chptr, source_p, CHFL_VOICE); sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s SJOIN %ld %s + :+%s", me.id, (long) chptr->channelts, chptr->chname, source_p->id); send_channel_join(chptr, source_p); sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +v %s", me.name, chptr->chname, source_p->name); } else { add_user_to_channel(chptr, source_p, CHFL_PEON); sendto_server(client_p, chptr, CAP_TS6, NOCAPS, ":%s JOIN %ld %s +", source_p->id, (long) chptr->channelts, chptr->chname); send_channel_join(chptr, source_p); } /* send the topic... */ if(chptr->topic != NULL) { sendto_one(source_p, form_str(RPL_TOPIC), me.name, source_p->name, chptr->chname, chptr->topic); sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name, source_p->name, chptr->chname, chptr->topic_info, chptr->topic_time); } source_p->localClient->last_join_time = rb_current_time(); channel_member_names(chptr, source_p, 1); }
/* ** mo_clearchan ** parv[0] = sender prefix ** parv[1] = channel */ static void mo_clearchan(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { struct Channel *chptr, *root_chptr; int on_vchan = 0; /* admins only */ if (!IsOperAdmin(source_p)) { sendto_one(source_p, ":%s NOTICE %s :You have no A flag", me.name, parv[0]); return; } /* XXX - we might not have CBURSTed this channel if we are a lazylink * yet. */ chptr= hash_find_channel(parv[1]); root_chptr = chptr; #ifdef VCHANS if (chptr && parc > 2 && parv[2][0] == '!') { chptr = find_vchan(chptr, parv[2]); if (root_chptr != chptr) on_vchan++; } #endif if( chptr == NULL ) { sendto_one(source_p, form_str(source_p,ERR_NOSUCHCHANNEL), me.name, parv[0], parv[1]); return; } if(IsMember(source_p, chptr)) { sendto_one(source_p, ":%s NOTICE %s :*** Please part %s before using CLEARCHAN", me.name, source_p->name, parv[1]); return; } if (!on_vchan) { sendto_wallops_flags(FLAGS_WALLOP, &me, "CLEARCHAN called for [%s] by %s!%s@%s", parv[1], source_p->name, source_p->username, source_p->host); sendto_server(NULL, source_p, NULL, NOCAPS, NOCAPS, LL_ICLIENT, ":%s WALLOPS :CLEARCHAN called for [%s] by %s!%s@%s", me.name, parv[1], source_p->name, source_p->username, source_p->host); ilog(L_NOTICE, "CLEARCHAN called for [%s] by %s!%s@%s", parv[1], source_p->name, source_p->username, source_p->host); } else { sendto_wallops_flags(FLAGS_WALLOP, &me, "CLEARCHAN called for [%s %s] by %s!%s@%s", parv[1], parv[2], source_p->name, source_p->username, source_p->host); sendto_server(NULL, source_p, NULL, NOCAPS, NOCAPS, LL_ICLIENT, ":%s WALLOPS :CLEARCHAN called for [%s %s] by %s!%s@%s", me.name, parv[1], parv[2], source_p->name, source_p->username, source_p->host); ilog(L_NOTICE, "CLEARCHAN called for [%s %s] by %s!%s@%s", parv[1], parv[2], source_p->name, source_p->username, source_p->host); } /* Kill all the modes we have about the channel.. making everyone a peon */ remove_our_modes(0, chptr, root_chptr, source_p); /* SJOIN the user to give them ops, and lock the channel */ sendto_server(client_p, source_p, chptr, NOCAPS, NOCAPS, LL_ICLIENT, ":%s SJOIN %lu %s +ntsi :@%s", me.name, (unsigned long) (chptr->channelts - 1), chptr->chname, source_p->name); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s", source_p->name, source_p->username, source_p->host, root_chptr->chname); sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s", me.name, chptr->chname, source_p->name); add_user_to_channel(chptr, source_p, CHFL_CHANOP); /* Take the TS down by 1, so we don't see the channel taken over * again. */ if (chptr->channelts) chptr->channelts--; #ifdef VCHANS if (on_vchan) add_vchan_to_client_cache(source_p,root_chptr,chptr); #endif chptr->mode.mode = MODE_SECRET | MODE_TOPICLIMIT | MODE_INVITEONLY | MODE_NOPRIVMSGS; free_topic(chptr); chptr->mode.key[0] = 0; /* Kick the users out and join the oper */ kick_list(client_p, source_p, chptr, &chptr->peons, chptr->chname); }
/* ** mo_ojoin ** parv[0] = sender prefix ** parv[1] = channel */ static void mo_ojoin(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { struct Channel *chptr; int move_me = 0; /* admins only */ if (!IsOperAdmin(source_p)) { sendto_one(source_p, ":%s NOTICE %s :You have no A flag", me.name, parv[0]); return; } if (*parv[1] == '@' || *parv[1] == '+') { parv[1]++; move_me = 1; } chptr = hash_find_channel(parv[1]); if(chptr == NULL) { sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL), me.name, parv[0], parv[1]); return; } if(IsMember(source_p, chptr)) { sendto_one(source_p, ":%s NOTICE %s :Please part %s before using OJOIN", me.name, source_p->name, parv[1]); return; } if (move_me == 1) parv[1]--; sendto_wallops_flags(UMODE_WALLOP, &me, "OJOIN called for [%s] by %s!%s@%s", parv[1], source_p->name, source_p->username, source_p->host); ilog(L_NOTICE, "OJOIN called for [%s] by %s!%s@%s", parv[1], source_p->name, source_p->username, source_p->host); if(*chptr->chname != '&') sendto_server(NULL, NULL, NOCAPS, NOCAPS, ":%s WALLOPS :OJOIN called for [%s] by %s!%s@%s", me.name, parv[1], source_p->name, source_p->username, source_p->host); if (*parv[1] == '@') { add_user_to_channel(chptr, source_p, CHFL_CHANOP); if(*chptr->chname != '&') sendto_server(client_p, chptr, NOCAPS, NOCAPS, ":%s SJOIN %lu %s + :@%s", me.name, chptr->channelts, chptr->chname, source_p->name); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s", source_p->name, source_p->username, source_p->host, chptr->chname); sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s", me.name, chptr->chname, source_p->name); } else if (*parv[1] == '+') { add_user_to_channel(chptr, source_p, CHFL_VOICE); if(*chptr->chname != '&') sendto_server(client_p, chptr, NOCAPS, NOCAPS, ":%s SJOIN %lu %s + :+%s", me.name, chptr->channelts, chptr->chname, source_p->name); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s", source_p->name, source_p->username, source_p->host, chptr->chname); sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +v %s", me.name, chptr->chname, source_p->name); } else { add_user_to_channel(chptr, source_p, CHFL_PEON); if(*chptr->chname != '&') sendto_server(client_p, chptr, NOCAPS, NOCAPS, ":%s SJOIN %lu %s + :%s", me.name, chptr->channelts, chptr->chname, source_p->name); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s", source_p->name, source_p->username, source_p->host, chptr->chname); } /* send the topic... */ if (chptr->topic != NULL) { sendto_one(source_p, form_str(RPL_TOPIC), me.name, source_p->name, chptr->chname, chptr->topic); sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name, source_p->name, chptr->chname, chptr->topic_info, chptr->topic_time); } source_p->localClient->last_join_time = CurrentTime; channel_member_names(chptr, source_p, 1); }
/* * mo_connect - CONNECT command handler * * Added by Jto 11 Feb 1989 * * m_connect * parv[0] = sender prefix * parv[1] = servername * parv[2] = port number * parv[3] = remote server */ static void mo_connect(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { int port; int tmpport; struct ConfItem *aconf; struct Client *target_p; /* always privileged with handlers */ if(MyConnect(source_p) && !IsOperRemote(source_p) && parc > 3) { sendto_one(source_p, ":%s NOTICE %s :You need remote = yes;", me.name, parv[0]); return; } if(hunt_server(client_p, source_p, ":%s CONNECT %s %s :%s", 3, parc, parv) != HUNTED_ISME) { return; } if(*parv[1] == '\0') { sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "CONNECT"); return; } if((target_p = find_server(parv[1]))) { sendto_one(source_p, ":%s NOTICE %s :Connect: Server %s already exists from %s.", me.name, parv[0], parv[1], target_p->from->name); return; } /* * try to find the name, then host, if both fail notify ops and bail */ if(!(aconf = find_conf_by_name(parv[1], CONF_SERVER))) { if(!(aconf = find_conf_by_host(parv[1], CONF_SERVER))) { sendto_one(source_p, "NOTICE %s :Connect: Host %s not listed in ircd.conf", parv[0], parv[1]); return; } } s_assert(0 != aconf); /* * Get port number from user, if given. If not specified, * use the default form configuration structure. If missing * from there, then use the precompiled default. */ tmpport = port = aconf->port; if(parc > 2 && !EmptyString(parv[2])) { if((port = atoi(parv[2])) <= 0) { sendto_one(source_p, "NOTICE %s :Connect: Illegal port number", parv[0]); return; } } else if(port <= 0 && (port = PORTNUM) <= 0) { sendto_one(source_p, ":%s NOTICE %s :Connect: missing port number", me.name, parv[0]); return; } /* * Notify all operators about remote connect requests */ ilog(L_TRACE, "CONNECT From %s : %s %s", parv[0], parv[1], parv[2] ? parv[2] : ""); aconf->port = port; /* * at this point we should be calling connect_server with a valid * C:line and a valid port in the C:line */ if(serv_connect(aconf, source_p)) { #ifndef HIDE_SERVERS_IPS if(IsOperAdmin(source_p)) sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s[%s].%d", me.name, parv[0], aconf->host, aconf->name, aconf->port); else #endif sendto_one(source_p, ":%s NOTICE %s :*** Connecting to %s.%d", me.name, parv[0], aconf->name, aconf->port); } else { sendto_one(source_p, ":%s NOTICE %s :*** Couldn't connect to %s.%d", me.name, parv[0], aconf->name, aconf->port); } /* * client is either connecting with all the data it needs or has been * destroyed */ aconf->port = tmpport; }
/* * m_forcejoin * parv[1] = user to force * parv[2] = channel to force them into */ static int mo_forcejoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p; struct Channel *chptr; int type; char mode; char sjmode; char *newch; if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin"); return 0; } if((hunt_server(client_p, source_p, ":%s FORCEJOIN %s %s", 1, parc, parv)) != HUNTED_ISME) return 0; /* if target_p is not existant, print message * to source_p and bail - scuzzy */ if((target_p = find_client(parv[1])) == NULL) { sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, parv[1]); return 0; } if(!IsPerson(target_p)) return 0; sendto_wallops_flags(UMODE_WALLOP, &me, "FORCEJOIN called for %s %s by %s!%s@%s", parv[1], parv[2], source_p->name, source_p->username, source_p->host); ilog(L_MAIN, "FORCEJOIN called for %s %s by %s!%s@%s", parv[1], parv[2], source_p->name, source_p->username, source_p->host); sendto_server(NULL, NULL, NOCAPS, NOCAPS, ":%s WALLOPS :FORCEJOIN called for %s %s by %s!%s@%s", me.name, parv[1], parv[2], source_p->name, source_p->username, source_p->host); /* select our modes from parv[2] if they exist... (chanop) */ if(*parv[2] == '@') { type = CHFL_CHANOP; mode = 'o'; sjmode = '@'; } else if(*parv[2] == '+') { type = CHFL_VOICE; mode = 'v'; sjmode = '+'; } else { type = CHFL_PEON; mode = sjmode = '\0'; } if(mode != '\0') parv[2]++; if((chptr = find_channel(parv[2])) != NULL) { if(IsMember(target_p, chptr)) { /* debugging is fun... */ sendto_one_notice(source_p, ":*** Notice -- %s is already in %s", target_p->name, chptr->chname); return 0; } add_user_to_channel(chptr, target_p, type); sendto_server(target_p, chptr, NOCAPS, NOCAPS, ":%s SJOIN %ld %s + :%c%s", me.name, (long) chptr->channelts, chptr->chname, type ? sjmode : ' ', target_p->name); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s", target_p->name, target_p->username, target_p->host, chptr->chname); if(type) sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +%c %s", me.name, chptr->chname, mode, target_p->name); if(chptr->topic != NULL) { sendto_one(target_p, form_str(RPL_TOPIC), me.name, target_p->name, chptr->chname, chptr->topic); sendto_one(target_p, form_str(RPL_TOPICWHOTIME), me.name, source_p->name, chptr->chname, chptr->topic_info, chptr->topic_time); } channel_member_names(chptr, target_p, 1); } else { newch = LOCAL_COPY(parv[2]); if(!check_channel_name(newch)) { sendto_one(source_p, form_str(ERR_BADCHANNAME), me.name, source_p->name, (unsigned char *) newch); return 0; } /* channel name must begin with & or # */ if(!IsChannelName(newch)) { sendto_one(source_p, form_str(ERR_BADCHANNAME), me.name, source_p->name, (unsigned char *) newch); return 0; } /* newch can't be longer than CHANNELLEN */ if(strlen(newch) > CHANNELLEN) { sendto_one_notice(source_p, ":Channel name is too long"); return 0; } chptr = get_or_create_channel(target_p, newch, NULL); add_user_to_channel(chptr, target_p, CHFL_CHANOP); /* send out a join, make target_p join chptr */ sendto_server(target_p, chptr, NOCAPS, NOCAPS, ":%s SJOIN %ld %s +nt :@%s", me.name, (long) chptr->channelts, chptr->chname, target_p->name); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s", target_p->name, target_p->username, target_p->host, chptr->chname); chptr->mode.mode |= MODE_TOPICLIMIT; chptr->mode.mode |= MODE_NOPRIVMSGS; sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +nt", me.name, chptr->chname); target_p->localClient->last_join_time = rb_current_time(); channel_member_names(chptr, target_p, 1); /* we do this to let the oper know that a channel was created, this will be * seen from the server handling the command instead of the server that * the oper is on. */ sendto_one_notice(source_p, ":*** Notice -- Creating channel %s", chptr->chname); } return 0; }
/* ** mo_ojoin ** parv[1] = channel */ static int mo_ojoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Channel *chptr; int move_me = 0; /* admins only */ if(!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "ojoin"); return 0; } /* XXX - we might not have CBURSTed this channel if we are a lazylink * yet. */ if(*parv[1] == '@' || *parv[1] == '%' || *parv[1] == '+') { parv[1]++; move_me = 1; } if((chptr = find_channel(parv[1])) == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), parv[1]); return 0; } if(IsMember(source_p, chptr)) { sendto_one(source_p, ":%s NOTICE %s :Please part %s before using OJOIN", me.name, source_p->name, parv[1]); return 0; } if(move_me == 1) parv[1]--; if(*parv[1] == '@') { add_user_to_channel(chptr, source_p, CHFL_CHANOP); sendto_server(client_p, chptr, NOCAPS, NOCAPS, ":%s SJOIN %ld %s + :@%s", me.name, (long)chptr->channelts, chptr->chname, source_p->name); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s", source_p->name, source_p->username, source_p->host, chptr->chname); sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s", me.name, chptr->chname, source_p->name); } else if(*parv[1] == '+') { add_user_to_channel(chptr, source_p, CHFL_VOICE); sendto_server(client_p, chptr, NOCAPS, NOCAPS, ":%s SJOIN %ld %s + :+%s", me.name, (long)chptr->channelts, chptr->chname, source_p->name); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s", source_p->name, source_p->username, source_p->host, chptr->chname); sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +v %s", me.name, chptr->chname, source_p->name); } else { add_user_to_channel(chptr, source_p, CHFL_PEON); sendto_server(client_p, chptr, NOCAPS, NOCAPS, ":%s SJOIN %ld %s + :%s", me.name, (long)chptr->channelts, chptr->chname, source_p->name); sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN %s", source_p->name, source_p->username, source_p->host, chptr->chname); } /* send the topic... */ if(chptr->topic != NULL) { sendto_one(source_p, form_str(RPL_TOPIC), me.name, source_p->name, chptr->chname, chptr->topic->topic); sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name, source_p->name, chptr->chname, chptr->topic->topic_info, chptr->topic->topic_time); } source_p->localClient->last_join_time = rb_time(); channel_member_names(chptr, source_p, 1); return 0; }
/* * mo_forcepart * parv[1] = forcepart victim * parv[2] = channels to part * parv[3] = reason */ static int mo_forcepart(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p; const char *user, *channels, *reason; const char default_reason[] = "Leaving"; int chasing = 0; user = parv[1]; channels = parv[2]; if(!IsOper(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name); return 0; } /* if target_p == NULL then let the oper know */ if((target_p = find_chasing(source_p, user, &chasing)) == NULL) { sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, user); return 0; } if(EmptyString(channels)) { sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, source_p->name, "FORCEPART"); return 0; } if(EmptyString(parv[3])) reason = default_reason; else { char *s; s = LOCAL_COPY(parv[3]); if(strlen(s) > (size_t) REASONLEN) s[REASONLEN] = '\0'; reason = s; } if(!IsClient(target_p)) return 0; if(!MyClient(target_p) && (!IsOperAdmin(source_p))) { sendto_one_notice(source_p, ":Nick %s is not on your server and you do not have admin priv", target_p->name); return 0; } sendto_realops_snomask(SNO_GENERAL, L_NETWIDE, "Received FORCEPART message for %s!%s@%s. From %s (Channels: %s)", target_p->name, target_p->username, target_p->host, source_p->name, channels); ilog(L_MAIN, "FORCEPART called for %s %s by %s!%s@%s (part reason %s)", user, channels, source_p->name, source_p->username, source_p->host, reason); sendto_one_notice(target_p, ":You have been forced to part %s", channels); if(!MyClient(target_p)) { struct Client *cptr = target_p->servptr; sendto_one(cptr, ":%s ENCAP %s FORCEPART %s :%s", get_id(source_p, cptr), cptr->name, get_id(target_p, cptr), channels); return 0; } forcepart_channels(client_p, source_p, target_p, channels, reason); return 0; }
/* * mo_omode - MODE command handler * parv[1] - channel */ static int mo_omode(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Channel *chptr = NULL; struct membership *msptr; char params[512]; int i; int wasonchannel; /* admins only */ if (!IsOperAdmin(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "admin"); return 0; } /* Now, try to find the channel in question */ if (!IsChanPrefix(parv[1][0]) || !check_channel_name(parv[1])) { sendto_one_numeric(source_p, ERR_BADCHANNAME, form_str(ERR_BADCHANNAME), parv[1]); return 0; } chptr = find_channel(parv[1]); if (chptr == NULL) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), parv[1]); return 0; } /* Now know the channel exists */ msptr = find_channel_membership(chptr, source_p); wasonchannel = msptr != NULL; if (is_any_op(msptr)) { sendto_one_notice(source_p, ":Use a normal MODE you idiot"); return 0; } params[0] = '\0'; for (i = 2; i < parc; i++) { if (i != 2) rb_strlcat(params, " ", sizeof params); rb_strlcat(params, parv[i], sizeof params); } sendto_wallops_flags(UMODE_WALLOP, &me, "OMODE called for [%s] [%s] by %s!%s@%s", parv[1], params, source_p->name, source_p->username, source_p->host); ilog(L_MAIN, "OMODE called for [%s] [%s] by %s", parv[1], params, get_oper_name(source_p)); if (*chptr->chname != '&') sendto_server(NULL, NULL, NOCAPS, NOCAPS, ":%s WALLOPS :OMODE called for [%s] [%s] by %s!%s@%s", me.name, parv[1], params, source_p->name, source_p->username, source_p->host); #if 0 set_channel_mode(client_p, source_p->servptr, chptr, msptr, parc - 2, parv + 2); #else if (parc == 4 && !strcmp(parv[2], "+y") && !irccmp(parv[3], source_p->name)) { /* Ownering themselves */ if (!wasonchannel) { sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL, form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname); return 0; } sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +y %s", me.name, parv[1], source_p->name); sendto_server(NULL, chptr, CAP_TS6, NOCAPS, ":%s TMODE %ld %s +y %s", me.id, (long) chptr->channelts, parv[1], source_p->id); msptr->flags |= CHFL_OWNER; } else if (parc == 4 && !strcmp(parv[2], "+a") && !irccmp(parv[3], source_p->name)) { /* Admining themselves */ if (!wasonchannel) { sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL, form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname); return 0; } sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +a %s", me.name, parv[1], source_p->name); sendto_server(NULL, chptr, CAP_TS6, NOCAPS, ":%s TMODE %ld %s +a %s", me.id, (long) chptr->channelts, parv[1], source_p->id); msptr->flags |= CHFL_ADMIN; } else if (parc == 4 && !strcmp(parv[2], "+o") && !irccmp(parv[3], source_p->name)) { /* Opping themselves */ if (!wasonchannel) { sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL, form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname); return 0; } sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +o %s", me.name, parv[1], source_p->name); sendto_server(NULL, chptr, CAP_TS6, NOCAPS, ":%s TMODE %ld %s +o %s", me.id, (long) chptr->channelts, parv[1], source_p->id); msptr->flags |= CHFL_CHANOP; } else if (parc == 4 && !strcmp(parv[2], "+h") && !irccmp(parv[3], source_p->name)) { /* Halfopping themselves */ if (!wasonchannel) { sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL, form_str(ERR_USERNOTINCHANNEL), parv[3], chptr->chname); return 0; } sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +h %s", me.name, parv[1], source_p->name); sendto_server(NULL, chptr, CAP_TS6, NOCAPS, ":%s TMODE %ld %s +h %s", me.id, (long) chptr->channelts, parv[1], source_p->id); msptr->flags |= CHFL_HALFOP; } else if (ConfigChannel.use_owner) { /* I hope this is correct. * -- Kabaka */ /* Hack it so set_channel_mode() will accept */ if (wasonchannel) msptr->flags |= CHFL_OWNER; else { add_user_to_channel(chptr, source_p, CHFL_CHANOP); msptr = find_channel_membership(chptr, source_p); } set_channel_mode(client_p, source_p, chptr, msptr, parc - 2, parv + 2); if (wasonchannel) msptr->flags &= ~CHFL_OWNER; else remove_user_from_channel(msptr); } else if (ConfigChannel.use_admin) { /* Hack it so set_channel_mode() will accept */ if (wasonchannel) msptr->flags |= CHFL_ADMIN; else { add_user_to_channel(chptr, source_p, CHFL_CHANOP); msptr = find_channel_membership(chptr, source_p); } set_channel_mode(client_p, source_p, chptr, msptr, parc - 2, parv + 2); /* We know they were not opped before and they can't have opped * themselves as set_channel_mode() does not allow that * -- jilles */ if (wasonchannel) msptr->flags &= ~CHFL_ADMIN; else remove_user_from_channel(msptr); } else { /* CHFL_ADMIN is only useful if admin is enabled * so hack it with op if it is not. */ if (wasonchannel) msptr->flags |= CHFL_CHANOP; else { add_user_to_channel(chptr, source_p, CHFL_CHANOP); msptr = find_channel_membership(chptr, source_p); } set_channel_mode(client_p, source_p, chptr, msptr, parc - 2, parv + 2); /* We know they were not opped before and they can't have opped * themselves as set_channel_mode() does not allow that * -- jilles */ if (wasonchannel) msptr->flags &= ~CHFL_CHANOP; else remove_user_from_channel(msptr); } #endif return 0; }
/* ** mo_jupe ** parv[0] = sender prefix ** parv[1] = server we're juping ** parv[2] = reason for jupe */ static void mo_jupe(struct Client *client_p, struct Client *source_p, int parc, char *parv[]) { struct Client *target_p; struct Client *ajupe; dlink_node *m; char reason[REALLEN+2]; if(!ServerInfo.hub) return; if(!IsOperAdmin(source_p)) { sendto_one(source_p, ":%s NOTICE %s :You must be an admin to use this command", me.name, parv[0]); return; } if (bogus_host(parv[1])) { sendto_one(source_p, ":%s NOTICE %s :Invalid servername: %s", me.name, parv[0], parv[1]); return; } if(match(parv[1], me.name)) { sendto_one(source_p, ":%s NOTICE %s :I cant jupe myself!", me.name, source_p->name); return; } sendto_wallops_flags(UMODE_WALLOP, &me, "JUPE for %s requested by %s: %s", parv[1], get_oper_name(source_p), parv[2]); sendto_server(NULL, NOCAPS, NOCAPS, ":%s WALLOPS :JUPE for %s requested by %s!%s@%s: %s", parv[0], parv[1], source_p->name, source_p->username, source_p->host, parv[2]); ilog(L_NOTICE, "JUPE for %s requested by %s: %s", parv[1], get_oper_name(source_p), parv[2]); target_p= find_server(parv[1]); if(target_p) exit_client(client_p, target_p, &me, parv[2]); sendto_server(NULL, NOCAPS, NOCAPS, ":%s SERVER %s 1 :JUPED: %s", me.name, parv[1], parv[2]); sendto_realops_flags(UMODE_ALL, L_ALL, "Link with %s established: (JUPED) link", parv[1]); ajupe = make_client(NULL); /* make_client() adds client to unknown_list */ m = dlinkFind(&unknown_list, ajupe); if(m != NULL) dlinkDelete(m, &unknown_list); free_dlink_node(m); make_server(ajupe); ajupe->hopcount = 1; strlcpy(ajupe->name,parv[1],HOSTLEN); /* we need to give 7 chars to prepend "JUPED: " */ if(strlen(parv[2]) > (REALLEN-7)) parv[2][REALLEN-7] = '\0'; ircsprintf(reason, "%s %s", "JUPED:", parv[2]); strlcpy(ajupe->info,reason,REALLEN); ajupe->serv->up = me.name; ajupe->servptr = &me; SetServer(ajupe); SetDead(ajupe); Count.server++; Count.myserver++; /* Some day, all these lists will be consolidated *sigh* */ add_client_to_list(ajupe); add_to_client_hash_table(ajupe->name, ajupe); dlinkAdd(ajupe, &ajupe->lnode, &ajupe->servptr->serv->servers); add_server_to_list(ajupe); }