X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fm_silence.c;h=ce9d4dc5ed58d63738f446cc68a1f32020ee2019;hb=a25ce1d73a5f5a92057a6e7c62894e4683eb4280;hp=a3baa5124a6c8f279edc55f5d35f06d192298dc2;hpb=4ce006b23328ec3570adeac8d6525c4c7bb3525f;p=ircu2.10.12-pk.git diff --git a/ircd/m_silence.c b/ircd/m_silence.c index a3baa51..ce9d4dc 100644 --- a/ircd/m_silence.c +++ b/ircd/m_silence.c @@ -32,6 +32,7 @@ #include "hash.h" #include "ircd.h" #include "ircd_features.h" +#include "ircd_log.h" #include "ircd_reply.h" #include "ircd_snprintf.h" #include "ircd_string.h" @@ -43,7 +44,7 @@ #include "send.h" #include "struct.h" -#include +/* #include -- Now using assert in ircd_log.h */ #include #include @@ -59,10 +60,12 @@ * @return The new ban entry on success, NULL on failure. */ static struct Ban * -apply_silence(struct Client *sptr, const char *mask) +apply_silence(struct Client *sptr, char *mask) { struct Ban *sile; int flags; + int res; + char orig_mask[NICKLEN+USERLEN+HOSTLEN+3]; assert(mask && mask[0]); @@ -82,10 +85,24 @@ apply_silence(struct Client *sptr, const char *mask) mask++; } - /* Make the silence, set flags, and apply it. */ - sile = make_ban(mask); + /* Make the silence and set additional flags. */ + ircd_strncpy(orig_mask, mask, sizeof(orig_mask) - 1); + sile = make_ban(pretty_mask(mask)); sile->flags |= flags; - return apply_ban(&cli_user(sptr)->silence, sile) ? NULL : sile; + + /* If they're a local user trying to ban too broad a mask, forbid it. */ + if (MyUser(sptr) + && (sile->flags & BAN_IPMASK) + && sile->addrbits > 0 + && sile->addrbits < (irc_in_addr_is_ipv4(&sile->address) ? 112 : 32)) { + send_reply(sptr, ERR_MASKTOOWIDE, orig_mask); + free_ban(sile); + return NULL; + } + + /* Apply it to the silence list. */ + res = apply_ban(&cli_user(sptr)->silence, sile, 1); + return res ? NULL : sile; } /** Apply and send silence updates for a user. @@ -108,7 +125,6 @@ forward_silences(struct Client *sptr, char *silences, struct Client *dest) accepted[ac_count++] = sile; } - if (MyUser(sptr)) { size_t siles, maxsiles, totlength, maxlength, jj; @@ -117,11 +133,13 @@ forward_silences(struct Client *sptr, char *silences, struct Client *dest) maxlength = maxsiles * feature_int(FEAT_AVBANLEN); siles = totlength = 0; /* Count number of current silences and their total length. */ + plast = &cli_user(sptr)->silence; for (sile = cli_user(sptr)->silence; sile; sile = sile->next) { if (sile->flags & (BAN_OVERLAPPED | BAN_ADD | BAN_DEL)) continue; siles++; totlength += strlen(sile->banstr); + plast = &sile->next; } for (ii = jj = 0; ii < ac_count; ++ii) { sile = accepted[ii]; @@ -131,12 +149,16 @@ forward_silences(struct Client *sptr, char *silences, struct Client *dest) if (!(sile->flags & (BAN_OVERLAPPED | BAN_DEL))) { slen = strlen(sile->banstr); if ((siles >= maxsiles) || (totlength + slen >= maxlength)) { + *plast = NULL; + if (MyUser(sptr)) + send_reply(sptr, ERR_SILELISTFULL, accepted[ii]->banstr); free_ban(accepted[ii]); continue; } /* Update counts. */ siles++; totlength += slen; + plast = &sile->next; } /* Store the update. */ accepted[jj++] = sile; @@ -237,8 +259,9 @@ forward_silences(struct Client *sptr, char *silences, struct Client *dest) /* Free any silence-deleting updates. */ for (ii = 0; ii < ac_count; ++ii) { - if (accepted[ii]->flags & BAN_DEL) + if ((accepted[ii]->flags & (BAN_ADD | BAN_DEL)) == BAN_DEL) { free_ban(accepted[ii]); + } } } @@ -266,7 +289,7 @@ int m_silence(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) /* See if the user is requesting a silence list. */ acptr = sptr; if (parc < 2 || EmptyString(parv[1]) || (acptr = FindUser(parv[1]))) { - if (cli_user(acptr)) { + if (cli_user(acptr) && ((acptr == sptr) || IsChannelService(acptr))) { for (sile = cli_user(acptr)->silence; sile; sile = sile->next) { send_reply(sptr, RPL_SILELIST, cli_name(acptr), (sile->flags & BAN_EXCEPTION ? "~" : ""), sile->banstr);