/* :%s NEWMASK %s parv[0] = sender parv[1] = new mask (if no '@', hostname is assumed) */ int denora_event_newmask(char *source, int ac, char **av) { char *newhost; char *newuser; if (denora->protocoldebug) { protocol_debug(source, ac, av); } if (ac != 1) { return MOD_CONT; } newuser = myStrGetOnlyToken(av[0], '@', 0); if (newuser) { newhost = myStrGetTokenRemainder(av[0], '@', 1); change_user_username(source, newuser); free(newuser); } else { newhost = av[0]; } if (*newhost == '@') newhost++; if (newhost) { change_user_host(source, newhost); } return MOD_CONT; }
/** * The /hs 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 myDoSet(User * u) { char *nick = strtok(NULL, " "); char *rawhostmask = strtok(NULL, " "); char *hostmask = smalloc(HOSTMAX); NickAlias *na; int32 tmp_time; char *s; char *vIdent = NULL; if (!nick || !rawhostmask) { syntax_error(s_HostServ, u, "SET", HOST_SET_SYNTAX); free(hostmask); return MOD_CONT; } vIdent = myStrGetOnlyToken(rawhostmask, '@', 0); /* Get the first substring, @ as delimiter */ if (vIdent) { rawhostmask = myStrGetTokenRemainder(rawhostmask, '@', 1); /* get the remaining string */ if (!rawhostmask) { syntax_error(s_HostServ, u, "SET", HOST_SET_SYNTAX); free(vIdent); free(hostmask); return MOD_CONT; } if (strlen(vIdent) > USERMAX - 1) { notice_lang(s_HostServ, u, HOST_SET_IDENTTOOLONG, USERMAX); free(vIdent); free(rawhostmask); free(hostmask); return MOD_CONT; } else { for (s = vIdent; *s; s++) { if (!isvalidchar(*s)) { notice_lang(s_HostServ, u, HOST_SET_IDENT_ERROR); free(vIdent); free(rawhostmask); free(hostmask); return MOD_CONT; } } } if (!ircd->vident) { notice_lang(s_HostServ, u, HOST_NO_VIDENT); free(vIdent); free(rawhostmask); free(hostmask); return MOD_CONT; } } if (strlen(rawhostmask) < HOSTMAX) snprintf(hostmask, HOSTMAX, "%s", rawhostmask); else { notice_lang(s_HostServ, u, HOST_SET_TOOLONG, HOSTMAX); if (vIdent) { free(vIdent); free(rawhostmask); } free(hostmask); return MOD_CONT; } if (!isValidHost(hostmask, 3)) { notice_lang(s_HostServ, u, HOST_SET_ERROR); if (vIdent) { free(vIdent); free(rawhostmask); } free(hostmask); return MOD_CONT; } tmp_time = time(NULL); if ((na = findnick(nick))) { if (na->status & NS_VERBOTEN) { notice_lang(s_HostServ, u, NICK_X_FORBIDDEN, nick); if (vIdent) { free(vIdent); free(rawhostmask); } free(hostmask); return MOD_CONT; } if (vIdent && ircd->vident) { alog("vHost for user \002%s\002 set to \002%s@%s\002 by oper \002%s\002", nick, vIdent, hostmask, u->nick); } else { alog("vHost for user \002%s\002 set to \002%s\002 by oper \002%s\002", nick, hostmask, u->nick); } addHostCore(nick, vIdent, hostmask, u->nick, tmp_time); if (vIdent) { notice_lang(s_HostServ, u, HOST_IDENT_SET, nick, vIdent, hostmask); } else { notice_lang(s_HostServ, u, HOST_SET, nick, hostmask); } } else { notice_lang(s_HostServ, u, HOST_NOREG, nick); } free(hostmask); if (vIdent) { free(vIdent); free(rawhostmask); } return MOD_CONT; }
static int hs_do_request(User * u) { char *cur_buffer; char *nick; char *rawhostmask; char hostmask[HOSTMAX]; NickAlias *na; int32 tmp_time; char *s; char *vIdent = NULL; time_t now = time(NULL); cur_buffer = moduleGetLastBuffer(); nick = u->nick; rawhostmask = myStrGetToken(cur_buffer, ' ', 0); if (!nick || !rawhostmask) { if (rawhostmask) free(rawhostmask); moduleNoticeLang(s_HostServ, u, LNG_REQUEST_SYNTAX); return MOD_CONT; } vIdent = myStrGetOnlyToken(rawhostmask, '@', 0); /* Get the first substring, @ as delimiter */ if (vIdent) { rawhostmask = myStrGetTokenRemainder(rawhostmask, '@', 1); /* get the remaining string */ if (!rawhostmask) { moduleNoticeLang(s_HostServ, u, LNG_REQUEST_SYNTAX); free(vIdent); return MOD_CONT; } if (strlen(vIdent) > USERMAX - 1) { notice_lang(s_HostServ, u, HOST_SET_IDENTTOOLONG, USERMAX); free(vIdent); free(rawhostmask); return MOD_CONT; } else { for (s = vIdent; *s; s++) { if (!my_isvalidchar(*s)) { notice_lang(s_HostServ, u, HOST_SET_IDENT_ERROR); free(vIdent); free(rawhostmask); return MOD_CONT; } } } if (!ircd->vident) { notice_lang(s_HostServ, u, HOST_NO_VIDENT); free(vIdent); free(rawhostmask); return MOD_CONT; } } if (strlen(rawhostmask) < HOSTMAX) { snprintf(hostmask, HOSTMAX, "%s", rawhostmask); } else { notice_lang(s_HostServ, u, HOST_SET_TOOLONG, HOSTMAX); if (vIdent) free(vIdent); free(rawhostmask); return MOD_CONT; } if (!isValidHost(hostmask, 3)) { notice_lang(s_HostServ, u, HOST_SET_ERROR); if (vIdent) free(vIdent); free(rawhostmask); return MOD_CONT; } tmp_time = time(NULL); if ((na = findnick(nick))) { if (HSRequestMemoOper || HSRequestMemoSetters) { if (MSSendDelay > 0 && u && u->lastmemosend + MSSendDelay > now) { moduleNoticeLang(s_HostServ, u, LNG_REQUEST_WAIT, MSSendDelay); u->lastmemosend = now; if (vIdent) free(vIdent); free(rawhostmask); return MOD_CONT; } } my_add_host_request(nick, vIdent, hostmask, u->nick, tmp_time); moduleNoticeLang(s_HostServ, u, LNG_REQUESTED); req_send_memos(u, hostmask); alog("New vHost Requested by %s", nick); } else { notice_lang(s_HostServ, u, HOST_NOREG, nick); } if (vIdent) free(vIdent); free(rawhostmask); 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 /hs list command. * @param u The user who issued the command * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing. **/ int listOut(User * u) { char *key = strtok(NULL, ""); struct tm *tm; char buf[BUFSIZE]; int counter = 1; int from = 0, to = 0; char *tmp = NULL; char *s = NULL; int display_counter = 0; HostCore *head = NULL; HostCore *current; head = hostCoreListHead(); current = head; if (current == NULL) notice_lang(s_HostServ, u, HOST_EMPTY); else { /** * Do a check for a range here, then in the next loop * we'll only display what has been requested.. **/ if (key) { if (key[0] == '#') { tmp = myStrGetOnlyToken((key + 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(key, '-', 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); key = NULL; } } while (current != NULL) { if (key) { if (((match_wild_nocase(key, current->nick)) || (match_wild_nocase(key, current->vHost))) && (display_counter < NSListMax)) { display_counter++; tm = localtime(¤t->time); strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm); if (current->vIdent) { notice_lang(s_HostServ, u, HOST_IDENT_ENTRY, counter, current->nick, current->vIdent, current->vHost, current->creator, buf); } else { notice_lang(s_HostServ, u, HOST_ENTRY, counter, current->nick, current->vHost, current->creator, buf); } } } else { /** * List the host if its in the display range, and not more * than NSListMax records have been displayed... **/ if ((((counter >= from) && (counter <= to)) || ((from == 0) && (to == 0))) && (display_counter < NSListMax)) { display_counter++; tm = localtime(¤t->time); strftime_lang(buf, sizeof(buf), u, STRFTIME_DATE_TIME_FORMAT, tm); if (current->vIdent) { notice_lang(s_HostServ, u, HOST_IDENT_ENTRY, counter, current->nick, current->vIdent, current->vHost, current->creator, buf); } else { notice_lang(s_HostServ, u, HOST_ENTRY, counter, current->nick, current->vHost, current->creator, buf); } } } counter++; current = current->next; } if (key) { notice_lang(s_HostServ, u, HOST_LIST_KEY_FOOTER, key, display_counter); } else { if (from != 0) { notice_lang(s_HostServ, u, HOST_LIST_RANGE_FOOTER, from, to); } else { notice_lang(s_HostServ, u, HOST_LIST_FOOTER, display_counter); } } } return MOD_CONT; }
static int do_exclude(User * u, int ac, char **av) { Exclude *e; char *tmp = NULL; char *s = NULL; int count = 0, from = 0, to = 0; int nnicks = 0, i; int disp = 1; char *name; char *ch = NULL; User *u2; if (ac < 1) { notice_lang(s_StatServ, u, STAT_EXCLUDE_SYNTAX); return MOD_CONT; } if (!stricmp(av[0], "ADD")) { if (ac < 2) { notice_lang(s_StatServ, u, STAT_EXCLUDE_SYNTAX); return MOD_CONT; } if (strlen(av[1]) > NICKMAX) { notice(s_StatServ, u->nick, "Invalid nick length"); return MOD_CONT; } if (isdigit(av[1][0]) || av[1][0] == '-') { notice(s_StatServ, u->nick, "Invalid nick"); return MOD_CONT; } for (ch = av[1]; *ch && (ch - av[1]) < NICKMAX; ch++) { if (!isvalidnick(*ch)) { notice(s_StatServ, u->nick, "Invalid nick"); return MOD_CONT; } } e = find_exclude(av[1], NULL); if (!e) { make_exclude(av[1]); notice_lang(s_StatServ, u, STAT_EXCLUDE_ADDED, av[1]); name = rdb_escape(av[1]); u2 = user_find(av[1]); rdb_query(QUERY_LOW, "DELETE FROM %s WHERE uname=\'%s\'", UStatsTable, u2 ? u2->sgroup : name); rdb_query(QUERY_LOW, "UPDATE `%s` SET `ignore`=\'Y\' WHERE `uname`=\'%s\'", AliasesTable, u2 ? u2->sgroup : name); free(name); } else { notice_lang(s_StatServ, u, STAT_EXCLUDE_ALREADY, av[1]); } } else if (!stricmp(av[0], "DEL")) { if (ac < 2) { notice_lang(s_StatServ, u, STAT_EXCLUDE_SYNTAX); return MOD_CONT; } e = find_exclude(av[1], NULL); if (e) { del_exclude(e); u->cstats = 0; notice_lang(s_StatServ, u, STAT_EXCLUDE_DELETED, av[1]); name = rdb_escape(av[1]); u2 = user_find(av[1]); rdb_query(QUERY_LOW, "UPDATE `%s` SET `ignore`=\'N\' WHERE `uname`=\'%s\'", AliasesTable, u2 ? u2->sgroup : name); for (i = 0; i < 4; i++) { rdb_query (QUERY_LOW, "INSERT IGNORE INTO %s SET uname=\'%s\', chan=\'global\', type=%i;", UStatsTable, u2 ? u2->sgroup : name, i); } free(name); } else { notice_lang(s_StatServ, u, STAT_EXCLUDE_NOT_FOUND, av[1]); } } else if (!stricmp(av[0], "LIST")) { if (ac >= 2) { if (*av[1] == '#') { tmp = myStrGetOnlyToken((av[1] + 1), '-', 0); /* Read FROM out */ if (!tmp) { return MOD_CONT; } for (s = tmp; *s; s++) { if (!isdigit(*s)) { free(tmp); return MOD_CONT; } } from = atoi(tmp); free(tmp); tmp = myStrGetTokenRemainder(av[1], '-', 1); /* Read TO out */ if (!tmp) { return MOD_CONT; } for (s = tmp; *s; s++) { if (!isdigit(*s)) { free(tmp); return MOD_CONT; } } to = atoi(tmp); free(tmp); } } notice_lang(s_StatServ, u, STAT_EXCLUDE_LIST_HEADER); for (i = 0; i < 1024; i++) { for (e = exlists[i]; e; e = e->next) { if ((count + 1 >= from) && (count + 1 <= to)) { notice(s_StatServ, u->nick, "%d %s", disp++, e->name); } else if (((from == 0) && (to == 0)) && (++nnicks <= 50)) { notice(s_StatServ, u->nick, "%d %s", disp++, e->name); } count++; } } } else { notice_lang(s_StatServ, u, STAT_EXCLUDE_SYNTAX); return MOD_CONT; } return MOD_CONT; }