X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/dab6375a1ee20c724bf93dda872245567b11d733..dc34aae05e6e299a6c53c60b728d73ecb88b21bf:/src/channel.c diff --git a/src/channel.c b/src/channel.c index 9c95fb7..a2e6fa6 100644 --- a/src/channel.c +++ b/src/channel.c @@ -66,8 +66,6 @@ static int h_can_join; static int h_can_create_channel; static int h_channel_join; -struct module_modes ModuleModes; - /* init_channels() * * input - @@ -87,40 +85,6 @@ init_channels(void) h_can_create_channel = register_hook("can_create_channel"); } -/* is this the best place to put this? */ -/* init_module_modes() - * - * input - - * output - - * side effects - various MODE_ values are set to 0 - */ -void -init_module_modes() -{ - ModuleModes.MODE_REGONLY = 0; - ModuleModes.MODE_NOCTCP = 0; - ModuleModes.MODE_NOCOLOR = 0; - ModuleModes.MODE_EXLIMIT = 0; - ModuleModes.MODE_PERMANENT = 0; - ModuleModes.MODE_OPMODERATE = 0; - ModuleModes.MODE_FREEINVITE = 0; - ModuleModes.MODE_FREETARGET = 0; - ModuleModes.MODE_DISFORWARD = 0; - ModuleModes.MODE_THROTTLE = 0; - ModuleModes.MODE_FORWARD = 0; - ModuleModes.MODE_NONOTICE = 0; - ModuleModes.MODE_NOACTION = 0; - ModuleModes.MODE_NOKICK = 0; - ModuleModes.MODE_NONICK = 0; - ModuleModes.MODE_NOCAPS = 0; - ModuleModes.MODE_NOREJOIN = 0; - ModuleModes.MODE_NOREPEAT = 0; - ModuleModes.MODE_NOOPERKICK = 0; - - ModuleModes.CHFL_QUIET = 0; -} - - /* * allocate_channel - Allocates a channel */ @@ -142,6 +106,7 @@ free_channel(struct Channel *chptr) { channel_metadata_clear(chptr); rb_free(chptr->chname); + rb_free(chptr->mode_lock); rb_bh_free(channel_heap, chptr); } @@ -388,7 +353,7 @@ remove_user_from_channel(struct membership *msptr) if(client_p->servptr == &me) rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers); - if(!(chptr->mode.mode & ModuleModes.MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0) + if(!(chptr->mode.mode & MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0) destroy_channel(chptr); rb_bh_free(member_heap, msptr); @@ -423,7 +388,7 @@ remove_user_from_channels(struct Client *client_p) if(client_p->servptr == &me) rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers); - if(!(chptr->mode.mode & ModuleModes.MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0) + if(!(chptr->mode.mode & MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0) destroy_channel(chptr); rb_bh_free(member_heap, msptr); @@ -759,10 +724,6 @@ is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr, struct Ban *actualBan = NULL; struct Ban *actualExcept = NULL; - /* check to make sure quiets even exist on this server first */ - if(ModuleModes.CHFL_QUIET == 0) - return 0; - if(!MyClient(who)) return 0; @@ -798,7 +759,7 @@ is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr, if(match(actualBan->banstr, s) || match(actualBan->banstr, s2) || match_cidr(actualBan->banstr, s2) || - match_extban(actualBan->banstr, who, chptr, ModuleModes.CHFL_QUIET) || + match_extban(actualBan->banstr, who, chptr, CHFL_QUIET) || (s3 != NULL && match(actualBan->banstr, s3))) break; else @@ -939,19 +900,15 @@ can_join(struct Client *source_p, struct Channel *chptr, char *key) if(chptr->mode.limit && rb_dlink_list_length(&chptr->members) >= (unsigned long) chptr->mode.limit) i = ERR_CHANNELISFULL; - if(chptr->mode.mode & ModuleModes.MODE_REGONLY && EmptyString(source_p->user->suser)) + if(chptr->mode.mode & MODE_REGONLY && EmptyString(source_p->user->suser)) i = ERR_NEEDREGGEDNICK; /* join throttling stuff --nenolod */ - /* only check for throttles if they exist on this server --Taros */ - else if(ModuleModes.MODE_THROTTLE) + else if(chptr->mode.join_num > 0 && chptr->mode.join_time > 0) { - if(chptr->mode.join_num > 0 && chptr->mode.join_time > 0) - { - if ((rb_current_time() - chptr->join_delta <= - chptr->mode.join_time) && (chptr->join_count >= - chptr->mode.join_num)) - i = ERR_THROTTLE; - } + if ((rb_current_time() - chptr->join_delta <= + chptr->mode.join_time) && (chptr->join_count >= + chptr->mode.join_num)) + i = ERR_THROTTLE; } /* allow /invite to override +l/+r/+j also -- jilles */ @@ -1030,6 +987,62 @@ can_send(struct Channel *chptr, struct Client *source_p, struct membership *mspt return CAN_SEND_NONOP; } +/* + * flood_attack_channel + * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC + * says NOTICE must not auto reply + * - pointer to source Client + * - pointer to target channel + * output - 1 if target is under flood attack + * side effects - check for flood attack on target chptr + */ +int +flood_attack_channel(int p_or_n, struct Client *source_p, struct Channel *chptr, char *chname) +{ + int delta; + + if(GlobalSetOptions.floodcount && MyClient(source_p) && (!IsOper(source_p) || !ConfigFileEntry.true_no_oper_flood)) + { + if((chptr->first_received_message_time + 1) < rb_current_time()) + { + delta = rb_current_time() - chptr->first_received_message_time; + chptr->received_number_of_privmsgs -= delta; + chptr->first_received_message_time = rb_current_time(); + if(chptr->received_number_of_privmsgs <= 0) + { + chptr->received_number_of_privmsgs = 0; + chptr->flood_noticed = 0; + } + } + + if((chptr->received_number_of_privmsgs >= GlobalSetOptions.floodcount) + || chptr->flood_noticed) + { + if(chptr->flood_noticed == 0) + { + sendto_realops_snomask(SNO_BOTS, *chptr->chname == '&' ? L_ALL : L_NETWIDE, + "Possible Flooder %s[%s@%s] on %s target: %s", + source_p->name, source_p->username, + source_p->orighost, + source_p->servptr->name, chptr->chname); + chptr->flood_noticed = 1; + + /* Add a bit of penalty */ + chptr->received_number_of_privmsgs += 2; + } + if(MyClient(source_p) && (p_or_n != 1)) + sendto_one(source_p, + ":%s NOTICE %s :*** Message to %s throttled due to flooding", + me.name, source_p->name, chptr->chname); + return 1; + } + else + chptr->received_number_of_privmsgs++; + } + + return 0; +} + /* find_bannickchange_channel() * Input: client to check * Output: channel preventing nick change @@ -1086,7 +1099,7 @@ find_nonickchange_channel(struct Client *client_p) { msptr = ptr->data; chptr = msptr->chptr; - if (chptr->mode.mode & ModuleModes.MODE_NONICK && (!ConfigChannel.exempt_cmode_N || !is_any_op(msptr))) + if (chptr->mode.mode & MODE_NONICK && (!ConfigChannel.exempt_cmode_N || !is_any_op(msptr))) return chptr; } return NULL; @@ -1341,7 +1354,7 @@ channel_modes(struct Channel *chptr, struct Client *client_p) chptr->mode.join_time); } - if(*chptr->mode.forward && (ModuleModes.MODE_FORWARD || !IsClient(client_p))) + if(*chptr->mode.forward && (ConfigChannel.use_forward || !IsClient(client_p))) { *mbuf++ = 'f'; @@ -1652,7 +1665,7 @@ check_forward(struct Client *source_p, struct Channel *chptr, if (hash_find_resv(chptr->chname)) return NULL; /* Don't forward to +Q channel */ - if (chptr->mode.mode & ModuleModes.MODE_DISFORWARD) + if (chptr->mode.mode & MODE_DISFORWARD) return NULL; i = can_join(source_p, chptr, key); if (i == 0) @@ -1873,7 +1886,10 @@ void user_join(struct Client * client_p, struct Client * source_p, const char * continue; } - flags = CHFL_CHANOP; + if(ConfigChannel.admin_on_channel_create && ConfigChannel.use_admin) + flags = CHFL_ADMIN | CHFL_CHANOP; + else + flags = CHFL_CHANOP; } if((rb_dlink_list_length(&source_p->user->channel) >= @@ -1912,7 +1928,7 @@ void user_join(struct Client * client_p, struct Client * source_p, const char * me.name, get_oper_name(source_p), chptr->chname); } else if ((i != ERR_NEEDREGGEDNICK && i != ERR_THROTTLE && i != ERR_INVITEONLYCHAN && i != ERR_CHANNELISFULL) || - (!ModuleModes.MODE_FORWARD || (chptr = check_forward(source_p, chptr, key)) == NULL)) + (!ConfigChannel.use_forward || (chptr = check_forward(source_p, chptr, key)) == NULL)) { /* might be wrong, but is there any other better location for such? * see extensions/chm_operonly.c for other comments on this