/** User request to join a channel. * This routine can be called from both m_join or via do_join->can_join->do_join * if the channel is 'linked' (chmode +L). We use a counter 'bouncedtimes' which * is set to 0 in m_join, increased every time we enter this loop and decreased * anytime we leave the loop. So be carefull ;p. */ DLLFUNC CMD_FUNC(_do_join) { char jbuf[BUFSIZE]; Membership *lp; aChannel *chptr; char *name, *key = NULL, *link = NULL; int i, flags = 0; char *p = NULL, *p2 = NULL; #define RET(x) { bouncedtimes--; return x; } if (parc < 2 || *parv[1] == '\0') { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "JOIN"); return 0; } bouncedtimes++; /* don't use 'return x;' but 'RET(x)' from here ;p */ if (bouncedtimes > MAXBOUNCE) { /* bounced too many times */ sendto_one(sptr, ":%s %s %s :*** Couldn't join %s ! - Link setting was too bouncy", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name, parv[1]); RET(0) }
/* ** m_addline (write a line to unrealircd.conf) ** ** De-Potvinized by codemastr */ DLLFUNC CMD_FUNC(m_addline) { FILE *conf; char *text; text = parc > 1 ? parv[1] : NULL; if (!MyClient(sptr) || !IsAnOper(sptr) || !OPCanAddline(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], "ADDLINE"); return 0; } /* writes to current -f */ conf = fopen(configfile, "a"); if (conf == NULL) { return 0; } /* Display what they wrote too */ sendto_one(sptr, ":%s %s %s :*** Wrote (%s) to %s", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], text, configfile); fprintf(conf, "// Added by %s\n", make_nick_user_host(sptr->name, sptr->user->username, sptr->user->realhost)); /* for (i=1 ; i<parc ; i++) { if (i!=parc-1) fprintf (conf,"%s ",parv[i]); else fprintf (conf,"%s\n",parv[i]); } * I dunno what Potvin was smoking when he made this code, but it plain SUX * this should work just as good, and no need for a loop -- codemastr */ fprintf(conf, "%s\n", text); fclose(conf); return 1; }
/* * Added to let the local console shutdown the server without just * calling exit(-1), in Windows mode. -Cabal95 */ int localdie(void) { aClient *acptr; int i; for (i = 0; i <= LastSlot; i++) { if (!(acptr = local[i])) continue; if (IsClient(acptr)) sendto_one(acptr, ":%s %s %s :Server Terminated by local console", me.name, IsWebTV(acptr) ? "PRIVMSG" : "NOTICE", acptr->name); else if (IsServer(acptr)) sendto_one(acptr, ":%s ERROR :Terminated by local console", me.name); } (void)s_die(); return 0; }
DLLFUNC int m_delaylist(Cmdoverride *anoverride, aClient *cptr, aClient *sptr, int parc, char *parv[]) { if (!IsAnOper(sptr)) { if (sptr->firsttime + 10 > TStime()) { /* DENIED! */ sendto_one(sptr, ":%s %s %s :*** You have not been connected long enough " "to use /list. You must wait 30 seconds after connecting", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name); /* if we don't do this, some clients have a hissy :p */ sendto_one(sptr, rpl_str(RPL_LISTSTART), me.name, sptr->name); sendto_one(sptr, rpl_str(RPL_LISTEND), me.name, sptr->name); return 0; } } /* aww, no fun. they've been connected a while :( - let it through */ return CallCmdoverride(delaylist_override, cptr, sptr, parc, parv); }
/* ** 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)) { 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; }
/* ** m_kill ** parv[0] = sender prefix ** parv[1] = kill victim(s) - comma separated list ** parv[2] = kill path */ DLLFUNC int m_kill(aClient *cptr, aClient *sptr, int parc, char *parv[]) { aClient *acptr; anUser *auser; char inpath[HOSTLEN * 2 + USERLEN + 5]; char *oinpath = get_client_name(cptr, FALSE); char *user, *path, *killer, *nick, *p, *s; int chasing = 0, kcount = 0; if (parc < 2 || *parv[1] == '\0') { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "KILL"); return 0; } user = parv[1]; path = parv[2]; /* Either defined or NULL (parc >= 2!!) */ strlcpy(inpath, oinpath, sizeof inpath); #ifndef ROXnet if (IsServer(cptr) && (s = (char *)index(inpath, '.')) != NULL) *s = '\0'; /* Truncate at first "." */ #endif if (!IsPrivileged(cptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } if (IsAnOper(cptr)) { if (BadPtr(path)) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "KILL"); return 0; } if (strlen(path) > (size_t)TOPICLEN) path[TOPICLEN] = '\0'; } if (MyClient(sptr)) user = (char *)canonize(user); for (p = NULL, nick = strtoken(&p, user, ","); nick; nick = strtoken(&p, NULL, ",")) { chasing = 0; if (!(acptr = find_client(nick, NULL))) { /* ** 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 (!(acptr = get_history(nick, (long)KILLCHASETIMELIMIT))) { sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], nick); continue; } sendto_one(sptr, ":%s %s %s :*** KILL changed from %s to %s", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], nick, acptr->name); chasing = 1; } if ((!MyConnect(acptr) && MyClient(cptr) && !OPCanGKill(cptr)) || (MyConnect(acptr) && MyClient(cptr) && !OPCanLKill(cptr))) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); continue; } if (IsServer(acptr) || IsMe(acptr)) { sendto_one(sptr, err_str(ERR_CANTKILLSERVER), me.name, parv[0]); continue; } if (!IsPerson(acptr)) { /* Nick exists but user is not registered yet: IOTW "doesn't exist". -- Syzop */ sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, parv[0], nick); continue; } if (IsServices(acptr) && !(IsNetAdmin(sptr) || IsULine(sptr))) { sendto_one(sptr, err_str(ERR_KILLDENY), me.name, parv[0], parv[1]); return 0; } /* From here on, the kill is probably going to be successful. */ kcount++; if (!IsServer(sptr) && (kcount > MAXKILLS)) { sendto_one(sptr, ":%s %s %s :*** Too many targets, kill list was truncated. Maximum is %d.", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], MAXKILLS); break; } if (!IsServer(cptr)) { /* ** The kill originates from this server, initialize path. ** (In which case the 'path' may contain user suplied ** explanation ...or some nasty comment, sigh... >;-) ** ** ...!operhost!oper ** ...!operhost!oper (comment) */ strlcpy(inpath, GetHost(cptr), sizeof inpath); if (kcount < 2) { /* Only check the path the first time around, or it gets appended to itself. */ if (!BadPtr(path)) { (void)ircsprintf(buf, "%s%s (%s)", cptr->name, IsOper(sptr) ? "" : "(L)", path); path = buf; } else path = cptr->name; } } else if (BadPtr(path)) path = "*no-path*"; /* Bogus server sending??? */ /* ** Notify all *local* opers about the KILL (this includes the one ** originating the kill, if from this server--the special numeric ** reply message is not generated anymore). ** ** Note: "acptr->name" is used instead of "user" because we may ** have changed the target because of the nickname change. */ auser = acptr->user; sendto_snomask_normal(SNO_KILLS, "*** Notice -- Received KILL message for %s!%s@%s from %s Path: %s!%s", acptr->name, auser->username, IsHidden(acptr) ? auser->virthost : auser->realhost, parv[0], inpath, path); #if defined(USE_SYSLOG) && defined(SYSLOG_KILL) if (IsOper(sptr)) syslog(LOG_DEBUG, "KILL From %s For %s Path %s!%s", parv[0], acptr->name, inpath, path); #endif /* * By otherguy */ ircd_log (LOG_KILL, "KILL (%s) by %s(%s!%s)", make_nick_user_host (acptr->name, acptr->user->username, GetHost(acptr)), parv[0], inpath, path); /* ** And pass on the message to other servers. Note, that if KILL ** was changed, the message has to be sent to all links, also ** back. ** Suicide kills are NOT passed on --SRB */ if (!MyConnect(acptr) || !MyConnect(sptr) || !IsAnOper(sptr)) { sendto_serv_butone(cptr, ":%s KILL %s :%s!%s", parv[0], acptr->name, inpath, path); if (chasing && IsServer(cptr)) sendto_one(cptr, ":%s KILL %s :%s!%s", me.name, acptr->name, inpath, path); acptr->flags |= FLAGS_KILLED; } /* ** Tell the victim she/he has been zapped, but *only* if ** the victim is on current server--no sense in sending the ** notification chasing the above kill, it won't get far ** anyway (as this user don't exist there any more either) */ if (MyConnect(acptr)) sendto_prefix_one(acptr, sptr, ":%s KILL %s :%s!%s", parv[0], acptr->name, inpath, path); /* ** Set FLAGS_KILLED. This prevents exit_one_client from sending ** the unnecessary QUIT for this. (This flag should never be ** set in any other place) */ if (MyConnect(acptr) && MyConnect(sptr) && IsAnOper(sptr)) (void)ircsprintf(buf2, "[%s] Local kill by %s (%s)", me.name, sptr->name, BadPtr(parv[2]) ? sptr->name : parv[2]); else { if ((killer = index(path, ' '))) { while ((killer >= path) && *killer && *killer != '!') killer--; if (!*killer) killer = path; else killer++; } else killer = path; (void)ircsprintf(buf2, "Killed (%s)", killer); } if (MyClient(sptr)) RunHook3(HOOKTYPE_LOCAL_KILL, sptr, acptr, parv[2]); if (exit_client(cptr, acptr, sptr, buf2) == FLUSH_BUFFER) return FLUSH_BUFFER; } return 0; }
/* ** m_mkpasswd ** parv[0] = sender prefix ** parv[1] = password to encrypt */ int m_mkpasswd(aClient *cptr, aClient *sptr, int parc, char *parv[]) { short type; char *result = NULL; if (!MKPASSWD_FOR_EVERYONE && !IsAnOper(sptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, sptr->name); return -1; } if (!IsAnOper(sptr)) { /* Non-opers /mkpasswd usage: lag them up, and send a notice to eyes snomask. * This notice is always sent, even in case of bad usage/bad auth methods/etc. */ sptr->since += 7; sendto_snomask(SNO_EYES, "*** /mkpasswd was used by %s (%s@%s) to create a hash.", sptr->name, sptr->user->username, GetHost(sptr)); } if ((parc < 3) || BadPtr(parv[2])) { sendto_one(sptr, ":%s NOTICE %s :*** Syntax: /mkpasswd <authmethod> <password>", me.name, sptr->name); return 0; } /* Don't want to take any risk ;p. -- Syzop */ if (strlen(parv[2]) > 64) { sendto_one(sptr, ":%s NOTICE %s :*** Your parameter (text-to-hash) is too long. Please Shorten it", me.name, sptr->name); return 0; } if ((type = Auth_FindType(parv[1])) == -1) { sendto_one(sptr, ":%s NOTICE %s :*** %s is not an enabled authentication method. SHA1 and above require an SSL compile.", me.name, sptr->name, parv[1]); return 0; } #ifdef AUTHENABLE_UNIXCRYPT if ((type == AUTHTYPE_UNIXCRYPT) && (strlen(parv[2]) > 8)) { sendnotice(sptr, "WARNING: Password truncated to 8 characters due to 'crypt' algorithm. " "You are suggested to use the 'md5' algorithm instead."); parv[2][8] = '\0'; } #endif if (!(result = Auth_Make(type, parv[2]))) { sendto_one(sptr, ":%s NOTICE %s :*** Failed to create hash using that encryption method %s", me.name, sptr->name, parv[1]); return 0; } sendto_one(sptr, ":%s %s %s :*** Your hashed password (method=%s, para=%s) is: %s", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], parv[1], parv[2], result); return 0; }
/*********************************************************************** * m_connect() - Added by Jto 11 Feb 1989 ***********************************************************************//* ** m_connect ** parv[0] = sender prefix ** parv[1] = servername ** parv[2] = port number ** parv[3] = remote server */ DLLFUNC CMD_FUNC(m_connect) { int port, tmpport, retval; ConfigItem_link *aconf; ConfigItem_deny_link *deny; aClient *acptr; if (!IsPrivileged(sptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return -1; } if (MyClient(sptr) && !OPCanGRoute(sptr) && parc > 3) { /* Only allow LocOps to make */ /* local CONNECTS --SRB */ sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } if (MyClient(sptr) && !OPCanLRoute(sptr) && parc <= 3) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } if (hunt_server_token(cptr, sptr, MSG_CONNECT, TOK_CONNECT, "%s %s :%s", 3, parc, parv) != HUNTED_ISME) return 0; if (parc < 2 || *parv[1] == '\0') { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "CONNECT"); return -1; } if ((acptr = find_server_quick(parv[1]))) { sendto_one(sptr, ":%s %s %s :*** Connect: Server %s %s %s.", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], parv[1], "already exists from", acptr->from->name); return 0; } for (aconf = conf_link; aconf; aconf = (ConfigItem_link *) aconf->next) if (!match(parv[1], aconf->servername)) break; /* Checked first servernames, then try hostnames. */ if (!aconf) { sendto_one(sptr, ":%s %s %s :*** Connect: Server %s is not configured for linking", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], parv[1]); return 0; } /* ** 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 && !BadPtr(parv[2])) { if ((port = atoi(parv[2])) <= 0) { sendto_one(sptr, ":%s %s %s :*** Connect: Illegal port number", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0]); return 0; } } else if (port <= 0 && (port = PORTNUM) <= 0) { sendto_one(sptr, ":%s %s %s :*** Connect: missing port number", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0]); return 0; } /* Evaluate deny link */ for (deny = conf_deny_link; deny; deny = (ConfigItem_deny_link *) deny->next) { if (deny->flag.type == CRULE_ALL && !match(deny->mask, aconf->servername) && crule_eval(deny->rule)) { sendto_one(sptr, ":%s %s %s :*** Connect: Disallowed by connection rule", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0]); return 0; } } if (strchr(aconf->hostname, '*') != NULL || strchr(aconf->hostname, '?') != NULL) { sendto_one(sptr, ":%s %s %s :*** Connect: You cannot connect to a server with wildcards (* and ?) in the hostname", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0]); return 0; } /* ** Notify all operators about remote connect requests */ if (!IsAnOper(cptr)) { sendto_serv_butone(&me, ":%s GLOBOPS :Remote CONNECT %s %s from %s", me.name, parv[1], parv[2] ? parv[2] : "", get_client_name(sptr, FALSE)); } /* Interesting */ aconf->port = port; switch (retval = connect_server(aconf, sptr, NULL)) { case 0: sendto_one(sptr, ":%s %s %s :*** Connecting to %s[%s].", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], aconf->servername, aconf->hostname); break; case -1: sendto_one(sptr, ":%s %s %s :*** Couldn't connect to %s.", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], aconf->servername); break; case -2: sendto_one(sptr, ":%s %s %s :*** Resolving hostname '%s'...", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], aconf->hostname); break; default: sendto_one(sptr, ":%s %s %s :*** Connection to %s failed: %s", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0], aconf->servername, STRERROR(retval)); } aconf->port = tmpport; return 0; }
DLLFUNC int listreg(Cmdoverride *anoverride, aClient *cptr, aClient *sptr, int parc, char *parv[]) { if (!IsAnOper(sptr)) { if (!IsARegNick(sptr)) { sendto_one(sptr, ":%s %s %s :in order to use this command to need to register your nickname", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name); sendto_one(sptr, rpl_str(RPL_LISTSTART), me.name, sptr->name); sendto_one(sptr, rpl_str(RPL_LISTEND), me.name, sptr->name); return 0; } } return CallCmdoverride(listreg_override, cptr, sptr, parc, parv); }