X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/03368cb9ab91801f0bf76d9733fec2e6bb91254d..55bb399f79289b68e9d25db15c60463502d4c2dc:/modules/m_xline.c diff --git a/modules/m_xline.c b/modules/m_xline.c index f3d87dc..d1975ec 100644 --- a/modules/m_xline.c +++ b/modules/m_xline.c @@ -51,6 +51,7 @@ #include "s_newconf.h" #include "reject.h" #include "bandbi.h" +#include "operhash.h" static int mo_xline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]); static int ms_xline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]); @@ -78,7 +79,7 @@ DECLARE_MODULE_AV1(xline, NULL, NULL, xline_clist, NULL, NULL, "$Revision$"); static int valid_xline(struct Client *, const char *, const char *); static void apply_xline(struct Client *client_p, const char *name, - const char *reason, int temp_time); + const char *reason, int temp_time, int propagated); static void propagate_xline(struct Client *source_p, const char *target, int temp_time, const char *name, const char *type, const char *reason); static void cluster_xline(struct Client *source_p, int temp_time, @@ -88,7 +89,8 @@ static void handle_remote_xline(struct Client *source_p, int temp_time, const char *name, const char *reason); static void handle_remote_unxline(struct Client *source_p, const char *name); -static void remove_xline(struct Client *source_p, const char *name); +static void remove_xline(struct Client *source_p, const char *name, + int propagated); /* m_xline() @@ -106,6 +108,7 @@ mo_xline(struct Client *client_p, struct Client *source_p, int parc, const char const char *target_server = NULL; int temp_time; int loc = 1; + int propagated = ConfigFileEntry.use_propagated_bans; if(!IsOperXline(source_p)) { @@ -151,21 +154,30 @@ mo_xline(struct Client *client_p, struct Client *source_p, int parc, const char if(!match(target_server, me.name)) return 0; + + /* Set as local-only. */ + propagated = 0; } - else if(rb_dlink_list_length(&cluster_conf_list) > 0) + else if(!propagated && rb_dlink_list_length(&cluster_conf_list) > 0) cluster_xline(source_p, temp_time, name, reason); if((aconf = find_xline_mask(name)) != NULL) { sendto_one(source_p, ":%s NOTICE %s :[%s] already X-Lined by [%s] - %s", - me.name, source_p->name, name, aconf->name, aconf->passwd); + me.name, source_p->name, name, aconf->host, aconf->passwd); return 0; } if(!valid_xline(source_p, name, reason)) return 0; - apply_xline(source_p, name, reason, temp_time); + if(propagated && temp_time == 0) + { + sendto_one_notice(source_p, ":Cannot set a permanent global ban"); + return 0; + } + + apply_xline(source_p, name, reason, temp_time, propagated); return 0; } @@ -220,12 +232,12 @@ handle_remote_xline(struct Client *source_p, int temp_time, const char *name, co /* already xlined */ if((aconf = find_xline_mask(name)) != NULL) { - sendto_one_notice(source_p, ":[%s] already X-Lined by [%s] - %s", name, aconf->name, + sendto_one_notice(source_p, ":[%s] already X-Lined by [%s] - %s", name, aconf->host, aconf->passwd); return; } - apply_xline(source_p, name, reason, temp_time); + apply_xline(source_p, name, reason, temp_time, 0); } /* valid_xline() @@ -269,72 +281,65 @@ valid_xline(struct Client *source_p, const char *gecos, const char *reason) } void -apply_xline(struct Client *source_p, const char *name, const char *reason, int temp_time) +apply_xline(struct Client *source_p, const char *name, const char *reason, int temp_time, int propagated) { struct ConfItem *aconf; aconf = make_conf(); aconf->status = CONF_XLINE; + aconf->created = rb_current_time(); + aconf->host = rb_strdup(name); + aconf->passwd = rb_strdup(reason); + collapse(aconf->host); + + aconf->info.oper = operhash_add(get_oper_name(source_p)); - if(strstr(name, "\\s")) + if(propagated) { - char *tmp = LOCAL_COPY(name); - char *orig = tmp; - char *new = tmp; + aconf->flags |= CONF_FLAGS_MYOPER | CONF_FLAGS_TEMPORARY; + aconf->hold = rb_current_time() + temp_time; + aconf->lifetime = aconf->hold; - while(*orig) - { - if(*orig == '\\' && *(orig + 1) != '\0') - { - if(*(orig + 1) == 's') - { - *new++ = ' '; - orig += 2; - } - /* otherwise skip that and the escaped - * character after it, so we dont mistake - * \\s as \s --fl - */ - else - { - *new++ = *orig++; - *new++ = *orig++; - } - } - else - *new++ = *orig++; - } + replace_old_ban(aconf); + rb_dlinkAddAlloc(aconf, &prop_bans); - *new = '\0'; - aconf->name = rb_strdup(tmp); + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "%s added global %d min. X-Line for [%s] [%s]", + get_oper_name(source_p), temp_time / 60, + aconf->host, reason); + ilog(L_KLINE, "X %s %d %s %s", + get_oper_name(source_p), temp_time / 60, name, reason); + sendto_one_notice(source_p, ":Added global %d min. X-Line [%s]", + temp_time / 60, aconf->host); + sendto_server(NULL, NULL, CAP_BAN|CAP_TS6, NOCAPS, + ":%s BAN X * %s %lu %d %d * :%s", + source_p->id, aconf->host, + (unsigned long)aconf->created, + (int)(aconf->hold - aconf->created), + (int)(aconf->lifetime - aconf->created), + reason); } - else - aconf->name = rb_strdup(name); - - aconf->passwd = rb_strdup(reason); - collapse(aconf->name); - - if(temp_time > 0) + else if(temp_time > 0) { aconf->hold = rb_current_time() + temp_time; sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s added temporary %d min. X-Line for [%s] [%s]", get_oper_name(source_p), temp_time / 60, - aconf->name, reason); + aconf->host, reason); ilog(L_KLINE, "X %s %d %s %s", get_oper_name(source_p), temp_time / 60, name, reason); sendto_one_notice(source_p, ":Added temporary %d min. X-Line [%s]", - temp_time / 60, aconf->name); + temp_time / 60, aconf->host); } else { sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s added X-Line for [%s] [%s]", - get_oper_name(source_p), aconf->name, aconf->passwd); + get_oper_name(source_p), aconf->host, aconf->passwd); sendto_one_notice(source_p, ":Added X-Line for [%s] [%s]", - aconf->name, aconf->passwd); + aconf->host, aconf->passwd); - bandb_add(BANDB_XLINE, source_p, aconf->name, NULL, aconf->passwd, NULL, 0); + bandb_add(BANDB_XLINE, source_p, aconf->host, NULL, aconf->passwd, NULL, 0); ilog(L_KLINE, "X %s 0 %s %s", get_oper_name(source_p), name, aconf->passwd); } @@ -397,6 +402,8 @@ cluster_xline(struct Client *source_p, int temp_time, const char *name, const ch static int mo_unxline(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { + int propagated = 1; + if(!IsOperXline(source_p)) { sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "xline"); @@ -416,11 +423,12 @@ mo_unxline(struct Client *client_p, struct Client *source_p, int parc, const cha if(match(parv[3], me.name) == 0) return 0; + + propagated = 0; } - else if(rb_dlink_list_length(&cluster_conf_list)) - cluster_generic(source_p, "UNXLINE", SHARED_UNXLINE, CAP_CLUSTER, "%s", parv[1]); + /* cluster{} moved to remove_xline */ - remove_xline(source_p, parv[1]); + remove_xline(source_p, parv[1], propagated); return 0; } @@ -465,13 +473,13 @@ handle_remote_unxline(struct Client *source_p, const char *name) source_p->servptr->name, SHARED_UNXLINE)) return; - remove_xline(source_p, name); + remove_xline(source_p, name, 0); return; } static void -remove_xline(struct Client *source_p, const char *name) +remove_xline(struct Client *source_p, const char *name, int propagated) { struct ConfItem *aconf; rb_dlink_node *ptr; @@ -480,8 +488,43 @@ remove_xline(struct Client *source_p, const char *name) { aconf = ptr->data; - if(!irccmp(aconf->name, name)) + if(!irccmp(aconf->host, name)) { + if(aconf->lifetime) + { + if(!propagated) + { + sendto_one_notice(source_p, ":Cannot remove global X-Line %s on specific servers", name); + return; + } + ptr = rb_dlinkFind(aconf, &prop_bans); + if(ptr == NULL) + return; + sendto_one_notice(source_p, ":X-Line for [%s] is removed", name); + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "%s has removed the global X-Line for: [%s]", + get_oper_name(source_p), name); + ilog(L_KLINE, "UX %s %s", get_oper_name(source_p), name); + if(aconf->created < rb_current_time()) + aconf->created = rb_current_time(); + else + aconf->created++; + aconf->hold = aconf->created; + operhash_delete(aconf->info.oper); + aconf->info.oper = operhash_add(get_oper_name(source_p)); + aconf->flags |= CONF_FLAGS_MYOPER | CONF_FLAGS_TEMPORARY; + sendto_server(NULL, NULL, CAP_BAN|CAP_TS6, NOCAPS, + ":%s BAN X * %s %lu %d %d * :*", + source_p->id, aconf->host, + (unsigned long)aconf->created, + 0, + (int)(aconf->lifetime - aconf->created)); + remove_reject_mask(aconf->host, NULL); + deactivate_conf(aconf, ptr); + return; + } + else if(propagated && rb_dlink_list_length(&cluster_conf_list)) + cluster_generic(source_p, "UNXLINE", SHARED_UNXLINE, CAP_CLUSTER, "%s", name); if(!aconf->hold) { bandb_del(BANDB_XLINE, aconf->host, NULL); @@ -501,13 +544,16 @@ remove_xline(struct Client *source_p, const char *name) ilog(L_KLINE, "UX %s %s", get_oper_name(source_p), name); } - remove_reject_mask(aconf->name, NULL); + remove_reject_mask(aconf->host, NULL); free_conf(aconf); rb_dlinkDestroy(ptr, &xline_conf_list); return; } } + if(propagated && rb_dlink_list_length(&cluster_conf_list)) + cluster_generic(source_p, "UNXLINE", SHARED_UNXLINE, CAP_CLUSTER, "%s", name); + sendto_one_notice(source_p, ":No X-Line for %s", name); return;