]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - modules/core/m_ban.c
Restore snotes, logs for UNRESV nick.
[irc/rqf/shadowircd.git] / modules / core / m_ban.c
index fb19c57efe56a2f408963d97bf8235abf432d99e..8481282d5cd3b398e6ecde6678ee72f11a86941f 100644 (file)
 
 #include "stdinc.h"
 #include "send.h"
+#include "channel.h"
 #include "client.h"
 #include "common.h"
 #include "config.h"
 #include "ircd.h"
 #include "match.h"
 #include "s_conf.h"
+#include "s_newconf.h"
 #include "msg.h"
 #include "modules.h"
 #include "hash.h"
@@ -47,7 +49,7 @@ static int ms_ban(struct Client *client_p, struct Client *source_p, int parc, co
 
 struct Message ban_msgtab = {
        "BAN", 0, 0, 0, MFLG_SLOW,
-       {mg_unreg, mg_ignore, {ms_ban, 10}, {ms_ban, 10}, mg_ignore, mg_ignore}
+       {mg_unreg, mg_ignore, {ms_ban, 9}, {ms_ban, 9}, mg_ignore, mg_ignore}
 };
 
 mapi_clist_av1 ban_clist[] =  { &ban_msgtab, NULL };
@@ -55,15 +57,14 @@ DECLARE_MODULE_AV1(ban, NULL, NULL, ban_clist, NULL, NULL, "$Revision: 1349 $");
 
 /* ms_ban()
  *
- * parv[1] - +/-
- * parv[2] - type
- * parv[3] - username mask or *
- * parv[4] - hostname mask
- * parv[5] - creation TS
- * parv[6] - duration (relative to creation)
- * parv[7] - lifetime (relative to creation)
- * parv[8] - oper or *
- * parv[9] - reason (possibly with |operreason)
+ * parv[1] - type
+ * parv[2] - username mask or *
+ * parv[3] - hostname mask
+ * parv[4] - creation TS
+ * parv[5] - duration (relative to creation)
+ * parv[6] - lifetime (relative to creation)
+ * parv[7] - oper or *
+ * parv[8] - reason (possibly with |operreason)
  */
 static int
 ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
@@ -75,45 +76,50 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
        time_t created, hold, lifetime;
        char *p;
        int act;
+       int valid;
 
-       if (strcmp(parv[1], "+") && strcmp(parv[1], "-"))
-       {
-               sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
-                               "Unknown BAN operation %s from %s",
-                               parv[1], source_p->name);
-               return 0;
-       }
-       if (strlen(parv[2]) != 1)
+       if (strlen(parv[1]) != 1)
        {
                sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
                                "Unknown BAN type %s from %s",
-                               parv[2], source_p->name);
+                               parv[1], source_p->name);
                return 0;
        }
-       switch (parv[2][0])
+       switch (parv[1][0])
        {
                case 'K':
                        ntype = CONF_KILL;
                        stype = "K-Line";
                        break;
+               case 'X':
+                       ntype = CONF_XLINE;
+                       stype = "X-Line";
+                       break;
+               case 'R':
+                       ntype = IsChannelName(parv[3]) ? CONF_RESV_CHANNEL :
+                               CONF_RESV_NICK;
+                       stype = "RESV";
+                       break;
                default:
                        sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
                                        "Unknown BAN type %s from %s",
-                                       parv[2], source_p->name);
+                                       parv[1], source_p->name);
                        return 0;
        }
-       created = atol(parv[5]);
-       hold = created + atoi(parv[6]);
-       lifetime = created + atoi(parv[7]);
-       if (!strcmp(parv[8], "*"))
+       created = atol(parv[4]);
+       hold = created + atoi(parv[5]);
+       lifetime = created + atoi(parv[6]);
+       if (!strcmp(parv[7], "*"))
                oper = IsServer(source_p) ? source_p->name : get_oper_name(source_p);
        else
-               oper = parv[8];
-       ptr = find_prop_ban(ntype, parv[3], parv[4]);
+               oper = parv[7];
+       ptr = find_prop_ban(ntype, parv[2], parv[3]);
        if (ptr != NULL)
        {
                aconf = ptr->data;
-               if (aconf->created >= created)
+               if (aconf->created > created ||
+                               (aconf->created == created &&
+                                aconf->lifetime >= lifetime))
                {
                        if (IsPerson(source_p))
                                sendto_one_notice(source_p,
@@ -124,7 +130,8 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
                                                aconf->host);
                        return 0;
                }
-               act = !(aconf->status & CONF_ILLEGAL) || !strcmp(parv[1], "+");
+               act = !(aconf->status & CONF_ILLEGAL) || (hold != created &&
+                               hold > rb_current_time());
                if (lifetime > aconf->lifetime)
                        aconf->lifetime = lifetime;
                /* already expired, hmm */
@@ -148,24 +155,56 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
                aconf->status = CONF_ILLEGAL | ntype;
                aconf->lifetime = lifetime;
                rb_dlinkAddAlloc(aconf, &prop_bans);
-               act = !strcmp(parv[1], "+");
+               act = hold != created && hold > rb_current_time();
        }
        aconf->flags &= ~CONF_FLAGS_MYOPER;
        aconf->flags |= CONF_FLAGS_TEMPORARY;
-       aconf->user = ntype == CONF_KILL ? rb_strdup(parv[3]) : NULL;
-       aconf->host = rb_strdup(parv[4]);
+       aconf->user = ntype == CONF_KILL ? rb_strdup(parv[2]) : NULL;
+       aconf->host = rb_strdup(parv[3]);
        aconf->info.oper = operhash_add(oper);
        aconf->created = created;
        aconf->hold = hold;
