X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/fc55e75707a416de48b94a17d6c664b35ccc8615..a3da4b66b05fa77dec803e29b525c464cbd5d37c:/src/opserv.c?ds=sidebyside diff --git a/src/opserv.c b/src/opserv.c index a5eac78..0f24c5a 100644 --- a/src/opserv.c +++ b/src/opserv.c @@ -182,12 +182,14 @@ static const struct message_entry msgtab[] = { { "OSMSG_KICKALL_DONE", "I have cleared out %s." }, { "OSMSG_LEAVING", "Leaving $b%s$b." }, { "OSMSG_MARK_INVALID", "Sorry, marks must contain only letters, numbers, and dashes ('-')." }, + { "OSMSG_MARK_NOTMARKED", "Action not mark but mark supplied. (Did you mean marked?)" }, { "OSMSG_MODE_SET", "I have set the modes for $b%s$b." }, { "OSMSG_OP_DONE", "Opped the requested lusers." }, { "OSMSG_OPALL_DONE", "Opped everyone on $b%s$b." }, { "OSMSG_HOP_DONE", "Halfopped the requested lusers." }, { "OSMSG_HOPALL_DONE", "Halfopped everyone on $b%s$b." }, { "OMSG_BAD_SVSNICK", "$b%s$b is an invalid nickname." }, + { "OSMSG_BAD_SVSCMDTARGET", "$b%s$b is an invalid target for %s." }, { "OSMSG_WHOIS_IDENT", "%s (%s@%s) from %d.%d.%d.%d" }, { "OSMSG_WHOIS_NICK", "Nick : %s" }, @@ -215,9 +217,10 @@ static const struct message_entry msgtab[] = { { "OSMSG_WHOIS_PRIVS", "IRCd Privs : %s" }, { "OSMSG_WHOIS_CHANNELS", "Channels : %s" }, { "OSMSG_WHOIS_HIDECHANS", "Channel list omitted for your sanity." }, - { "OSMSG_WHOIS_VERSION", "Version : %s" }, - { "OSMSG_WHOIS_SSLFP", "SSL f/print : %s" }, - { "OSMSG_WHOIS_MARK", "Mark : %s" }, + { "OSMSG_WHOIS_VERSION", "Version : %s" }, + { "OSMSG_WHOIS_SSLFP", "Cert f/print : %s" }, + { "OSMSG_WHOIS_MARK", "Mark : %s" }, + { "OSMSG_WHOIS_MARKS", "Marks : %s" }, { "OSMSG_WHOIS_NO_NOTICE", "No_notices : %s" }, { "OSMSG_UNBAN_DONE", "Ban(s) removed from channel %s." }, { "OSMSG_CHANNEL_VOICED", "All users on %s voiced." }, @@ -571,7 +574,7 @@ struct discrim_and_source { unsigned int disp_limit; }; -static discrim_t opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int argc, char *argv[], int allow_channel); +static discrim_t opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int argc, char *argv[], int allow_channel, const char *action); static unsigned int opserv_discrim_search(discrim_t discrim, discrim_search_func dsf, void *data); static int gag_helper_func(struct userNode *match, void *extra); static int ungag_helper_func(struct userNode *match, void *extra); @@ -583,6 +586,7 @@ typedef enum { REACT_GLINE, REACT_TRACK, REACT_SHUN, + REACT_TEMPSHUN, REACT_SVSJOIN, REACT_SVSPART, REACT_VERSION, @@ -1528,6 +1532,12 @@ opserv_shun(struct userNode *target, char *src_handle, char *reason, unsigned lo return shun_add(src_handle, mask, duration, reason, now, 1); } +static void +opserv_tempshun(struct userNode *target, char *src_handle, char *reason) +{ + irc_tempshun(opserv, target, 0, reason); +} + static MODCMD_FUNC(cmd_sblock) { struct userNode *target; @@ -1584,7 +1594,7 @@ static MODCMD_FUNC(cmd_shun) struct shun *shun; reason = unsplit_string(argv+3, argc-3, NULL); - if (!is_shun(argv[1]) && !IsChannelName(argv[1]) && (argv[1][0] != '&')) { + if (!is_shun(argv[1])) { reply("MSG_INVALID_SHUN", argv[1]); return 0; } @@ -1723,6 +1733,11 @@ static MODCMD_FUNC(cmd_svsjoin) return 0; } + if (IsLocal(target)) { + reply("OSMSG_BAD_SVSCMDTARGET", argv[1], "SVSJOIN"); + return 0; + } + if (!(channel = GetChannel(argv[2]))) { channel = AddChannel(argv[2], now, NULL, NULL, NULL); } @@ -1744,6 +1759,12 @@ static MODCMD_FUNC(cmd_svsnick) reply("MSG_NICK_UNKNOWN", argv[1]); return 0; } + + if (IsLocal(target)) { + reply("OSMSG_BAD_SVSCMDTARGET", argv[1], "SVSNICK"); + return 0; + } + if(!is_valid_nick(argv[2])) { reply("OMSG_BAD_SVSNICK", argv[2]); return 0; @@ -1969,6 +1990,11 @@ static MODCMD_FUNC(cmd_svspart) return 0; } + if (IsLocal(target)) { + reply("OSMSG_BAD_SVSCMDTARGET", argv[1], "SVSPART"); + return 0; + } + if (!GetUserMode(target_channel, target)) { reply("OSMSG_NOT_ON_CHANNEL", cmd->parent->bot->nick, target_channel->name); return 0; @@ -2192,6 +2218,28 @@ static MODCMD_FUNC(cmd_whois) if(target->mark) { reply("OSMSG_WHOIS_MARK", target->mark); } + if(target->marks) { + char markbuf[MAXLEN] = ""; + unsigned int ii = 0; + + string_list_sort(user->marks); + + for (ii=0; iimarks->used; ii++) + { + if (markbuf[0] && strlen(markbuf) + strlen(user->marks->list[ii]) + 4 > 70) { + reply("OSMSG_WHOIS_MARKS", markbuf); + memset(&markbuf, 0, MAXLEN); + } + + if (markbuf[0]) + strcat(markbuf, ", "); + strcat(markbuf, user->marks->list[ii]); + } + + if (markbuf[0]) + reply("OSMSG_WHOIS_MARKS", markbuf); + } + reply("OSMSG_WHOIS_NO_NOTICE", target->no_notice ? "YES":"NO"); if (target->modes) { @@ -2546,6 +2594,7 @@ static MODCMD_FUNC(cmd_stats_alerts) { case REACT_GLINE: reaction = "gline"; break; case REACT_TRACK: reaction = "track"; break; case REACT_SHUN: reaction = "shun"; break; + case REACT_TEMPSHUN: reaction = "tempshun"; break; case REACT_SVSJOIN: reaction = "svsjoin"; break; case REACT_SVSPART: reaction = "svspart"; break; case REACT_VERSION: reaction = "version"; break; @@ -4773,7 +4822,7 @@ add_gag_helper(const char *key, void *data, UNUSED_ARG(void *extra)) } static struct opserv_user_alert * -opserv_add_user_alert(struct userNode *req, const char *name, opserv_alert_reaction reaction, const char *text_discrim, int last, int expire) +opserv_add_user_alert(struct userNode *req, const char *name, opserv_alert_reaction reaction, const char *text_discrim, int last, int expire, const char *action) { unsigned int wordc; char *wordv[MAXNUMPARAMS], *discrim_copy; @@ -4790,7 +4839,7 @@ opserv_add_user_alert(struct userNode *req, const char *name, opserv_alert_react alert->last = last; discrim_copy = strdup(text_discrim); /* save a copy of the discrim */ wordc = split_line(discrim_copy, false, ArrayLength(wordv), wordv); - alert->discrim = opserv_discrim_create(req, opserv, wordc, wordv, 0); + alert->discrim = opserv_discrim_create(req, opserv, wordc, wordv, 0, action); alert->expire = expire; /* Check for missing required criteria or broken records */ if (!alert->discrim || (reaction==REACT_SVSJOIN && !alert->discrim->chantarget) || @@ -4878,6 +4927,8 @@ add_user_alert(const char *key, void *data, UNUSED_ARG(void *extra)) reaction = REACT_TRACK; else if (!irccasecmp(react, "shun")) reaction = REACT_SHUN; + else if (!irccasecmp(react, "tempshun")) + reaction = REACT_TEMPSHUN; else if (!irccasecmp(react, "svsjoin")) reaction = REACT_SVSJOIN; else if (!irccasecmp(react, "svspart")) @@ -4894,7 +4945,7 @@ add_user_alert(const char *key, void *data, UNUSED_ARG(void *extra)) log_module(OS_LOG, LOG_ERROR, "Invalid reaction %s for alert %s.", react, key); return 0; } - alert = opserv_add_user_alert(opserv, key, reaction, discrim, last, expire); + alert = opserv_add_user_alert(opserv, key, reaction, discrim, last, expire, react); if (!alert) { log_module(OS_LOG, LOG_ERROR, "Unable to create alert %s from database.", key); return 0; @@ -5173,6 +5224,7 @@ opserv_saxdb_write(struct saxdb_context *ctx) case REACT_GLINE: reaction = "gline"; break; case REACT_TRACK: reaction = "track"; break; case REACT_SHUN: reaction = "shun"; break; + case REACT_TEMPSHUN: reaction = "tempshun"; break; case REACT_SVSJOIN: reaction = "svsjoin"; break; case REACT_SVSPART: reaction = "svspart"; break; case REACT_VERSION: reaction = "version"; break; @@ -5280,7 +5332,7 @@ static MODCMD_FUNC(cmd_settime) } static discrim_t -opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int argc, char *argv[], int allow_channel) +opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int argc, char *argv[], int allow_channel, const char *action) { unsigned int i, j; discrim_t discrim; @@ -5388,6 +5440,10 @@ opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int goto fail; } } else if (irccasecmp(argv[i], "mark") == 0) { + if (irccasecmp(action, "mark")) { + send_message(user, bot, "OSMSG_MARK_NOTMARKED"); + goto fail; + } if(!is_valid_mark(argv[i+1])) { send_message(user, bot, "OSMSG_MARK_INVALID"); goto fail; @@ -5675,6 +5731,20 @@ discrim_match(discrim_t discrim, struct userNode *user) { unsigned int level, i; char *scmp=NULL, *dcmp=NULL; + int markmatched = 0; + + if (discrim->mask_mark) + { + unsigned int ii = 0; + + if (user->mark && match_ircglob(user->mark, discrim->mask_mark)) + markmatched = 1; + + if (user->marks) + for (ii=0; iimarks->used; ii++) + if (match_ircglob(user->marks->list[ii], discrim->mask_mark)) + markmatched = 1; + } if ((user->timestamp < discrim->min_ts) || (user->timestamp > discrim->max_ts) @@ -5685,7 +5755,7 @@ discrim_match(discrim_t discrim, struct userNode *user) || (discrim->info_space == 0 && user->info[0] == ' ') || (discrim->info_space == 1 && user->info[0] != ' ') || (discrim->server && !match_ircglob(user->uplink->name, discrim->server)) - || (discrim->mask_mark && (!user->mark || !match_ircglob(user->mark, discrim->mask_mark))) + || (discrim->mask_mark && !markmatched) || (discrim->accountmask && (!user->handle_info || !match_ircglob(user->handle_info->handle, discrim->accountmask))) || (discrim->ip_mask_bits && !irc_check_mask(&user->ip, &discrim->ip_mask, discrim->ip_mask_bits)) ) @@ -5743,52 +5813,80 @@ discrim_match(discrim_t discrim, struct userNode *user) if (discrim->modes) { unsigned int ii, matches = 0; + unsigned int negate = 0; for (ii = 0; ii < strlen(discrim->modes); ii++) { switch(discrim->modes[ii]) { + case '+': + negate = 0; + matches++; + break; + case '-': + negate = 1; + matches++; + break; case 'O': - if(IsOper(user)) matches++; + if(IsOper(user) != 0 != negate) matches++; break; case 'o': - if(IsOper(user)) matches++; + if(IsOper(user) != 0 != negate) matches++; break; case 'i': - if(IsInvisible(user)) matches++; + if(IsInvisible(user) != 0 != negate) matches++; break; case 'w': - if(IsWallOp(user)) matches++; + if(IsWallOp(user) != 0 != negate) matches++; break; case 'd': - if(IsDeaf(user)) matches++; + if(IsDeaf(user) != 0 != negate) matches++; break; case 'k': - if(IsService(user)) matches++; + if(IsService(user) != 0 != negate) matches++; break; case 'g': - if(IsGlobal(user)) matches++; + if(IsGlobal(user) != 0 != negate) matches++; break; case 'h': - if(IsSetHost(user)) matches++; + if(IsSetHost(user) != 0 != negate) matches++; break; case 'B': - if(IsBotM(user)) matches++; + if(IsBotM(user) != 0 != negate) matches++; break; + case 'p': case 'n': - if(IsHideChans(user)) matches++; + if(IsHideChans(user) != 0 != negate) matches++; break; case 'I': - if(IsHideIdle(user)) matches++; + if(IsHideIdle(user) != 0 != negate) matches++; break; case 'X': - if(IsXtraOp(user)) matches++; + if(IsXtraOp(user) != 0 != negate) matches++; break; case 'x': - if(IsHiddenHost(user)) matches++; + if(IsHiddenHost(user) != 0 != negate) matches++; break; case 'a': - if(IsAdmin(user)) matches++; + if(IsAdmin(user) != 0 != negate) matches++; break; case 'z': - if(IsSSL(user)) matches++; + if(IsSSL(user) != 0 != negate) matches++; + break; + case 'D': + if(IsPrivDeaf(user) != 0 != negate) matches++; + break; + case 'R': + if(IsAccountOnly(user) != 0 != negate) matches++; + break; + case 'W': + if(IsWhoisNotice(user) != 0 != negate) matches++; + break; + case 'H': + if(IsHideOper(user) != 0 != negate) matches++; + break; + case 'L': + if(IsHideOper(user) != 0 != negate) matches++; + break; + case 'q': + if(IsCommonChansOnly(user) != 0 != negate) matches++; break; } } @@ -5988,6 +6086,18 @@ trace_shun_func(struct userNode *match, void *extra) return 0; } +static int +trace_tempshun_func(struct userNode *match, void *extra) +{ + struct discrim_and_source *das = extra; + + if (is_oper_victim(das->source, match, das->discrim->match_opers, 1) && is_trust_victim(match, das->discrim->match_trusted)) { + opserv_tempshun(match, das->source->handle_info->handle, das->discrim->reason); + } + + return 0; +} + static int trace_kill_func(struct userNode *match, void *extra) { @@ -6225,6 +6335,8 @@ static MODCMD_FUNC(cmd_trace) action = trace_gline_func; else if (!irccasecmp(argv[1], "shun")) action = trace_shun_func; + else if (!irccasecmp(argv[1], "tempshun")) + action = trace_tempshun_func; else if (!irccasecmp(argv[1], "kill")) action = trace_kill_func; else if (!irccasecmp(argv[1], "gag")) @@ -6250,7 +6362,7 @@ static MODCMD_FUNC(cmd_trace) das.dict = NULL; das.source = user; das.destination = cmd->parent->bot; - das.discrim = opserv_discrim_create(user, cmd->parent->bot, argc-2, argv+2, 1); + das.discrim = opserv_discrim_create(user, cmd->parent->bot, argc-2, argv+2, 1, argv[1]); if (!das.discrim) return 0; @@ -6788,6 +6900,9 @@ alert_check_user(const char *key, void *data, void *extra) case REACT_SHUN: opserv_shun(user, alert->owner, alert->discrim->reason, alert->discrim->duration); return 1; + case REACT_TEMPSHUN: + opserv_tempshun(user, alert->owner, alert->discrim->reason); + return 1; case REACT_SVSJOIN: opserv_svsjoin(user, alert->owner, alert->discrim->reason, alert->discrim->chantarget, alert->discrim->checkrestrictions); break; @@ -7001,6 +7116,8 @@ static MODCMD_FUNC(cmd_addalert) #endif } else if (!irccasecmp(argv[2], "shun")) reaction = REACT_SHUN; + else if(!irccasecmp(argv[2], "tempshun")) + reaction = REACT_TEMPSHUN; else if(!irccasecmp(argv[2], "svsjoin")) reaction = REACT_SVSJOIN; else if(!irccasecmp(argv[2], "svspart")) @@ -7022,7 +7139,7 @@ static MODCMD_FUNC(cmd_addalert) expire = now + ParseInterval(argv[4]); if (!svccmd_can_invoke(user, opserv_service->bot, subcmd, channel, SVCCMD_NOISY) - || !opserv_add_user_alert(user, name, reaction, unsplit_string(argv + (expire ? 5 : 3), argc - (expire ? 5 : 3), NULL), 0, expire)) { + || !opserv_add_user_alert(user, name, reaction, unsplit_string(argv + (expire ? 5 : 3), argc - (expire ? 5 : 3), NULL), 0, expire, argv[2])) { reply("OSMSG_ALERT_ADD_FAILED"); return 0; } @@ -7302,6 +7419,7 @@ init_opserv(const char *nick) opserv_define_func("ADDALERT SILENT", NULL, 900, 0, 0); opserv_define_func("ADDALERT GLINE", NULL, 900, 0, 0); opserv_define_func("ADDALERT SHUN", NULL, 900, 0, 0); + opserv_define_func("ADDALERT TEMPSHUN", NULL, 900, 0, 0); opserv_define_func("ADDALERT TRACK", NULL, 900, 0, 0); opserv_define_func("ADDALERT KILL", NULL, 900, 0, 0); opserv_define_func("ADDALERT SVSJOIN", NULL, 999, 0, 0); @@ -7415,6 +7533,7 @@ init_opserv(const char *nick) opserv_define_func("TRACE DOMAINS", NULL, 0, 0, 0); opserv_define_func("TRACE GLINE", NULL, 600, 0, 0); opserv_define_func("TRACE SHUN", NULL, 600, 0, 0); + opserv_define_func("TRACE TEMPSHUN", NULL, 600, 0, 0); opserv_define_func("TRACE GAG", NULL, 600, 0, 0); opserv_define_func("TRACE KILL", NULL, 600, 0, 0); opserv_define_func("TRACE VERSION", NULL, 999, 0, 0);