]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - src/chmode.c
Add extensions/m_oaccept , a module to allow opers to bypass +gGR with a command.
[irc/rqf/shadowircd.git] / src / chmode.c
index f6c393491045d0e30898918beda2d001d130bd35..442d6f194b4dc1c2131ab5f5d9e5cd4575e6f9ec 100644 (file)
@@ -587,6 +587,59 @@ chm_orphaned(struct Client *source_p, struct Channel *chptr,
        }
 }
 
+void
+chm_hidden(struct Client *source_p, struct Channel *chptr,
+               int alevel, int parc, int *parn,
+               const char **parv, int *errors, int dir, char c, long mode_type)
+{
+       if(!IsOper(source_p) && !IsServer(source_p))
+       {
+               if(!(*errors & SM_ERR_NOPRIVS))
+                       sendto_one_numeric(source_p, ERR_NOPRIVILEGES, form_str(ERR_NOPRIVILEGES));
+               *errors |= SM_ERR_NOPRIVS;
+               return;
+       }
+       if(MyClient(source_p) && !IsOperAdmin(source_p))
+       {
+               if(!(*errors & SM_ERR_NOPRIVS))
+                       sendto_one(source_p, form_str(ERR_NOPRIVS), me.name,
+                                       source_p->name, "cmodes");
+               *errors |= SM_ERR_NOPRIVS;
+               return;
+       }
+
+       if(MyClient(source_p) && (++mode_limit_simple > MAXMODES_SIMPLE))
+               return;
+
+       /* setting + */
+       if((dir == MODE_ADD) && !(chptr->mode.mode & mode_type))
+       {
+               chptr->mode.mode |= mode_type;
+
+               mode_changes[mode_count].letter = c;
+               mode_changes[mode_count].dir = MODE_ADD;
+               mode_changes[mode_count].caps = 0;
+               mode_changes[mode_count].nocaps = 0;
+               mode_changes[mode_count].id = NULL;
+               mode_changes[mode_count].mems = ONLY_OPERS;
+               mode_changes[mode_count].override = 0;
+               mode_changes[mode_count++].arg = NULL;
+       }
+       else if((dir == MODE_DEL) && (chptr->mode.mode & mode_type))
+       {
+               chptr->mode.mode &= ~mode_type;
+
+               mode_changes[mode_count].letter = c;
+               mode_changes[mode_count].dir = MODE_DEL;
+               mode_changes[mode_count].caps = 0;
+               mode_changes[mode_count].nocaps = 0;
+               mode_changes[mode_count].mems = ONLY_OPERS;
+               mode_changes[mode_count].id = NULL;
+               mode_changes[mode_count].override = 0;
+               mode_changes[mode_count++].arg = NULL;
+       }
+}
+
 void
 chm_staff(struct Client *source_p, struct Channel *chptr,
          int alevel, int parc, int *parn,
@@ -730,7 +783,12 @@ chm_ban(struct Client *source_p, struct Channel *chptr,
                                mode_type != CHFL_QUIET)
                {
                        if(IsOverride(source_p))
-                               override = 1;
+                       {
+                               sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+                                               "%s is overriding modes on %s: (%s list)",
+                                               get_oper_name(source_p), chptr->chname,
+                                               mode_type == CHFL_INVEX ? "invex" : "exempt");
+                       }
                        else
                        {
 
@@ -914,8 +972,11 @@ chm_owner(struct Client *source_p, struct Channel *chptr,
                if(targ_p == source_p)
                {
                        no_override_deop = 1;
+                       /* Don't reject modes from remote. It desyncs, and this is perfectly
+                        * legitimate from a remote override oper.
                        if(!override)
                                return;
+                       */
                }
 
                mode_changes[mode_count].letter = c;
@@ -1015,8 +1076,11 @@ chm_op(struct Client *source_p, struct Channel *chptr,
                if(targ_p == source_p)
                {
                        no_override_deop = 1;
+                       /* Don't reject modes from remote. It desyncs, and this is perfectly
+                        * legitimate from a remote override oper.
                        if(!override)
                                return;
+                       */
                }
 
                mode_changes[mode_count].letter = c;
@@ -1125,8 +1189,11 @@ chm_halfop(struct Client *source_p, struct Channel *chptr,
                if(targ_p == source_p)
                {
                        no_override_deop = 1;
+                       /* Don't reject modes from remote. It desyncs, and this is perfectly
+                        * legitimate from a remote override oper.
                        if(!override)
                                return;
+                       */
                }
 
                mode_changes[mode_count].letter = c;
@@ -1731,7 +1798,7 @@ struct ChannelMode chmode_table[256] =
   {chm_simple, MODE_NOREJOIN },        /* J */
   {chm_simple, MODE_NOREPEAT },        /* K */
   {chm_staff,  MODE_EXLIMIT },         /* L */
-  {chm_nosuch, 0 },                    /* M */
+  {chm_hidden, MODE_NOOPERKICK },      /* M */
   {chm_simple, MODE_NONICK },          /* N */
   {chm_nosuch, 0 },                    /* O */
   {chm_staff,  MODE_PERMANENT },       /* P */
@@ -1949,6 +2016,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
        const char *ml = parv[0];
        char c;
        struct Client *fakesource_p;
+       int flags_list[3] = { ALL_MEMBERS, ONLY_CHANOPS, ONLY_OPERS };
 
        mask_pos = 0;
        mode_count = 0;
@@ -1998,7 +2066,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
                                  source_p->name, source_p->username,
                                  source_p->host, chptr->chname);
 
-       for (override = 0; override < (IsOverride(source_p) ? 2 : 1); ++override)
+       for (override = 0; override < (IsOverride(source_p) && alevel != CHFL_CHANOP ? 2 : 1); ++override)
        {
                int was_on_chan = 0;
 
@@ -2013,7 +2081,7 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
                                add_user_to_channel(chptr, source_p, CHFL_CHANOP);
                }
 
-               for(j = 0, flags = ALL_MEMBERS; j < 2; j++, flags = ONLY_CHANOPS)
+               for(j = 0, flags = flags_list[0]; j < 3; j++, flags = flags_list[j])
                {
                        cur_len = mlen;
                        mbuf = modebuf + mlen;