int m_sdesc(aClient *cptr, aClient *sptr, int parc, char *parv[]) { if (!IsAdmin(sptr) && !IsCoAdmin(sptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, sptr->name); return 0; } if (parc < 2) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, sptr->name, "SDESC"); return 0; } if (strlen(parv[1]) < 1) if (MyConnect(sptr)) { sendto_one(sptr, ":%s NOTICE %s :*** Nothing to change to (SDESC)", me.name, sptr->name); return 0; } if (strlen(parv[1]) > (REALLEN)) { if (MyConnect(sptr)) { sendto_one(sptr, ":%s NOTICE %s :*** /SDESC Error: \"Server info\" may maximum be %i characters of length", me.name, sptr->name, REALLEN); } return 0; } ircsprintf(sptr->srvptr->info, "%s", parv[1]); sendto_serv_butone_token(cptr, sptr->name, MSG_SDESC, TOK_SDESC, ":%s", parv[1]); if (MyConnect(sptr)) { sendto_one(sptr, ":%s NOTICE %s :Your \"server description\" is now set to be %s - you have to set it manually to undo it", me.name, parv[0], parv[1]); return 0; } sendto_ops("Server description for %s is now '%s' changed by %s", sptr->srvptr->name, sptr->srvptr->info, parv[0]); return 0; }
/* ** m_addmotd (write a line to ircd.motd) ** ** De-Potvinized by codemastr */ DLLFUNC CMD_FUNC(m_addmotd) { FILE *conf; char *text; text = parc > 1 ? parv[1] : NULL; if (!MyConnect(sptr)) return 0; if (!(IsAdmin(sptr) || IsCoAdmin(sptr))) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } if (parc < 2) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "ADDMOTD"); return 0; } conf = fopen(MOTD, "a"); if (conf == NULL) { return 0; } sendto_one(sptr, ":%s %s %s :*** Wrote (%s) to file: ircd.motd", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], text); /* for (i=1 ; i<parc ; i++) { if (i!=parc-1) fprintf (conf,"%s ",parv[i]); else fprintf (conf,"%s\n",parv[i]); } */ fprintf(conf, "%s\n", text); fclose(conf); return 1; }
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_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 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; }