From d6e7d684d688494848fda2ee86adc5d50c3bce10 Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Fri, 27 Oct 2006 00:21:32 +0000 Subject: [PATCH] Pull ThiefMaster's patch-3..5. Patches applied: * thiefmaster@gamesurge.net--2006/srvx--devo--1.3--base-0 tag of srvx@srvx.net--2006/srvx--devo--1.3--patch-58 * thiefmaster@gamesurge.net--2006/srvx--devo--1.3--patch-3 Implement complete remote whois. * thiefmaster@gamesurge.net--2006/srvx--devo--1.3--patch-4 Improve override logging and ignore godmode in !trim. * thiefmaster@gamesurge.net--2006/srvx--devo--1.3--patch-5 Announce ounregisters to staff via Global. git-archimport-id: srvx@srvx.net--2006/srvx--devo--1.3--patch-63 --- ChangeLog | 32 ++++++++++++++++++++ src/chanserv.c | 78 ++++++++++++++++++++++++++++++++++++------------- src/hash.h | 4 ++- src/modcmd.c | 8 +++-- src/modcmd.h | 6 ++++ src/nickserv.c | 5 +++- src/opserv.c | 1 + src/proto-p10.c | 73 +++++++++++++++++++++++++++++++++++++++------ src/proto.h | 4 +++ 9 files changed, 177 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2b0b2ab..bba3689 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,38 @@ # arch-tag: automatic-ChangeLog--srvx@srvx.net--2006/srvx--devo--1.3 # +2006-10-27 00:21:32 GMT Michael Poole patch-63 + + Summary: + Pull ThiefMaster's patch-3..5. + Revision: + srvx--devo--1.3--patch-63 + + Patches applied: + + * thiefmaster@gamesurge.net--2006/srvx--devo--1.3--base-0 + tag of srvx@srvx.net--2006/srvx--devo--1.3--patch-58 + + * thiefmaster@gamesurge.net--2006/srvx--devo--1.3--patch-3 + Implement complete remote whois. + + * thiefmaster@gamesurge.net--2006/srvx--devo--1.3--patch-4 + Improve override logging and ignore godmode in !trim. + + * thiefmaster@gamesurge.net--2006/srvx--devo--1.3--patch-5 + Announce ounregisters to staff via Global. + + modified files: + ChangeLog src/chanserv.c src/hash.h src/modcmd.c src/modcmd.h + src/nickserv.c src/opserv.c src/proto-p10.c src/proto.h + + new patches: + thiefmaster@gamesurge.net--2006/srvx--devo--1.3--base-0 + thiefmaster@gamesurge.net--2006/srvx--devo--1.3--patch-3 + thiefmaster@gamesurge.net--2006/srvx--devo--1.3--patch-4 + thiefmaster@gamesurge.net--2006/srvx--devo--1.3--patch-5 + + 2006-10-26 23:44:10 GMT Michael Poole patch-62 Summary: diff --git a/src/chanserv.c b/src/chanserv.c index d2ab69a..9ee271b 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -2213,9 +2213,9 @@ static CHANSERV_FUNC(cmd_opchan) static CHANSERV_FUNC(cmd_adduser) { struct userData *actee; - struct userData *actor; + struct userData *actor, *real_actor; struct handle_info *handle; - unsigned short access; + unsigned short access, override = 0; REQUIRE_PARAMS(3); @@ -2233,16 +2233,22 @@ static CHANSERV_FUNC(cmd_adduser) } actor = GetChannelUser(channel->channel_info, user->handle_info); + real_actor = GetChannelAccess(channel->channel_info, user->handle_info); + if(actor->access <= access) { reply("CSMSG_NO_BUMP_ACCESS"); return 0; } + // Trying to add someone with equal/more access + if (!real_actor || real_actor->access <= access) + override = CMD_LOG_OVERRIDE; + if(!(handle = modcmd_get_handle_info(user, argv[1]))) return 0; - if((actee = GetTrueChannelAccess(channel->channel_info, handle))) + if((actee = GetChannelAccess(channel->channel_info, handle))) { reply("CSMSG_USER_EXISTS", handle->handle, channel->name, actee->access); return 0; @@ -2251,20 +2257,21 @@ static CHANSERV_FUNC(cmd_adduser) actee = add_channel_user(channel->channel_info, handle, access, 0, NULL); scan_user_presence(actee, NULL); reply("CSMSG_ADDED_USER", handle->handle, channel->name, access); - return 1; + return 1 | override; } static CHANSERV_FUNC(cmd_clvl) { struct handle_info *handle; struct userData *victim; - struct userData *actor; - unsigned short new_access; + struct userData *actor, *real_actor; + unsigned short new_access, override = 0; int privileged = IsHelping(user) && ((user->handle_info->opserv_level >= chanserv_conf.nodelete_level) || !IsProtected(channel->channel_info)); REQUIRE_PARAMS(3); actor = GetChannelUser(channel->channel_info, user->handle_info); + real_actor = GetChannelAccess(channel->channel_info, user->handle_info); if(!(handle = modcmd_get_handle_info(user, argv[1]))) return 0; @@ -2301,22 +2308,32 @@ static CHANSERV_FUNC(cmd_clvl) return 0; } + // Trying to clvl a equal/higher user + if(!real_actor || (real_actor->access <= victim->access && handle != user->handle_info)) + override = CMD_LOG_OVERRIDE; + // Trying to clvl someone to equal/higher access + if(!real_actor || new_access >= real_actor->access) + override = CMD_LOG_OVERRIDE; + // Helpers clvling themselves get caught by the "clvl someone to equal/higher access" check. + // If they lower their own access it's not a big problem. + victim->access = new_access; reply("CSMSG_CHANGED_ACCESS", handle->handle, new_access, channel->name); - return 1; + return 1 | override; } static CHANSERV_FUNC(cmd_deluser) { struct handle_info *handle; struct userData *victim; - struct userData *actor; - unsigned short access; + struct userData *actor, *real_actor; + unsigned short access, override = 0; char *chan_name; REQUIRE_PARAMS(2); actor = GetChannelUser(channel->channel_info, user->handle_info); + real_actor = GetChannelAccess(channel->channel_info, user->handle_info); if(!(handle = modcmd_get_handle_info(user, argv[argc-1]))) return 0; @@ -2352,19 +2369,25 @@ static CHANSERV_FUNC(cmd_deluser) return 0; } + // If people delete themselves it is an override, but they could've used deleteme so we don't log it as an override + if(!real_actor || (real_actor->access <= victim->access && real_actor != victim)) + override = CMD_LOG_OVERRIDE; + chan_name = strdup(channel->name); del_channel_user(victim, 1); reply("CSMSG_DELETED_USER", handle->handle, access, chan_name); free(chan_name); - return 1; + return 1 | override; } static int cmd_mdel_user(struct userNode *user, struct chanNode *channel, unsigned short min_access, unsigned short max_access, char *mask, struct svccmd *cmd) { - struct userData *actor, *uData, *next; + struct userData *actor, *real_actor, *uData, *next; + unsigned int override = 0; actor = GetChannelUser(channel->channel_info, user->handle_info); + real_actor = GetChannelAccess(channel->channel_info, user->handle_info); if(min_access > max_access) { @@ -2378,6 +2401,9 @@ cmd_mdel_user(struct userNode *user, struct chanNode *channel, unsigned short mi return 0; } + if(!real_actor || real_actor->access <= max_access) + override = CMD_LOG_OVERRIDE; + for(uData = channel->channel_info->users; uData; uData = next) { next = uData->next; @@ -2389,7 +2415,7 @@ cmd_mdel_user(struct userNode *user, struct chanNode *channel, unsigned short mi } reply("CSMSG_DELETED_USERS", mask, min_access, max_access, channel->name); - return 1; + return 1 | override; } static CHANSERV_FUNC(cmd_mdelowner) @@ -2451,14 +2477,14 @@ cmd_trim_users(struct userNode *user, struct chanNode *channel, unsigned short m unsigned int count; time_t limit; - actor = GetChannelUser(channel->channel_info, user->handle_info); + actor = GetChannelAccess(channel->channel_info, user->handle_info); if(min_access > max_access) { send_message(user, chanserv, "CSMSG_BAD_RANGE", min_access, max_access); return 0; } - if((actor->access <= max_access) && !IsHelping(user)) + if(!actor || actor->access <= max_access) { send_message(user, chanserv, "CSMSG_NO_ACCESS"); return 0; @@ -4128,10 +4154,12 @@ static CHANSERV_FUNC(cmd_peek) static MODCMD_FUNC(cmd_wipeinfo) { struct handle_info *victim; - struct userData *ud, *actor; + struct userData *ud, *actor, *real_actor; + unsigned int override = 0; REQUIRE_PARAMS(2); actor = GetChannelUser(channel->channel_info, user->handle_info); + real_actor = GetChannelAccess(channel->channel_info, user->handle_info); if(!(victim = modcmd_get_handle_info(user, argv[1]))) return 0; if(!(ud = GetTrueChannelAccess(channel->channel_info, victim))) @@ -4144,11 +4172,13 @@ static MODCMD_FUNC(cmd_wipeinfo) reply("MSG_USER_OUTRANKED", victim->handle); return 0; } + if((ud->access >= real_actor->access) && (ud != real_actor)) + override = CMD_LOG_OVERRIDE; if(ud->info) free(ud->info); ud->info = NULL; reply("CSMSG_WIPED_INFO_LINE", argv[1], channel->name); - return 1; + return 1 | override; } static CHANSERV_FUNC(cmd_resync) @@ -5597,11 +5627,13 @@ static CHANSERV_FUNC(cmd_giveownership) static CHANSERV_FUNC(cmd_suspend) { struct handle_info *hi; - struct userData *self, *target; + struct userData *self, *real_self, *target; + unsigned int override = 0; REQUIRE_PARAMS(2); if(!(hi = modcmd_get_handle_info(user, argv[1]))) return 0; self = GetChannelUser(channel->channel_info, user->handle_info); + real_self = GetChannelAccess(channel->channel_info, user->handle_info); if(!(target = GetTrueChannelAccess(channel->channel_info, hi))) { reply("CSMSG_NO_CHAN_USER", hi->handle, channel->name); @@ -5622,19 +5654,23 @@ static CHANSERV_FUNC(cmd_suspend) target->present = 0; target->seen = now; } + if(!real_self || target->access >= real_self->access) + override = CMD_LOG_OVERRIDE; target->flags |= USER_SUSPENDED; reply("CSMSG_USER_SUSPENDED", hi->handle, channel->name); - return 1; + return 1 | override; } static CHANSERV_FUNC(cmd_unsuspend) { struct handle_info *hi; - struct userData *self, *target; + struct userData *self, *real_self, *target; + unsigned int override = 0; REQUIRE_PARAMS(2); if(!(hi = modcmd_get_handle_info(user, argv[1]))) return 0; self = GetChannelUser(channel->channel_info, user->handle_info); + real_self = GetChannelAccess(channel->channel_info, user->handle_info); if(!(target = GetTrueChannelAccess(channel->channel_info, hi))) { reply("CSMSG_NO_CHAN_USER", hi->handle, channel->name); @@ -5650,10 +5686,12 @@ static CHANSERV_FUNC(cmd_unsuspend) reply("CSMSG_NOT_SUSPENDED", hi->handle); return 0; } + if(!real_self || target->access >= real_self->access) + override = CMD_LOG_OVERRIDE; target->flags &= ~USER_SUSPENDED; scan_user_presence(target, NULL); reply("CSMSG_USER_UNSUSPENDED", hi->handle, channel->name); - return 1; + return 1 | override; } static MODCMD_FUNC(cmd_deleteme) diff --git a/src/hash.h b/src/hash.h index f1b9f48..84bb8a3 100644 --- a/src/hash.h +++ b/src/hash.h @@ -51,6 +51,7 @@ #define FLAGS_DEAF 0x0020 /* deaf +d */ #define FLAGS_SERVICE 0x0040 /* cannot be kicked, killed or deoped +k */ #define FLAGS_GLOBAL 0x0080 /* receives global messages +g */ +#define FLAGS_NOCHAN 0x0100 /* hide channels in whois +n */ #define FLAGS_PERSISTENT 0x0200 /* for reserved nicks, this isn't just one-shot */ #define FLAGS_GAGGED 0x0400 /* for gagged users */ #define FLAGS_AWAY 0x0800 /* for away users */ @@ -65,9 +66,10 @@ #define IsDeaf(x) ((x)->modes & FLAGS_DEAF) #define IsInvisible(x) ((x)->modes & FLAGS_INVISIBLE) #define IsGlobal(x) ((x)->modes & FLAGS_GLOBAL) +#define IsNoChan(x) ((x)->modes & FLAGS_NOCHAN) #define IsWallOp(x) ((x)->modes & FLAGS_WALLOP) #define IsGagged(x) ((x)->modes & FLAGS_GAGGED) -#define IsPersistent(x) ((x)->modes & FLAGS_PERSISTENT) +#define IsPersistent(x) ((x)->modes & FLAGS_PERSISTENT) #define IsAway(x) ((x)->modes & FLAGS_AWAY) #define IsStamped(x) ((x)->modes & FLAGS_STAMPED) #define IsHiddenHost(x) ((x)->modes & FLAGS_HIDDEN_HOST) diff --git a/src/modcmd.c b/src/modcmd.c index f1720f2..e3b51a2 100644 --- a/src/modcmd.c +++ b/src/modcmd.c @@ -626,7 +626,7 @@ int svccmd_invoke_argv(struct userNode *user, struct service *service, struct chanNode *channel, unsigned int argc, char *argv[], unsigned int server_qualified) { extern struct userNode *chanserv; struct svccmd *cmd; - unsigned int cmd_arg, perms, flags, options; + unsigned int cmd_arg, perms, flags, options, result; char channel_name[CHANNELLEN+1]; /* First check pubcmd for the channel. */ @@ -737,11 +737,13 @@ svccmd_invoke_argv(struct userNode *user, struct service *service, struct chanNo safestrncpy(channel_name, channel->name, sizeof(channel_name)); else channel_name[0] = 0; - if (!cmd->command->func(user, channel, argc, argv, cmd)) + if (!(result = cmd->command->func(user, channel, argc, argv, cmd))) return 0; if (!(flags & MODCMD_NO_LOG)) { enum log_severity slvl; - if (perms & ACTION_STAFF) + if (result & CMD_LOG_OVERRIDE) + slvl = LOG_OVERRIDE; + else if ((perms & ACTION_STAFF) || (result & CMD_LOG_STAFF)) slvl = LOG_STAFF; else if (perms & ACTION_OVERRIDE) slvl = LOG_OVERRIDE; diff --git a/src/modcmd.h b/src/modcmd.h index 3523356..b65c235 100644 --- a/src/modcmd.h +++ b/src/modcmd.h @@ -75,6 +75,12 @@ DECLARE_LIST(module_list, struct module*); #define SVCCMD_DEBIT 0x000002 #define SVCCMD_NOISY 0x000004 +/* We do not use constants for 0 (no logging) and 1 (regular logging) as those + * are used very often and are intuitive enough. + */ +#define CMD_LOG_STAFF 0x02 +#define CMD_LOG_OVERRIDE 0x04 + /* Modularized commands work like this: * * Modules define commands. Services contain "bindings" of those diff --git a/src/nickserv.c b/src/nickserv.c index 869b435..7ac7c2e 100644 --- a/src/nickserv.c +++ b/src/nickserv.c @@ -1217,7 +1217,7 @@ static NICKSERV_FUNC(cmd_register) nickserv_make_cookie(user, hi, ACTIVATION, hi->passwd); /* Set registering flag.. */ - user->modes |= FLAGS_REGISTERING; + user->modes |= FLAGS_REGISTERING; return 1; } @@ -2593,10 +2593,13 @@ static NICKSERV_FUNC(cmd_unregister) static NICKSERV_FUNC(cmd_ounregister) { struct handle_info *hi; + char reason[MAXLEN]; NICKSERV_MIN_PARMS(2); if (!(hi = get_victim_oper(user, argv[1]))) return 0; + snprintf(reason, sizeof(reason), "%s unregistered account %s.", user->handle_info->handle, hi->handle); + global_message(MESSAGE_RECIPIENT_STAFF, reason); nickserv_unregister_handle(hi, user); return 1; } diff --git a/src/opserv.c b/src/opserv.c index 7a768a8..cd384a6 100644 --- a/src/opserv.c +++ b/src/opserv.c @@ -1187,6 +1187,7 @@ static MODCMD_FUNC(cmd_whois) if (IsGlobal(target)) buffer[bpos++] = 'g'; if (IsService(target)) buffer[bpos++] = 'k'; if (IsDeaf(target)) buffer[bpos++] = 'd'; + if (IsNoChan(target)) buffer[bpos++] = 'n'; if (IsHiddenHost(target)) buffer[bpos++] = 'x'; if (IsGagged(target)) buffer_cat(" (gagged)"); if (IsRegistering(target)) buffer_cat(" (registered account)"); diff --git a/src/proto-p10.c b/src/proto-p10.c index 4d64e83..e748474 100644 --- a/src/proto-p10.c +++ b/src/proto-p10.c @@ -475,6 +475,8 @@ irc_user(struct userNode *user) modes[modelen++] = 'd'; if (IsGlobal(user)) modes[modelen++] = 'g'; + if (IsNoChan(user)) + modes[modelen++] = 'n'; if (IsHiddenHost(user)) modes[modelen++] = 'x'; modes[modelen] = 0; @@ -888,6 +890,8 @@ static CMD_FUNC(cmd_whois) { struct userNode *from; struct userNode *who; + char buf[MAXLEN]; + unsigned int i, mlen, len; if (argc < 3) return 0; @@ -899,17 +903,67 @@ static CMD_FUNC(cmd_whois) irc_numeric(from, ERR_NOSUCHNICK, "%s@%s :No such nick", argv[2], self->name); return 1; } - if (IsHiddenHost(who) && !IsOper(from)) { - /* Just stay quiet. */ - return 1; + + if (IsFakeHost(who) && IsHiddenHost(who)) + irc_numeric(from, RPL_WHOISUSER, "%s %s %s * :%s", who->nick, who->ident, who->fakehost, who->info); + else if (IsHiddenHost(who) && who->handle_info && hidden_host_suffix) + irc_numeric(from, RPL_WHOISUSER, "%s %s %s.%s * :%s", who->nick, who->ident, who->handle_info->handle, hidden_host_suffix, who->info); + else + irc_numeric(from, RPL_WHOISUSER, "%s %s %s * :%s", who->nick, who->ident, who->hostname, who->info); + + if ((!IsService(who) && !IsNoChan(who)) || (from == who)) { + struct modeNode *mn; + mlen = strlen(self->name) + strlen(from->nick) + 12 + strlen(who->nick); + len = 0; + *buf = '\0'; + for (i = 0; i < who->channels.used; i++) + { + mn = who->channels.list[i]; + + if (!IsOper(from) && (mn->channel->modes & (MODE_PRIVATE | MODE_SECRET)) && !GetUserMode(mn->channel, from)) + continue; + + if (len + strlen(mn->channel->name) + mlen > MAXLEN - 5) + { + irc_numeric(from, RPL_WHOISCHANNELS, "%s :%s", who->nick, buf); + *buf = '\0'; + len = 0; + } + + if (IsDeaf(who)) + *(buf + len++) = '-'; + if ((mn->channel->modes & (MODE_PRIVATE | MODE_SECRET)) && !GetUserMode(mn->channel, from)) + *(buf + len++) = '*'; + if (mn->modes & MODE_CHANOP) + *(buf + len++) = '@'; + else if (mn->modes & MODE_VOICE) + *(buf + len++) = '+'; + + if (len) + *(buf + len) = '\0'; + strcpy(buf + len, mn->channel->name); + len += strlen(mn->channel->name); + strcat(buf + len, " "); + len++; + } + if (buf[0] != '\0') + irc_numeric(from, RPL_WHOISCHANNELS, "%s :%s", who->nick, buf); } - irc_numeric(from, RPL_WHOISUSER, "%s %s %s * :%s", who->nick, who->ident, who->hostname, who->info); - if (his_servername && his_servercomment) + + if (his_servername && his_servercomment && !IsOper(from) && from != who) irc_numeric(from, RPL_WHOISSERVER, "%s %s :%s", who->nick, his_servername, his_servercomment); else irc_numeric(from, RPL_WHOISSERVER, "%s %s :%s", who->nick, who->uplink->name, who->uplink->description); + + if (IsAway(who)) + irc_numeric(from, RPL_AWAY, "%s :Away", who->nick); if (IsOper(who)) - irc_numeric(from, RPL_WHOISOPERATOR, "%s :is a megalomaniacal power hungry tyrant", who->nick); + irc_numeric(from, RPL_WHOISOPERATOR, "%s :%s", who->nick, IsLocal(who) ? "is a megalomaniacal power hungry tyrant" : "is an IRC Operator"); + if (who->handle_info) + irc_numeric(from, RPL_WHOISACCOUNT, "%s %s :is logged in as", who->nick, who->handle_info->handle); + if (IsHiddenHost(who) && who->handle_info && (IsOper(from) || from == who)) + irc_numeric(from, RPL_WHOISACTUALLY, "%s %s@%s %s :Actual user@host, Actual IP", who->nick, who->ident, who->hostname, irc_ntoa(&who->ip)); + irc_numeric(from, RPL_ENDOFWHOIS, "%s :End of /WHOIS list", who->nick); return 1; } @@ -2167,6 +2221,7 @@ void mod_usermode(struct userNode *user, const char *mode_change) { case 'd': do_user_mode(FLAGS_DEAF); break; case 'k': do_user_mode(FLAGS_SERVICE); break; case 'g': do_user_mode(FLAGS_GLOBAL); break; + case 'n': do_user_mode(FLAGS_NOCHAN); break; case 'x': do_user_mode(FLAGS_HIDDEN_HOST); break; case 'r': if (*word) { @@ -2709,10 +2764,10 @@ unreg_privmsg_func(struct userNode *user, privmsg_func_t handler) memset(privmsg_funcs+user->num_local, 0, sizeof(privmsg_func_t)); - for (x = user->num_local+1; x < num_privmsg_funcs; x++) + for (x = user->num_local+1; x < num_privmsg_funcs; x++) memmove(privmsg_funcs+x-1, privmsg_funcs+x, sizeof(privmsg_func_t)); - - privmsg_funcs = realloc(privmsg_funcs, num_privmsg_funcs*sizeof(privmsg_func_t)); + + privmsg_funcs = realloc(privmsg_funcs, num_privmsg_funcs*sizeof(privmsg_func_t)); num_privmsg_funcs--; } diff --git a/src/proto.h b/src/proto.h index 451c889..6f4dccf 100644 --- a/src/proto.h +++ b/src/proto.h @@ -158,10 +158,14 @@ void irc_numeric(struct userNode *user, unsigned int num, const char *format, .. #define RPL_ENDOFSTATS 219 #define RPL_STATSUPTIME 242 #define RPL_MAXCONNECTIONS 250 +#define RPL_AWAY 301 #define RPL_WHOISUSER 311 #define RPL_WHOISSERVER 312 #define RPL_WHOISOPERATOR 313 #define RPL_ENDOFWHOIS 318 +#define RPL_WHOISCHANNELS 319 +#define RPL_WHOISACCOUNT 330 +#define RPL_WHOISACTUALLY 338 #define ERR_NOSUCHNICK 401 /* stuff originally from other headers that is really protocol-specific */ -- 2.20.1