-       p = strchr(parv[parc - 1], '|');
-       if (p == NULL)
+       if (ntype != CONF_KILL || (p = strchr(parv[parc - 1], '|')) == NULL)
                aconf->passwd = rb_strdup(parv[parc - 1]);
        else
        {
                aconf->passwd = rb_strndup(parv[parc - 1], p - parv[parc - 1] + 1);
                aconf->spasswd = rb_strdup(p + 1);
        }
-       if (!strcmp(parv[1], "+"))
+       switch (ntype)
+       {
+               case CONF_KILL:
+                       valid = valid_wild_card(aconf->user, aconf->host);
+                       break;
+               case CONF_RESV_CHANNEL:
+                       valid = 1;
+                       break;
+               default:
+                       valid = valid_wild_card_simple(aconf->host);
+                       break;
+       }
+       if (act && hold != created && !valid)
+       {
+               sendto_realops_snomask(SNO_GENERAL, L_ALL,
+                                      "Ignoring global %d min. %s from %s%s%s for [%s%s%s]: too few non-wildcard characters",
+                                      (hold - rb_current_time()) / 60,
+                                      stype,
+                                      IsServer(source_p) ? source_p->name : get_oper_name(source_p),
+                                      strcmp(parv[7], "*") ? " on behalf of " : "",
+                                      strcmp(parv[7], "*") ? parv[7] : "",
+                                      aconf->user ? aconf->user : "",
+                                      aconf->user ? "@" : "",
+                                      aconf->host);
+               if(IsPerson(source_p))
+                       sendto_one_notice(source_p,
+                                       ":Your %s [%s%s%s] has too few non-wildcard characters",
+                                       stype,
+                                       aconf->user ? aconf->user : "",
+                                       aconf->user ? "@" : "",
+                                       aconf->host);
+               /* Propagate it, but do not apply it locally. */
+       }
+       else if (act && hold != created)
        {
                /* Keep the notices in sync with modules/m_kline.c etc. */
                sendto_realops_snomask(SNO_GENERAL, L_ALL,
@@ -173,18 +212,20 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
                                       IsServer(source_p) ? source_p->name : get_oper_name(source_p),
                                       (hold - rb_current_time()) / 60,
                                       stype,
-                                      strcmp(parv[8], "*") ? " from " : "",
-                                      strcmp(parv[8], "*") ? parv[8] : "",
+                                      strcmp(parv[7], "*") ? " from " : "",
+                                      strcmp(parv[7], "*") ? parv[7] : "",
                                       aconf->user ? aconf->user : "",
                                       aconf->user ? "@" : "",
                                       aconf->host,
                                       parv[parc - 1]);
-               aconf->status &= ~CONF_ILLEGAL;
-               ilog(L_KLINE, "%s %s %d %s %s %s", parv[2],
+               ilog(L_KLINE, "%s %s %d %s%s%s %s", parv[1],
                                IsServer(source_p) ? source_p->name : get_oper_name(source_p),
                                (hold - rb_current_time()) / 60,
-                               aconf->user, aconf->host,
+                               aconf->user ? aconf->user : "",
+                               aconf->user ? " " : "",
+                               aconf->host,
                                parv[parc - 1]);
+               aconf->status &= ~CONF_ILLEGAL;
        }
        else if (act)
        {
@@ -195,11 +236,13 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
                                aconf->user ? aconf->user : "",
                                aconf->user ? "@" : "",
                                aconf->host,
-                               strcmp(parv[8], "*") ? " on behalf of " : "",
-                               strcmp(parv[8], "*") ? parv[8] : "");
-               ilog(L_KLINE, "U%s %s %s %s", parv[2],
+                               strcmp(parv[7], "*") ? " on behalf of " : "",
+                               strcmp(parv[7], "*") ? parv[7] : "");
+               ilog(L_KLINE, "U%s %s %s%s %s", parv[1],
                                IsServer(source_p) ? source_p->name : get_oper_name(source_p),
-                               aconf->user, aconf->host);
+                               aconf->user ? aconf->user : "",
+                               aconf->user ? " " : "",
+                               aconf->host);
        }
        switch (ntype)
        {
@@ -224,9 +267,29 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
                                        check_klines();
                        }
                        break;
+               case CONF_XLINE:
+                       if (aconf->status & CONF_ILLEGAL)
+                               remove_reject_mask(aconf->host, NULL);
+                       else
+                       {
+                               rb_dlinkAddAlloc(aconf, &xline_conf_list);
+                               check_xlines();
+                       }
+                       break;
+               case CONF_RESV_CHANNEL:
+                       if (!(aconf->status & CONF_ILLEGAL))
+                       {
+                               add_to_resv_hash(aconf->host, aconf);
+                               resv_chan_forcepart(aconf->host, aconf->passwd, hold - rb_current_time());
+                       }
+                       break;
+               case CONF_RESV_NICK:
+                       if (!(aconf->status & CONF_ILLEGAL))
+                               rb_dlinkAddAlloc(aconf, &resv_conf_list);
+                       break;
        }
-       sendto_server(NULL, NULL, CAP_BAN|CAP_TS6, NOCAPS,
-                       ":%s BAN %s %s %s %s %s %s %s %s :%s",
+       sendto_server(client_p, NULL, CAP_BAN|CAP_TS6, NOCAPS,
+                       ":%s BAN %s %s %s %s %s %s %s :%s",
                        source_p->id,
                        parv[1],
                        parv[2],
@@ -235,7 +298,6 @@ ms_ban(struct Client *client_p, struct Client *source_p, int parc, const char *p
                        parv[5],
                        parv[6],
                        parv[7],
-                       parv[8],
                        parv[parc - 1]);
        return 0;
 }