From 4f57d083c810f57edc0fe449b0de1f48e402107b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 5 Jun 2016 14:16:36 +0100 Subject: Add global channel operator support --- include/client.h | 4 +++- modules/core/m_kick.c | 6 +++--- modules/m_invite.c | 3 ++- modules/m_topic.c | 3 ++- src/channel.c | 2 +- src/channel_mode.c | 2 +- src/conf.c | 2 +- src/conf_lexer.l | 1 + src/conf_parser.y | 11 +++++++++++ src/s_user.c | 2 +- 10 files changed, 26 insertions(+), 10 deletions(-) diff --git a/include/client.h b/include/client.h index beed244..e799eca 100644 --- a/include/client.h +++ b/include/client.h @@ -168,6 +168,7 @@ struct MaskItem; #define UMODE_HIDDENHOST 0x01000000 /**< User's host is hidden */ #define UMODE_SSL 0x02000000 /**< User is connected via TLS/SSL */ #define UMODE_WEBIRC 0x04000000 /**< User connected via a webirc gateway */ +#define UMODE_GCHANOP 0x08000000 /**< Global channel operator */ #define UMODE_ALL UMODE_SERVNOTICE @@ -179,7 +180,8 @@ struct MaskItem; #define SEND_UMODES (UMODE_INVISIBLE | UMODE_OPER | UMODE_WALLOP |\ UMODE_REGONLY | UMODE_REGISTERED | UMODE_ADMIN |\ UMODE_HIDDEN | UMODE_HIDDENHOST | UMODE_SSL |\ - UMODE_WEBIRC | UMODE_CALLERID | UMODE_SOFTCALLERID) + UMODE_WEBIRC | UMODE_CALLERID | UMODE_SOFTCALLERID |\ + UMODE_GCHANOP) diff --git a/modules/core/m_kick.c b/modules/core/m_kick.c index 3d9bfd5..a9f012f 100644 --- a/modules/core/m_kick.c +++ b/modules/core/m_kick.c @@ -97,7 +97,7 @@ m_kick(struct Client *client_p, struct Client *source_p, } } - if (!has_member_flags(ms_source, CHFL_CHANOP|CHFL_HALFOP)) + if (!has_member_flags(ms_source, CHFL_CHANOP|CHFL_HALFOP) && !HasUMode(source_p, UMODE_GCHANOP)) { /* was a user, not a server, and user isn't seen as a chanop here */ if (MyConnect(source_p)) @@ -146,10 +146,10 @@ m_kick(struct Client *client_p, struct Client *source_p, { #ifdef HALFOPS /* half ops cannot kick other halfops on private channels */ - if (has_member_flags(ms_source, CHFL_HALFOP) && !has_member_flags(ms_source, CHFL_CHANOP)) + if (has_member_flags(ms_source, CHFL_HALFOP) && !has_member_flags(ms_source, CHFL_CHANOP) && !HasUMode(source_p, UMODE_GCHANOP)) { if (((chptr->mode.mode & MODE_PRIVATE) && has_member_flags(ms_target, - CHFL_CHANOP|CHFL_HALFOP)) || has_member_flags(ms_target, CHFL_CHANOP)) + CHFL_CHANOP|CHFL_HALFOP)) || has_member_flags(ms_target, CHFL_CHANOP) || HasUMode(who, UMODE_GCHANOP)) { sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), me.name, source_p->name, chptr->chname); diff --git a/modules/m_invite.c b/modules/m_invite.c index 2eb3de6..48e86e6 100644 --- a/modules/m_invite.c +++ b/modules/m_invite.c @@ -90,7 +90,8 @@ m_invite(struct Client *client_p, struct Client *source_p, return 0; } - if (MyConnect(source_p) && !has_member_flags(ms, CHFL_CHANOP)) + if (MyConnect(source_p) && !has_member_flags(ms, CHFL_CHANOP) + && !HasUMode(source_p, UMODE_GCHANOP)) { sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), me.name, source_p->name, chptr->chname); diff --git a/modules/m_topic.c b/modules/m_topic.c index 4606e32..3aa5e3d 100644 --- a/modules/m_topic.c +++ b/modules/m_topic.c @@ -81,7 +81,8 @@ m_topic(struct Client *client_p, struct Client *source_p, } if (!(chptr->mode.mode & MODE_TOPICLIMIT) || - has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP)) + has_member_flags(ms, CHFL_CHANOP|CHFL_HALFOP) || + HasUMode(source_p, UMODE_GCHANOP)) { char topic_info[USERHOST_REPLYLEN]; diff --git a/src/channel.c b/src/channel.c index f000b7f..1feb5d1 100644 --- a/src/channel.c +++ b/src/channel.c @@ -750,7 +750,7 @@ can_send(struct Channel *chptr, struct Client *source_p, { struct MaskItem *conf = NULL; - if (IsServer(source_p) || HasFlag(source_p, FLAGS_SERVICE)) + if (IsServer(source_p) || HasFlag(source_p, FLAGS_SERVICE) || HasUMode(source_p, UMODE_GCHANOP)) return CAN_SEND_OPV; if (MyClient(source_p) && !IsExemptResv(source_p)) diff --git a/src/channel_mode.c b/src/channel_mode.c index 7241da8..b4d2373 100644 --- a/src/channel_mode.c +++ b/src/channel_mode.c @@ -1595,7 +1595,7 @@ get_channel_access(const struct Client *source_p, const struct Membership *member) { /* Let hacked servers in for now... */ - if (!MyClient(source_p)) + if (!MyClient(source_p) || HasUMode(source_p, UMODE_GCHANOP)) return CHACCESS_CHANOP; if (member == NULL) diff --git a/src/conf.c b/src/conf.c index f52281e..3bf306a 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1172,7 +1172,7 @@ set_default_conf(void) ConfigFileEntry.true_no_oper_flood = 0; ConfigFileEntry.oper_pass_resv = 1; ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT; - ConfigFileEntry.oper_only_umodes = UMODE_DEBUG; + ConfigFileEntry.oper_only_umodes = UMODE_GCHANOP | UMODE_DEBUG; ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE | UMODE_OPERWALL | UMODE_WALLOP; ConfigFileEntry.use_egd = 0; diff --git a/src/conf_lexer.l b/src/conf_lexer.l index 466e827..88fb7d0 100644 --- a/src/conf_lexer.l +++ b/src/conf_lexer.l @@ -191,6 +191,7 @@ gline_min_cidr { return GLINE_MIN_CIDR; } gline_min_cidr6 { return GLINE_MIN_CIDR6; } gline_request_duration { return GLINE_REQUEST_DURATION; } global_kill { return GLOBAL_KILL; } +globalchops { return T_GCHANOPS; } globops { return T_GLOBOPS; } have_ident { return NEED_IDENT; } havent_read_conf { return HAVENT_READ_CONF; } diff --git a/src/conf_parser.y b/src/conf_parser.y index 3a1948b..efb1176 100644 --- a/src/conf_parser.y +++ b/src/conf_parser.y @@ -308,6 +308,7 @@ reset_block_state(void) %token T_FARCONNECT %token T_FILE %token T_FULL +%token T_GCHANOPS %token T_GLOBOPS %token T_INVISIBLE %token T_INVITEONLY @@ -1260,6 +1261,10 @@ oper_umodes_item: T_BOTS { if (conf_parser_ctx.pass == 2) block_state.modes.value |= UMODE_FARCONNECT; +} | T_GCHANOPS +{ + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_GCHANOP; }; oper_flags: IRCD_FLAGS @@ -2782,6 +2787,9 @@ umode_oitem: T_BOTS } | T_FARCONNECT { ConfigFileEntry.oper_umodes |= UMODE_FARCONNECT; +} | T_GCHANOPS +{ + ConfigFileEntry.oper_umodes |= UMODE_GCHANOP; }; general_oper_only_umodes: OPER_ONLY_UMODES @@ -2853,6 +2861,9 @@ umode_item: T_BOTS } | T_FARCONNECT { ConfigFileEntry.oper_only_umodes |= UMODE_FARCONNECT; +} | T_GCHANOPS +{ + ConfigFileEntry.oper_only_umodes |= UMODE_GCHANOP; }; general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';' diff --git a/src/s_user.c b/src/s_user.c index 772c16a..9482508 100644 --- a/src/s_user.c +++ b/src/s_user.c @@ -99,7 +99,7 @@ const unsigned int user_modes[256] = 0, /* L */ 0, /* M */ 0, /* N */ - 0, /* O */ + UMODE_GCHANOP, /* O */ 0, /* P */ 0, /* Q */ UMODE_REGONLY, /* R */ -- cgit