/* * m_userhost added by Darren Reed 13/8/91 to aid clients and reduce * the need for complicated requests like WHOIS. It returns user/host * information only (no spurious AWAY labels or channels). * Re-written by Dianora 1999 */ DLLFUNC CMD_FUNC(m_userhost) { char *p; /* scratch end pointer */ char *cn; /* current name */ struct Client *acptr; char response[5][NICKLEN * 2 + CHANNELLEN + USERLEN + HOSTLEN + 30]; int i; /* loop counter */ if (parc < 2) { sendto_one(sptr, rpl_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "USERHOST"); return 0; } /* The idea is to build up the response string out of pieces * none of this strlen() nonsense. * 5 * (NICKLEN*2+CHANNELLEN+USERLEN+HOSTLEN+30) is still << sizeof(buf) * and our ircsprintf() truncates it to fit anyway. There is * no danger of an overflow here. -Dianora */ response[0][0] = response[1][0] = response[2][0] = response[3][0] = response[4][0] = '\0'; cn = parv[1]; for (i = 0; (i < 5) && cn; i++) { if ((p = strchr(cn, ' '))) *p = '\0'; if ((acptr = find_person(cn, NULL))) { ircsprintf(response[i], "%s%s=%c%s@%s", acptr->name, (IsAnOper(acptr) && (!IsHideOper(acptr) || sptr == acptr || IsAnOper(sptr))) ? "*" : "", (acptr->user->away) ? '-' : '+', acptr->user->username, ((acptr != sptr) && !IsOper(sptr) && IsHidden(acptr) ? acptr->user->virthost : acptr->user->realhost)); } if (p) p++; cn = p; } sendto_one(sptr, rpl_str(RPL_USERHOST), me.name, parv[0], response[0], response[1], response[2], response[3], response[4]); return 0; }
static void send_who_reply(aClient *sptr, aClient *acptr, char *channel, char *status, char *xstat) { char *stat; char *host; int flat = (FLAT_MAP && !IsAnOper(sptr)) ? 1 : 0; stat = malloc(strlen(status) + strlen(xstat) + 1); sprintf(stat, "%s%s", status, xstat); if (IsAnOper(sptr)) { if (who_flags & WF_REALHOST) host = acptr->user->realhost; else if (who_flags & WF_IP) host = (acptr->user->ip_str ? acptr->user->ip_str : acptr->user->realhost); else host = GetHost(acptr); } else host = GetHost(acptr); if (IsULine(acptr) && !IsOper(sptr) && HIDE_ULINES) sendto_one(sptr, getreply(RPL_WHOREPLY), me.name, sptr->name, channel, /* channel name */ acptr->user->username, /* user name */ host, /* hostname */ "hidden", /* let's hide the server from normal users if the server is a uline and HIDE_ULINES is on */ acptr->name, /* nick */ stat, /* status */ 0, /* hops (hidden) */ acptr->info /* realname */ ); else sendto_one(sptr, getreply(RPL_WHOREPLY), me.name, sptr->name, channel, /* channel name */ acptr->user->username, /* user name */ host, /* hostname */ acptr->user->server, /* server name */ acptr->name, /* nick */ stat, /* status */ flat ? 0 : acptr->hopcount, /* hops */ acptr->info /* realname */ ); free(stat); }
DLLFUNC int m_lag(aClient *cptr, aClient *sptr, int parc, char *parv[]) { if (MyClient(sptr)) if (!IsAnOper(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], "LAG"); return 0; } if (*parv[1] == '\0') { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "LAG"); return 0; } if (hunt_server_token(cptr, sptr, MSG_LAG, TOK_LAG, ":%s", 1, parc, parv) == HUNTED_NOSUCH) { return 0; } sendto_one(sptr, ":%s NOTICE %s :Lag reply -- %s %s %li", me.name, sptr->name, me.name, parv[1], TStime()); return 0; }
static void show_opers(aClient *cptr, char *name) { aClient *cptr2; DLink *lp; int j = 0; for (lp = oper_list; lp; lp = lp->next) { cptr2 = lp->value.cptr; if (!IsAnOper(cptr)) { if (cptr2->umode & UMODE_h) { sendto_one(cptr, ":%s %d %s :%s (%s@%s) Idle: %ld", me.name, RPL_STATSDEBUG, name, cptr2->name, cptr2->user->username, cptr2->user->host, (long)(timeofday - cptr2->user->last)); j++; } } else { sendto_one(cptr, ":%s %d %s :%s (%s@%s) Idle: %ld", me.name, RPL_STATSDEBUG, name, cptr2->name, cptr2->user->username, cptr2->user->host, (long)(timeofday - cptr2->user->last)); j++; } } sendto_one(cptr, ":%s %d %s :%d OPER%s", me.name, RPL_STATSDEBUG, name, j, (j == 1) ? "" : "s"); }
int m_svso(aClient *cptr, aClient *sptr, int parc, char *parv[]) { aClient *acptr; long fLag; if (!IsULine(sptr)) return 0; if (parc < 3) return 0; if (!(acptr = find_person(parv[1], (aClient *)NULL))) return 0; if (!MyClient(acptr)) { sendto_one(acptr, ":%s SVSO %s %s", parv[0], parv[1], parv[2]); return 0; } if (*parv[2] == '+') { int *i, flag; char *m = NULL; for (m = (parv[2] + 1); *m; m++) { for (i = oper_access; (flag = *i); i += 2) { if (*m == (char) *(i + 1)) { acptr->oflag |= flag; break; } } } } if (*parv[2] == '-') { fLag = acptr->umodes; if (IsOper(acptr) && !IsHideOper(acptr)) { IRCstats.operators--; VERIFY_OPERCOUNT(acptr, "svso"); } if (IsAnOper(acptr)) delfrom_fdlist(acptr->slot, &oper_fdlist); acptr->umodes &= ~(UMODE_OPER | UMODE_LOCOP | UMODE_HELPOP |UMODE_SERVICES | UMODE_SADMIN | UMODE_ADMIN | UMODE_COADMIN); acptr->umodes &= ~(UMODE_NETADMIN | UMODE_WHOIS); acptr->umodes &= ~(UMODE_KIX | UMODE_DEAF | UMODE_HIDEOPER | UMODE_VICTIM); acptr->oflag = 0; remove_oper_snomasks(acptr); RunHook2(HOOKTYPE_LOCAL_OPER, acptr, 0); send_umode_out(acptr, acptr, fLag); } return 0; }
/* show_servers * replies to stats v requests */ static void show_servers(aClient *cptr, char *name) { aClient *cptr2; DLink *lp; int j = 0; for (lp = server_list; lp; lp = lp->next) { cptr2 = lp->value.cptr; #ifdef HIDEULINEDSERVS if(IsULine(cptr2) && !IsAnOper(cptr)) continue; #endif j++; sendto_one(cptr, ":%s %d %s :%s (%s!%s@%s) Idle: %ld", me.name, RPL_STATSDEBUG, name, cptr2->name, (cptr2->serv->bynick[0] ? cptr2->serv->bynick : "Remote."), (cptr2->serv->byuser[0] ? cptr2->serv->byuser : "******"), (cptr2->serv->byhost[0] ? cptr2->serv->byhost : "*"), (long)(timeofday - cptr2->lasttime)); } sendto_one(cptr, ":%s %d %s :%d Server%s", me.name, RPL_STATSDEBUG, name, j, (j == 1) ? "" : "s"); }
int umode_allow_opers(aClient *sptr, int what) { if (MyClient(sptr)) return IsAnOper(sptr) ? 1 : 0; else return 1; }
/* * m_globops (write to *all* opers currently online) * parv[0] = sender prefix * parv[1] = message text */ int m_globops(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) { char* message; message = parc > 1 ? parv[1] : NULL; if (EmptyString(message)) { sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "GLOBOPS"); return 0; } if (!IsServer(sptr) && MyConnect(sptr) && !IsAnOper(sptr)) { sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]); return(0); } sendto_serv_butone(IsServer(cptr) ? cptr : NULL, ":%s GLOBOPS :%s", parv[0], message); sendto_globops("from %s: %s", parv[0], message); return 0; }
/** Handle a TRACE message from a local oper. * * \a parv has the following elements: * \li \a parv[1] is the nick or servername to trace * \li \a parv[2] is the optional 'target' server to trace from * * See @ref m_functions for discussion of the arguments. * @param[in] cptr Client that sent us the message. * @param[in] sptr Original source of message. * @param[in] parc Number of arguments. * @param[in] parv Argument vector. */ int mo_trace(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { if (feature_bool(FEAT_HIS_TRACE) && !IsAnOper(sptr)) return send_reply(cptr, ERR_NOPRIVILEGES); do_trace(cptr, sptr, parc, parv); return 0; }
/* * m_lnotice (send notice to all local users) * parv[0] = sender prefix * parv[1] = message text */ int m_lnotice(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) { char* message; struct Client *acptr; message = parc > 1 ? parv[1] : NULL; if (EmptyString(message)) { sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "LNOTICE"); return 0; } if (MyClient(sptr) && !IsAnOper(sptr)) { sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]); return(0); } for(acptr = local_cptr_list; acptr; acptr = acptr->next_local_client) { sendto_one(acptr,":%s NOTICE %s :%s", me.name, acptr->name, parv[1]); } sendto_ops("LNOTICE sent by \2%s\2",parv[0]); sendto_serv_butone(&me, ":%s GLOBOPS :LNOTICE on %s :%s", me.name, sptr->name, parv[1]); return 0; }
/* This function adds as an extra (weird) operoverride. * Currently it's only used if you try to operoverride for a +z channel, * if you then do '/join #chan override' it will put the channel -z and allow you directly in. * This is to avoid attackers from using 'race conditions' to prevent you from joining. * PARAMETERS: sptr = the client, chptr = the channel, mval = mode value (eg MODE_ONLYSECURE), * mchar = mode char (eg 'z') * RETURNS: 1 if operoverride, 0 if not. */ int extended_operoverride(aClient *sptr, aChannel *chptr, char *key, int mval, char mchar) { unsigned char invited = 0; Link *lp; if (!IsAnOper(sptr) || !OPCanOverride(sptr)) return 0; for (lp = sptr->user->invited; lp; lp = lp->next) if (lp->value.chptr == chptr) { invited = 1; break; } if (invited) { if (key && !strcasecmp(key, "override")) { sendto_channelprefix_butone(NULL, &me, chptr, PREFIX_OP|PREFIX_ADMIN|PREFIX_OWNER, ":%s NOTICE @%s :setting channel -%c due to OperOverride request from %s", me.name, chptr->chname, mchar, sptr->name); sendto_serv_butone(&me, ":%s MODE %s -%c 0", me.name, chptr->chname, mchar); sendto_channel_butserv(chptr, &me, ":%s MODE %s -%c", me.name, chptr->chname, mchar); chptr->mode.mode &= ~mval; return 1; } } return 0; }
int m_svsnoop(aClient *cptr, aClient *sptr, int parc, char *parv[]) { aClient *acptr; if (!(IsULine(sptr) && parc > 2)) return 0; /* svsnoop bugfix --binary */ if (hunt_server_token(cptr, sptr, MSG_SVSNOOP, TOK_SVSNOOP, "%s :%s", 1, parc, parv) == HUNTED_ISME) { if (parv[2][0] == '+') { SVSNOOP = 1; sendto_ops("This server has been placed in NOOP mode"); for (acptr = &me; acptr; acptr = acptr->prev) { if (MyClient(acptr) && IsAnOper(acptr)) { if (IsOper(acptr)) { IRCstats.operators--; VERIFY_OPERCOUNT(acptr, "svsnoop"); } if (IsAnOper(acptr)) delfrom_fdlist(acptr->slot, &oper_fdlist); if (IsTotalInvis(acptr)) { sendto_channels_inviso_join(acptr); } acptr->umodes &= ~(UMODE_OPER|UMODE_HELPOP|UMODE_SADMIN|UMODE_ADMIN|UMODE_LOCOP|UMODE_SERVICES|UMODE_NETADMIN); acptr->umodes &= ~(UMODE_WHOIS|UMODE_KIX|UMODE_HIDEOPER|UMODE_HIDEWHOIS|UMODE_TOTALINVIS|UMODE_MODEWALK|UMODE_NOFAKELAG); acptr->oflag = 0; remove_oper_snomasks(acptr); sendto_one(acptr, ":%s NOTICE %s :*** Your OFLAGS have been cleared, because this server has been placed in NOOP mode", me.name, acptr->name); RunHook2(HOOKTYPE_LOCAL_OPER, acptr, 0); } } } else { SVSNOOP = 0; sendto_ops("This server is no longer in NOOP mode"); } } return 0; }
/** Handle a JOIN message from a client connection. * See @ref m_functions for discussion of the arguments. * @param[in] cptr Client that sent us the message. * @param[in] sptr Original source of message. * @param[in] parc Number of arguments. * @param[in] parv Argument vector. */ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) { struct JoinBuf join; struct JoinBuf create; char *p = 0; char *chanlist; char *name; char *keys; if (parc < 2 || *parv[1] == '\0') return need_more_params(sptr, "JOIN"); if (!IsAnOper(sptr) && IsRestrictJoin(sptr)) { send_reply(sptr, ERR_BANNEDFROMCHAN, parv[1]); return 0; } joinbuf_init(&join, sptr, cptr, JOINBUF_TYPE_JOIN, 0, 0); joinbuf_init(&create, sptr, cptr, JOINBUF_TYPE_CREATE, 0, TStime()); chanlist = last0(cptr, sptr, parv[1]); /* find last "JOIN 0" */ keys = parv[2]; /* remember where keys are */ for (name = ircd_strtok(&p, chanlist, ","); name; name = ircd_strtok(&p, 0, ",")) { char *key = 0; /* If we have any more keys, take the first for this channel. */ if (!BadPtr(keys) && (keys = strchr(key = keys, ','))) *keys++ = '\0'; /* Empty keys are the same as no keys. */ if (key && !key[0]) key = 0; if (!IsChannelName(name) || !strIsIrcCh(name)) { /* bad channel name */ send_reply(sptr, ERR_NOSUCHCHANNEL, name); continue; } if (cli_user(sptr)->joined >= get_client_maxchans(sptr) && !HasPriv(sptr, PRIV_CHAN_LIMIT)) { send_reply(sptr, ERR_TOOMANYCHANNELS, name); break; /* no point processing the other channels */ } do_join(cptr, sptr, &join, &create, name, key, 0); } joinbuf_flush(&join); /* must be first, if there's a JOIN 0 */ joinbuf_flush(&create); return 0; }
DLLFUNC char *privdeaf_checkmsg(aClient *cptr, aClient *sptr, aClient *acptr, char *text, int notice) { if ((acptr->umodes & UMODE_PRIVDEAF) && !IsAnOper(sptr) && !IsULine(sptr) && !IsServer(sptr)) { sendnotice(sptr, "Message to '%s' not delivered: User does not accept private messages", acptr->name); return NULL; } else return text; }
DLLFUNC char *privdeaf_checkmsg(aClient *cptr, aClient *sptr, aClient *acptr, char *text, int notice) { if ((acptr->umodes & UMODE_PRIVDEAF) && !IsAnOper(sptr) && !IsULine(sptr) && !IsServer(sptr)) { sendnotice(sptr, "Message to '%s' has not been sent. The user has +D set. This blocks private messages.", acptr->name); return NULL; } else return text; }
/* * mo_close - oper message handler * - added by Darren Reed Jul 13 1992. */ int mo_close(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { assert(0 != cptr); assert(cptr == sptr); assert(IsAnOper(sptr)); return send_reply(sptr, RPL_CLOSEEND, net_close_unregistered_connections(sptr)); }
static void make_who_status(aClient *sptr, aClient *acptr, aChannel *channel, Member *cm, char *status, int cansee) { int i = 0; if (acptr->user->away) status[i++] = 'G'; else status[i++] = 'H'; if (IsARegNick(acptr)) status[i++] = 'r'; if (acptr->umodes & UMODE_BOT) status[i++] = 'B'; if (IsAnOper(acptr) && (!IsHideOper(acptr) || sptr == acptr || IsAnOper(sptr))) status[i++] = '*'; if (IsAnOper(acptr) && (IsHideOper(acptr) && sptr != acptr && IsAnOper(sptr))) status[i++] = '!'; if (cansee & WHO_OPERSEE) status[i++] = '?'; if (cm) { #ifdef PREFIX_AQ if (cm->flags & CHFL_CHANOWNER) status[i++] = '~'; else if (cm->flags & CHFL_CHANPROT) status[i++] = '&'; else #endif if (cm->flags & CHFL_CHANOP) status[i++] = '@'; else if (cm->flags & CHFL_HALFOP) status[i++] = '%'; else if (cm->flags & CHFL_VOICE) status[i++] = '+'; } status[i] = '\0'; }
void foo() { if (mask && ((mask[0] == '\0') || (mask[1] == '\0' && ((mask[0] == '0') || (mask[0] == '*'))))) mask = NULL; if ((acptr = FindUser(nick)) && ((!(bitsel & WHOSELECT_OPER)) || IsAnOper(acptr)) && Process(acptr) && SHOW_MORE(sptr, counter)) mask = NULL; }
/* * m_whowas - generic message handler * * parv[0] = sender prefix * parv[1] = nickname queried * parv[2] = maximum returned items (optional, default is unlimited) * parv[3] = remote server target (Opers only, max returned items 20) */ int m_whowas(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { struct Whowas *temp; int cur = 0; int max = -1, found = 0; char *p, *nick, *s; if (parc < 2) { send_reply(sptr, ERR_NONICKNAMEGIVEN); return 0; } if (parc > 2) max = atoi(parv[2]); if (parc > 3) if (hunt_server_cmd(sptr, CMD_WHOWAS, cptr, 1, "%s %s :%C", 3, parc, parv)) return 0; parv[1] = canonize(parv[1]); if (!MyConnect(sptr) && (max > 20)) max = 20; /* Set max replies at 20 */ for (s = parv[1]; (nick = ircd_strtok(&p, s, ",")); s = 0) { /* Search through bucket, finding all nicknames that match */ found = 0; for (temp = whowashash[hash_whowas_name(nick)]; temp; temp = temp->hnext) { if (0 == ircd_strcmp(nick, temp->name)) { send_reply(sptr, RPL_WHOWASUSER, temp->name, temp->username, temp->hostname, temp->realname); if (IsAnOper(sptr) && temp->realhost) send_reply(sptr, RPL_WHOISACTUALLY, temp->name, temp->username, temp->realhost, "<untracked>"); send_reply(sptr, RPL_WHOISSERVER, temp->name, (feature_bool(FEAT_HIS_WHOIS_SERVERNAME) && !IsOper(sptr)) ? feature_str(FEAT_HIS_SERVERNAME) : temp->servername, myctime(temp->logoff)); if (temp->away) send_reply(sptr, RPL_AWAY, temp->name, temp->away); cur++; found++; } if (max >= 0 && cur >= max) break; } if (!found) send_reply(sptr, ERR_WASNOSUCHNICK, nick); /* To keep parv[1] intact for ENDOFWHOWAS */ if (p) p[-1] = ','; } send_reply(sptr, RPL_ENDOFWHOWAS, parv[1]); return 0; }
/** Report all F-lines to a user. * @param[in] to Client requesting statistics. * @param[in] sd Stats descriptor for request (ignored). * @param[in] param Extra parameter from user (ignored). */ void feature_report(struct Client* to, const struct StatDesc* sd, char* param) { char changed; int report; int i; /* send header so the client knows what we are showing */ send_reply(to, SND_EXPLICIT | RPL_STATSHEADER, "F Feature/Log Value"); for (i = 0; features[i].type; i++) { if ((features[i].flags & FEAT_NODISP) || (features[i].flags & FEAT_MYOPER && !MyOper(to)) || (features[i].flags & FEAT_OPER && !IsAnOper(to))) continue; /* skip this one */ changed = (features[i].flags & FEAT_MARK) ? 'F' : 'f'; report = (features[i].flags & FEAT_MARK) || sd->sd_funcdata; switch (features[i].flags & FEAT_MASK) { case FEAT_NONE: if (features[i].report) /* let the callback handle this */ (*features[i].report)(to, report); break; case FEAT_INT: /* Report an F-line with integer values */ if (features[i].flags & FEAT_MARK) /* it's been changed */ send_reply(to, SND_EXPLICIT | RPL_STATSFLINE, "F %s %d", features[i].type, features[i].v_int); break; case FEAT_BOOL: /* Report an F-line with boolean values */ if (report) /* it's been changed */ send_reply(to, SND_EXPLICIT | RPL_STATSFLINE, "%c %s %s", changed, features[i].type, features[i].v_int ? "TRUE" : "FALSE"); break; case FEAT_STR: /* Report an F-line with string values */ if (report) { /* it's been changed */ if (features[i].v_str) send_reply(to, SND_EXPLICIT | RPL_STATSFLINE, "%c %s %s", changed, features[i].type, features[i].v_str); else /* Actually, F:<type> would reset it; you want F:<type>: */ send_reply(to, SND_EXPLICIT | RPL_STATSFLINE, "%c %s", changed, features[i].type); } break; } } }
/* * mo_kill - oper message handler * * NOTE: IsPrivileged(sptr), IsAnOper(sptr) == true * IsServer(cptr), IsServer(sptr) == false * * parv[0] = sender prefix * parv[1] = kill victim * parv[parc-1] = kill path */ int mo_kill(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { struct Client* victim; char* user; char msg[TOPICLEN + 3]; /* (, ), and \0 */ assert(0 != cptr); assert(0 != sptr); /* * oper connection to this server, cptr is always sptr */ assert(cptr == sptr); assert(IsAnOper(sptr)); if (parc < 3 || EmptyString(parv[parc - 1])) return need_more_params(sptr, "KILL"); user = parv[1]; ircd_snprintf(0, msg, sizeof(msg), "(%.*s)", TOPICLEN, parv[parc - 1]); if (!(victim = FindClient(user))) { /* * If the user has recently changed nick, we automaticly * rewrite the KILL for this new nickname--this keeps * servers in synch when nick change and kill collide */ if (!(victim = get_history(user, (long)15))) return send_reply(sptr, ERR_NOSUCHNICK, user); sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Changed KILL %s into %s", sptr, user, cli_name(victim)); } if (!HasPriv(sptr, MyConnect(victim) ? PRIV_LOCAL_KILL : PRIV_KILL)) return send_reply(sptr, ERR_NOPRIVILEGES); if (IsServer(victim) || IsMe(victim)) { return send_reply(sptr, ERR_CANTKILLSERVER); } /* * if the user is +k, prevent a kill from local user */ if (IsChannelService(victim)) return send_reply(sptr, ERR_ISCHANSERVICE, "KILL", cli_name(victim)); if (!MyConnect(victim) && !HasPriv(sptr, PRIV_KILL)) { sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :Nick %s isnt on your server", sptr, cli_name(victim)); return 0; } return do_kill(cptr, sptr, victim, cli_user(sptr)->host, cli_name(sptr), msg); }
static char *show_iline_prefix(aClient *sptr,aConfItem *aconf,char *name) { static char prefix_of_host[MAXPREFIX]; char *prefix_ptr; prefix_ptr = prefix_of_host; if (IsNoTilde(aconf)) *prefix_ptr++ = '-'; if (IsLimitIp(aconf)) *prefix_ptr++ = '!'; if (IsNeedIdentd(aconf)) *prefix_ptr++ = '+'; if (IsPassIdentd(aconf)) *prefix_ptr++ = '$'; if (IsNoMatchIp(aconf)) *prefix_ptr++ = '%'; #ifdef E_LINES_OPER_ONLY if(IsAnOper(sptr)) #endif if (IsConfElined(aconf)) *prefix_ptr++ = '^'; #ifdef B_LINES_OPER_ONLY if(IsAnOper(sptr)) #endif if (IsConfBlined(aconf)) *prefix_ptr++ = '&'; #ifdef F_LINES_OPER_ONLY if(IsAnOper(sptr)) #endif if (IsConfFlined(aconf)) *prefix_ptr++ = '>'; *prefix_ptr = '\0'; strncat(prefix_of_host,name,MAXPREFIX); return(prefix_of_host); }
/* * m_wallops (write to *all* opers currently online) * parv[0] = sender prefix * parv[1] = message text */ int m_wallops(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) { char* message; message = parc > 1 ? parv[1] : NULL; if (EmptyString(message)) { sendto_one(sptr, form_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "WALLOPS"); return 0; } if (!IsServer(sptr) && MyConnect(sptr) && !IsAnOper(sptr)) { sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]); return(0); } /* If its coming from a server, do the normal thing if its coming from an oper, send the wallops along and only send the wallops to our local opers (those who are +ow) -Dianora */ if(!IsServer(sptr)) /* If source of message is not a server, i.e. oper */ { #ifdef PACE_WALLOPS if( MyClient(sptr) ) { if( (LastUsedWallops + WALLOPS_WAIT) > CurrentTime ) { sendto_one(sptr, ":%s NOTICE %s :Oh, one of those annoying opers who doesn't know how to use a channel", me.name,parv[0]); return 0; } LastUsedWallops = CurrentTime; } #endif send_operwall(sptr, "WALLOPS", message); sendto_serv_butone( IsServer(cptr) ? cptr : NULL, ":%s WALLOPS :%s", parv[0], message); } else /* its a server wallops */ sendto_wallops_butone(IsServer(cptr) ? cptr : NULL, sptr, ":%s WALLOPS :%s", parv[0], message); return 0; }
/** Gets the value of a specific feature and reports it to the user. * @param[in] from Client trying to get the feature. * @param[in] fields Parameters to set, starting with feature name. * @param[in] count Number of fields in \a fields. * @return Zero (or, theoretically, CPTR_KILLED). */ int feature_get(struct Client* from, const char* const* fields, int count) { struct FeatureDesc *feat; assert(0 != from); if (count < 1) /* check parameters */ need_more_params(from, "GET"); else if ((feat = feature_desc(from, fields[0]))) { if ((feat->flags & FEAT_NODISP) || (feat->flags & FEAT_MYOPER && !MyOper(from)) || (feat->flags & FEAT_OPER && !IsAnOper(from))) /* check privs */ return send_reply(from, ERR_NOPRIVILEGES); switch (feat_type(feat)) { case FEAT_NONE: /* none, call the callback... */ if (feat->get) /* if there's a callback, use it */ (*feat->get)(from, fields + 1, count - 1); break; case FEAT_INT: /* integer, report integer value */ send_reply(from, SND_EXPLICIT | RPL_FEATURE, ":Integer value of %s: %d", feat->type, feat->v_int); break; case FEAT_UINT: /* unsigned integer, report its value */ send_reply(from, SND_EXPLICIT | RPL_FEATURE, ":Unsigned value of %s: %u", feat->type, feat->v_int); break; case FEAT_BOOL: /* boolean, report boolean value */ send_reply(from, SND_EXPLICIT | RPL_FEATURE, ":Boolean value of %s: %s", feat->type, feat->v_int ? "TRUE" : "FALSE"); break; case FEAT_STR: /* string, report string value */ if (feat->v_str) /* deal with null case */ send_reply(from, SND_EXPLICIT | RPL_FEATURE, ":String value of %s: %s", feat->type, feat->v_str); else send_reply(from, SND_EXPLICIT | RPL_FEATURE, ":String value for %s not set", feat->type); break; } } return 0; }
/* * m_version - VERSION command handler * parv[0] = sender prefix * parv[1] = remote server */ int m_version(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { char *mename; if (!MyClient(sptr) || IsAnOper(sptr)) { if (hunt_server(cptr, sptr, ":%s VERSION :%s", 1, parc, parv) != HUNTED_ISME) return 0; } mename = (sptr->user->vlink) ? sptr->user->vlink->name : me.name; if(IsAnOper(sptr)) sendto_one(sptr, form_str(RPL_VERSION), mename, parv[0], ircdversion, serno, debugmode, mename, serveropts); else sendto_one(sptr, form_str(RPL_VERSION), mename, parv[0], SHORT_VERSION, "2005", debugmode, mename, serveropts); show_isupport(sptr); return 0; }
/* * m_map - generic message handler * -- by Run * * parv[0] = sender prefix * parv[1] = server mask */ int m_map(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { void *args[1]; if (feature_bool(FEAT_HIS_MAP) && !IsAnOper(sptr)) { sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s %s", sptr, "/MAP has been disabled; visit", feature_str(FEAT_HIS_URLSERVERS)); return 0; } if (parc < 2) parv[1] = "*"; args[0] = sptr; if (feature_bool(FEAT_HIS_MAP_SCRAMBLED) && !IsAnOper(sptr)) map_dump_head_in_sand(sptr, map_reply, args); else map_dump(&me, parv[1], 0, map_reply, args); send_reply(sptr, RPL_MAPEND); return 0; }
static void userhost_formatter(struct Client* cptr, struct Client *sptr, struct MsgBuf* mb) { assert(IsUser(cptr)); msgq_append(0, mb, "%s%s=%c%s@%s", cli_name(cptr), SeeOper(sptr,cptr) ? "*" : "", cli_user(cptr)->away ? '-' : '+', cli_user(cptr)->username, /* Do not *EVER* change this to give opers the real host. * Too many scripts rely on this data and can inadvertently * publish the user's real host, thus breaking the security * of +x. If an oper wants the real host, he should go to * /whois to get it. */ !IsAnOper(sptr) ? cli_user(cptr)->host : cli_user(cptr)->realhost); }
/* Remove a temporary dccdeny line * parv[0] - sender * parv[1] - file/mask */ DLLFUNC CMD_FUNC(m_undccdeny) { ConfigItem_deny_dcc *p; if (!MyClient(sptr)) return 0; if (!IsAnOper(sptr) || !OPCanDCCDeny(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], "UNDCCDENY"); return 0; } if (BadPtr(parv[1])) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "UNDCCDENY"); return 0; } /* If we find an exact match even if it is a wild card only remove the exact match -- codemastr */ if ((p = Find_deny_dcc(parv[1])) && p->flag.type2 == CONF_BAN_TYPE_TEMPORARY) { sendto_ops("%s removed a temp dccdeny for %s", parv[0], parv[1]); DCCdeny_del(p); return 1; } /* Next search using the wild card -- codemastr */ /* Uncommented by Stskeeps: else if (dcc_del_wild_match(parv[1]) == 1) sendto_ops ("%s removed a temp dccdeny for all dccdenys matching %s", parv[0], parv[1]); */ /* If still no match, give an error */ else sendto_one(sptr, "NOTICE %s :*** Unable to find a temp dccdeny matching %s", parv[0], parv[1]); return 0; }
static int show_usage(struct Client *sptr) { if (!sptr) { /* configuration file error... */ log_write(LS_CONFIG, L_ERROR, 0, "Invalid default list parameter"); return LPARAM_ERROR; } send_reply(sptr, RPL_LISTUSAGE, "Usage: \002/QUOTE LIST\002 \037parameters\037"); send_reply(sptr, RPL_LISTUSAGE, "Where \037parameters\037 is a space or comma separated " "list of one or more of:"); send_reply(sptr, RPL_LISTUSAGE, " \002<\002\037max_users\037 ; Show all channels with less " "than \037max_users\037."); send_reply(sptr, RPL_LISTUSAGE, " \002>\002\037min_users\037 ; Show all channels with more " "than \037min_users\037."); send_reply(sptr, RPL_LISTUSAGE, " \002C<\002\037max_minutes\037 ; Channels that exist less " "than \037max_minutes\037."); send_reply(sptr, RPL_LISTUSAGE, " \002C>\002\037min_minutes\037 ; Channels that exist more " "than \037min_minutes\037."); send_reply(sptr, RPL_LISTUSAGE, " \002T<\002\037max_minutes\037 ; Channels with a topic last " "set less than \037max_minutes\037 ago."); send_reply(sptr, RPL_LISTUSAGE, " \002T>\002\037min_minutes\037 ; Channels with a topic last " "set more than \037min_minutes\037 ago."); send_reply(sptr, RPL_LISTUSAGE, " \037pattern\037 ; Channels with names matching " "\037pattern\037. "); send_reply(sptr, RPL_LISTUSAGE, " !\037pattern\037 ; Channels with names not " "matching \037pattern\037. "); send_reply(sptr, RPL_LISTUSAGE, "Note: Patterns may contain * and ?. " "You may only give one pattern match constraint."); if (IsAnOper(sptr)) send_reply(sptr, RPL_LISTUSAGE, " \002S\002 ; Show secret channels."); send_reply(sptr, RPL_LISTUSAGE, "Example: LIST <3,>1,C<10,T>0,#a* ; 2 users, younger than 10 " "min., topic set., starts with #a"); return LPARAM_ERROR; /* return error condition */ }
static int crule_directop(int numargs, void **crulearg) { #if !defined(CR_DEBUG) && !defined(CR_CHKCONF) int i; struct Client *acptr; /* adapted from m_trace */ for (i = 0; i <= HighestFd; i++) { if (!(acptr = LocalClientArray[i]) || !IsAnOper(acptr)) continue; return (1); } #endif return (0); }