static void ns_cmd_status(sourceinfo_t *si, int parc, char *parv[]) { logcommand(si, CMDLOG_GET, "STATUS"); if (!si->smu) command_success_nodata(si, _("You are not logged in.")); else { command_success_nodata(si, _("You are logged in as \2%s\2."), entity(si->smu)->name); if (is_soper(si->smu)) { soper_t *soper = si->smu->soper; command_success_nodata(si, _("You are a services operator of class %s."), soper->operclass ? soper->operclass->name : soper->classname); } } if (si->su != NULL) { mynick_t *mn; mn = mynick_find(si->su->nick); if (mn != NULL && mn->owner != si->smu && myuser_access_verify(si->su, mn->owner)) command_success_nodata(si, _("You are recognized as \2%s\2."), entity(mn->owner)->name); } if (si->su != NULL && is_admin(si->su)) command_success_nodata(si, _("You are a server administrator.")); if (si->su != NULL && is_ircop(si->su)) command_success_nodata(si, _("You are an IRC operator.")); }
static void on_user_away(user_t *u) { myuser_t *mu; mynick_t *mn; if (u->flags & UF_AWAY) return; mu = u->myuser; if (mu == NULL) { mn = mynick_find(u->nick); if (mn != NULL && myuser_access_verify(u, mn->owner)) mu = mn->owner; } if (mu == NULL) return; if (mu->memoct_new > 0) { notice(memosvs->me->nick, u->nick, ngettext(N_("You have %d new memo."), N_("You have %d new memos."), mu->memoct_new), mu->memoct_new); notice(memosvs->me->nick, u->nick, _("To read them, type /%s%s READ NEW"), ircd->uses_rcommand ? "" : "msg ", memosvs->disp); } }
static void on_user_away(struct user *u) { struct myuser *mu; struct mynick *mn; if (u->flags & UF_AWAY) return; mu = u->myuser; if (mu == NULL) { mn = mynick_find(u->nick); if (mn != NULL && myuser_access_verify(u, mn->owner)) mu = mn->owner; } if (mu == NULL) return; if (mu->memoct_new > 0) { notice(memosvs->me->nick, u->nick, "You have %u new memo(s).", mu->memoct_new); notice(memosvs->me->nick, u->nick, "To read them, type \2/msg %s READ NEW\2", memosvs->disp); } if (mu->memos.count >= maxmemos) { notice(memosvs->me->nick, u->nick, "Your memo inbox is full! Please " "delete memos you no longer need."); } }
static void ns_cmd_acc(sourceinfo_t *si, int parc, char *parv[]) { const char *targuser = parv[0]; const char *targaccount = parv[1]; user_t *u; myuser_t *mu; mynick_t *mn; bool show_id = config_options.show_entity_id || has_priv(si, PRIV_USER_AUSPEX); if (!targuser) { u = si->su; targuser = u != NULL ? u->nick : "?"; } else u = user_find_named(targuser); if (!u) { command_fail(si, fault_nosuch_target, _("%s%s%s ACC 0 (offline)"), targuser, parc >= 2 ? " -> " : "", parc >= 2 ? targaccount : ""); return; } if (!targaccount) targaccount = u->nick; if (!strcmp(targaccount, "*")) mu = u->myuser; else mu = myuser_find_ext(targaccount); if (!mu) { command_fail(si, fault_nosuch_target, _("%s%s%s ACC 0 (not registered)"), u->nick, parc >= 2 ? " -> " : "", parc >= 2 ? targaccount : ""); return; } if (u->myuser == mu) command_success_nodata(si, "%s%s%s ACC 3 %s", u->nick, parc >= 2 ? " -> " : "", parc >= 2 ? entity(mu)->name : "", show_id ? entity(mu)->id : ""); else if ((mn = mynick_find(u->nick)) != NULL && mn->owner == mu && myuser_access_verify(u, mu)) command_success_nodata(si, "%s%s%s ACC 2 %s", u->nick, parc >= 2 ? " -> " : "", parc >= 2 ? entity(mu)->name : "", show_id ? entity(mu)->id : ""); else command_success_nodata(si, "%s%s%s ACC 1 %s", u->nick, parc >= 2 ? " -> " : "", parc >= 2 ? entity(mu)->name : "", show_id ? entity(mu)->id : ""); }
static void nickserv_handle_nickchange(user_t *u) { mynick_t *mn; hook_nick_enforce_t hdata; if (nicksvs.me == NULL || nicksvs.no_nick_ownership) return; /* They're logged in, don't send them spam -- jilles */ if (u->myuser) u->flags |= UF_SEENINFO; /* Also don't send it if they came back from a split -- jilles */ if (!(u->server->flags & SF_EOB)) u->flags |= UF_SEENINFO; if (!(mn = mynick_find(u->nick))) { if (!nicksvs.spam) return; if (!(u->flags & UF_SEENINFO)) { notice(nicksvs.nick, u->nick, "Welcome to %s, %s! Here on %s, we provide services to enable the " "registration of nicknames and channels! For details, type \2/%s%s help\2 and \2/%s%s help\2.", me.netname, u->nick, me.netname, (ircd->uses_rcommand == false) ? "msg " : "", nicksvs.me->disp, (ircd->uses_rcommand == false) ? "msg " : "", chansvs.me->disp); u->flags |= UF_SEENINFO; } return; } if (u->myuser == mn->owner) { mn->lastseen = CURRTIME; return; } /* OpenServices: is user on access list? -nenolod */ if (myuser_access_verify(u, mn->owner)) { notice(nicksvs.nick, u->nick, _("Please identify via \2/%s%s identify <password>\2."), (ircd->uses_rcommand == false) ? "msg " : "", nicksvs.me->disp); return; } notice(nicksvs.nick, u->nick, _("This nickname is registered. Please choose a different nickname, or identify via \2/%s%s identify <password>\2."), (ircd->uses_rcommand == false) ? "msg " : "", nicksvs.me->disp); hdata.u = u; hdata.mn = mn; hook_call_nick_enforce(&hdata); }
/* SET ACCOUNTNAME <nick> */ static void ns_cmd_set_accountname(sourceinfo_t *si, int parc, char *parv[]) { char *newname = parv[0]; mynick_t *mn; if (!newname) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "ACCOUNTNAME"); command_fail(si, fault_needmoreparams, _("Syntax: SET ACCOUNTNAME <nick>")); return; } if (!si->smu) { command_fail(si, fault_noprivs, _("You are not logged in.")); return; } if (is_conf_soper(si->smu)) { command_fail(si, fault_noprivs, _("You may not modify your account name because your operclass is defined in the configuration file.")); return; } mn = mynick_find(newname); if (mn == NULL) { command_fail(si, fault_nosuch_target, _("Nick \2%s\2 is not registered."), newname); return; } if (mn->owner != si->smu) { command_fail(si, fault_noprivs, _("Nick \2%s\2 is not registered to your account."), newname); return; } if (!strcmp(entity(si->smu)->name, newname)) { command_fail(si, fault_nochange, _("Your account name is already set to \2%s\2."), newname); return; } logcommand(si, CMDLOG_REGISTER, "SET:ACCOUNTNAME: \2%s\2", newname); command_success_nodata(si, _("Your account name is now set to \2%s\2."), newname); myuser_rename(si->smu, newname); return; }
static void ns_cmd_fdrop(sourceinfo_t *si, int parc, char *parv[]) { myuser_t *mu; mynick_t *mn; char *acc = parv[0]; if (!acc) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FDROP"); command_fail(si, fault_needmoreparams, _("Syntax: FDROP <account>")); return; } if (!(mu = myuser_find(acc))) { if (!nicksvs.no_nick_ownership) { mn = mynick_find(acc); if (mn != NULL && command_find(si->service->cmdtree, "FUNGROUP")) { command_fail(si, fault_nosuch_target, _("\2%s\2 is a grouped nick, use %s to remove it."), acc, "FUNGROUP"); return; } } command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), acc); return; } if (is_soper(mu)) { command_fail(si, fault_noprivs, _("The nickname \2%s\2 belongs to a services operator; it cannot be dropped."), acc); return; } if (mu->flags & MU_HOLD) { command_fail(si, fault_noprivs, _("The account \2%s\2 is held; it cannot be dropped."), acc); return; } wallops("%s dropped the account \2%s\2", get_oper_name(si), mu->name); snoop("FDROP: \2%s\2 by \2%s\2", mu->name, get_oper_name(si)); logcommand(si, CMDLOG_ADMIN | LG_REGISTER, "FDROP %s", mu->name); hook_call_user_drop(mu); command_success_nodata(si, _("The account \2%s\2 has been dropped."), mu->name); object_unref(mu); }
static void make_forbid(sourceinfo_t *si, const char *account, const char *reason) { myuser_t *mu; mynick_t *mn = NULL; user_t *u; if (!nicksvs.no_nick_ownership && IsDigit(*account)) { command_fail(si, fault_badparams, "For security reasons, you can't forbid a UID."); return; } if (strchr(account, ' ') || strchr(account, '\n') || strchr(account, '\r') || account[0] == '=' || account[0] == '#' || account[0] == '@' || account[0] == '+' || account[0] == '%' || account[0] == '!' || strchr(account, ',')) { command_fail(si, fault_badparams, "The account name \2%s\2 is invalid.", account); return; } /* make sure it isn't registered already */ if (nicksvs.no_nick_ownership ? myuser_find(account) != NULL : mynick_find(account) != NULL) { command_fail(si, fault_alreadyexists, "\2%s\2 is already registered.", account); return; } mu = myuser_add(account, "*", FORBID_EMAIL, MU_CRYPTPASS | MU_ENFORCE | MU_HOLD | MU_NOBURSTLOGIN); mu->registered = CURRTIME; mu->lastlogin = CURRTIME; metadata_add(mu, "private:freeze:freezer", get_oper_name(si)); metadata_add(mu, "private:freeze:reason", reason); metadata_add(mu, "private:freeze:timestamp", number_to_string(CURRTIME)); if (!nicksvs.no_nick_ownership) { mn = mynick_add(mu, entity(mu)->name); mn->registered = CURRTIME; mn->lastseen = CURRTIME; u = user_find_named(entity(mu)->name); if (u != NULL) { notice(si->service->nick, u->nick, _("The nick \2%s\2 is now forbidden."), entity(mu)->name); hook_call_nick_enforce((&(hook_nick_enforce_t){ .u = u, .mn = mn }));
static void hs_cmd_off(sourceinfo_t *si, int parc, char *parv[]) { mynick_t *mn = NULL; metadata_t *md; char buf[BUFSIZE]; if (si->su == NULL) { command_fail(si, fault_noprivs, _("\2%s\2 can only be executed via IRC."), "OFF"); return; } if (si->smu == NULL) { command_fail(si, fault_noprivs, _("You are not logged in.")); return; } mn = mynick_find(si->su->nick); if (mn == NULL) { command_fail(si, fault_nosuch_target, _("Nick \2%s\2 is not registered."), si->su->nick); return; } if (mn->owner != si->smu && !myuser_access_verify(si->su, mn->owner)) { command_fail(si, fault_noprivs, _("You are not recognized as \2%s\2."), mn->owner->name); return; } snprintf(buf, BUFSIZE, "%s:%s", "private:usercloak", mn->nick); md = metadata_find(si->smu, buf); if (md == NULL) md = metadata_find(si->smu, "private:usercloak"); if (md == NULL) { command_success_nodata(si, _("Please contact an Operator to get a vhost assigned to this nick.")); return; } do_sethost(si->su, NULL); command_success_nodata(si, _("Your vhost of \2%s\2 is now deactivated."), md->value); }
static void hs_cmd_drop(struct sourceinfo *si, int parc, char *parv[]) { struct mynick *mn; struct metadata *md; char buf[BUFSIZE]; // This is only because we need a nick to copy from. if (si->su == NULL) { command_fail(si, fault_noprivs, _("\2%s\2 can only be executed via IRC."), "DROP"); return; } mn = mynick_find(si->su->nick); if (mn == NULL) { command_fail(si, fault_nosuch_target, _("Nick \2%s\2 is not registered."), si->su->nick); return; } if (mn->owner != si->smu) { command_fail(si, fault_noprivs, _("Nick \2%s\2 is not registered to your account."), mn->nick); return; } snprintf(buf, BUFSIZE, "%s:%s", "private:usercloak", mn->nick); md = metadata_find(si->smu, buf); if (md == NULL) md = metadata_find(si->smu, "private:usercloak"); if (md == NULL) { command_success_nodata(si, _("There is not a vhost assigned to this nick.")); return; } hs_sethost_all(si->smu, NULL, get_source_name(si)); command_success_nodata(si, _("Dropped all vhosts for \2%s\2."), get_source_name(si)); logcommand(si, CMDLOG_ADMIN, "VHOST:DROP: \2%s\2", get_source_name(si)); do_sethost_all(si->smu, NULL); // restore user vhost from user host }
static void ns_cmd_ungroup(sourceinfo_t *si, int parc, char *parv[]) { mynick_t *mn; const char *target; hook_user_req_t hdata; if (parc >= 1) target = parv[0]; else if (si->su != NULL) target = si->su->nick; else target = "?"; mn = mynick_find(target); if (mn == NULL) { command_fail(si, fault_nosuch_target, _("Nick \2%s\2 is not registered."), target); return; } if (mn->owner != si->smu) { command_fail(si, fault_noprivs, _("Nick \2%s\2 is not registered to your account."), mn->nick); return; } if (!irccasecmp(mn->nick, entity(si->smu)->name)) { command_fail(si, fault_noprivs, _("Nick \2%s\2 is your account name; you may not remove it."), mn->nick); return; } logcommand(si, CMDLOG_REGISTER, "UNGROUP: \2%s\2", mn->nick); hdata.si = si; hdata.mu = si->smu; hdata.mn = mn; hook_call_nick_ungroup(&hdata); holdnick_sts(si->service->me, 0, mn->nick, NULL); command_success_nodata(si, _("Nick \2%s\2 has been removed from your account."), mn->nick); object_unref(mn); }
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); } }
static void ns_cmd_register(sourceinfo_t *si, int parc, char *parv[]) { myuser_t *mu; mynick_t *mn = NULL; mowgli_node_t *n; const char *account; const char *pass; const char *email; char lau[BUFSIZE], lao[BUFSIZE]; hook_user_register_check_t hdata; hook_user_req_t req; if (si->smu) { command_fail(si, fault_already_authed, _("You are already logged in as \2%s\2."), entity(si->smu)->name); if (si->su != NULL && !mynick_find(si->su->nick) && command_find(si->service->commands, "GROUP")) command_fail(si, fault_already_authed, _("Use %s to register %s to your account."), "GROUP", si->su->nick); return; } if (nicksvs.no_nick_ownership || si->su == NULL) account = parv[0], pass = parv[1], email = parv[2]; else account = si->su->nick, pass = parv[0], email = parv[1]; if (!account || !pass || !email) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "REGISTER"); if (nicksvs.no_nick_ownership || si->su == NULL) command_fail(si, fault_needmoreparams, _("Syntax: REGISTER <account> <password> <email>")); else command_fail(si, fault_needmoreparams, _("Syntax: REGISTER <password> <email>")); return; } if (strlen(pass) >= PASSLEN) { command_fail(si, fault_badparams, STR_INVALID_PARAMS, "REGISTER"); command_fail(si, fault_badparams, _("Registration passwords may not be longer than \2%d\2 characters."), PASSLEN - 1); return; } if (!nicksvs.no_nick_ownership && si->su == NULL && user_find_named(account)) { command_fail(si, fault_noprivs, _("A user matching this account is already on IRC.")); return; } if (!nicksvs.no_nick_ownership && IsDigit(*account)) { command_fail(si, fault_badparams, _("For security reasons, you can't register your UID.")); command_fail(si, fault_badparams, _("Please change to a real nickname, and try again.")); return; } if (nicksvs.no_nick_ownership || si->su == NULL) { if (strchr(account, ' ') || strchr(account, '\n') || strchr(account, '\r') || account[0] == '=' || account[0] == '#' || account[0] == '@' || account[0] == '+' || account[0] == '%' || account[0] == '!' || strchr(account, ',')) { command_fail(si, fault_badparams, _("The account name \2%s\2 is invalid."), account); return; } } if (strlen(account) >= NICKLEN) { command_fail(si, fault_badparams, _("The account name \2%s\2 is invalid."), account); return; } if ((si->su != NULL && !strcasecmp(pass, si->su->nick)) || !strcasecmp(pass, account)) { command_fail(si, fault_badparams, _("You cannot use your nickname as a password.")); if (nicksvs.no_nick_ownership || si->su == NULL) command_fail(si, fault_needmoreparams, _("Syntax: REGISTER <account> <password> <email>")); else command_fail(si, fault_needmoreparams, _("Syntax: REGISTER <password> <email>")); return; } /* make sure it isn't registered already */ if (nicksvs.no_nick_ownership ? myuser_find(account) != NULL : mynick_find(account) != NULL) { command_fail(si, fault_alreadyexists, _("\2%s\2 is already registered."), account); return; } if ((unsigned int)(CURRTIME - ratelimit_firsttime) > config_options.ratelimit_period) ratelimit_count = 0, ratelimit_firsttime = CURRTIME; /* Still do flood priv checking because the user may be in the ircop operclass */ if (ratelimit_count > config_options.ratelimit_uses && !has_priv(si, PRIV_FLOOD)) { command_fail(si, fault_toomany, _("The system is currently too busy to process your registration, please try again later.")); slog(LG_INFO, "NICKSERV:REGISTER:THROTTLED: \2%s\2 by \2%s\2", account, si->su != NULL ? si->su->nick : get_source_name(si)); return; } hdata.si = si; hdata.account = account; hdata.email = email; hdata.password = pass; hdata.approved = 0; hook_call_user_can_register(&hdata); if (hdata.approved != 0) return; if (!nicksvs.no_nick_ownership) { hook_call_nick_can_register(&hdata); if (hdata.approved != 0) return; } if (!validemail(email)) { command_fail(si, fault_badparams, _("\2%s\2 is not a valid email address."), email); return; } if (!email_within_limits(email)) { command_fail(si, fault_toomany, _("\2%s\2 has too many accounts registered."), email); return; } mu = myuser_add(account, auth_module_loaded ? "*" : pass, email, config_options.defuflags | MU_NOBURSTLOGIN | (auth_module_loaded ? MU_CRYPTPASS : 0)); mu->registered = CURRTIME; mu->lastlogin = CURRTIME; if (!nicksvs.no_nick_ownership) { mn = mynick_add(mu, entity(mu)->name); mn->registered = CURRTIME; mn->lastseen = CURRTIME; } if (config_options.ratelimit_uses && config_options.ratelimit_period) ratelimit_count++; if (auth_module_loaded) { if (!verify_password(mu, pass)) { command_fail(si, fault_authfail, _("Invalid password for \2%s\2."), entity(mu)->name); bad_password(si, mu); object_unref(mu); return; } } if (me.auth == AUTH_EMAIL) { char *key = random_string(12); mu->flags |= MU_WAITAUTH; metadata_add(mu, "private:verify:register:key", key); metadata_add(mu, "private:verify:register:timestamp", number_to_string(time(NULL))); if (!sendemail(si->su != NULL ? si->su : si->service->me, mu, EMAIL_REGISTER, mu->email, key)) { command_fail(si, fault_emailfail, _("Sending email failed, sorry! Registration aborted.")); object_unref(mu); free(key); return; } command_success_nodata(si, _("An email containing nickname activation instructions has been sent to \2%s\2."), mu->email); command_success_nodata(si, _("If you do not complete registration within one day, your nickname will expire.")); free(key); } if (si->su != NULL) { si->su->myuser = mu; n = mowgli_node_create(); mowgli_node_add(si->su, n, &mu->logins); if (!(mu->flags & MU_WAITAUTH)) /* only grant ircd registered status if it's verified */ ircd_on_login(si->su, mu, NULL); } command_add_flood(si, FLOOD_MODERATE); if (!nicksvs.no_nick_ownership && si->su != NULL) logcommand(si, CMDLOG_REGISTER, "REGISTER: \2%s\2 to \2%s\2", account, email); else logcommand(si, CMDLOG_REGISTER, "REGISTER: \2%s\2 to \2%s\2 by \2%s\2", account, email, si->su != NULL ? si->su->nick : get_source_name(si)); if (is_soper(mu)) { wallops("%s registered the nick \2%s\2 and gained services operator privileges.", get_oper_name(si), entity(mu)->name); logcommand(si, CMDLOG_ADMIN, "SOPER: \2%s\2 as \2%s\2", get_oper_name(si), entity(mu)->name); } command_success_nodata(si, _("\2%s\2 is now registered to \2%s\2, with the password \2%s\2."), entity(mu)->name, mu->email, pass); hook_call_user_register(mu); if (si->su != NULL) { snprintf(lau, BUFSIZE, "%s@%s", si->su->user, si->su->vhost); metadata_add(mu, "private:host:vhost", lau); snprintf(lao, BUFSIZE, "%s@%s", si->su->user, si->su->host); metadata_add(mu, "private:host:actual", lao); } if (!(mu->flags & MU_WAITAUTH)) { req.si = si; req.mu = mu; req.mn = mn; hook_call_user_verify_register(&req); } }
static void cs_cmd_status(sourceinfo_t *si, int parc, char *parv[]) { char *chan = parv[0]; if (chan) { mychan_t *mc = mychan_find(chan); unsigned int flags; if (*chan != '#') { command_fail(si, fault_badparams, STR_INVALID_PARAMS, "STATUS"); return; } if (!mc) { command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), chan); return; } logcommand(si, CMDLOG_GET, "STATUS: \2%s\2", mc->name); if (metadata_find(mc, "private:close:closer")) { command_fail(si, fault_noprivs, _("\2%s\2 is closed."), chan); return; } flags = chanacs_source_flags(mc, si); if (flags & CA_AKICK && !(flags & CA_EXEMPT)) command_success_nodata(si, _("You are banned from \2%s\2."), mc->name); else if (flags != 0) { command_success_nodata(si, _("You have access flags \2%s\2 on \2%s\2."), bitmask_to_flags(flags), mc->name); } else command_success_nodata(si, _("You have no special access to \2%s\2."), mc->name); return; } logcommand(si, CMDLOG_GET, "STATUS"); if (!si->smu) command_success_nodata(si, _("You are not logged in.")); else { command_success_nodata(si, _("You are logged in as \2%s\2."), entity(si->smu)->name); if (is_soper(si->smu)) { soper_t *soper = si->smu->soper; command_success_nodata(si, _("You are a services operator of class %s."), soper->operclass ? soper->operclass->name : soper->classname); } } if (si->su != NULL) { mynick_t *mn; mn = mynick_find(si->su->nick); if (mn != NULL && mn->owner != si->smu && myuser_access_verify(si->su, mn->owner)) command_success_nodata(si, _("You are recognized as \2%s\2."), entity(mn->owner)->name); } if (si->su != NULL && is_admin(si->su)) command_success_nodata(si, _("You are a server administrator.")); if (si->su != NULL && is_ircop(si->su)) command_success_nodata(si, _("You are an IRC operator.")); }
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); } }
static void ns_cmd_fungroup(sourceinfo_t *si, int parc, char *parv[]) { mynick_t *mn, *mn2 = NULL; myuser_t *mu; hook_user_req_t hdata; if (parc < 1) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "FUNGROUP"); command_fail(si, fault_needmoreparams, _("Syntax: FUNGROUP <nickname> [newaccountname]")); return; } mn = mynick_find(parv[0]); if (mn == NULL) { command_fail(si, fault_nosuch_target, _("Nick \2%s\2 is not registered."), parv[0]); return; } mu = mn->owner; if (!irccasecmp(mn->nick, entity(mu)->name)) { if (MOWGLI_LIST_LENGTH(&mu->nicks) <= 1 || !module_find_published("nickserv/set_accountname")) { command_fail(si, fault_noprivs, _("Nick \2%s\2 is an account name; you may not remove it."), mn->nick); return; } if (is_conf_soper(mu)) { command_fail(si, fault_noprivs, _("You may not modify \2%s\2's account name because their operclass is defined in the configuration file."), entity(mu)->name); return; } if (parc < 2) { command_fail(si, fault_needmoreparams, _("Please specify a new account name for \2%s\2."), entity(mu)->name); command_fail(si, fault_needmoreparams, _("Syntax: FUNGROUP <nickname> <newaccountname>")); return; } mn2 = mynick_find(parv[1]); if (mn2 == NULL) { command_fail(si, fault_nosuch_target, _("Nick \2%s\2 is not registered."), parv[1]); return; } if (mn2 == mn) { command_fail(si, fault_noprivs, _("The new account name must be different from the nick to be ungrouped.")); return; } if (mn2->owner != mu) { command_fail(si, fault_noprivs, _("Nick \2%s\2 is not registered to \2%s\2."), mn2->nick, entity(mu)->name); return; } } else if (parc > 1) { command_fail(si, fault_badparams, _("Nick \2%s\2 is not an account name so no new account name is needed."), mn->nick); return; } if (mn2 != NULL) { logcommand(si, CMDLOG_ADMIN | LG_REGISTER, "FUNGROUP: \2%s\2 from \2%s\2 (new account name: \2%s\2)", mn->nick, entity(mu)->name, mn2->nick); wallops("%s dropped the nick \2%s\2 from %s, changing account name to \2%s\2", get_oper_name(si), mn->nick, entity(mu)->name, mn2->nick); myuser_rename(mu, mn2->nick); } else { logcommand(si, CMDLOG_ADMIN | LG_REGISTER, "FUNGROUP: \2%s\2 from \2%s\2", mn->nick, entity(mu)->name); wallops("%s dropped the nick \2%s\2 from %s", get_oper_name(si), mn->nick, entity(mu)->name); } hdata.si = si; hdata.mu = mu; hdata.mn = mn; hook_call_nick_ungroup(&hdata); holdnick_sts(si->service->me, 0, mn->nick, NULL); if (mn2 != NULL) command_success_nodata(si, _("Nick \2%s\2 has been removed from account \2%s\2, name changed to \2%s\2."), mn->nick, entity(mu)->name, mn2->nick); else command_success_nodata(si, _("Nick \2%s\2 has been removed from account \2%s\2."), mn->nick, entity(mu)->name); object_unref(mn); }
static void ns_cmd_group(sourceinfo_t *si, int parc, char *parv[]) { mynick_t *mn; hook_user_req_t hdata; hook_user_register_check_t hdata_reg; if (si->su == NULL) { command_fail(si, fault_noprivs, _("\2%s\2 can only be executed via IRC."), "GROUP"); return; } if (nicksvs.no_nick_ownership) { command_fail(si, fault_noprivs, _("Nickname ownership is disabled.")); return; } if (MOWGLI_LIST_LENGTH(&si->smu->nicks) >= nicksvs.maxnicks && !has_priv(si, PRIV_REG_NOLIMIT)) { command_fail(si, fault_noprivs, _("You have too many nicks registered already.")); return; } mn = mynick_find(si->su->nick); if (mn != NULL) { if (mn->owner == si->smu) command_fail(si, fault_nochange, _("Nick \2%s\2 is already registered to your account."), mn->nick); else command_fail(si, fault_alreadyexists, _("Nick \2%s\2 is already registered to \2%s\2."), mn->nick, entity(mn->owner)->name); return; } if (IsDigit(si->su->nick[0])) { command_fail(si, fault_badparams, _("For security reasons, you can't register your UID.")); return; } if (metadata_find(si->smu, "private:restrict:setter")) { command_fail(si, fault_noprivs, _("You have been restricted from grouping nicks by network staff.")); return; } hdata_reg.si = si; hdata_reg.account = si->su->nick; hdata_reg.email = si->smu->email; hdata_reg.approved = 0; hook_call_nick_can_register(&hdata_reg); if (hdata_reg.approved != 0) return; logcommand(si, CMDLOG_REGISTER, "GROUP: \2%s\2 to \2%s\2", si->su->nick, entity(si->smu)->name); mn = mynick_add(si->smu, si->su->nick); mn->registered = CURRTIME; mn->lastseen = CURRTIME; command_success_nodata(si, _("Nick \2%s\2 is now registered to your account."), mn->nick); hdata.si = si; hdata.mu = si->smu; hdata.mn = mn; hook_call_nick_group(&hdata); }
static void ns_cmd_drop(sourceinfo_t *si, int parc, char *parv[]) { myuser_t *mu; mynick_t *mn; char *acc = parv[0]; char *pass = parv[1]; if (!acc || !pass) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "DROP"); command_fail(si, fault_needmoreparams, _("Syntax: DROP <account> <password>")); return; } if (!(mu = myuser_find(acc))) { if (!nicksvs.no_nick_ownership) { mn = mynick_find(acc); if (mn != NULL && command_find(si->service->cmdtree, "UNGROUP")) { command_fail(si, fault_nosuch_target, _("\2%s\2 is a grouped nick, use %s to remove it."), acc, "UNGROUP"); return; } } command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), acc); return; } if (metadata_find(mu, "private:freeze:freezer")) { command_fail(si, fault_authfail, nicksvs.no_nick_ownership ? "You cannot login as \2%s\2 because the account has been frozen." : "You cannot identify to \2%s\2 because the nickname has been frozen.", mu->name); return; } if (!verify_password(mu, pass)) { command_fail(si, fault_authfail, _("Authentication failed. Invalid password for \2%s\2."), mu->name); bad_password(si, mu); return; } if (!nicksvs.no_nick_ownership && LIST_LENGTH(&mu->nicks) > 1 && command_find(si->service->cmdtree, "UNGROUP")) { command_fail(si, fault_noprivs, _("Account \2%s\2 has %d other nick(s) grouped to it, remove those first."), mu->name, LIST_LENGTH(&mu->nicks) - 1); return; } if (is_soper(mu)) { command_fail(si, fault_noprivs, _("The nickname \2%s\2 belongs to a services operator; it cannot be dropped."), acc); return; } if (mu->flags & MU_HOLD) { command_fail(si, fault_noprivs, _("The account \2%s\2 is held; it cannot be dropped."), acc); return; } snoop("DROP: \2%s\2 by \2%s\2", mu->name, get_source_name(si)); command_add_flood(si, FLOOD_MODERATE); logcommand(si, CMDLOG_REGISTER, "DROP %s", mu->name); hook_call_user_drop(mu); command_success_nodata(si, _("The account \2%s\2 has been dropped."), mu->name); object_unref(mu); }
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); } }