/* * m_samode * parv[0] = sender * parv[1] = channel * parv[2] = modes * -t */ DLLFUNC CMD_FUNC(m_samode) { aChannel *chptr; if (!IsPrivileged(cptr) || !IsSAdmin(sptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } if (parc > 2) { chptr = find_channel(parv[1], NullChn); if (chptr == NullChn) return 0; } else { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "SAMODE"); return 0; } opermode = 0; (void)do_mode(chptr, cptr, sptr, parc - 2, parv + 2, 0, 1); return 0; }
DLLFUNC int _can_join(aClient *cptr, aClient *sptr, aChannel *chptr, char *key, char *link, char *parv[]) { Link *lp; Ban *banned; if ((chptr->mode.mode & MODE_ONLYSECURE) && !(sptr->umodes & UMODE_SECURE)) { if (IsAnOper(sptr)) { /* Yeah yeah.. duplicate code.. * Anyway: if the channel is +z we still allow an ircop to bypass it * if they are invited. */ for (lp = sptr->user->invited; lp; lp = lp->next) if (lp->value.chptr == chptr) return 0; } return (ERR_SECUREONLYCHAN); } if ((chptr->mode.mode & MODE_OPERONLY) && !IsAnOper(sptr)) return (ERR_OPERONLY); if ((chptr->mode.mode & MODE_ADMONLY) && !IsSkoAdmin(sptr)) return (ERR_ADMONLY); /* Admin, Coadmin, Netadmin, and SAdmin can still walk +b in +O */ banned = is_banned(sptr, chptr, BANCHK_JOIN); if (banned && (chptr->mode.mode & MODE_OPERONLY) && IsAnOper(sptr) && !IsSkoAdmin(sptr) && !IsCoAdmin(sptr)) return (ERR_BANNEDFROMCHAN); /* Only NetAdmin/SAdmin can walk +b in +A */ if (banned && (chptr->mode.mode & MODE_ADMONLY) && IsAnOper(sptr) && !IsNetAdmin(sptr) && !IsSAdmin(sptr)) return (ERR_BANNEDFROMCHAN); for (lp = sptr->user->invited; lp; lp = lp->next) if (lp->value.chptr == chptr) return 0; if ((chptr->mode.limit && chptr->users >= chptr->mode.limit)) { if (chptr->mode.link) { if (*chptr->mode.link != '\0') { /* We are linked. */ sendto_one(sptr, err_str(ERR_LINKCHANNEL), me.name, sptr->name, chptr->chname, chptr->mode.link); parv[0] = sptr->name; parv[1] = (chptr->mode.link); do_join(cptr, sptr, 2, parv); return -1; } } /* We check this later return (ERR_CHANNELISFULL); */ } if ((chptr->mode.mode & MODE_RGSTRONLY) && !IsLoggedIn(sptr)) return (ERR_NEEDREGGEDNICK); if (*chptr->mode.key && (BadPtr(key) || strcmp(chptr->mode.key, key))) return (ERR_BADCHANNELKEY); if ((chptr->mode.mode & MODE_INVITEONLY) && !find_invex(chptr, sptr)) return (ERR_INVITEONLYCHAN); if ((chptr->mode.limit && chptr->users >= chptr->mode.limit)) return (ERR_CHANNELISFULL); if (banned) return (ERR_BANNEDFROMCHAN); #ifndef NO_OPEROVERRIDE #ifdef OPEROVERRIDE_VERIFY if (IsOper(sptr) && (chptr->mode.mode & MODE_SECRET || chptr->mode.mode & MODE_PRIVATE) && !is_autojoin_chan(chptr->chname)) return (ERR_OPERSPVERIFY); #endif #endif #ifdef JOINTHROTTLE if (!IsAnOper(cptr) && (chptr->mode.extmode & EXTMODE_JOINTHROTTLE) && isjthrottled(cptr, chptr)) return ERR_TOOMANYJOINS; #endif return 0; }
/* ** m_ircops() By Claudio ** Rewritten by HAMLET ** Lists online IRCOps ** */ int m_ircops(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { struct Client *acptr; char *status; char buf[BUFSIZE]; int locals = 0, globals = 0; if (!IRCopsForAll && !IsPrivileged(cptr)) { sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } strcpy(buf, "========================================================================================"); sendto_one(sptr, form_str(RPL_LISTS), me.name, parv[0], buf); strcpy(buf, "\2Nick Status Server\2"); sendto_one(sptr, form_str(RPL_LISTS), me.name, parv[0], buf); strcpy(buf, "----------------------------------------------------------------------------------------"); sendto_one(sptr, form_str(RPL_LISTS), me.name, parv[0], buf); for (acptr = GlobalClientList; acptr; acptr = acptr->next) { if (!IsService(acptr) && !IsStealth(acptr) && IsAnOper(acptr) && (!IsHideOper(acptr) || IsAnOper(sptr)) ) { if (!acptr->user) continue; if (IsTechAdmin(acptr)) status = "Technical Administrator"; else if (IsNetAdmin(acptr)) status = "Network Administrator"; else if (IsSAdmin(acptr)) status = "Services Administrator"; else if (IsAdmin(acptr)) status = "Server Administrator"; else if(IsOper(acptr)) status = "Global IRC Operator"; else status = "Local IRC Operator"; /* vlinks on /IRCops * code by openglx * idea to this by Midnight_Commander */ if (acptr->user && acptr->user->vlink) { ircsprintf(buf, "\2%-29s\2 %-23s %-6s %s", acptr->name ? acptr->name : "<unknown>", status, acptr->user->away ? "(AWAY)" : "", acptr->user->vlink->name); } else { ircsprintf(buf, "\2%-29s\2 %-23s %-6s %s", acptr->name ? acptr->name : "<unknown>", status, acptr->user->away ? "(AWAY)" : "", acptr->user->server); } /* end of the vlink support code */ sendto_one(sptr, form_str(RPL_LISTS), me.name, parv[0], buf); sendto_one(sptr, form_str(RPL_LISTS), me.name, parv[0], "-"); if (IsOper(acptr)) globals++; else locals++; } } ircsprintf(buf, "Total: \2%d\2 IRCOp%s connected - \2%d\2 Globa%s, \2%d\2 Loca%s", globals+locals, (globals+locals) > 1 ? "s" : "", globals, globals > 1 ? "ls" : "l", locals, locals > 1 ? "ls" : "l"); sendto_one(sptr, form_str(RPL_LISTS), me.name, parv[0], buf); strcpy(buf, "========================================================================================"); sendto_one(sptr, form_str(RPL_LISTS), me.name, parv[0], buf); sendto_one(sptr, form_str(RPL_ENDOFLISTS), me.name, parv[0], "IRCOPS"); return 0; }
/* m_sajoin() - Lamego - Wed Jul 21 20:04:48 1999 Copied off PTlink IRCd (C) PTlink coders team. Coded for Sadmin by Stskeeps also Modified by NiQuiL ([email protected]) parv[0] - sender parv[1] - nick to make join parv[2] - channel(s) to join */ DLLFUNC CMD_FUNC(m_sajoin) { aClient *acptr; char jbuf[BUFSIZE]; int did_anything = 0; if (!IsSAdmin(sptr) && !IsULine(sptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } if (parc < 3) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "SAJOIN"); return 0; } if (!(acptr = find_person(parv[1], NULL))) { sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], parv[1]); return 0; } if (MyClient(acptr)) { char *name, *p = NULL; int i, parted = 0; *jbuf = 0; /* Now works like m_join */ for (i = 0, name = strtoken(&p, parv[2], ","); name; name = strtoken(&p, NULL, ",")) { aChannel *chptr; Membership *lp; if (strlen(name) > CHANNELLEN) name[CHANNELLEN] = 0; clean_channelname(name); if (*name == '0' && !atoi(name)) { (void)strcpy(jbuf, "0"); i = 1; parted = 1; continue; } if (check_channelmask(sptr, cptr, name) == -1 || *name == '0' || !IsChannelName(name)) { sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL), me.name, parv[0], name); continue; } chptr = get_channel(acptr, name, 0); if (!parted && chptr && (lp = find_membership_link(acptr->user->channel, chptr))) { sendto_one(sptr, err_str(ERR_USERONCHANNEL), me.name, parv[0], parv[1], name); continue; } if (*jbuf) (void)strlcat(jbuf, ",", sizeof jbuf); (void)strlncat(jbuf, name, sizeof jbuf, sizeof(jbuf) - i - 1); i += strlen(name) + 1; } if (!*jbuf) return -1; i = 0; strcpy(parv[2], jbuf); *jbuf = 0; for (name = strtoken(&p, parv[2], ","); name; name = strtoken(&p, NULL, ",")) { int flags; aChannel *chptr; Membership *lp; if (*name == '0' && !atoi(name)) { did_anything = 1; while ((lp = acptr->user->channel)) { chptr = lp->chptr; sendto_channel_butserv(chptr, acptr, ":%s PART %s :%s", acptr->name, chptr->chname, "Left all channels"); if (MyConnect(acptr)) RunHook4(HOOKTYPE_LOCAL_PART, acptr, acptr, chptr, "Left all channels"); remove_user_from_channel(acptr, chptr); } sendto_serv_butone_token(acptr, acptr->name, MSG_JOIN, TOK_JOIN, "0"); strcpy(jbuf, "0"); i = 1; continue; } flags = (ChannelExists(name)) ? CHFL_DEOPPED : CHFL_CHANOP; chptr = get_channel(acptr, name, CREATE); if (chptr && (lp = find_membership_link(acptr->user->channel, chptr))) continue; if ((chptr->mode.mode & MODE_ONLYSECURE) && !IsSecure(acptr)) { sendnotice(sptr, "You cannot SAJOIN %s to %s because the channel is +z and the user is not connected via SSL", acptr->name, chptr->chname); continue; } join_channel(chptr, acptr, acptr, flags); did_anything = 1; if (*jbuf) (void)strlcat(jbuf, ",", sizeof jbuf); (void)strlncat(jbuf, name, sizeof jbuf, sizeof(jbuf) - i - 1); i += strlen(name) + 1; } if (did_anything) { sendnotice(acptr, "*** You were forced to join %s", jbuf); sendto_realops("%s used SAJOIN to make %s join %s", sptr->name, acptr->name, jbuf); sendto_serv_butone(&me, ":%s GLOBOPS :%s used SAJOIN to make %s join %s", me.name, sptr->name, acptr->name, jbuf); /* Logging function added by XeRXeS */ ircd_log(LOG_SACMDS,"SAJOIN: %s used SAJOIN to make %s join %s", sptr->name, parv[1], jbuf); } } else { sendto_one(acptr, ":%s SAJOIN %s %s", parv[0], parv[1], parv[2]); /* Logging function added by XeRXeS */ ircd_log(LOG_SACMDS,"SAJOIN: %s used SAJOIN to make %s join %s", sptr->name, parv[1], parv[2]); } return 0; }
/* ** m_whois ** parv[0] = sender prefix ** parv[1] = nickname masklist */ DLLFUNC int m_whois(aClient *cptr, aClient *sptr, int parc, char *parv[]) { Membership *lp; anUser *user; aClient *acptr, *a2cptr; aChannel *chptr; char *nick, *tmp, *name; char *p = NULL; int found, len, mlen, cnt = 0; char querybuf[BUFSIZE]; if (IsServer(sptr)) return 0; if (parc < 2) { sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]); return 0; } if (parc > 2) { if (hunt_server(cptr, sptr, ":%s WHOIS %s :%s", 1, parc, parv) != HUNTED_ISME) return 0; parv[1] = parv[2]; } strcpy(querybuf, parv[1]); for (tmp = canonize(parv[1]); (nick = strtok_r(tmp, ",", &p)); tmp = NULL) { unsigned char invis, showchannel, member, wilds, hideoper; /* <- these are all boolean-alike */ if (++cnt > MAXTARGETS) break; found = 0; /* We do not support "WHOIS *" */ wilds = (index(nick, '?') || index(nick, '*')); if (wilds) continue; if ((acptr = find_client(nick, NULL))) { if (IsServer(acptr)) continue; /* * I'm always last :-) and acptr->next == NULL!! */ if (IsMe(acptr)) break; /* * 'Rules' established for sending a WHOIS reply: * - only send replies about common or public channels * the target user(s) are on; */ if (!IsPerson(acptr)) continue; user = acptr->user; name = (!*acptr->name) ? "?" : acptr->name; invis = acptr != sptr && IsInvisible(acptr); member = (user->channel) ? 1 : 0; a2cptr = find_server_quick(user->server); hideoper = 0; if (IsHideOper(acptr) && (acptr != sptr) && !IsAnOper(sptr)) hideoper = 1; if (IsWhois(acptr) && (sptr != acptr)) { sendnotice(acptr, "*** %s (%s@%s) did a /whois on you.", sptr->name, sptr->user->username, sptr->user->realhost); } sendto_one(sptr, rpl_str(RPL_WHOISUSER), me.name, parv[0], name, user->username, IsHidden(acptr) ? user->virthost : user->realhost, acptr->info); if (IsOper(sptr) || acptr == sptr) { char sno[512]; strcpy(sno, get_sno_str(acptr)); /* send the target user's modes */ sendto_one(sptr, rpl_str(RPL_WHOISMODES), me.name, parv[0], name, get_mode_str(acptr), sno[1] == 0 ? "" : sno); } if ((acptr == sptr) || IsAnOper(sptr)) { sendto_one(sptr, rpl_str(RPL_WHOISHOST), me.name, parv[0], acptr->name, (MyConnect(acptr) && strcmp(acptr->username, "unknown")) ? acptr->username : "******", user->realhost, user->ip_str ? user->ip_str : ""); } if (IsARegNick(acptr)) sendto_one(sptr, rpl_str(RPL_WHOISREGNICK), me.name, parv[0], name); found = 1; mlen = strlen(me.name) + strlen(parv[0]) + 10 + strlen(name); for (len = 0, *buf = '\0', lp = user->channel; lp; lp = lp->next) { chptr = lp->chptr; showchannel = 0; if (ShowChannel(sptr, chptr)) showchannel = 1; if (OPCanSeeSecret(sptr)) showchannel = 1; if ((acptr->umodes & UMODE_HIDEWHOIS) && !IsMember(sptr, chptr) && !IsAnOper(sptr)) showchannel = 0; if (IsServices(acptr) && !IsNetAdmin(sptr) && !IsSAdmin(sptr)) showchannel = 0; if (acptr == sptr) showchannel = 1; /* Hey, if you are editting here... don't forget to change the webtv w_whois ;p. */ if (showchannel) { long access; if (len + strlen(chptr->chname) > (size_t)BUFSIZE - 4 - mlen) { sendto_one(sptr, ":%s %d %s %s :%s", me.name, RPL_WHOISCHANNELS, parv[0], name, buf); *buf = '\0'; len = 0; } #ifdef SHOW_SECRET if (IsAnOper(sptr) #else if (IsNetAdmin(sptr) #endif && SecretChannel(chptr) && !IsMember(sptr, chptr)) *(buf + len++) = '?'; if (acptr->umodes & UMODE_HIDEWHOIS && !IsMember(sptr, chptr) && IsAnOper(sptr)) *(buf + len++) = '!'; access = get_access(acptr, chptr); if (!SupportNAMESX(sptr)) { #ifdef PREFIX_AQ if (access & CHFL_CHANOWNER) *(buf + len++) = '~'; else if (access & CHFL_CHANPROT) *(buf + len++) = '&'; else #endif if (access & CHFL_CHANOP) *(buf + len++) = '@'; else if (access & CHFL_HALFOP) *(buf + len++) = '%'; else if (access & CHFL_VOICE) *(buf + len++) = '+'; } else { #ifdef PREFIX_AQ if (access & CHFL_CHANOWNER) *(buf + len++) = '~'; if (access & CHFL_CHANPROT) *(buf + len++) = '&'; #endif if (access & CHFL_CHANOP) *(buf + len++) = '@'; if (access & CHFL_HALFOP) *(buf + len++) = '%'; if (access & CHFL_VOICE) *(buf + len++) = '+'; } if (len) *(buf + len) = '\0'; (void)strcpy(buf + len, chptr->chname); len += strlen(chptr->chname); (void)strcat(buf + len, " "); len++; } } if (buf[0] != '\0') sendto_one(sptr, rpl_str(RPL_WHOISCHANNELS), me.name, parv[0], name, buf); if (!(IsULine(acptr) && !IsOper(sptr) && HIDE_ULINES)) sendto_one(sptr, rpl_str(RPL_WHOISSERVER), me.name, parv[0], name, user->server, a2cptr ? a2cptr->info : "*Not On This Net*"); if (user->away) sendto_one(sptr, rpl_str(RPL_AWAY), me.name, parv[0], name, user->away); /* makesure they aren't +H (we'll also check before we display a helpop or IRCD Coder msg) -- codemastr */ if ((IsAnOper(acptr) || IsServices(acptr)) && !hideoper) { buf[0] = '\0'; if (IsNetAdmin(acptr)) strlcat(buf, "a Network Administrator", sizeof buf); else if (IsSAdmin(acptr)) strlcat(buf, "a Services Administrator", sizeof buf); else if (IsAdmin(acptr) && !IsCoAdmin(acptr)) strlcat(buf, "a Server Administrator", sizeof buf); else if (IsCoAdmin(acptr)) strlcat(buf, "a Co Administrator", sizeof buf); else if (IsServices(acptr)) strlcat(buf, "a Network Service", sizeof buf); else if (IsOper(acptr)) strlcat(buf, "an IRC Operator", sizeof buf); else strlcat(buf, "a Local IRC Operator", sizeof buf); if (buf[0]) { if (IsOper(sptr) && MyClient(acptr)) sendto_one(sptr, ":%s 313 %s %s :is %s (%s)", me.name, parv[0], name, buf, acptr->user->operlogin); else sendto_one(sptr, rpl_str(RPL_WHOISOPERATOR), me.name, parv[0], name, buf); } } if (IsHelpOp(acptr) && !hideoper && !user->away) sendto_one(sptr, rpl_str(RPL_WHOISHELPOP), me.name, parv[0], name); if (acptr->umodes & UMODE_BOT) sendto_one(sptr, rpl_str(RPL_WHOISBOT), me.name, parv[0], name, ircnetwork); if (acptr->umodes & UMODE_SECURE) sendto_one(sptr, rpl_str(RPL_WHOISSECURE), me.name, parv[0], name, "is using a Secure Connection"); if (!BadPtr(user->swhois) && !hideoper) sendto_one(sptr, ":%s %d %s %s :%s", me.name, RPL_WHOISSPECIAL, parv[0], name, acptr->user->swhois); /* * display services account name if it's actually a services account name and * not a legacy timestamp. --nenolod */ if (!isdigit(*user->svid)) sendto_one(sptr, rpl_str(RPL_WHOISLOGGEDIN), me.name, parv[0], name, user->svid); /* * Umode +I hides an oper's idle time from regular users. * -Nath. */ if (MyConnect(acptr) && (IsAnOper(sptr) || !(acptr->umodes & UMODE_HIDLE))) { sendto_one(sptr, rpl_str(RPL_WHOISIDLE), me.name, parv[0], name, TStime() - acptr->last, acptr->firsttime); } } if (!found) sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], nick); } sendto_one(sptr, rpl_str(RPL_ENDOFWHOIS), me.name, parv[0], querybuf); return 0; }
DLLFUNC CMD_FUNC(m_sapart) { aClient *acptr; aChannel *chptr; Membership *lp; char *name, *p = NULL; int i; char *comment = (parc > 3 && parv[3] ? parv[3] : NULL); char commentx[512]; char jbuf[BUFSIZE]; if (!IsSAdmin(sptr) && !IsULine(sptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } if (parc < 3) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "SAPART"); return 0; } if (!(acptr = find_person(parv[1], NULL))) { sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], parv[1]); return 0; } if (MyClient(acptr)) { /* Now works like m_join */ *jbuf = 0; for (i = 0, name = strtoken(&p, parv[2], ","); name; name = strtoken(&p, NULL, ",")) { if (!(chptr = get_channel(acptr, name, 0))) { sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL), me.name, parv[0], name); continue; } if (!(lp = find_membership_link(acptr->user->channel, chptr))) { sendto_one(sptr, err_str(ERR_USERNOTINCHANNEL), me.name, parv[0], parv[1], name); continue; } if (*jbuf) (void)strlcat(jbuf, ",", sizeof jbuf); (void)strlncat(jbuf, name, sizeof jbuf, sizeof(jbuf) - i - 1); i += strlen(name) + 1; } if (!*jbuf) return -1; strcpy(parv[2], jbuf); if (comment) { strcpy(commentx, "SAPart: "); strlcat(commentx, comment, 512); } parv[0] = parv[1]; // nick parv[1] = parv[2]; // chan parv[2] = comment ? commentx : NULL; // comment if (comment) { sendnotice(acptr, "*** You were forced to part %s (%s)", parv[1], commentx); sendto_realops("%s used SAPART to make %s part %s (%s)", sptr->name, parv[0], parv[1], comment); sendto_server(&me, 0, 0, ":%s GLOBOPS :%s used SAPART to make %s part %s (%s)", me.name, sptr->name, parv[0], parv[1], comment); /* Logging function added by XeRXeS */ ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s (%s)", sptr->name, parv[0], parv[1], comment); } else { sendnotice(acptr, "*** You were forced to part %s", parv[1]); sendto_realops("%s used SAPART to make %s part %s", sptr->name, parv[0], parv[1]); sendto_server(&me, 0, 0, ":%s GLOBOPS :%s used SAPART to make %s part %s", me.name, sptr->name, parv[0], parv[1]); /* Logging function added by XeRXeS */ ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s", sptr->name, parv[0], parv[1]); } do_cmd(acptr, acptr, "PART", comment ? 3 : 2, parv); } else { if (comment) { sendto_one(acptr, ":%s SAPART %s %s :%s", parv[0], parv[1], parv[2], comment); /* Logging function added by XeRXeS */ ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s (%s)", sptr->name, parv[1], parv[2], comment); } else { sendto_one(acptr, ":%s SAPART %s %s", parv[0], parv[1], parv[2]); /* Logging function added by XeRXeS */ ircd_log(LOG_SACMDS,"SAPART: %s used SAPART to make %s part %s", sptr->name, parv[1], parv[2]); } } return 0; }
DLLFUNC int m_jumpserver(aClient *cptr, aClient *sptr, int parc, char *parv[]) { char *serv, *sslserv=NULL, *reason, *p, *p2; int all=0, port=6667, sslport=6697; char logbuf[512]; if (!IsCoAdmin(sptr) && !IsAdmin(sptr) && !IsNetAdmin(sptr) && !IsSAdmin(sptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } if ((parc < 2) || BadPtr(parv[1])) { #ifdef USE_SSL if (jss && jss->ssl_server) sendnotice(sptr, "JumpServer is \002ENABLED\002 to %s:%d (SSL: %s:%d) with reason '%s'", jss->server, jss->port, jss->ssl_server, jss->ssl_port, jss->reason); else #endif if (jss) sendnotice(sptr, "JumpServer is \002ENABLED\002 to %s:%d with reason '%s'", jss->server, jss->port, jss->reason); else sendnotice(sptr, "JumpServer is \002DISABLED\002"); return 0; } if ((parc > 1) && (!strcasecmp(parv[1], "OFF") || !strcasecmp(parv[1], "STOP"))) { if (!jss) { sendnotice(sptr, "JUMPSERVER: No redirect active (already OFF)"); return 0; } free_jss(); snprintf(logbuf, sizeof(logbuf), "%s (%s@%s) turned JUMPSERVER OFF", sptr->name, sptr->user->username, sptr->user->realhost); sendto_realops("%s", logbuf); ircd_log(LOG_ERROR, "%s", logbuf); return 0; } if (parc < 4) { /* Waah, pretty verbose usage info ;) */ sendnotice(sptr, "Use: /JUMPSERVER <server>[:port] <NEW|ALL> <reason>"); #ifdef USE_SSL sendnotice(sptr, " Or: /JUMPSERVER <server>[:port]/<sslserver>[:port] <NEW|ALL> <reason>"); #endif sendnotice(sptr, "if 'NEW' is chosen then only new (incoming) connections will be redirected"); sendnotice(sptr, "if 'ALL' is chosen then all clients except opers will be redirected immediately (+incoming connections)"); sendnotice(sptr, "Example: /JUMPSERVER irc2.test.net NEW This server will be upgraded, please use irc2.test.net for now"); sendnotice(sptr, "And then for example 10 minutes later..."); sendnotice(sptr, " /JUMPSERVER irc2.test.net ALL This server will be upgraded, please use irc2.test.net for now"); sendnotice(sptr, "Use: '/JUMPSERVER OFF' to turn off any redirects"); return 0; } /* Parsing code follows... * The parsing of the SSL stuff is still done even on non-SSL, * but it's simply not used/applied :). * Reason for this is to reduce non-SSL/SSL inconsistency issues. */ serv = parv[1]; p = strchr(serv, '/'); if (p) { *p = '\0'; sslserv = p+1; } p = strchr(serv, ':'); if (p) { *p++ = '\0'; port = atoi(p); if ((port < 1) || (port > 65535)) { sendnotice(sptr, "Invalid serverport specified (%d)", port); return 0; } } if (sslserv) { p = strchr(sslserv, ':'); if (p) { *p++ = '\0'; sslport = atoi(p); if ((sslport < 1) || (sslport > 65535)) { sendnotice(sptr, "Invalid SSL serverport specified (%d)", sslport); return 0; } } if (!*sslserv) sslserv = NULL; } if (!strcasecmp(parv[2], "new")) all = 0; else if (!strcasecmp(parv[2], "all")) all = 1; else { sendnotice(sptr, "ERROR: Invalid action '%s', should be 'NEW' or 'ALL' (see /jumpserver help for usage)", parv[2]); return 0; } reason = parv[3]; /* Free any old stuff (needed!) */ if (jss) free_jss(); jss = MyMallocEx(sizeof(JSS)); /* Set it */ jss->server = strdup(serv); jss->port = port; #ifdef USE_SSL if (sslserv) { jss->ssl_server = strdup(sslserv); jss->ssl_port = sslport; } #endif jss->reason = strdup(reason); /* Broadcast/log */ #ifdef USE_SSL if (sslserv) snprintf(logbuf, sizeof(logbuf), "%s (%s@%s) added JUMPSERVER redirect for %s to %s:%d [SSL: %s:%d] with reason '%s'", sptr->name, sptr->user->username, sptr->user->realhost, all ? "ALL CLIENTS" : "all new clients", jss->server, jss->port, jss->ssl_server, jss->ssl_port, jss->reason); else #endif snprintf(logbuf, sizeof(logbuf), "%s (%s@%s) added JUMPSERVER redirect for %s to %s:%d with reason '%s'", sptr->name, sptr->user->username, sptr->user->realhost, all ? "ALL CLIENTS" : "all new clients", jss->server, jss->port, jss->reason); sendto_realops("%s", logbuf); ircd_log(LOG_ERROR, "%s", logbuf); if (all) redirect_all_clients(); return 0; }
/* ** m_whois ** parv[0] = sender prefix ** parv[1] = nickname masklist */ int m_whois(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) { static anUser UnknownUser = { NULL, /* next */ NULL, /* channel */ NULL, /* invited */ NULL, /* silence */ NULL, /* away */ 0, /* last */ 1, /* refcount */ 0, /* joined */ "<Unknown>" /* server */ }; static char rpl_oper[] = "an IRC Operator"; static char rpl_locop[] = "an IRC Operator - Local IRC Operator"; static char rpl_sadmin[] = "an IRC Operator - Services Administrator"; static char rpl_admin[] = "an IRC Operator - Server Administrator"; static char rpl_tadmin[] = "an IRC Operator - Technical Administrator"; static char rpl_nadmin[] = "an IRC Operator - Network Administrator"; Link *lp; anUser *user; struct Client *acptr, *a2cptr; aChannel *chptr; char *nick, *name; /* char *tmp; */ char *p = NULL; int found, len, mlen; static time_t last_used=0L; char *nick_match=NULL, *user_match=NULL, *host_match=NULL, *server_match=NULL; char *name_match=NULL; int found_mode; int hits = 0; char *mename = me.name; if(sptr->user && sptr->user->vlink) mename = sptr->user->vlink->name; if (parc < 2) { sendto_one(sptr, form_str(ERR_NONICKNAMEGIVEN), mename, parv[0]); return 0; } if(parc > 2) { if (hunt_server(cptr,sptr,":%s WHOIS %s :%s", 1,parc,parv) != HUNTED_ISME) return 0; parv[1] = parv[2]; } if(!IsAnOper(sptr) && !MyConnect(sptr)) /* pace non local requests */ { if((last_used + WHOIS_WAIT) > CurrentTime) { /* Unfortunately, returning anything to a non local * request =might= increase sendq to be usable in a split hack * Sorry gang ;-( - Dianora */ return 0; } else { last_used = CurrentTime; } } /* Multiple whois from remote hosts, can be used * to flood a server off. One could argue that multiple whois on * local server could remain. Lets think about that, for now * removing it totally. * -Dianora */ /* for (tmp = parv[1]; (nick = strtoken(&p, tmp, ",")); tmp = NULL) */ nick = parv[1]; p = strchr(parv[1],','); if(p) *p = '\0'; { int invis, member, wilds; found = 0; (void)collapse(nick); wilds = (nick[0]=='$' || strchr(nick, '?') || strchr(nick, '*')); /* ** We're no longer allowing remote users to generate ** requests with wildcards. */ if (wilds && !IsAnOper(sptr)) { sendto_one(sptr, form_str(ERR_NOSUCHNICK), mename, parv[0], nick); return 0; } /* continue; */ /* If the nick doesn't have any wild cards in it, * then just pick it up from the hash table * - Dianora */ if(!wilds) { acptr = hash_find_client(nick,(struct Client *)NULL); if(!acptr) { sendto_one(sptr, form_str(ERR_NOSUCHNICK), mename, parv[0], nick); sendto_one(sptr, form_str(RPL_ENDOFWHOIS), mename, parv[0], parv[1]); return 0; /* continue; */ } if(IsStealth(acptr)) { sendto_one(sptr, form_str(ERR_NOSUCHNICK), mename, parv[0], nick); return 0; // Add by ^Stinger^ after the idea of Soldier (: } if(!IsPerson(acptr)) { sendto_one(sptr, form_str(RPL_ENDOFWHOIS), mename, parv[0], parv[1]); return 0; } /* continue; */ user = acptr->user ? acptr->user : &UnknownUser; name = (!*acptr->name) ? "?" : acptr->name; invis = IsInvisible(acptr); member = (user->channel) ? 1 : 0; a2cptr = find_server(user->server); sendto_one(sptr, form_str(RPL_WHOISUSER), mename, parv[0], name, acptr->username, acptr->host, acptr->info); if((IsOper(sptr) || (acptr == sptr)) && WhoisExtension) { sendto_one(sptr, form_str(RPL_WHOISREALHOST), mename, parv[0], name, acptr->realhost); } mlen = strlen(mename) + strlen(parv[0]) + 6 + strlen(name); *buf = '\0'; if (IsSsl(acptr)) { sendto_one(sptr, form_str(RPL_WHOISSECURE), mename, parv[0], parv[1]); } if(((!IsPrivate(acptr) || IsOper(sptr)) || (acptr==sptr)) && !IsStealth(acptr)) for (len = 0, *buf = '\0', lp = user->channel; lp; lp = lp->next) { chptr = lp->value.chptr; if (ShowChannel(sptr, chptr)) { if (len + strlen(chptr->chname) > (size_t) BUFSIZE - 4 - mlen) { sendto_one(sptr, ":%s %d %s %s :%s", mename, RPL_WHOISCHANNELS, parv[0], name, buf); *buf = '\0'; len = 0; } found_mode = user_channel_mode(acptr, chptr); #ifdef HIDE_OPS if(is_chan_op(sptr,chptr)) #endif { if(found_mode & CHFL_CHANOP) *(buf + len++) = '@'; #ifdef HALFOPS else if (found_mode & CHFL_HALFOP) *(buf + len++) = '%'; #endif else if (found_mode & CHFL_VOICE) *(buf + len++) = '+'; } if (len) *(buf + len) = '\0'; (void)strcpy(buf + len, chptr->chname); len += strlen(chptr->chname); (void)strcat(buf + len, " "); len++; } } if (buf[0] != '\0') sendto_one(sptr, form_str(RPL_WHOISCHANNELS), mename, parv[0], name, buf); if(IsAnOper(sptr) || !HideServerOnWhois) { #ifdef SERVERHIDE if (!(IsAnOper(sptr) || acptr == sptr)) sendto_one(sptr, form_str(RPL_WHOISSERVER), mename, parv[0], name, NetworkName, NetworkDesc); else #endif if(acptr->user && acptr->user->vlink) sendto_one(sptr, form_str(RPL_WHOISSERVER), mename, parv[0], name, user->vlink->name, user->vlink->passwd); else { if(!IsService(acptr) || IsAnOper(sptr) || !HideServicesServer) sendto_one(sptr, form_str(RPL_WHOISSERVER), mename, parv[0], name, user->server, a2cptr?a2cptr->info:"*Not On This Net*"); } } /* if(IsAnOper(sptr) || HideServerOnWhois) */ if (IsIdentified(acptr)) sendto_one(sptr, form_str(RPL_WHOISIDENTIFIED), mename, parv[0], name); if (IsHelper(acptr)) sendto_one(sptr, form_str(RPL_WHOISHELPOP), mename, parv[0], name); if(IsOper(sptr) && WhoisExtension) { sendto_one(sptr, form_str(RPL_WHOISMODE), mename, parv[0], name, get_mode_string(acptr)); } if (user->away) sendto_one(sptr, form_str(RPL_AWAY), mename, parv[0], name, user->away); if(!IsHideOper(acptr) || IsOper(sptr)) { if (IsNetAdmin(acptr)) sendto_one(sptr, form_str(RPL_WHOISOPERATOR), mename, parv[0], name, rpl_nadmin); else if (IsTechAdmin(acptr)) sendto_one(sptr, form_str(RPL_WHOISOPERATOR), mename, parv[0], name, rpl_tadmin); else if (IsSAdmin(acptr)) sendto_one(sptr, form_str(RPL_WHOISOPERATOR), mename, parv[0], name, rpl_sadmin); else if (IsAdmin(acptr)) sendto_one(sptr, form_str(RPL_WHOISOPERATOR), mename, parv[0], name, rpl_admin); else if (IsOper(acptr)) sendto_one(sptr, form_str(RPL_WHOISOPERATOR), mename, parv[0], name, rpl_oper); else if (IsLocOp(acptr)) sendto_one(sptr, form_str(RPL_WHOISOPERATOR), mename, parv[0], name, rpl_locop); } #ifdef WHOIS_NOTICE if ((IsOper(acptr)) && ((acptr)->umodes & UMODE_SPY) && (MyConnect(sptr)) && (IsPerson(sptr)) && (acptr != sptr) && !is_silenced(sptr, acptr)) sendto_one(acptr, ":%s NOTICE %s :*** Notice -- %s (%s@%s) is doing a /whois on you.", me.name, acptr->name, parv[0], sptr->username, sptr->realhost); #endif /* #ifdef WHOIS_NOTICE */ if ((acptr->user #ifdef SERVERHIDE && IsAnOper(sptr) #endif && MyConnect(acptr))) sendto_one(sptr, form_str(RPL_WHOISIDLE), mename, parv[0], name, CurrentTime - user->last, acptr->firsttime); sendto_one(sptr, form_str(RPL_ENDOFWHOIS), mename, parv[0], parv[1]); return 0; /* continue; */ } /* wild is true so here we go */ if(nick[0]==':') /* real name match */ { name_match = &nick[1]; nick_match = NULL; } else if(nick[0]=='$') /* server name match */ { server_match = &nick[1]; nick_match = NULL; } else { host_match = strchr(nick,'@'); if(host_match) { if(*host_match) *(host_match++) = '\0'; user_match=nick; if(host_match=='\0') host_match="*"; if(user_match=='\0') user_match="*"; } else nick_match = nick; } for (acptr = GlobalClientList; acptr; acptr = acptr->next) { if (IsServer(acptr)) continue; /* * I'm always last :-) and acptr->next == NULL!! */ if (IsMe(acptr)) break; /* * 'Rules' established for sending a WHOIS reply: * * * - if wildcards are being used dont send a reply if * the querier isnt any common channels and the * client in question is invisible and wildcards are * in use (allow exact matches only); * * - only send replies about common or public channels * the target user(s) are on; */ /* If its an unregistered client, ignore it, it can be "seen" on a /trace anyway -Dianora */ if(!IsRegistered(acptr)) continue; user = acptr->user ? acptr->user : &UnknownUser; name = (!*acptr->name) ? "?" : acptr->name; if( (server_match && !match(server_match, user->server)) || (nick_match && !match(nick, name)) || (host_match && !match(host_match, acptr->realhost) && !match(host_match, acptr->host)) || (user_match && !match(user_match, acptr->username)) || (name_match && !match(name_match, acptr->info)) ) continue; ++hits; a2cptr = find_server(user->server); sendto_one(sptr, form_str(RPL_WHOISUSER), mename, parv[0], name, acptr->username, IsOper(sptr) ? acptr->realhost : acptr->host, acptr->info); found = 1; mlen = strlen(mename) + strlen(parv[0]) + 6 + strlen(name); for (len = 0, *buf = '\0', lp = user->channel; lp; lp = lp->next) { chptr = lp->value.chptr; if (ShowChannel(sptr, chptr)) { if (len + strlen(chptr->chname) > (size_t) BUFSIZE - 4 - mlen) { sendto_one(sptr, ":%s %d %s %s :%s", mename, RPL_WHOISCHANNELS, parv[0], name, buf); *buf = '\0'; len = 0; } found_mode = user_channel_mode(acptr, chptr); #ifdef HIDE_OPS if(is_chan_op(sptr,chptr)) #endif { if (found_mode & CHFL_CHANOP) *(buf + len++) = '@'; #ifdef HALFOPS else if (found_mode & CHFL_HALFOP) *(buf + len++) = '%'; #endif else if (found_mode & CHFL_VOICE) *(buf + len++) = '+'; } if (len) *(buf + len) = '\0'; (void)strcpy(buf + len, chptr->chname); len += strlen(chptr->chname); (void)strcat(buf + len, " "); len++; } } if (buf[0] != '\0') sendto_one(sptr, form_str(RPL_WHOISCHANNELS), mename, parv[0], name, buf); #ifdef SERVERHIDE if (!(IsAnOper(sptr) || acptr == sptr)) sendto_one(sptr, form_str(RPL_WHOISSERVER), mename, parv[0], name, NetworkName, NetworkDesc); else #endif sendto_one(sptr, form_str(RPL_WHOISSERVER), mename, parv[0], name, user->server, a2cptr?a2cptr->info:"*Not On This Net*"); if (user->away) sendto_one(sptr, form_str(RPL_AWAY), mename, parv[0], name, user->away); if (IsNetAdmin(acptr)) sendto_one(sptr, form_str(RPL_WHOISOPERATOR), mename, parv[0], name, rpl_nadmin); else if (IsTechAdmin(acptr)) sendto_one(sptr, form_str(RPL_WHOISOPERATOR), mename, parv[0], name, rpl_tadmin); else if (IsSAdmin(acptr)) sendto_one(sptr, form_str(RPL_WHOISOPERATOR), mename, parv[0], name, rpl_sadmin); else if (IsAdmin(acptr)) sendto_one(sptr, form_str(RPL_WHOISOPERATOR), mename, parv[0], name, rpl_admin); else if (IsAnOper(acptr)) sendto_one(sptr, form_str(RPL_WHOISOPERATOR), mename, parv[0], name, rpl_oper); #ifdef WHOIS_NOTICE if ((MyOper(acptr)) && ((acptr)->umodes & UMODE_SPY) && (MyConnect(sptr)) && (IsPerson(sptr)) && (acptr != sptr)) sendto_one(acptr, ":%s NOTICE %s :*** Notice -- %s (%s@%s) is doing a /whois on you.", mename, acptr->name, parv[0], sptr->username, sptr->realhost); #endif /* #ifdef WHOIS_NOTICE */ if ((acptr->user #ifdef SERVERHIDE && IsAnOper(sptr) #endif && MyConnect(acptr))) sendto_one(sptr, form_str(RPL_WHOISIDLE), mename, parv[0], name, CurrentTime - user->last, acptr->firsttime); if(hits>50) { sendto_one(sptr,":%s NOTICE %s :Aborting /whois output as flood prevention", mename, sptr->name); break; } } if (!found) sendto_one(sptr, form_str(ERR_NOSUCHNICK), mename, parv[0], nick); else sendto_one(sptr,":%s NOTICE %s :This /whois matched \2%i\2 user(s)", mename, sptr->name,hits); /* if (p) p[-1] = ','; */ } sendto_one(sptr, form_str(RPL_ENDOFWHOIS), mename, parv[0], parv[1]); return 0; }