From: Kevin L. Mitchell Date: Mon, 29 Jan 2001 17:46:31 +0000 (+0000) Subject: Author: Kev X-Git-Url: http://git.pk910.de/?a=commitdiff_plain;h=b82de00525251410a50b42966dfd7a7af2f28a7d;p=ircu2.10.12-pk.git Author: Kev Log message: Fixes for 3 bugs: 1) /mode -o wasn't propagated; the privileges were being set before send_umode_out() could get at them, so the PRIV_PROPAGATE setting went away. 2) /mode #channel +b banmask, under certain circumstances, would allow multiple bans of the exact same mask to be added to the channel. 3) /mode #channel +b banmask would leak memory if another ban of the exact same mask was already present on the channel (and bug #2 wasn't triggered). Testing: Compiled and ran; unable to duplicate the errors, now. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@382 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- diff --git a/ChangeLog b/ChangeLog index 88f5d32..6302d7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2001-01-29 Kevin L. Mitchell + + * ircd/channel.c (mode_parse_ban): stopper a tiny leak--if a ban + already existed, then the logic would (attempt to) skip it, but + would not free the ban string; now the ban string is free'd and + the ban count is decremented, releasing the ban for use + + * ircd/s_user.c: make send_umode_out() take a prop argument + instead of testing for the PRIV_PROPAGATE privilege itself; fix + set_umode() to use this new argument, calculating it before + calculating the new privileges for a -o'd user + + * ircd/m_oper.c (m_oper): pass the new prop argument to + send_umode_out() + + * ircd/channel.c (mode_parse_ban): turn off MODE_ADD bit in bans + that we're not actually going to add because they already exist; + test that particular bit before adding to the linked list + + * include/s_user.h: add a prop argument to send_umode_out() to + indicate whether or not to propagate the user mode + 2001-01-24 Kevin L. Mitchell * ircd/msgq.c: ircd_vsnprintf() returns the number of bytes that diff --git a/include/s_user.h b/include/s_user.h index e91de32..c8457ad 100644 --- a/include/s_user.h +++ b/include/s_user.h @@ -67,7 +67,8 @@ extern int user_set_away(struct User* user, char* message); extern int do_nick_name(char* nick); extern int set_nick_name(struct Client* cptr, struct Client* sptr, const char* nick, int parc, char* parv[]); -extern void send_umode_out(struct Client* cptr, struct Client* sptr, int old); +extern void send_umode_out(struct Client* cptr, struct Client* sptr, int old, + int prop); extern int whisper(struct Client* source, const char* nick, const char* channel, const char* text, int is_notice); extern void send_user_info(struct Client* to, char* names, int rpl, diff --git a/ircd/channel.c b/ircd/channel.c index edb4229..7ad4534 100644 --- a/ircd/channel.c +++ b/ircd/channel.c @@ -2175,16 +2175,18 @@ mode_parse_ban(struct ParseState *state, int *flag_p) } else if (state->dir == MODE_ADD) { /* if the ban already exists, don't worry about it */ if (!ircd_strcmp(ban->value.ban.banstr, t_str)) { + newban->flags &= ~MODE_ADD; /* don't add ban at all */ + MyFree(newban->value.ban.banstr); /* stopper a leak */ + state->numbans--; /* deallocate last ban */ if (state->done & DONE_BANCLEAN) /* If we're cleaning, finish */ break; - continue; } else if (!mmatch(ban->value.ban.banstr, t_str)) { if (!(ban->flags & MODE_DEL)) newban->flags |= CHFL_BAN_OVERLAPPED; /* our ban overlaps */ } else if (!mmatch(t_str, ban->value.ban.banstr)) ban->flags |= MODE_DEL; /* mark ban for deletion: overlapping */ - if (!ban->next) { + if (!ban->next && (newban->flags & MODE_ADD)) { ban->next = newban; /* add our ban with its flags */ break; /* get out of loop */ } diff --git a/ircd/m_oper.c b/ircd/m_oper.c index 813e2b3..5bbf215 100644 --- a/ircd/m_oper.c +++ b/ircd/m_oper.c @@ -186,7 +186,7 @@ int m_oper(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) set_snomask(sptr, SNO_OPERDEFAULT, SNO_ADD); client_set_privs(sptr); - send_umode_out(cptr, sptr, old_mode); + send_umode_out(cptr, sptr, old_mode, HasPriv(sptr, PRIV_PROPAGATE)); send_reply(sptr, RPL_YOUREOPER); sendto_opmask_butone(0, SNO_OLDSNO, "%s (%s@%s) is now operator (%c)", diff --git a/ircd/s_user.c b/ircd/s_user.c index 1faaf2a..b4695ed 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -1002,13 +1002,13 @@ int whisper(struct Client* source, const char* nick, const char* channel, /* * added Sat Jul 25 07:30:42 EST 1992 */ -void send_umode_out(struct Client *cptr, struct Client *sptr, int old) +void send_umode_out(struct Client *cptr, struct Client *sptr, int old, + int prop) { int i; struct Client *acptr; - send_umode(NULL, sptr, old, - SEND_UMODES & ~(HasPriv(sptr, PRIV_PROPAGATE) ? 0 : FLAGS_OPER)); + send_umode(NULL, sptr, old, SEND_UMODES & ~(prop ? 0 : FLAGS_OPER)); for (i = HighestFd; i >= 0; i--) { if ((acptr = LocalClientArray[i]) && IsServer(acptr) && @@ -1072,6 +1072,7 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv unsigned int tmpmask = 0; int snomask_given = 0; char buf[BUFSIZE]; + int prop = 0; what = MODE_ADD; @@ -1240,19 +1241,21 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv * Compare new flags with old flags and send string which * will cause servers to update correctly. */ - if ((setflags & FLAGS_OPER) && !IsOper(sptr)) { - --UserStats.opers; - client_set_privs(sptr); - } - if (!(setflags & FLAGS_OPER) && IsOper(sptr)) { + if (!(setflags & FLAGS_OPER) && IsOper(sptr)) { /* user now oper */ ++UserStats.opers; - client_set_privs(sptr); + client_set_privs(sptr); /* may set propagate privilege */ + } + if (HasPriv(sptr, PRIV_PROPAGATE)) /* remember propagate privilege setting */ + prop = 1; + if ((setflags & FLAGS_OPER) && !IsOper(sptr)) { /* user no longer oper */ + --UserStats.opers; + client_set_privs(sptr); /* will clear propagate privilege */ } if ((setflags & FLAGS_INVISIBLE) && !IsInvisible(sptr)) --UserStats.inv_clients; if (!(setflags & FLAGS_INVISIBLE) && IsInvisible(sptr)) ++UserStats.inv_clients; - send_umode_out(cptr, sptr, setflags); + send_umode_out(cptr, sptr, setflags, prop); return 0; }