/* * EOS (End Of Sync) command. * Type: Broadcast * Purpose: Broadcasted over a network if a server is synced (after the users, channels, * etc are introduced). Makes us able to know if a server is linked. * History: Added in beta18 (in cvs since 2003-08-11) by Syzop */ DLLFUNC CMD_FUNC(m_eos) { if (!IsServer(sptr)) return 0; sptr->serv->flags.synced = 1; /* pass it on ^_- */ #ifdef DEBUGMODE ircd_log(LOG_ERROR, "[EOSDBG] m_eos: got sync from %s (path:%s)", sptr->name, cptr->name); ircd_log(LOG_ERROR, "[EOSDBG] m_eos: broadcasting it back to everyone except route from %s", cptr->name); #endif sendto_serv_butone_token(cptr, parv[0], MSG_EOS, TOK_EOS, "", NULL); return 0; }
/* This is called on module init, before Server Ready */ DLLFUNC int MOD_INIT(m_dummy)(ModuleInfo *modinfo) { CmodeInfo req; ircd_log(LOG_ERROR, "debug: mod_init called from chmodetst module"); ModuleSetOptions(modinfo->handle, MOD_OPT_PERM); sendto_realops("chmodetst loading..."); /* TODO: load mode here */ /* +w doesn't do anything, it's just for testing */ memset(&req, 0, sizeof(req)); req.paracount = 0; req.is_ok = extcmode_default_requirechop; req.flag = 'w'; ModeTest = CmodeAdd(modinfo->handle, req, &EXTCMODE_TEST); /* +y doesn't do anything except that you can set/unset it with a * numeric parameter (1-100) */ memset(&req, 0, sizeof(req)); req.paracount = 1; req.is_ok = modey_is_ok; req.put_param = modey_put_param; req.get_param = modey_get_param; req.conv_param = modey_conv_param; req.free_param = modey_free_param; req.sjoin_check = modey_sjoin_check; req.dup_struct = modey_dup_struct; req.flag = 'y'; ModeTest2 = CmodeAdd(modinfo->handle, req, &EXTCMODE_TEST2); return MOD_SUCCESS; }
DLLFUNC int MOD_UNLOAD(m_restrictcolors)(int module_unload) { HookDel(CheckMsg); CmodeDel(ModeRcolors); ircd_log(LOG_ERROR, "debug: mod_unload called from m_restrictcolors"); sendto_realops("unloading m_restrictcolors"); return MOD_SUCCESS; }
/* ** m_sanick() - PID - 08-08-2011 ** ** parv[0] - sender ** parv[1] - nick to make join ** parv[2] - channel(s) to join */ int m_sanick(aClient * cptr, aClient * sptr, int parc, char *parv[]) { aClient *acptr; char *param[3]; int self = 0; // if (IsServer(sptr) || IsServices(sptr)) // return 0; //Servers and Services should be invoking SVSNICK directly... if (!IsOper(sptr) && !IsAdmin(sptr) && !IsULine(sptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } if (parv[1] == NULL || !parv[1] || !parv[2]) { sendnotice(sptr, "*** Usage: \2/sanick oldnick newnick\2"); return 0; } if (parv[2] == NULL || !(acptr = find_person(parv[1], NULL))) { sendnotice(sptr, "*** No such user, %s.", parv[1]); return 0; } if (!strcmp(parv[2], parv[1]) || !strcmp(parv[2], parv[0])) { sendnotice(sptr, "*** Perhaps I should warn people that they have given an idiot IRCOp access?"); return 0; } if (!strcmp(parv[0], parv[1])) self = 1; if (find_client(parv[2], NULL)) { sendnotice(sptr, "*** WARNING: User %s already exists!", parv[2]); return 0; } if(acptr->umodes & UMODE_REGNICK) acptr->umodes &= ~UMODE_REGNICK; param[0] = acptr->name; param[1] = parv[2]; param[2] = NULL; sendnotice(acptr, "*** You were forced to change your nick to %s", parv[2]); do_cmd(acptr, acptr, "NICK", 2, param); if(self) { sendto_realops("%s used \2SANICK\2 to change their nick to %s.", parv[1], parv[2]); ircd_log(LOG_SACMDS,"SANICK: %s used SANICK to change their nick to %s", parv[1], parv[2]); } else { sendto_realops("%s used \2SANICK\2 to make %s change their nick to %s.", parv[0], parv[1], parv[2]); ircd_log(LOG_SACMDS,"SANICK: %s used SANICK to make %s change their nick to %s", acptr->name, parv[1], parv[2]); } return 0; }
DLLFUNC int MOD_INIT(m_restrictcolors)(ModuleInfo *modinfo) { ModuleSetOptions(modinfo->handle, MOD_OPT_PERM); CmodeInfo req; ircd_log(LOG_ERROR, "debug: mod_init called from m_restrictcolors"); sendto_realops("loading m_restrictcolors"); memset(&req, 0, sizeof(req)); req.paracount = 0; req.is_ok = extcmode_default_requirehalfop; req.flag = 'W'; ModeRcolors = CmodeAdd(modinfo->handle, req, &RESTRICT_COLORS); bcopy(modinfo,&RestrictColorsModInfo,modinfo->size); CheckMsg = HookAddPCharEx(RestrictColorsModInfo.handle, HOOKTYPE_CHANMSG, restrictcolors_checkmsg); return MOD_SUCCESS; }
DLLFUNC int MOD_INIT(m_nocaps)(ModuleInfo *modinfo) { ModuleSetOptions(modinfo->handle, MOD_OPT_PERM); CmodeInfo req; ircd_log(LOG_ERROR, "debug: mod_init called from m_nocaps"); sendto_realops("loading m_nocaps"); memset(&req, 0, sizeof(req)); req.paracount = 0; req.is_ok = extcmode_default_requirehalfop; req.flag = 'd'; ModeBlock = CmodeAdd(modinfo->handle, req, &NOCAPS_BLOCK); bcopy(modinfo,&NoCapsModInfo,modinfo->size); CheckMsg = HookAddPCharEx(NoCapsModInfo.handle, HOOKTYPE_CHANMSG, nocaps_checkmsg); return MOD_SUCCESS; }
/* ** zip_init ** Initialize compression structures for a server. ** If failed, zip_free() has to be called. */ int zip_init(aClient *cptr, int compressionlevel) { cptr->zip = (aZdata *) MyMalloc(sizeof(aZdata)); cptr->zip->incount = 0; cptr->zip->outcount = 0; cptr->zip->in = (z_stream *) MyMalloc(sizeof(z_stream)); bzero(cptr->zip->in, sizeof(z_stream)); /* Just to be sure -- Syzop */ cptr->zip->in->total_in = 0; cptr->zip->in->total_out = 0; cptr->zip->in->zalloc = NULL; cptr->zip->in->zfree = NULL; cptr->zip->in->data_type = Z_ASCII; if (inflateInit(cptr->zip->in) != Z_OK) { cptr->zip->out = NULL; return -1; } cptr->zip->out = (z_stream *) MyMalloc(sizeof(z_stream)); bzero(cptr->zip->out, sizeof(z_stream)); /* Just to be sure -- Syzop */ cptr->zip->out->total_in = 0; cptr->zip->out->total_out = 0; cptr->zip->out->zalloc = NULL; cptr->zip->out->zfree = NULL; cptr->zip->out->data_type = Z_ASCII; if (deflateInit(cptr->zip->out, compressionlevel) != Z_OK) return -1; if (!unzipbuf) { unzipbuf = MyMallocEx(UNZIP_BUFFER_SIZE); /* big chunk! */ if (!unzipbuf) { ircd_log(LOG_ERROR, "zip_init(): out of memory (trying to alloc %d bytes)!", UNZIP_BUFFER_SIZE); sendto_realops("zip_init(): out of memory (trying to alloc %d bytes)!", UNZIP_BUFFER_SIZE); return -1; } } return 0; }
DLLFUNC int m_rmtkl(aClient *cptr, aClient *sptr, int parc, char *parv[]) { aTKline *tk, *next = NULL; TKLType *tkltype; char *types, *uhmask, *cmask, *p; char gmt[256], flag; int tklindex; if (!IsULine(sptr) && !(IsPerson(sptr) && IsAnOper(sptr))) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return -1; } if (IsNotParam(1)) return dumpit(sptr, rmtkl_help); if (IsNotParam(2)) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "RMTKL"); sendnotice(sptr, "Type '/RMTKL' for help"); return 0; } types = parv[1]; uhmask = parv[2]; cmask = IsParam(3) ? parv[3] : NULL; /* I don't add 'q' and 'Q' here. They are different. */ if (strchr(types, '*')) types = "KzGZs"; /* check access */ if (!IsULine(sptr)) for (p = types; *p; p++) { tkltype = find_TKLType_by_flag(*p); if (!tkltype->type) continue; if (((tkltype->type & TKL_GLOBAL) && !IsOper(sptr)) || !(sptr->oflag & tkltype->oflag)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return -1; } } for (tkltype = tkl_types; tkltype->type; tkltype++) { flag = tkltype->flag; tklindex = tkl_hash(flag); if (!strchr(types, flag)) continue; for (tk = tklines[tklindex]; tk; tk = next) { next = tk->next; if (tk->type != tkltype->type) continue; if (tk->type & TKL_NICK) { /* * If it's a services hold (ie. NickServ is holding * a nick), it's better not to touch it */ if (*tk->usermask == 'H') continue; if (match(uhmask, tk->hostmask)) continue; } else if (match(uhmask, make_user_host(tk->usermask, tk->hostmask))) continue; if (cmask && _match(cmask, tk->reason)) continue; strncpyzt(gmt, asctime(gmtime((TS *)&tk->set_at)), sizeof gmt); iCstrip(gmt); if (tk->type & TKL_NICK) { sendto_snomask(SNO_TKL, "%s removed %s %s (set at %s " "- reason: %s)", sptr->name, tkltype->txt, tk->hostmask, gmt, tk->reason); ircd_log(LOG_TKL, "%s removed %s %s (set at %s " "- reason: %s)", sptr->name, tkltype->txt, tk->hostmask, gmt, tk->reason); } else { sendto_snomask(SNO_TKL, "%s removed %s %s@%s (set at " "%s - reason: %s)", sptr->name, tkltype->txt, tk->usermask, tk->hostmask, gmt, tk->reason); ircd_log(LOG_TKL, "%s removed %s %s@%s (set at " "%s - reason: %s)", sptr->name, tkltype->txt, tk->usermask, tk->hostmask, gmt, tk->reason); } if ((tk->type & TKL_GLOBAL) && flag) sendto_serv_butone_token(&me, me.name, MSG_TKL, TOK_TKL, "- %c %s %s %s", flag, tk->usermask, tk->hostmask, parv[0]); if (tk->type & TKL_SHUN) tkl_check_local_remove_shun(tk); my_tkl_del_line(tk, tklindex); } } return 0; }
/* ** 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; }
DLLFUNC int m_chghost(aClient *cptr, aClient *sptr, int parc, char *parv[]) { aClient *acptr; if (MyClient(sptr) && !IsAnOper(sptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } #ifdef DISABLE_USERMOD if (MyClient(sptr)) { sendto_one(sptr, err_str(ERR_DISABLED), me.name, sptr->name, "CHGHOST", "This command is disabled on this server"); return 0; } #endif if ((parc < 3) || !*parv[2]) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, sptr->name, "CHGHOST"); return 0; } if (strlen(parv[2]) > (HOSTLEN)) { sendnotice(sptr, "*** ChgName Error: Requested hostname too long -- rejected."); return 0; } if (!valid_host(parv[2])) { sendnotice(sptr, "*** /ChgHost Error: A hostname may contain a-z, A-Z, 0-9, '-' & '.' - Please only use them"); return 0; } if (parv[2][0] == ':') { sendnotice(sptr, "*** A hostname cannot start with ':'"); return 0; } if ((acptr = find_person(parv[1], NULL))) { if (MyClient(sptr) && (IsLocOp(sptr) && !MyClient(acptr))) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } if (!strcmp(GetHost(acptr), parv[2])) { sendnotice(sptr, "*** /ChgHost Error: requested host is same as current host."); return 0; } switch (UHOST_ALLOWED) { case UHALLOW_NEVER: if (MyClient(sptr)) { sendto_one(sptr, err_str(ERR_DISABLED), me.name, sptr->name, "CHGHOST", "This command is disabled on this server"); return 0; } break; case UHALLOW_ALWAYS: break; case UHALLOW_NOCHANS: if (IsPerson(acptr) && MyClient(sptr) && acptr->user->joined) { sendnotice(sptr, "*** /ChgHost can not be used while %s is on a channel", acptr->name); return 0; } break; case UHALLOW_REJOIN: rejoin_doquits(acptr); /* join sent later when the host has been changed */ break; } if (!IsULine(sptr)) { sendto_snomask(SNO_EYES, "%s changed the virtual hostname of %s (%s@%s) to be %s", sptr->name, acptr->name, acptr->user->username, acptr->user->realhost, parv[2]); /* Logging added by XeRXeS */ ircd_log(LOG_CHGCMDS, "CHGHOST: %s changed the virtual hostname of %s (%s@%s) to be %s", sptr->name, acptr->name, acptr->user->username, acptr->user->realhost, parv[2]); } acptr->umodes |= UMODE_HIDE; acptr->umodes |= UMODE_SETHOST; sendto_server(cptr, 0, 0, ":%s CHGHOST %s %s", sptr->name, acptr->name, parv[2]); if (acptr->user->virthost) { MyFree(acptr->user->virthost); acptr->user->virthost = 0; } acptr->user->virthost = strdup(parv[2]); if (UHOST_ALLOWED == UHALLOW_REJOIN) rejoin_dojoinandmode(acptr); return 0; } else { sendto_one(sptr, err_str(ERR_NOSUCHNICK), me.name, sptr->name, parv[1]); return 0; } return 0; }
int m_chgident(aClient *cptr, aClient *sptr, int parc, char *parv[]) { aClient *acptr; char *s; int legalident = 1; if (MyClient(sptr) && !IsAnOper(sptr)) { sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]); return 0; } #ifdef DISABLE_USERMOD if (MyClient(sptr)) { sendto_one(sptr, err_str(ERR_DISABLED), me.name, sptr->name, "CHGIDENT", "This command is disabled on this server"); return 0; } #endif if ((parc < 3) || !*parv[2]) { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, sptr->name, "CHGIDENT"); return 0; } if (strlen(parv[2]) > (USERLEN)) { sendnotice(sptr, "*** ChgIdent Error: Requested ident too long -- rejected."); return 0; } /* illegal?! */ for (s = parv[2]; *s; s++) { if ((*s == '~') && (s == parv[2])) continue; if (!isallowed(*s)) { legalident = 0; } } if (legalident == 0) { sendnotice(sptr, "*** /ChgIdent Error: A ident may contain a-z, A-Z, 0-9, '-' & '.' - Please only use them"); return 0; } if ((acptr = find_person(parv[1], NULL))) { DYN_LOCAL(char, did_parts, acptr->user->joined); switch (UHOST_ALLOWED) { case UHALLOW_NEVER: if (MyClient(sptr)) { sendto_one(sptr, err_str(ERR_DISABLED), me.name, sptr->name, "CHGIDENT", "This command is disabled on this server"); DYN_FREE(did_parts); return 0; } break; case UHALLOW_ALWAYS: break; case UHALLOW_NOCHANS: if (IsPerson(acptr) && MyClient(sptr) && acptr->user->joined) { sendnotice(sptr, "*** /ChgIdent can not be used while %s is on a channel", acptr->name); DYN_FREE(did_parts); return 0; } break; case UHALLOW_REJOIN: rejoin_doparts(acptr, did_parts); /* join sent later when the ident has been changed */ break; } if (!IsULine(sptr)) { sendto_snomask(SNO_EYES, "%s changed the virtual ident of %s (%s@%s) to be %s", sptr->name, acptr->name, acptr->user->username, GetHost(acptr), parv[2]); /* Logging ability added by XeRXeS */ ircd_log(LOG_CHGCMDS, "CHGIDENT: %s changed the virtual ident of %s (%s@%s) to be %s", sptr->name, acptr->name, acptr->user->username, GetHost(acptr), parv[2]); } sendto_serv_butone_token(cptr, sptr->name, MSG_CHGIDENT, TOK_CHGIDENT, "%s %s", acptr->name, parv[2]); ircsprintf(acptr->user->username, "%s", parv[2]); if (UHOST_ALLOWED == UHALLOW_REJOIN) rejoin_dojoinandmode(acptr, did_parts); DYN_FREE(did_parts); 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; }
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; }