diff --git a/include/s_user.h b/include/s_user.h index e0f41aa3..9fb6f7ed 100644 --- a/include/s_user.h +++ b/include/s_user.h @@ -54,3 +54,5 @@ extern void construct_umodebuf(void); extern void oper_up(struct Client *, struct oper_conf *); #endif + +extern bool has_common_channel(struct Client *source_p, struct Client *target_p); diff --git a/ircd/s_user.c b/ircd/s_user.c index 0fa78ba4..7ea20e7f 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -1644,3 +1644,20 @@ change_nick_user_host(struct Client *target_p, const char *nick, const char *use del_all_accepts(target_p); } } + +bool +has_common_channel(struct Client *source_p, struct Client *target_p) +{ + rb_dlink_node *ps, *pt; + struct membership *ms, *mt; + struct Channel *chptr; + + ITER_COMM_CHANNELS(ps, pt, source_p->user->channel.head, target_p->user->channel.head, ms, mt, chptr) + { + if (ms != NULL && mt != NULL) + return true; + } + + return false; +} + diff --git a/modules/core/m_nick.c b/modules/core/m_nick.c index a5b94d59..890d0c2b 100644 --- a/modules/core/m_nick.c +++ b/modules/core/m_nick.c @@ -712,8 +712,11 @@ change_local_nick(struct Client *client_p, struct Client *source_p, { target_p = ptr->data; - rb_dlinkFindDestroy(source_p, &target_p->localClient->allow_list); - rb_dlinkDestroy(ptr, &source_p->on_allow_list); + if (!has_common_channel(source_p, target_p)) + { + rb_dlinkFindDestroy(source_p, &target_p->localClient->allow_list); + rb_dlinkDestroy(ptr, &source_p->on_allow_list); + } } snprintf(note, sizeof(note), "Nick: %s", nick); @@ -729,6 +732,8 @@ static void change_remote_nick(struct Client *client_p, struct Client *source_p, time_t newts, const char *nick, int dosend) { + struct Client *target_p; + rb_dlink_node *ptr, *next_ptr; struct nd_entry *nd; int samenick = irccmp(source_p->name, nick) ? 0 : 1; hook_cdata hook_info; @@ -771,7 +776,16 @@ change_remote_nick(struct Client *client_p, struct Client *source_p, monitor_signon(source_p); /* remove all accepts pointing to the client */ - del_all_accepts(source_p); + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, source_p->on_allow_list.head) + { + target_p = ptr->data; + + if (!has_common_channel(source_p, target_p)) + { + rb_dlinkFindDestroy(source_p, &target_p->localClient->allow_list); + rb_dlinkDestroy(ptr, &source_p->on_allow_list); + } + } } static void diff --git a/modules/um_callerid.c b/modules/um_callerid.c index 56394986..2fa47db4 100644 --- a/modules/um_callerid.c +++ b/modules/um_callerid.c @@ -87,22 +87,6 @@ um_callerid_moddeinit(void) static const char um_callerid_desc[] = "Provides usermodes +g and +G which restrict messages from unauthorized users."; -static bool -has_common_channel(struct Client *source_p, struct Client *target_p) -{ - rb_dlink_node *ps, *pt; - struct membership *ms, *mt; - struct Channel *chptr; - - ITER_COMM_CHANNELS(ps, pt, source_p->user->channel.head, target_p->user->channel.head, ms, mt, chptr) - { - if (ms != NULL && mt != NULL) - return true; - } - - return false; -} - static bool allow_message(struct Client *source_p, struct Client *target_p) {