/** * The /ns ghost command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ static int do_ghost(User * u) { char *nick = strtok(NULL, " "); char *pass = strtok(NULL, " "); NickAlias *na; User *u2; if (!nick) { syntax_error(s_NickServ, u, "GHOST", NICK_GHOST_SYNTAX); } else if (!(u2 = finduser(nick))) { notice_lang(s_NickServ, u, NICK_X_NOT_IN_USE, nick); } else if (!(na = u2->na)) { notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick); } else if (na->status & NS_VERBOTEN) { notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, na->nick); } else if (na->nc->flags & NI_SUSPENDED) { notice_lang(s_NickServ, u, NICK_X_SUSPENDED, na->nick); } else if (stricmp(nick, u->nick) == 0) { notice_lang(s_NickServ, u, NICK_NO_GHOST_SELF); } else if (pass) { int res = enc_check_password(pass, na->nc->pass); if (res == 1) { char buf[NICKMAX + 32]; snprintf(buf, sizeof(buf), "GHOST command used by %s", u->nick); send_event(EVENT_NICK_GHOSTED, 3, EVENT_START, u->nick, nick); alog("%s: %s!%s@%s used GHOST on %s", s_NickServ, u->nick, u->username, u->host, u2->nick); kill_user(s_NickServ, nick, buf); notice_lang(s_NickServ, u, NICK_GHOST_KILLED, nick); send_event(EVENT_NICK_GHOSTED, 3, EVENT_STOP, u->nick, nick); } else { notice_lang(s_NickServ, u, ACCESS_DENIED); if (res == 0) { alog("%s: GHOST: invalid password for %s by %s!%s@%s", s_NickServ, nick, u->nick, u->username, u->host); bad_password(u); } } } else { if (group_identified(u, na->nc) || (!(na->nc->flags & NI_SECURE) && is_on_access(u, na->nc))) { char buf[NICKMAX + 32]; snprintf(buf, sizeof(buf), "GHOST command used by %s", u->nick); send_event(EVENT_NICK_GHOSTED, 3, EVENT_START, u->nick, nick); alog("%s: %s!%s@%s used GHOST on %s", s_NickServ, u->nick, u->username, u->host, u2->nick); kill_user(s_NickServ, nick, buf); notice_lang(s_NickServ, u, NICK_GHOST_KILLED, nick); send_event(EVENT_NICK_GHOSTED, 3, EVENT_STOP, u->nick, nick); } else { notice_lang(s_NickServ, u, ACCESS_DENIED); } } return MOD_CONT; }
int check_sqline(char *nick, int nick_change) { int i; SXLine *sx; char reason[300]; if (sqlines.count == 0) return 0; for (i = 0; i < sqlines.count; i++) { sx = sqlines.list[i]; if (!sx) continue; if (ircd->chansqline) { if (*sx->mask == '#') continue; } if (match_wild_nocase(sx->mask, nick)) { sqline(sx->mask, sx->reason); /* We kill nick since s_sqline can't */ snprintf(reason, sizeof(reason), "Q-Lined: %s", sx->reason); kill_user(s_OperServ, nick, reason); return 1; } } return 0; }
/* P10 does not support logout, so kill the user * we can't keep track of which logins are stale and which aren't -- jilles */ static bool asuka_on_logout(user_t *u, const char *account) { return_val_if_fail(u != NULL, false); kill_user(NULL, u, "Forcing logout %s -> %s", u->nick, account); return true; }
int add_session(char *nick, char *host, char *hostip) { Session *session, **list; Exception *exception; int sessionlimit = 0; session = findsession(host); if (session) { exception = find_hostip_exception(host, hostip); if (checkDefCon(DEFCON_REDUCE_SESSION)) { sessionlimit = exception ? exception->limit : DefConSessionLimit; } else { sessionlimit = exception ? exception->limit : DefSessionLimit; } if (sessionlimit != 0 && session->count >= sessionlimit) { if (SessionLimitExceeded) notice(s_OperServ, nick, SessionLimitExceeded, host); if (SessionLimitDetailsLoc) notice(s_OperServ, nick, "%s", SessionLimitDetailsLoc); /* We don't use kill_user() because a user stucture has not yet * been created. Simply kill the user. -TheShadow */ kill_user(s_OperServ, nick, "Session limit exceeded"); session->hits++; if (MaxSessionKill && session->hits >= MaxSessionKill) { char akillmask[BUFSIZE]; snprintf(akillmask, sizeof(akillmask), "*@%s", host); add_akill(NULL, akillmask, s_OperServ, time(NULL) + SessionAutoKillExpiry, "Session limit exceeded"); anope_cmd_global(s_OperServ, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask); } return 0; } else { session->count++; return 1; } } nsessions++; session = scalloc(sizeof(Session), 1); session->host = sstrdup(host); list = &sessionlist[HASH(session->host)]; session->next = *list; if (*list) (*list)->prev = session; *list = session; session->count = 1; return 1; }
static void do_killclones(User * u) { char killreason[NICKMAX + 32]; char akillreason[] = "Temporary KILLCLONES akill."; int count; char *clonenick, *clonemask, *akillmask; User *cloneuser, *user, *tempuser; clonenick = strtok(NULL, " "); count = 0; if (!clonenick) { notice_lang(s_OperServ, u, OPER_KILLCLONES_SYNTAX); } else if (!(cloneuser = finduser(clonenick))) { notice_lang(s_OperServ, u, OPER_KILLCLONES_UNKNOWN_NICK, clonenick); } else { clonemask = smalloc(strlen(cloneuser->host) + 5); sprintf(clonemask, "*!*@%s", cloneuser->host); akillmask = smalloc(strlen(cloneuser->host) + 3); sprintf(akillmask, "*@%s", strlower(cloneuser->host)); user = firstuser(); while (user) { if (match_usermask(clonemask, user) != 0) { tempuser = nextuser(); count++; snprintf(killreason, sizeof(killreason), "Cloning [%d]", count); kill_user(NULL, user->nick, killreason); user = tempuser; } else { user = nextuser(); } } add_akill(akillmask, akillreason, u->nick, time(NULL) + (60 * 60 * 6)); wallops(s_OperServ, "\2%s\2 used KILLCLONES for \2%s\2 " "killing \2%d\2 clones. A temporary AKILL has been " "added for \2%s\2.", u->nick, clonemask, count, akillmask); log("%s: KILLCLONES: %d clone(s) matching %s killed.", s_OperServ, count, clonemask); free(akillmask); free(clonemask); } }
static int do_qakill_some_lameass(User * u) { char *to_be_akilled, *reason; char reasonx[512]; char mask[USERMAX + HOSTMAX + 2]; User *target; to_be_akilled = strtok(NULL, " "); reason = strtok(NULL, ""); if (!is_services_admin(u)) { notice(s_OperServ, u->nick, "Access Denied"); return MOD_STOP; } if (to_be_akilled) { if (!reason) { reason = "You have been AKILLED"; } if (AddAkiller) { snprintf(reasonx, sizeof(reasonx), "[%s] %s", u->nick, reason); } if ((target = finduser(to_be_akilled))) { sprintf(mask, "*@%s", target->host); #ifdef DISABLE_LOWER_QAKILL if ((is_services_admin(target)) && (!is_services_root(u))) { notice(s_OperServ, u->nick, "Permission Denied"); #ifndef ANOPE17x wallops(s_OperServ, "%s attempted to QAKILL %s (%s)", u->nick, target->nick, reasonx); #else anope_cmd_global(s_OperServ, "%s attempted to QAKILL %s (%s)", u->nick, target->nick, reasonx); #endif return MOD_STOP; } #endif add_akill(u, mask, u->nick, time(NULL)+AutokillExpiry, reason); if (WallOSAkill) { #ifndef ANOPE17x wallops(s_OperServ, "%s used QAKILL on %s (%s)", u->nick, target->nick, reasonx); #else anope_cmd_global(s_OperServ, "%s used QAKILL on %s (%s)", u->nick, target->nick, reasonx); #endif } if (!AkillOnAdd) { kill_user(s_OperServ, target->nick, reasonx); } } else { notice_lang(s_OperServ, u, NICK_X_NOT_IN_USE, to_be_akilled); } } else { notice(s_OperServ, u->nick, "See /msg OperServ HELP QAKILL for more info."); } return MOD_CONT; }
int check_akill(char *nick, const char *username, const char *host, const char *vhost, const char *ip) { int i; Akill *ak; /** * If DefCon is set to NO new users - kill the user ;). **/ if (checkDefCon(DEFCON_NO_NEW_CLIENTS)) { kill_user(s_OperServ, nick, DefConAkillReason); return 1; } if (akills.count == 0) return 0; for (i = 0; i < akills.count; i++) { ak = akills.list[i]; if (!ak) continue; if (match_wild_nocase(ak->user, username) && match_wild_nocase(ak->host, host)) { xanadu_cmd_akill(ak->user, ak->host, ak->by, ak->seton, ak->expires, ak->reason); return 1; } if (ircd->vhost) { if (vhost) { if (match_wild_nocase(ak->user, username) && match_wild_nocase(ak->host, vhost)) { xanadu_cmd_akill(ak->user, ak->host, ak->by, ak->seton, ak->expires, ak->reason); return 1; } } } if (ircd->nickip) { if (ip) { if (match_wild_nocase(ak->user, username) && match_wild_nocase(ak->host, ip)) { xanadu_cmd_akill(ak->user, ak->host, ak->by, ak->seton, ak->expires, ak->reason); return 1; } } } } return 0; }
/* P10 does not support logout, so kill the user * we can't keep track of which logins are stale and which aren't -- jilles */ static bool asuka_on_logout(user_t *u, const char *account) { if (!me.connected) return false; if (u != NULL) { kill_user(NULL, u, "Forcing logout %s -> %s", u->nick, account); return true; } else return false; }
/** * Note a bad password attempt for the given user. If they've used up * their limit, toss them off. * @param u the User to check * @return void */ void bad_password(User * u) { time_t now = time(NULL); if (!u || !BadPassLimit) { return; } if (BadPassTimeout > 0 && u->invalid_pw_time > 0 && u->invalid_pw_time < now - BadPassTimeout) u->invalid_pw_count = 0; u->invalid_pw_count++; u->invalid_pw_time = now; if (u->invalid_pw_count >= BadPassLimit) { kill_user(NULL, u->nick, "Too many invalid passwords"); } }
/* * Handle reporting for both fantasy commands and normal commands in GameServ * quickly and easily. Of course, sourceinfo has a vtable that can be manipulated, * but this is quicker and easier... -- nenolod */ static void gs_command_report(sourceinfo_t *si, const char *fmt, ...) { va_list args; char buf[BUFSIZE]; va_start(args, fmt); vsnprintf(buf, BUFSIZE, fmt, args); va_end(args); if (si->c != NULL) msg(chansvs.nick, si->c->name, "%s", buf); else command_success_nodata(si, "%s", buf); if (!strcasecmp(buf, "*BANG*")) kill_user(si->service->me, si->su, "Lost at Russian Roulette."); }
/** @brief Exe_Builtin Ό³Έν OPERATED MMC COMMAND IN MMCD @param mml_msg @param sockfd @param In_Arg */ int Exe_Builtin(mml_msg *ml, int sockfd, In_Arg in_para[]) { log_print(LOGN_INFO, "sockfd[%d] MSG_ID[%d]", sockfd, ml->msg_id ); switch(ml->msg_id) { case MI_USER_LOGIN: usr_login(&in_para[0], sockfd, ml); break; case MI_USER_LOGOUT: usr_logout(&in_para[0], sockfd, ml); fflush(stdout); break; case MI_KILL_USER: kill_user(&in_para[0], sockfd, ml); fflush(stdout); break; /* needed test by uamyd 2008.01.08 */ case MI_DIS_HIS_CMD: dis_his_cmd(&in_para[0], sockfd, ml); break; case MI_DIS_CMD_EXE: dis_cmd_exe(&in_para[0], sockfd, ml); break; case MI_DEL_CMD_EXE: del_cmd_exe(&in_para[0], sockfd, ml); break; case MI_GET_COM: dGetCOMString(&in_para[0], sockfd, ml); break; default : break; } return 1; }
void ns_cmd_regain(sourceinfo_t *si, int parc, char *parv[]) { myuser_t *mu; char *target = parv[0]; char *password = parv[1]; user_t *target_u; mynick_t *mn; if (si->su == NULL) { command_fail(si, fault_noprivs, _("\2%s\2 can only be executed via IRC."), "REGAIN"); return; } if (!target) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "REGAIN"); command_fail(si, fault_needmoreparams, _("Syntax: REGAIN <target> [password]")); return; } if (nicksvs.no_nick_ownership) mn = NULL, mu = myuser_find(target); else { mn = mynick_find(target); mu = mn != NULL ? mn->owner : NULL; } target_u = user_find_named(target); if (!mu) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not a registered nickname."), target); return; } if (!target_u) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not online."), target); return; } else if (target_u == si->su) { command_fail(si, fault_badparams, _("You may not ghost yourself.")); return; } if ((!nicksvs.no_nick_ownership && mn && mu == si->smu) || /* we're identified under their nick's account */ (!nicksvs.no_nick_ownership && password && mn && verify_password(mu, password))) /* we have their nick's password */ { logcommand(si, CMDLOG_DO, "REGAIN %s!%s@%s", target_u->nick, target_u->user, target_u->vhost); kill_user(si->service->me, target_u, "REGAIN command used by %s", si->su != NULL && !strcmp(si->su->user, target_u->user) && !strcmp(si->su->vhost, target_u->vhost) ? si->su->nick : get_source_mask(si)); command_success_nodata(si, _("\2%s\2 has been regained."), target); fnc_sts(si->service->me, si->su, target, FNC_REGAIN); /* don't update the nick's last seen time */ mu->lastlogin = CURRTIME; return; } if (password && mu) { logcommand(si, CMDLOG_DO, "failed REGAIN %s (bad password)", target); command_fail(si, fault_authfail, _("Invalid password for \2%s\2."), mu->name); } else { logcommand(si, CMDLOG_DO, "failed REGAIN %s (invalid login)", target); command_fail(si, fault_noprivs, _("You may not regain \2%s\2."), target); } }
int add_sgline(User * u, char *mask, const char *by, const time_t expires, const char *reason) { int deleted = 0, i; SXLine *entry; User *u2, *next; char buf[BUFSIZE]; *buf = '\0'; /* Checks whether there is an SGLINE that already covers * the one we want to add, and whether there are SGLINEs * that would be covered by this one. * If so, warn the user in the first case and cleanup * the useless SGLINEs in the second. */ if (!mask) { return -1; } if (sglines.count > 0) { for (i = sglines.count - 1; i >= 0; i--) { entry = sglines.list[i]; if (!entry) continue; if (!stricmp(entry->mask, mask)) { if (entry->expires >= expires || entry->expires == 0) { if (u) notice_lang(s_OperServ, u, OPER_SGLINE_EXISTS, mask); return -1; } else { entry->expires = expires; if (u) notice_lang(s_OperServ, u, OPER_SGLINE_CHANGED, entry->mask); return -2; } } if (match_wild_nocase(entry->mask, mask) && (entry->expires >= expires || entry->expires == 0)) { if (u) notice_lang(s_OperServ, u, OPER_SGLINE_ALREADY_COVERED, mask, entry->mask); return -1; } if (match_wild_nocase(mask, entry->mask) && (entry->expires <= expires || expires == 0)) { slist_delete(&sglines, i); deleted++; } } } /* We can now check whether the list is full or not. */ if (slist_full(&sglines)) { if (u) notice_lang(s_OperServ, u, OPER_SGLINE_REACHED_LIMIT, sglines.limit); return -1; } /* We can now (really) add the SGLINE. */ entry = scalloc(sizeof(SXLine), 1); if (!entry) return -1; entry->mask = sstrdup(mask); entry->by = sstrdup(by); entry->reason = sstrdup(reason); entry->seton = time(NULL); entry->expires = expires; slist_add(&sglines, entry); xanadu_cmd_sgline(entry->mask, entry->reason); if (KillonSGline && !ircd->sglineenforce) { snprintf(buf, (BUFSIZE - 1), "G-Lined: %s", entry->reason); u2 = firstuser(); while (u2) { next = nextuser(); if (!is_oper(u2)) { if (match_wild_nocase(entry->mask, u2->realname)) { kill_user(ServerName, u2->nick, buf); } } u2 = next; } } return deleted; }
void ns_cmd_ghost(sourceinfo_t *si, int parc, char *parv[]) { myuser_t *mu; char *target = parv[0]; char *password = parv[1]; user_t *target_u; mynick_t *mn; if (!target) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "GHOST"); command_fail(si, fault_needmoreparams, _("Syntax: GHOST <target> [password]")); return; } if (nicksvs.no_nick_ownership) mn = NULL, mu = myuser_find(target); else { mn = mynick_find(target); mu = mn != NULL ? mn->owner : NULL; } target_u = user_find_named(target); if (!target_u) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not online."), target); return; } else if (!mu && !target_u->myuser) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not a registered nickname."), target); return; } else if (target_u == si->su) { command_fail(si, fault_badparams, _("You may not ghost yourself.")); return; } /* At this point, we're now checking metadata associated with the target's account. * If the target nick is unregistered, mu will be unset thus far. */ if (target_u->myuser && !mu) mu = target_u->myuser; if (password && metadata_find(mu, "private:freeze:freezer")) { command_fail(si, fault_authfail, "You cannot ghost users as \2%s\2 because the account has been frozen.", entity(mu)->name); logcommand(si, CMDLOG_DO, "failed GHOST \2%s\2 (frozen)", target); return; } if (password && (mu->flags & MU_NOPASSWORD)) { command_fail(si, fault_authfail, _("Password authentication is disabled for this account.")); logcommand(si, CMDLOG_DO, "failed GHOST \2%s\2 (password authentication disabled)", target); return; } if ((target_u->myuser && target_u->myuser == si->smu) || /* they're identified under our account */ (!nicksvs.no_nick_ownership && mn && mu == si->smu) || /* we're identified under their nick's account */ (!nicksvs.no_nick_ownership && password && verify_password(mu, password))) /* we have the correct password */ { logcommand(si, CMDLOG_DO, "GHOST: \2%s!%s@%s\2", target_u->nick, target_u->user, target_u->vhost); kill_user(si->service->me, target_u, "GHOST command used by %s", si->su != NULL && !strcmp(si->su->user, target_u->user) && !strcmp(si->su->vhost, target_u->vhost) ? si->su->nick : get_source_mask(si)); command_success_nodata(si, _("\2%s\2 has been ghosted."), target); /* Update the account's last seen time. * Perhaps the ghosted nick belonged to someone else, but we were identified to it? * Try this first. */ if (target_u->myuser && target_u->myuser == si->smu) target_u->myuser->lastlogin = CURRTIME; else mu->lastlogin = CURRTIME; return; } if (password) { logcommand(si, CMDLOG_DO, "failed GHOST \2%s\2 (bad password)", target); command_fail(si, fault_authfail, _("Invalid password for \2%s\2."), entity(mu)->name); bad_password(si, mu); } else { logcommand(si, CMDLOG_DO, "failed GHOST \2%s\2 (invalid login)", target); command_fail(si, fault_noprivs, _("You may not ghost \2%s\2."), target); } }
void ns_cmd_ghost(sourceinfo_t *si, int parc, char *parv[]) { myuser_t *mu; char *target = parv[0]; char *password = parv[1]; user_t *target_u; mynick_t *mn; if (!target) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "GHOST"); command_fail(si, fault_needmoreparams, _("Syntax: GHOST <target> [password]")); return; } if (nicksvs.no_nick_ownership) mn = NULL, mu = myuser_find(target); else { mn = mynick_find(target); mu = mn != NULL ? mn->owner : NULL; } target_u = user_find_named(target); if (!mu && (!target_u || !target_u->myuser)) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not a registered nickname."), target); return; } if (!target_u) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not online."), target); return; } else if (target_u == si->su) { command_fail(si, fault_badparams, _("You may not ghost yourself.")); return; } if (password && metadata_find(mu, "private:freeze:freezer")) { command_fail(si, fault_authfail, "You cannot ghost users as \2%s\2 because the account has been frozen.", entity(mu)->name); logcommand(si, CMDLOG_DO, "failed GHOST \2%s\2 (frozen)", target); return; } if ((target_u->myuser && target_u->myuser == si->smu) || /* they're identified under our account */ (!nicksvs.no_nick_ownership && mn && mu == si->smu) || /* we're identified under their nick's account */ (!nicksvs.no_nick_ownership && password && mn && verify_password(mu, password))) /* we have their nick's password */ { /* If we're ghosting an unregistered nick, mu will be unset, * however if it _is_ registered, we still need to set it or * the wrong user will have their last seen time updated... */ if(target_u->myuser && target_u->myuser == si->smu) mu = target_u->myuser; logcommand(si, CMDLOG_DO, "GHOST: \2%s!%s@%s\2", target_u->nick, target_u->user, target_u->vhost); kill_user(si->service->me, target_u, "GHOST command used by %s", si->su != NULL && !strcmp(si->su->user, target_u->user) && !strcmp(si->su->vhost, target_u->vhost) ? si->su->nick : get_source_mask(si)); command_success_nodata(si, _("\2%s\2 has been ghosted."), target); /* don't update the nick's last seen time */ mu->lastlogin = CURRTIME; return; } if (password && mu) { logcommand(si, CMDLOG_DO, "failed GHOST \2%s\2 (bad password)", target); command_fail(si, fault_authfail, _("Invalid password for \2%s\2."), entity(mu)->name); bad_password(si, mu); } else { logcommand(si, CMDLOG_DO, "failed GHOST \2%s\2 (invalid login)", target); command_fail(si, fault_noprivs, _("You may not ghost \2%s\2."), target); } }