/** * The /ms set 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_set(User * u) { char *cmd = strtok(NULL, " "); char *param = strtok(NULL, ""); MemoInfo *mi = &u->na->nc->memos; if (readonly) { notice_lang(s_MemoServ, u, MEMO_SET_DISABLED); return MOD_CONT; } if (!param) { syntax_error(s_MemoServ, u, "SET", MEMO_SET_SYNTAX); } else if (!nick_identified(u)) { notice_lang(s_MemoServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); return MOD_CONT; } else if (stricmp(cmd, "NOTIFY") == 0) { do_set_notify(u, mi, param); } else if (stricmp(cmd, "LIMIT") == 0) { do_set_limit(u, mi, param); } else { notice_lang(s_MemoServ, u, MEMO_SET_UNKNOWN_OPTION, cmd); notice_lang(s_MemoServ, u, MORE_INFO, s_MemoServ, "SET"); } return MOD_CONT; }
static int do_saset_display(User * u, NickCore * nc, char *param) { int i; NickAlias *na; /* First check whether param is a valid nick of the group */ for (i = 0; i < nc->aliases.count; i++) { na = nc->aliases.list[i]; if (stricmp(na->nick, param) == 0) { param = na->nick; /* Because case may differ */ break; } } if (i == nc->aliases.count) { notice_lang(s_NickServ, u, NICK_SASET_DISPLAY_INVALID, nc->display); return MOD_CONT; } alog("%s: %s!%s@%s set the display of %s to: %s", s_NickServ, u->nick, u->username, u->host, nc->display, param); change_core_display(nc, param); notice_lang(s_NickServ, u, NICK_SASET_DISPLAY_CHANGED, nc->display); if (NSNickTracking) { for (i = 0; i < nc->aliases.count; ++i) { na = nc->aliases.list[i]; if (na->u && nick_identified(na->u)) nsStartNickTracking(na->u); } } return MOD_CONT; }
int do_resendcode(User * u) { char *buffer = NULL; char *nick = NULL; NickAlias *na = NULL; buffer = moduleGetLastBuffer(); if (buffer) nick = myStrGetToken(buffer, ' ', 0); if (!nick) { moduleNoticeLang(s_NickServ, u, RESENDCODE_SYNTAX); } else if (!anope_valid_nick(nick)) { notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick); } else if (!(na = findnick(nick))) { notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick); } else if (nick_identified(na->u)) { notice_lang(s_NickServ, u, NICK_ALREADY_IDENTIFIED); } else if (!(moduleGetData(&na->nc->moduleData, MODULEDATAKEY))) { moduleNoticeLang(s_NickServ, u, RESETPASS_NOT_REQUESTED, u->nick); } else { if (do_sendmail(u, na) != 0) { alog(LOG_COULDNT_SENDMAIL, MYNAME, na->nick); } else { moduleNoticeLang(s_NickServ, u, RESETPASS_SUCCESS, na->nick); moduleNoticeLang(s_NickServ, u, RESETPASS_INSTRUC); } } return MOD_CONT; }
int is_services_root(User * u) { if (!(u->mode & UMODE_o) || stricmp(u->nick, ServicesRoot) != 0) return 0; if (nick_identified(u)) return 1; return 0; }
int is_services_root(User * u) { if ((NSStrictPrivileges && !is_oper(u)) || (!skeleton && !nick_identified(u))) return 0; if (skeleton || (u->na->nc->flags & NI_SERVICES_ROOT)) return 1; return 0; }
/** * The /ns logout command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_logout(User * u) { char *nick = strtok(NULL, " "); char *param = strtok(NULL, " "); User *u2; if (!is_services_admin(u) && nick) { syntax_error(s_NickServ, u, "LOGOUT", NICK_LOGOUT_SYNTAX); } else if (!(u2 = (nick ? finduser(nick) : u))) { notice_lang(s_NickServ, u, NICK_X_NOT_IN_USE, nick); } else if (!u2->na) { if (nick) notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick); else notice_lang(s_NickServ, u, NICK_NOT_REGISTERED); } else if (u2->na->status & NS_VERBOTEN) { notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, u2->na->nick); } else if (!nick && !nick_identified(u)) { notice_lang(s_NickServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); } else if (nick && is_services_admin(u2)) { notice_lang(s_NickServ, u, NICK_LOGOUT_SERVICESADMIN, nick); } else { if (nick && param && !stricmp(param, "REVALIDATE")) { cancel_user(u2); validate_user(u2); } else { u2->na->status &= ~(NS_IDENTIFIED | NS_RECOGNIZED); } if (ircd->modeonreg) { common_svsmode(u2, ircd->modeonunreg, "1"); } u->isSuperAdmin = 0; /* Dont let people logout and remain a SuperAdmin */ alog("%s: %s!%s@%s logged out nickname %s", s_NickServ, u->nick, u->username, u->host, u2->nick); if (nick) notice_lang(s_NickServ, u, NICK_LOGOUT_X_SUCCEEDED, nick); else notice_lang(s_NickServ, u, NICK_LOGOUT_SUCCEEDED); /* Stop nick tracking if enabled */ if (NSNickTracking) /* Shouldn't this be u2? -GD */ nsStopNickTracking(u); /* Clear any timers again */ if (u->na->nc->flags & NI_KILLPROTECT) { del_ns_timeout(u->na, TO_COLLIDE); } /* Send out an event */ send_event(EVENT_NICK_LOGOUT, 1, u2->nick); } return MOD_CONT; }
int do_on_update(User *u) { if (!AutoOwner || !nick_identified(u)) return MOD_CONT; if (NSModeOnID) do_set_modes(u); return MOD_CONT; }
int do_mynicks(User * u) { char *nick = strtok(NULL, " "); NickAlias *na, *na2; int is_servadmin = is_services_admin(u); int nick_ided = nick_identified(u); int i; if ((nick ? (stricmp(nick, u->nick) ? !is_servadmin : !nick_ided) : !nick_ided)) { notice_lang(s_NickServ, u, (nick_ided ? ACCESS_DENIED : NICK_IDENTIFY_REQUIRED), s_NickServ); } else if ((!nick ? !(na = u->na) : !(na = findnick(nick)))) { notice_lang(s_NickServ, u, (!nick ? NICK_NOT_REGISTERED : NICK_X_NOT_REGISTERED), nick); } else if (na->status & NS_VERBOTEN) { notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, na->nick); } else { time_t expt; struct tm *tm; char buf[BUFSIZE]; int wont_expire; notice_lang(s_NickServ, u, nick ? NS_MYNICKS_HEADER_X : NS_MYNICKS_HEADER, na->nc->display); for (i = 0; i < na->nc->aliases.count; i++) { na2 = na->nc->aliases.list[i]; if (na2->nc == na->nc) { if (!(wont_expire = na2->status & NS_NO_EXPIRE)) { expt = na2->last_seen + NSExpire; tm = localtime(&expt); strftime_lang(buf, sizeof(buf), na2->u, STRFTIME_DATE_TIME_FORMAT, tm); } notice_lang(s_NickServ, u, ((is_services_admin(u) && !wont_expire) ? NS_MYNICKS_REPLY_ADMIN : NS_MYNICKS_REPLY), (wont_expire ? '!' : ' '), na2->nick, buf); } } notice_lang(s_NickServ, u, NS_MYNICKS_FOOTER, na->nc->aliases.count); } return MOD_CONT; }
int do_on_identify(int argc, char **argv) { User *u; if (!AutoOwner || argc != 1) return MOD_CONT; u = finduser(argv[0]); if (!u || !nick_identified(u)) return MOD_CONT; /* user not found/identified */ if (NSModeOnID) do_set_modes(u); return MOD_CONT; }
void change_user_realname(User * user, const char *realname) { if (user->realname) free(user->realname); user->realname = sstrdup(realname); if (user->na && (nick_identified(user) || (!(user->na->nc->flags & NI_SECURE) && nick_recognized(user)))) { if (user->na->last_realname) free(user->na->last_realname); user->na->last_realname = sstrdup(realname); } if (debug) alog("debug: %s changes its realname to %s", user->nick, realname); }
int is_services_oper(User * u) { unsigned int fields, rows; MYSQL_RES *result; if (!(u->mode & UMODE_o)) return(0); if (!nick_identified(u)) return(0); if (is_services_admin(u)) return(1); result = smysql_bulk_query(mysqlconn, &fields, &rows, "SELECT 1 FROM oper WHERE nick_id=%u || nick_id=%u", u->nick_id, u->real_id); mysql_free_result(result); return(rows? 1 : 0); }
void update_host(User * user) { if (user->na && (nick_identified(user) || (!(user->na->nc->flags & NI_SECURE) && nick_recognized(user)))) { if (user->na->last_usermask) free(user->na->last_usermask); user->na->last_usermask = smalloc(strlen(common_get_vident(user)) + strlen(common_get_vhost(user)) + 2); sprintf(user->na->last_usermask, "%s@%s", common_get_vident(user), common_get_vhost(user)); } if (debug) alog("debug: %s changes its host to %s", user->nick, common_get_vhost(user)); }
void change_user_username(User * user, const char *username) { if (user->vident) free(user->vident); user->vident = sstrdup(username); if (user->na && (nick_identified(user) || (!(user->na->nc->flags & NI_SECURE) && nick_recognized(user)))) { if (user->na->last_usermask) free(user->na->last_usermask); user->na->last_usermask = smalloc(strlen(common_get_vident(user)) + strlen(common_get_vhost(user)) + 2); sprintf(user->na->last_usermask, "%s@%s", common_get_vident(user), common_get_vhost(user)); } if (debug) alog("debug: %s changes its username to %s", user->nick, username); }
int do_confirm(User * u) { char *buffer = NULL; char *nick = NULL; char *passcode = NULL; char *moduledata = NULL; NickAlias *na = NULL; buffer = moduleGetLastBuffer(); if (buffer) { nick = myStrGetToken(buffer, ' ', 0); passcode = myStrGetToken(buffer, ' ', 1); } if (!nick) { moduleNoticeLang(s_NickServ, u, ENTERCODE_SYNTAX); } else if (!anope_valid_nick(nick)) { notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick); } else if (!(na = findnick(nick))) { notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick); } else if (nick_identified(na->u)) { notice_lang(s_NickServ, u, NICK_ALREADY_IDENTIFIED); } else if (!passcode) { moduleNoticeLang(s_NickServ, u, ENTERCODE_SYNTAX); } else { if (!(moduledata = moduleGetData(&na->nc->moduleData, MODULEDATAKEY))) { moduleNoticeLang(s_NickServ, u, RESETPASS_NOT_REQUESTED, nick); } else if (strcmp(passcode, moduledata) != 0) { moduleNoticeLang(s_NickServ, u, ENTERCODE_WRONG_PASSCODE); free(moduledata); } else { ns_setpassword(u, na->nc); moduleDelData(&na->nc->moduleData, MODULEDATAKEY); free(moduledata); } } return MOD_CONT; }
int do_on_join(int argc, char **argv) { User *u; Channel *c = NULL; int status; char *tmp; if (!AutoOwner) return MOD_CONT; if (argc != 3) return MOD_CONT; if (stricmp(argv[0], EVENT_STOP)) return MOD_CONT; if (UseTS6 && ircd->ts6) { u = find_byuid(argv[1]); if (!u) u = finduser(argv[1]); } else u = finduser(argv[1]); c = findchan(argv[2]); if (!c || !c->ci) return MOD_CONT; /* chan not registered */ if (!u || !nick_identified(u)) return MOD_CONT; /* user not found/identified */ status = chan_get_user_status(c, u); if ((get_access_level(c->ci, u->na) >= AutoOwnerLevel) && (!is_founder(u,c->ci))) { if (!(status & CUS_OWNER)) { tmp = stripModePrefix(ircd->ownerset); xanadu_cmd_mode(whosends(c->ci), c->name, "+%s %s", tmp, u->nick); if (tmp) free(tmp); chan_set_user_status(c, u, CUS_OWNER); } } return MOD_CONT; }
/** * The /ns update 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_nickupdate(User * u) { NickAlias *na; if (!nick_identified(u)) { notice_lang(s_NickServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); } else { na = u->na; do_setmodes(u); check_memos(u); if (na->last_realname) free(na->last_realname); na->last_realname = sstrdup(u->realname); na->status |= NS_IDENTIFIED; na->last_seen = time(NULL); if (ircd->vhost) { do_on_id(u); } notice_lang(s_NickServ, u, NICK_UPDATE_SUCCESS, s_NickServ); } return MOD_CONT; }
void do_enforce_cmode_R(Channel * c) { struct c_userlist *user; struct c_userlist *next; ChannelInfo *ci; char mask[BUFSIZE]; char *reason; char *av[3]; User *u; CBMode *cbm; if (!(ci = c->ci)) return; if (debug) alog("debug: cs_enforce: Enforcing mode +R on %s", c->name); user = c->users; do { next = user->next; u = user->user; if (!nick_identified(u)) { get_idealban(ci, u, mask, sizeof(mask)); reason = getstring(u->na, CHAN_NOT_ALLOWED_TO_JOIN); if (((cbm = &cbmodes['R'])->flag == 0) || !(c->mode & cbm->flag)) anope_cmd_mode(whosends(ci), ci->name, "+b %s %lu", mask, time(NULL)); anope_cmd_kick(whosends(ci), ci->name, u->nick, "%s", reason); av[0] = ci->name; av[1] = u->nick; av[2] = reason; do_kick(s_ChanServ, 3, av); } user = next; } while (user); }
int mEventJoin(int argc, char **argv) { ChannelInfo *ci; User *u; NickAlias *na; char *data = NULL; if (argc != 3) { return MOD_CONT; } if (!(u = finduser(argv[1]))) { return MOD_CONT; } if (strcmp(argv[0], EVENT_STOP) == 0) { if (u) { if ((ci = cs_findchan(argv[2]))) { if ((data = moduleGetData(&ci->moduleData, "avoice"))) { if (stricmp(data, "REG") == 0) { if ((na = findnick(u->nick))) { if (!check_access(na->u, ci, CA_AUTOVOICE) && nick_identified(u) && !(na->nc->flags & NI_AUTOOP)) { anope_cmd_mode(whosends(ci), ci->name, "+v %s", na->nick); chan_set_user_status(ci->c, u, CUS_VOICE); } } } else if (stricmp(data, "ALL") == 0) { if (!check_access(u, ci, CA_AUTOVOICE)) { anope_cmd_mode(whosends(ci), ci->name, "+v %s", u->nick); chan_set_user_status(ci->c, u, CUS_VOICE); } } free(data); } } } } return MOD_CONT; }
/** * The /ms read command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_read(User * u) { MemoInfo *mi; ChannelInfo *ci; char *numstr = strtok(NULL, " "), *chan = NULL; int num, count; if (numstr && *numstr == '#') { chan = numstr; numstr = strtok(NULL, " "); if (!(ci = cs_findchan(chan))) { notice_lang(s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan); return MOD_CONT; } else if (ci->flags & CI_VERBOTEN) { notice_lang(s_MemoServ, u, CHAN_X_FORBIDDEN, chan); return MOD_CONT; } else if (!check_access(u, ci, CA_MEMO)) { notice_lang(s_MemoServ, u, ACCESS_DENIED); return MOD_CONT; } mi = &ci->memos; } else { if (!nick_identified(u)) { notice_lang(s_MemoServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); return MOD_CONT; } mi = &u->na->nc->memos; } num = numstr ? atoi(numstr) : -1; if (!numstr || (stricmp(numstr, "LAST") != 0 && stricmp(numstr, "NEW") != 0 && num <= 0)) { syntax_error(s_MemoServ, u, "READ", MEMO_READ_SYNTAX); } else if (mi->memocount == 0) { if (chan) notice_lang(s_MemoServ, u, MEMO_X_HAS_NO_MEMOS, chan); else notice_lang(s_MemoServ, u, MEMO_HAVE_NO_MEMOS); } else { int i; if (stricmp(numstr, "NEW") == 0) { int readcount = 0; for (i = 0; i < mi->memocount; i++) { if (mi->memos[i].flags & MF_UNREAD) { read_memo(u, i, mi, chan); readcount++; } } if (!readcount) { if (chan) notice_lang(s_MemoServ, u, MEMO_X_HAS_NO_NEW_MEMOS, chan); else notice_lang(s_MemoServ, u, MEMO_HAVE_NO_NEW_MEMOS); } } else if (stricmp(numstr, "LAST") == 0) { for (i = 0; i < mi->memocount - 1; i++); read_memo(u, i, mi, chan); } else { /* number[s] */ if (!process_numlist(numstr, &count, read_memo_callback, u, mi, chan)) { if (count == 1) notice_lang(s_MemoServ, u, MEMO_DOES_NOT_EXIST, num); else notice_lang(s_MemoServ, u, MEMO_LIST_NOT_FOUND, numstr); } } } return MOD_CONT; }
/** * Adds a new user to anopes internal userlist. * * If the SVID passed is 2, the user will not be marked registered or requested to ID. * This is an addition to accomodate IRCds where we cannot determine this based on the NICK * or UID command. Some IRCd's keep +r on when changing nicks and do not use SVID (ex. InspIRCd 1.2). * Instead we get a METADATA command containing the accountname the user was last identified to. * Since this is received after the user is introduced to us we should not yet mark the user * as identified or ask him to identify. We will mark him as recognized for the time being and let * him keep his +r if he has it. * It is the responsibility of the protocol module to make sure that this is either invalidated, * or changed to identified. ~ Viper **/ User *do_nick(const char *source, char *nick, char *username, char *host, char *server, char *realname, time_t ts, uint32 svid, uint32 ip, char *vhost, char *uid) { User *user = NULL; char *tmp = NULL; NickAlias *old_na; /* Old nick rec */ int nc_changed = 1; /* Did nick core change? */ int status = 0; /* Status to apply */ char mask[USERMAX + HOSTMAX + 2]; char *logrealname; char *oldnick; if (!*source) { char ipbuf[16]; struct in_addr addr; if (ircd->nickvhost) { if (vhost) { if (!strcmp(vhost, "*")) { vhost = NULL; if (debug) alog("debug: new user�with no vhost in NICK command: %s", nick); } } } /* This is a new user; create a User structure for it. */ if (debug) alog("debug: new user: %s", nick); if (ircd->nickip) { addr.s_addr = htonl(ip); ntoa(addr, ipbuf, sizeof(ipbuf)); } if (LogUsers) { /** * Ugly swap routine for Flop's bug :) **/ if (realname) { tmp = strchr(realname, '%'); while (tmp) { *tmp = '-'; tmp = strchr(realname, '%'); } } logrealname = normalizeBuffer(realname); /** * End of ugly swap **/ if (ircd->nickvhost) { if (ircd->nickip) { alog("LOGUSERS: %s (%s@%s => %s) (%s) [%s] connected to the network (%s).", nick, username, host, (vhost ? vhost : "none"), logrealname, ipbuf, server); } else { alog("LOGUSERS: %s (%s@%s => %s) (%s) connected to the network (%s).", nick, username, host, (vhost ? vhost : "none"), logrealname, server); } } else { if (ircd->nickip) { alog("LOGUSERS: %s (%s@%s) (%s) [%s] connected to the network (%s).", nick, username, host, logrealname, ipbuf, server); } else { alog("LOGUSERS: %s (%s@%s) (%s) connected to the network (%s).", nick, username, host, logrealname, server); } } Anope_Free(logrealname); } /* We used to ignore the ~ which a lot of ircd's use to indicate no * identd response. That caused channel bans to break, so now we * just take what the server gives us. People are still encouraged * to read the RFCs and stop doing anything to usernames depending * on the result of an identd lookup. */ /* First check for AKILLs. */ /* DONT just return null if its an akill match anymore - yes its more efficent to, however, now that ircd's are * starting to use things like E/F lines, we cant be 100% sure the client will be removed from the network :/ * as such, create a user_struct, and if the client is removed, we'll delete it again when the QUIT notice * comes in from the ircd. **/ if (check_akill(nick, username, host, vhost, ipbuf)) { /* return NULL; */ } /** * DefCon AKILL system, if we want to akill all connecting user's here's where to do it * then force check_akill again on them... **/ /* don't akill on netmerges -Certus */ /* don't akill clients introduced by ulines. -Viper */ if (is_sync(findserver(servlist, server)) && checkDefCon(DEFCON_AKILL_NEW_CLIENTS) && !is_ulined(server)) { strncpy(mask, "*@", 3); strncat(mask, host, HOSTMAX); alog("DEFCON: adding akill for %s", mask); add_akill(NULL, mask, s_OperServ, time(NULL) + dotime(DefConAKILL), DefConAkillReason ? DefConAkillReason : "DEFCON AKILL"); if (check_akill(nick, username, host, vhost, ipbuf)) { /* return NULL; */ } } /* SGLINE */ if (ircd->sgline) { if (check_sgline(nick, realname)) return NULL; } /* SQLINE */ if (ircd->sqline) { if (check_sqline(nick, 0)) return NULL; } /* SZLINE */ if (ircd->szline && ircd->nickip) { if (check_szline(nick, ipbuf)) return NULL; } /* Now check for session limits */ if (LimitSessions && !is_ulined(server) && !add_session(nick, host, ipbuf)) return NULL; /* Allocate User structure and fill it in. */ user = new_user(nick); user->username = sstrdup(username); user->host = sstrdup(host); user->server = findserver(servlist, server); user->realname = sstrdup(realname); user->timestamp = ts; user->my_signon = time(NULL); user->chost = vhost ? sstrdup(vhost) : sstrdup(host); user->vhost = vhost ? sstrdup(vhost) : sstrdup(host); if (uid) { user->uid = sstrdup(uid); /* p10/ts6 stuff */ } else { user->uid = NULL; } user->vident = sstrdup(username); /* We now store the user's ip in the user_ struct, * because we will use it in serveral places -- DrStein */ if (ircd->nickip) { user->hostip = sstrdup(ipbuf); } else { user->hostip = NULL; } if (svid == 0) { display_news(user, NEWS_LOGON); display_news(user, NEWS_RANDOM); } if (svid == 2 && user->na) { /* We do not yet know if the user should be identified or not. * mark him as recognized for now. * It s up to the protocol module to make sure this either becomes ID'd or * is invalidated. ~ Viper */ if (debug) alog("debug: Marking %s as recognized..", user->nick); user->svid = 1; user->na->status |= NS_RECOGNIZED; nc_changed = 0; } else if (svid == ts && user->na) { /* Timestamp and svid match, and nick is registered; automagically identify the nick */ user->svid = svid; user->na->status |= NS_IDENTIFIED; check_memos(user); nc_changed = 0; /* Start nick tracking if available */ if (NSNickTracking) nsStartNickTracking(user); } else if (svid != 1) { /* Resets the svid because it doesn't match */ user->svid = 1; anope_cmd_svid_umode(user->nick, user->timestamp); } else { user->svid = 1; } send_event(EVENT_NEWNICK, 1, nick); } else { /* An old user changing nicks. */ if (UseTS6 && ircd->ts6) user = find_byuid(source); if (!user) user = finduser(source); if (!user) { alog("user: NICK from nonexistent nick %s", source); return NULL; } user->isSuperAdmin = 0; /* Dont let people nick change and stay SuperAdmins */ if (debug) alog("debug: %s changes nick to %s", source, nick); if (LogUsers) { logrealname = normalizeBuffer(user->realname); if (ircd->vhost) { alog("LOGUSERS: %s (%s@%s => %s) (%s) changed nick to %s (%s).", user->nick, user->username, user->host, (user->vhost ? user->vhost : "(none)"), logrealname, nick, user->server->name); } else { alog("LOGUSERS: %s (%s@%s) (%s) changed nick to %s (%s).", user->nick, user->username, user->host, logrealname, nick, user->server->name); } if (logrealname) { free(logrealname); } } user->timestamp = ts; if (stricmp(nick, user->nick) == 0) { /* No need to redo things */ change_user_nick(user, nick); nc_changed = 0; } else { /* Update this only if nicks aren't the same */ user->my_signon = time(NULL); old_na = user->na; if (old_na) { if (nick_recognized(user)) user->na->last_seen = time(NULL); status = old_na->status & NS_TRANSGROUP; cancel_user(user); } oldnick = sstrdup(user->nick); change_user_nick(user, nick); if ((old_na ? old_na->nc : NULL) == (user->na ? user->na->nc : NULL)) nc_changed = 0; if (!nc_changed && (user->na)) user->na->status |= status; else { anope_cmd_nc_change(user); } send_event(EVENT_CHANGE_NICK, 2, nick, oldnick); free(oldnick); } if (ircd->sqline) { if (!is_oper(user) && check_sqline(user->nick, 1)) return NULL; } } /* if (!*source) */ /* Check for nick tracking to bypass identification */ if (NSNickTracking && nsCheckNickTracking(user)) { user->na->status |= NS_IDENTIFIED; nc_changed = 0; } if (nc_changed || !nick_recognized(user)) { if (validate_user(user)) check_memos(user); } else { if (nick_identified(user)) { char tsbuf[16]; user->na->last_seen = time(NULL); if (user->na->last_usermask) free(user->na->last_usermask); user->na->last_usermask = smalloc(strlen(common_get_vident(user)) + strlen(common_get_vhost(user)) + 2); sprintf(user->na->last_usermask, "%s@%s", common_get_vident(user), common_get_vhost(user)); snprintf(tsbuf, sizeof(tsbuf), "%lu", (unsigned long int) user->timestamp); anope_cmd_svid_umode2(user, tsbuf); alog("%s: %s!%s@%s automatically identified for nick %s", s_NickServ, user->nick, user->username, user->host, user->nick); } } /* Bahamut sets -r on every nick changes, so we must test it even if nc_changed == 0 */ if (ircd->check_nick_id) { if (nick_identified(user)) { char tsbuf[16]; snprintf(tsbuf, sizeof(tsbuf), "%lu", (unsigned long int) user->timestamp); anope_cmd_svid_umode3(user, tsbuf); } } return user; }
/** * Split from do_send, this way we can easily send a memo from any point. * * @param u User Struct * @param name Target of the memo * @param text Memo Text * @param z type see info * @param source Nickname of the alias the memo originates from. * 0 - reply to user * 1 - silent * 2 - silent with no delay timer * 3 - reply to user and request read receipt * @return void */ void memo_send_from(User * u, char *name, char *text, int z, char *source) { int ischan; int isforbid; Memo *m; MemoInfo *mi; time_t now = time(NULL); int is_servoper = is_services_oper(u); if (readonly) { notice_lang(s_MemoServ, u, MEMO_SEND_DISABLED); } else if (checkDefCon(DEFCON_NO_NEW_MEMOS)) { notice_lang(s_MemoServ, u, OPER_DEFCON_DENIED); return; } else if (!text) { if (z == 0) syntax_error(s_MemoServ, u, "SEND", MEMO_SEND_SYNTAX); if (z == 3) syntax_error(s_MemoServ, u, "RSEND", MEMO_RSEND_SYNTAX); } else if (!nick_recognized(u)) { if (z == 0 || z == 3) notice_lang(s_MemoServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); } else if (!(mi = getmemoinfo(name, &ischan, &isforbid))) { if (z == 0 || z == 3) { if (isforbid) { notice_lang(s_MemoServ, u, ischan ? CHAN_X_FORBIDDEN : NICK_X_FORBIDDEN, name); } else { notice_lang(s_MemoServ, u, ischan ? CHAN_X_NOT_REGISTERED : NICK_X_NOT_REGISTERED, name); } } } else if (z != 2 && MSSendDelay > 0 && u && u->lastmemosend + MSSendDelay > now && !is_servoper) { u->lastmemosend = now; if (z == 0) notice_lang(s_MemoServ, u, MEMO_SEND_PLEASE_WAIT, MSSendDelay); if (z == 3) notice_lang(s_MemoServ, u, MEMO_RSEND_PLEASE_WAIT, MSSendDelay); } else if (mi->memomax == 0 && !is_servoper) { if (z == 0 || z == 3) notice_lang(s_MemoServ, u, MEMO_X_GETS_NO_MEMOS, name); } else if (mi->memocount >= 32767 || (mi->memomax > 0 && mi->memocount >= mi->memomax && !is_servoper)) { if (z == 0 || z == 3) notice_lang(s_MemoServ, u, MEMO_X_HAS_TOO_MANY_MEMOS, name); } else { u->lastmemosend = now; mi->memocount++; mi->memos = srealloc(mi->memos, sizeof(Memo) * mi->memocount); m = &mi->memos[mi->memocount - 1]; strscpy(m->sender, source, NICKMAX); m->moduleData = NULL; if (mi->memocount > 1) { m->number = m[-1].number + 1; if (m->number < 1) { int i; for (i = 0; i < mi->memocount; i++) { mi->memos[i].number = i + 1; } } } else { m->number = 1; } m->time = time(NULL); m->text = sstrdup(text); m->flags = MF_UNREAD; #ifdef USE_MYSQL m->id = 0; #endif /* Set notify sent flag - DrStein */ if (z == 2) { m->flags |= MF_NOTIFYS; } /* Set receipt request flag */ if (z == 3) m->flags |= MF_RECEIPT; if (z == 0 || z == 3) notice_lang(s_MemoServ, u, MEMO_SENT, name); if (!ischan) { NickAlias *na; NickCore *nc = (findnick(name))->nc; if (MSNotifyAll) { if ((nc->flags & NI_MEMO_RECEIVE) && get_ignore(name) == NULL) { int i; for (i = 0; i < nc->aliases.count; i++) { na = nc->aliases.list[i]; if (na->u && nick_identified(na->u)) notice_lang(s_MemoServ, na->u, MEMO_NEW_MEMO_ARRIVED, source, s_MemoServ, m->number); } } else { if ((u = finduser(name)) && nick_identified(u) && (nc->flags & NI_MEMO_RECEIVE)) notice_lang(s_MemoServ, u, MEMO_NEW_MEMO_ARRIVED, source, s_MemoServ, m->number); } /* if (flags & MEMO_RECEIVE) */ } /* if (MSNotifyAll) */ /* let's get out the mail if set in the nickcore - certus */ if (nc->flags & NI_MEMO_MAIL) new_memo_mail(nc, m); } else { struct c_userlist *cu, *next; Channel *c; if (MSNotifyAll && (c = findchan(name))) { for (cu = c->users; cu; cu = next) { next = cu->next; if (check_access(cu->user, c->ci, CA_MEMO)) { if (cu->user->na && (cu->user->na->nc->flags & NI_MEMO_RECEIVE) && get_ignore(cu->user->nick) == NULL) { notice_lang(s_MemoServ, cu->user, MEMO_NEW_X_MEMO_ARRIVED, c->ci->name, s_MemoServ, c->ci->name, m->number); } } } } /* MSNotifyAll */ } /* if (!ischan) */ } /* if command is valid */ }
/** * The /ms info 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_info(User * u) { MemoInfo *mi; NickAlias *na = NULL; ChannelInfo *ci = NULL; char *name = strtok(NULL, " "); int is_servadmin = is_services_admin(u); int hardmax = 0; if (is_servadmin && name && *name != '#') { na = findnick(name); if (!na) { notice_lang(s_MemoServ, u, NICK_X_NOT_REGISTERED, name); return MOD_CONT; } else if (na->status & NS_VERBOTEN) { notice_lang(s_MemoServ, u, NICK_X_FORBIDDEN, name); return MOD_CONT; } mi = &na->nc->memos; hardmax = na->nc->flags & NI_MEMO_HARDMAX ? 1 : 0; } else if (name && *name == '#') { ci = cs_findchan(name); if (!ci) { notice_lang(s_MemoServ, u, CHAN_X_NOT_REGISTERED, name); return MOD_CONT; } else if (ci->flags & CI_VERBOTEN) { notice_lang(s_MemoServ, u, CHAN_X_FORBIDDEN, name); return MOD_CONT; } else if (!check_access(u, ci, CA_MEMO)) { notice_lang(s_MemoServ, u, ACCESS_DENIED); return MOD_CONT; } mi = &ci->memos; hardmax = ci->flags & CI_MEMO_HARDMAX ? 1 : 0; } else if (name) { /* It's not a chan and we aren't services admin */ notice_lang(s_MemoServ, u, ACCESS_DENIED); return MOD_CONT; } else { /* !name */ if (!nick_identified(u)) { notice_lang(s_MemoServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); return MOD_CONT; } mi = &u->na->nc->memos; hardmax = u->na->nc->flags & NI_MEMO_HARDMAX ? 1 : 0; } if (name && (ci || na->nc != u->na->nc)) { if (!mi->memocount) { notice_lang(s_MemoServ, u, MEMO_INFO_X_NO_MEMOS, name); } else if (mi->memocount == 1) { if (mi->memos[0].flags & MF_UNREAD) notice_lang(s_MemoServ, u, MEMO_INFO_X_MEMO_UNREAD, name); else notice_lang(s_MemoServ, u, MEMO_INFO_X_MEMO, name); } else { int count = 0, i; for (i = 0; i < mi->memocount; i++) { if (mi->memos[i].flags & MF_UNREAD) count++; } if (count == mi->memocount) notice_lang(s_MemoServ, u, MEMO_INFO_X_MEMOS_ALL_UNREAD, name, count); else if (count == 0) notice_lang(s_MemoServ, u, MEMO_INFO_X_MEMOS, name, mi->memocount); else if (count == 1) notice_lang(s_MemoServ, u, MEMO_INFO_X_MEMOS_ONE_UNREAD, name, mi->memocount); else notice_lang(s_MemoServ, u, MEMO_INFO_X_MEMOS_SOME_UNREAD, name, mi->memocount, count); } if (mi->memomax == 0) { if (hardmax) notice_lang(s_MemoServ, u, MEMO_INFO_X_HARD_LIMIT, name, mi->memomax); else notice_lang(s_MemoServ, u, MEMO_INFO_X_LIMIT, name, mi->memomax); } else if (mi->memomax > 0) { if (hardmax) notice_lang(s_MemoServ, u, MEMO_INFO_X_HARD_LIMIT, name, mi->memomax); else notice_lang(s_MemoServ, u, MEMO_INFO_X_LIMIT, name, mi->memomax); } else { notice_lang(s_MemoServ, u, MEMO_INFO_X_NO_LIMIT, name); } /* I ripped this code out of ircservices 4.4.5, since I didn't want to rewrite the whole thing (it pisses me off). */ if (na) { if ((na->nc->flags & NI_MEMO_RECEIVE) && (na->nc->flags & NI_MEMO_SIGNON)) { notice_lang(s_MemoServ, u, MEMO_INFO_X_NOTIFY_ON, name); } else if (na->nc->flags & NI_MEMO_RECEIVE) { notice_lang(s_MemoServ, u, MEMO_INFO_X_NOTIFY_RECEIVE, name); } else if (na->nc->flags & NI_MEMO_SIGNON) { notice_lang(s_MemoServ, u, MEMO_INFO_X_NOTIFY_SIGNON, name); } else { notice_lang(s_MemoServ, u, MEMO_INFO_X_NOTIFY_OFF, name); } } } else { /* !name || (!ci || na->nc == u->na->nc) */ if (!mi->memocount) { notice_lang(s_MemoServ, u, MEMO_INFO_NO_MEMOS); } else if (mi->memocount == 1) { if (mi->memos[0].flags & MF_UNREAD) notice_lang(s_MemoServ, u, MEMO_INFO_MEMO_UNREAD); else notice_lang(s_MemoServ, u, MEMO_INFO_MEMO); } else { int count = 0, i; for (i = 0; i < mi->memocount; i++) { if (mi->memos[i].flags & MF_UNREAD) count++; } if (count == mi->memocount) notice_lang(s_MemoServ, u, MEMO_INFO_MEMOS_ALL_UNREAD, count); else if (count == 0) notice_lang(s_MemoServ, u, MEMO_INFO_MEMOS, mi->memocount); else if (count == 1) notice_lang(s_MemoServ, u, MEMO_INFO_MEMOS_ONE_UNREAD, mi->memocount); else notice_lang(s_MemoServ, u, MEMO_INFO_MEMOS_SOME_UNREAD, mi->memocount, count); } if (mi->memomax == 0) { if (!is_servadmin && hardmax) notice_lang(s_MemoServ, u, MEMO_INFO_HARD_LIMIT_ZERO); else notice_lang(s_MemoServ, u, MEMO_INFO_LIMIT_ZERO); } else if (mi->memomax > 0) { if (!is_servadmin && hardmax) notice_lang(s_MemoServ, u, MEMO_INFO_HARD_LIMIT, mi->memomax); else notice_lang(s_MemoServ, u, MEMO_INFO_LIMIT, mi->memomax); } else { notice_lang(s_MemoServ, u, MEMO_INFO_NO_LIMIT); } /* Ripped too. But differently because of a seg fault (loughs) */ if ((u->na->nc->flags & NI_MEMO_RECEIVE) && (u->na->nc->flags & NI_MEMO_SIGNON)) { notice_lang(s_MemoServ, u, MEMO_INFO_NOTIFY_ON); } else if (u->na->nc->flags & NI_MEMO_RECEIVE) { notice_lang(s_MemoServ, u, MEMO_INFO_NOTIFY_RECEIVE); } else if (u->na->nc->flags & NI_MEMO_SIGNON) { notice_lang(s_MemoServ, u, MEMO_INFO_NOTIFY_SIGNON); } else { notice_lang(s_MemoServ, u, MEMO_INFO_NOTIFY_OFF); } } return MOD_CONT; /* if (name && (ci || na->nc != u->na->nc)) */ }
int do_addnick(User * u) { NickAlias *na, *target; NickCore *nc; char *nick = strtok(NULL, " "); char *pass = strtok(NULL, " "); int i; char tsbuf[16]; char modes[512]; int len; if (NSEmailReg && (findrequestnick(u->nick))) { notice_lang(s_NickServ, u, NS_REQUESTED); return MOD_CONT; } if (readonly) { notice_lang(s_NickServ, u, NS_ADDNICK_DISABLED); return MOD_CONT; } if (checkDefCon(DEFCON_NO_NEW_NICKS)) { notice_lang(s_NickServ, u, OPER_DEFCON_DENIED); return MOD_CONT; } if (RestrictOperNicks) { for (i = 0; i < RootNumber; i++) { if (stristr(u->nick, ServicesRoots[i]) && !is_oper(u)) { notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick); return MOD_CONT; } } for (i = 0; i < servadmins.count && (nc = servadmins.list[i]); i++) { if (stristr(u->nick, nc->display) && !is_oper(u)) { notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick); return MOD_CONT; } } for (i = 0; i < servopers.count && (nc = servopers.list[i]); i++) { if (stristr(u->nick, nc->display) && !is_oper(u)) { notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick); return MOD_CONT; } } } if (!nick || !pass) { syntax_error(s_NickServ, u, "ADDNICK", NS_ADDNICK_SYNTAX); } else if (!(target = findnick(nick))) { notice_lang(s_NickServ, u, NICK_X_NOT_REGISTERED, nick); } else if (time(NULL) < u->lastnickreg + NSRegDelay) { notice_lang(s_NickServ, u, NS_ADDNICK_PLEASE_WAIT, NSRegDelay); } else if (u->na && (u->na->status & NS_VERBOTEN)) { alog("%s: %s@%s tried to use ADDNICK from forbidden nick %s.", s_NickServ, u->username, u->host, u->nick); notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, u->nick); } else if (u->na && (u->na->nc->flags & NI_SUSPENDED)) { alog("%s: %s!%s@%s tried to use ADDNICK from suspended nick %s.", s_NickServ, u->nick, u->username, u->host, target->nick); notice_lang(s_NickServ, u, NICK_X_SUSPENDED, u->nick); } else if (u->na && NSNoGroupChange) { notice_lang(s_NickServ, u, NS_ADDNICK_CHANGE_DISABLED, s_NickServ); } else if (u->na && !nick_identified(u)) { notice_lang(s_NickServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); } else if (target && (target->nc->flags & NI_SUSPENDED)) { alog("%s: %s!%s@%s tried to use GROUP from SUSPENDED nick %s", s_NickServ, u->nick, u->username, u->host, target->nick); notice_lang(s_NickServ, u, NICK_X_SUSPENDED, target->nick); } else if (target->status & NS_VERBOTEN) { notice_lang(s_NickServ, u, NICK_X_FORBIDDEN, nick); } else if (u->na && target->nc == u->na->nc) { notice_lang(s_NickServ, u, NS_ADDNICK_SAME, target->nick); } else if (NSMaxAliases && (target->nc->aliases.count >= NSMaxAliases) && !nick_is_services_admin(target->nc)) { notice_lang(s_NickServ, u, NS_ADDNICK_TOO_MANY, target->nick, s_NickServ, s_NickServ); } else if (enc_check_password(pass, target->nc->pass) != 1) { alog("%s: Failed ADDNICK for %s!%s@%s (invalid password).", s_NickServ, u->nick, u->username, u->host); notice_lang(s_NickServ, u, PASSWORD_INCORRECT); bad_password(u); } else { /* If the nick is already registered, drop it. * If not, check that it is valid. */ if (u->na) { delnick(u->na); } else { int prefixlen = strlen(NSGuestNickPrefix); int nicklen = strlen(u->nick); if (nicklen <= prefixlen + 7 && nicklen >= prefixlen + 1 && stristr(u->nick, NSGuestNickPrefix) == u->nick && strspn(u->nick + prefixlen, "1234567890") == nicklen - prefixlen) { notice_lang(s_NickServ, u, NICK_CANNOT_BE_REGISTERED, u->nick); return MOD_CONT; } } na = makealias(u->nick, target->nc); if (na) { na->last_usermask = scalloc(strlen(common_get_vident(u)) + strlen(common_get_vhost(u)) + 2, 1); sprintf(na->last_usermask, "%s@%s", common_get_vident(u), common_get_vhost(u)); na->last_realname = sstrdup(u->realname); na->time_registered = na->last_seen = time(NULL); na->status = (int16) (NS_IDENTIFIED | NS_RECOGNIZED); if (!(na->nc->flags & NI_SERVICES_ROOT)) { for (i = 0; i < RootNumber; i++) { if (!stricmp(ServicesRoots[i], u->nick)) { na->nc->flags |= NI_SERVICES_ROOT; break; } } } u->na = na; na->u = u; #ifdef USE_RDB /* Is this really needed? Since this is a new alias it will get * its unique id on the next update, since it was previously * deleted by delnick. Must observe... */ if (rdb_open()) { rdb_save_ns_alias(na); rdb_close(); } #endif send_event(EVENT_GROUP, 1, u->nick); alog("%s: %s!%s@%s makes %s join group of %s (%s) (e-mail: %s)", s_NickServ, u->nick, u->username, u->host, u->nick, target->nick, target->nc->display, (target->nc->email ? target->nc->email : "none")); notice_lang(s_NickServ, u, NS_ADDNICK_SUCCESS, target->nick); u->lastnickreg = time(NULL); snprintf(tsbuf, sizeof(tsbuf), "%lu", (unsigned long int) u->timestamp); if (ircd->modeonreg) { len = strlen(ircd->modeonreg); strncpy(modes,ircd->modeonreg,512); if(ircd->rootmodeonid && is_services_root(u)) { strncat(modes,ircd->rootmodeonid,512-len); } else if(ircd->adminmodeonid && is_services_admin(u)) { strncat(modes,ircd->adminmodeonid,512-len); } else if(ircd->opermodeonid && is_services_oper(u)) { strncat(modes,ircd->opermodeonid,512-len); } if (ircd->tsonmode) { common_svsmode(u, modes, tsbuf); } else { common_svsmode(u, modes, NULL); } } check_memos(u); } else { alog("%s: makealias(%s) failed", s_NickServ, u->nick); notice_lang(s_NickServ, u, NS_ADDNICK_FAILED); } } return MOD_CONT; }
/** * The /ns list 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_list(User * u) { /* SADMINS can search for nicks based on their NS_VERBOTEN and NS_NO_EXPIRE * status. The keywords FORBIDDEN and NOEXPIRE represent these two states * respectively. These keywords should be included after the search pattern. * Multiple keywords are accepted and should be separated by spaces. Only one * of the keywords needs to match a nick's state for the nick to be displayed. * Forbidden nicks can be identified by "[Forbidden]" appearing in the last * seen address field. Nicks with NOEXPIRE set are preceeded by a "!". Only * SADMINS will be shown forbidden nicks and the "!" indicator. * Syntax for sadmins: LIST pattern [FORBIDDEN] [NOEXPIRE] * -TheShadow * * UPDATE: SUSPENDED keyword is now accepted as well. */ char *pattern = strtok(NULL, " "); char *keyword; NickAlias *na; NickCore *mync; int nnicks, i; char buf[BUFSIZE]; int is_servadmin = is_services_admin(u); int16 matchflags = 0; NickRequest *nr = NULL; int nronly = 0; int susp_keyword = 0; char noexpire_char = ' '; int count = 0, from = 0, to = 0, tofree = 0; char *tmp = NULL; char *s = NULL; if (!(!NSListOpersOnly || (is_oper(u)))) { /* reverse the help logic */ notice_lang(s_NickServ, u, ACCESS_DENIED); return MOD_STOP; } if (!pattern) { syntax_error(s_NickServ, u, "LIST", is_servadmin ? NICK_LIST_SERVADMIN_SYNTAX : NICK_LIST_SYNTAX); } else { if (pattern) { if (pattern[0] == '#') { tmp = myStrGetOnlyToken((pattern + 1), '-', 0); /* Read FROM out */ if (!tmp) { notice_lang(s_ChanServ, u, LIST_INCORRECT_RANGE); return MOD_CONT; } for (s = tmp; *s; s++) { if (!isdigit(*s)) { free(tmp); notice_lang(s_ChanServ, u, LIST_INCORRECT_RANGE); return MOD_CONT; } } from = atoi(tmp); free(tmp); tmp = myStrGetTokenRemainder(pattern, '-', 1); /* Read TO out */ if (!tmp) { notice_lang(s_ChanServ, u, LIST_INCORRECT_RANGE); return MOD_CONT; } for (s = tmp; *s; s++) { if (!isdigit(*s)) { free(tmp); notice_lang(s_ChanServ, u, LIST_INCORRECT_RANGE); return MOD_CONT; } } to = atoi(tmp); free(tmp); pattern = sstrdup("*"); tofree = 1; } } nnicks = 0; while (is_servadmin && (keyword = strtok(NULL, " "))) { if (stricmp(keyword, "FORBIDDEN") == 0) matchflags |= NS_VERBOTEN; if (stricmp(keyword, "NOEXPIRE") == 0) matchflags |= NS_NO_EXPIRE; if (stricmp(keyword, "SUSPENDED") == 0) susp_keyword = 1; if (stricmp(keyword, "UNCONFIRMED") == 0) nronly = 1; } mync = (nick_identified(u) ? u->na->nc : NULL); notice_lang(s_NickServ, u, NICK_LIST_HEADER, pattern); if (nronly != 1) { for (i = 0; i < 1024; i++) { for (na = nalists[i]; na; na = na->next) { /* Don't show private and forbidden nicks to non-services admins. */ if ((na->status & NS_VERBOTEN) && !is_servadmin) continue; if ((na->nc->flags & NI_PRIVATE) && !is_servadmin && na->nc != mync) continue; if ((matchflags != 0) && !(na->status & matchflags) && (susp_keyword == 0)) continue; else if ((susp_keyword == 1) && !(na->nc->flags & NI_SUSPENDED)) continue; /* We no longer compare the pattern against the output buffer. * Instead we build a nice nick!user@host buffer to compare. * The output is then generated separately. -TheShadow */ snprintf(buf, sizeof(buf), "%s!%s", na->nick, (na->last_usermask && !(na->status & NS_VERBOTEN)) ? na-> last_usermask : "*@*"); if (stricmp(pattern, na->nick) == 0 || match_wild_nocase(pattern, buf)) { if ((((count + 1 >= from) && (count + 1 <= to)) || ((from == 0) && (to == 0))) && (++nnicks <= NSListMax)) { if (is_servadmin && (na->status & NS_NO_EXPIRE)) noexpire_char = '!'; else { noexpire_char = ' '; } if ((na->nc->flags & NI_HIDE_MASK) && !is_servadmin && na->nc != mync) { snprintf(buf, sizeof(buf), "%-20s [Hostname Hidden]", na->nick); } else if (na->status & NS_VERBOTEN) { snprintf(buf, sizeof(buf), "%-20s [Forbidden]", na->nick); } else if (na->nc->flags & NI_SUSPENDED) { snprintf(buf, sizeof(buf), "%-20s [Suspended]", na->nick); } else { snprintf(buf, sizeof(buf), "%-20s %s", na->nick, na->last_usermask); } notice_user(s_NickServ, u, " %c%s", noexpire_char, buf); } count++; } } } } if (nronly == 1 || (is_servadmin && matchflags == 0 && susp_keyword == 0)) { noexpire_char = ' '; for (i = 0; i < 1024; i++) { for (nr = nrlists[i]; nr; nr = nr->next) { snprintf(buf, sizeof(buf), "%s!*@*", nr->nick); if (stricmp(pattern, nr->nick) == 0 || match_wild_nocase(pattern, buf)) { if (++nnicks <= NSListMax) { snprintf(buf, sizeof(buf), "%-20s [UNCONFIRMED]", nr->nick); notice_user(s_NickServ, u, " %c%s", noexpire_char, buf); } } } } } notice_lang(s_NickServ, u, NICK_LIST_RESULTS, nnicks > NSListMax ? NSListMax : nnicks, nnicks); } if (tofree) free(pattern); return MOD_CONT; }
/** * The /ns identify command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int do_identify(User * u) { char *pass = strtok(NULL, " "); NickAlias *na; NickRequest *nr; int res; char tsbuf[16]; char modes[512]; int len; if (!pass) { syntax_error(s_NickServ, u, "IDENTIFY", NICK_IDENTIFY_SYNTAX); } else if (!(na = u->na)) { if ((nr = findrequestnick(u->nick))) { notice_lang(s_NickServ, u, NICK_IS_PREREG); } else { notice_lang(s_NickServ, u, NICK_NOT_REGISTERED); } } 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 (nick_identified(u)) { notice_lang(s_NickServ, u, NICK_ALREADY_IDENTIFIED); } else if (!(res = enc_check_password(pass, na->nc->pass))) { alog("%s: Failed IDENTIFY for %s!%s@%s", s_NickServ, u->nick, u->username, u->host); notice_lang(s_NickServ, u, PASSWORD_INCORRECT); bad_password(u); } else if (res == -1) { notice_lang(s_NickServ, u, NICK_IDENTIFY_FAILED); } else { if (!(na->status & NS_IDENTIFIED) && !(na->status & NS_RECOGNIZED)) { if (na->last_usermask) free(na->last_usermask); na->last_usermask = scalloc(strlen(common_get_vident(u)) + strlen(common_get_vhost(u)) + 2, 1); sprintf(na->last_usermask, "%s@%s", common_get_vident(u), common_get_vhost(u)); if (na->last_realname) free(na->last_realname); na->last_realname = sstrdup(u->realname); } na->status |= NS_IDENTIFIED; na->last_seen = time(NULL); snprintf(tsbuf, sizeof(tsbuf), "%lu", (unsigned long int) u->timestamp); if (ircd->modeonreg) { len = strlen(ircd->modeonreg); strncpy(modes,ircd->modeonreg,512); if(ircd->rootmodeonid && is_services_root(u)) { strncat(modes,ircd->rootmodeonid,512-len); } else if(ircd->adminmodeonid && is_services_admin(u)) { strncat(modes,ircd->adminmodeonid,512-len); } else if(ircd->opermodeonid && is_services_oper(u)) { strncat(modes,ircd->opermodeonid,512-len); } if (ircd->tsonmode) { common_svsmode(u, modes, tsbuf); } else { common_svsmode(u, modes, ""); } } send_event(EVENT_NICK_IDENTIFY, 1, u->nick); alog("%s: %s!%s@%s identified for nick %s", s_NickServ, u->nick, u->username, u->host, u->nick); notice_lang(s_NickServ, u, NICK_IDENTIFY_SUCCEEDED); if (ircd->vhost) { do_on_id(u); } if (NSModeOnID) { do_setmodes(u); } if (NSForceEmail && u->na && !u->na->nc->email) { notice_lang(s_NickServ, u, NICK_IDENTIFY_EMAIL_REQUIRED); notice_help(s_NickServ, u, NICK_IDENTIFY_EMAIL_HOWTO); } if (!(na->status & NS_RECOGNIZED)) check_memos(u); /* Enable nick tracking if enabled */ if (NSNickTracking) nsStartNickTracking(u); /* Clear any timers */ if (na->nc->flags & NI_KILLPROTECT) { del_ns_timeout(na, TO_COLLIDE); } } return MOD_CONT; }
void viagra_set_umode(User * user, int ac, char **av) { int add = 1; /* 1 if adding modes, 0 if deleting */ char *modes = av[0]; ac--; if (debug) alog("debug: Changing mode for %s to %s", user->nick, modes); while (*modes) { /* This looks better, much better than "add ? (do_add) : (do_remove)". * At least this is readable without paying much attention :) -GD */ if (add) user->mode |= umodes[(int) *modes]; else user->mode &= ~umodes[(int) *modes]; switch (*modes++) { case '+': add = 1; break; case '-': add = 0; break; case 'd': if (ac == 0) { alog("user: umode +d with no parameter (?) for user %s", user->nick); break; } ac--; av++; user->svid = strtoul(*av, NULL, 0); break; case 'o': if (add) { opcnt++; if (WallOper) { xanadu_cmd_global(s_OperServ, "\2%s\2 is now an IRC operator.", user->nick); } display_news(user, NEWS_OPER); } else { opcnt--; } break; case 'r': if (add && !nick_identified(user)) { common_svsmode(user, "-r", NULL); user->mode &= ~UMODE_r; } break; case 'x': update_host(user); break; } } }
/** * List the memos (if any) for the source nick or given channel. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ static int do_list(User * u) { char *param = strtok(NULL, " "), *chan = NULL; ChannelInfo *ci; MemoInfo *mi; Memo *m; int i; if (param && *param == '#') { chan = param; param = strtok(NULL, " "); if (!(ci = cs_findchan(chan))) { notice_lang(s_MemoServ, u, CHAN_X_NOT_REGISTERED, chan); return MOD_CONT; } else if (ci->flags & CI_VERBOTEN) { notice_lang(s_MemoServ, u, CHAN_X_FORBIDDEN, chan); return MOD_CONT; } else if (!check_access(u, ci, CA_MEMO)) { notice_lang(s_MemoServ, u, ACCESS_DENIED); return MOD_CONT; } mi = &ci->memos; } else { if (!nick_identified(u)) { notice_lang(s_MemoServ, u, NICK_IDENTIFY_REQUIRED, s_NickServ); return MOD_CONT; } mi = &u->na->nc->memos; } if (param && !isdigit(*param) && stricmp(param, "NEW") != 0) { syntax_error(s_MemoServ, u, "LIST", MEMO_LIST_SYNTAX); } else if (mi->memocount == 0) { if (chan) notice_lang(s_MemoServ, u, MEMO_X_HAS_NO_MEMOS, chan); else notice_lang(s_MemoServ, u, MEMO_HAVE_NO_MEMOS); } else { int sent_header = 0; if (param && isdigit(*param)) { process_numlist(param, NULL, list_memo_callback, u, mi, &sent_header, chan); } else { if (param) { for (i = 0, m = mi->memos; i < mi->memocount; i++, m++) { if (m->flags & MF_UNREAD) break; } if (i == mi->memocount) { if (chan) notice_lang(s_MemoServ, u, MEMO_X_HAS_NO_NEW_MEMOS, chan); else notice_lang(s_MemoServ, u, MEMO_HAVE_NO_NEW_MEMOS); return MOD_CONT; } } for (i = 0, m = mi->memos; i < mi->memocount; i++, m++) { if (param && !(m->flags & MF_UNREAD)) continue; list_memo(u, i, mi, &sent_header, param != NULL, chan); } } } return MOD_CONT; }