X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Firc-channel.c;h=72fbdc242f6069cc4758dbda43cb666d2426feca;hp=52ba0930caac5c9ab89f189dd684fe65e7976529;hb=62a07596d6a3a8da206bde8d34edc8b02781d33d;hpb=c5beca8aabab6d1822f63e86e5db02649d7b1a41 diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c index 52ba0930..72fbdc24 100644 --- a/src/ngircd/irc-channel.c +++ b/src/ngircd/irc-channel.c @@ -82,7 +82,7 @@ static bool join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame, const char *key) { - bool is_invited, is_banned; + bool is_invited, is_banned, is_exception; const char *channel_modes; /* Allow IRC operators to overwrite channel limits */ @@ -90,9 +90,10 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame, return true; is_banned = Lists_Check(Channel_GetListBans(chan), Client); + is_exception = Lists_Check(Channel_GetListExcepts(chan), Client); is_invited = Lists_Check(Channel_GetListInvites(chan), Client); - if (is_banned && !is_invited) { + if (is_banned && !is_invited && !is_exception) { /* Client is banned from channel (and not on invite list) */ IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG, Client_ID(Client), channame); @@ -364,22 +365,32 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req ) /* channel must be created, but forbidden by config */ IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG, Client_ID(Client), channame); - break; + goto join_next; } /* Local client? */ if (Client_Type(Client) == CLIENT_USER) { + if (chan) { + /* Already existing channel: already member? */ + if (Channel_IsMemberOf(chan, Client)) + goto join_next; + } + /* Test if the user has reached the channel limit */ if ((Conf_MaxJoins > 0) && - (Channel_CountForUser(Client) >= Conf_MaxJoins)) - return IRC_WriteStrClient(Client, + (Channel_CountForUser(Client) >= Conf_MaxJoins)) { + if (!IRC_WriteStrClient(Client, ERR_TOOMANYCHANNELS_MSG, - Client_ID(Client), channame); + Client_ID(Client), channame)) + return DISCONNECTED; + goto join_next; + } + if (chan) { /* Already existing channel: check if the * client is allowed to join */ if (!join_allowed(Client, chan, channame, key)) - break; + goto join_next; } else { /* New channel: first user will become channel * operator unless this is a modeless channel */ @@ -499,7 +510,7 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req ) CHANNEL *chan; CLIENT *from; char *topic; - bool onchannel, topicok, use_servermode, r; + bool r, is_oper; assert( Client != NULL ); assert( Req != NULL ); @@ -522,10 +533,9 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req ) return IRC_WriteStrClient(from, ERR_NOSUCHCHANNEL_MSG, Client_ID(from), Req->argv[0]); - Channel_CheckAdminRights(chan, Client, from, - &onchannel, &topicok, &use_servermode); - - if (!onchannel && !topicok) + /* Only IRC opers and channel members allowed */ + is_oper = Client_OperByMe(from); + if (!Channel_IsMemberOf(chan, from) && !is_oper) return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG, Client_ID(from), Req->argv[0]); @@ -554,8 +564,12 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req ) } if (strchr(Channel_Modes(chan), 't')) { - /* Topic Lock. Is the user a channel or IRC operator? */ - if (!topicok) + /* Topic Lock. Is the user a channel op or IRC operator? */ + if(!strchr(Channel_UserModes(chan, from), 'h') && + !strchr(Channel_UserModes(chan, from), 'o') && + !strchr(Channel_UserModes(chan, from), 'a') && + !strchr(Channel_UserModes(chan, from), 'q') && + !is_oper) return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG, Client_ID(from), Channel_Name(chan)); @@ -567,7 +581,7 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req ) Client_TypeText(from), Client_Mask(from), Channel_Name(chan), Req->argv[1][0] ? Req->argv[1] : ""); - if (use_servermode) + if (Conf_OperServerMode) from = Client_ThisServer(); /* Update channel and forward new topic to other servers */ @@ -640,7 +654,7 @@ IRC_LIST( CLIENT *Client, REQUEST *Req ) /* Target is indeed an other server, forward it! */ return IRC_WriteStrClientPrefix(target, from, "LIST %s :%s", - Client_ID(from), + Req->argv[0], Req->argv[1]); } } @@ -655,7 +669,8 @@ IRC_LIST( CLIENT *Client, REQUEST *Req ) if (MatchCaseInsensitive(pattern, Channel_Name(chan))) { /* Gotcha! */ if (!strchr(Channel_Modes(chan), 's') - || Channel_IsMemberOf(chan, from)) { + || Channel_IsMemberOf(chan, from) + || (!Conf_MorePrivacy && Client_OperByMe(Client))) { if (IRC_CheckListTooBig(from, count, MAX_RPL_LIST, "LIST"))