commit ba32d594fd7a93305cd01a14978971d948392510 from: Alexander Barton date: Sun Jan 09 21:40:11 2011 UTC Channel_CheckAdminRights(): test if client can admin a channel This generic function tests if a client is allowed to do administrative tasks to a specific channel: - servers and services are always truested ("allowed everything"), - channel operators are allowed, - IRC operarors are allowed if OperCanUseMode is set in the config. commit - 3460c87c589b0bfd735dbdd761e9a508a2d9a3c7 commit + ba32d594fd7a93305cd01a14978971d948392510 blob - e49e5a9a6127cc3f34771af77af096fc6d951eb6 blob + c8c15d96c3a6033d401a3e61be5caf69e5c3b2aa --- src/ngircd/channel.c +++ src/ngircd/channel.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2009 Alexander Barton (alex@barton.de) + * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1117,8 +1117,66 @@ Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const fclose(fd); return false; } /* Channel_CheckKey */ + + +/** + * Check wether a client is allowed to administer a channel or not. + * + * @param Chan The channel to test. + * @param Client The client from which the command has been received. + * @param Origin The originator of the command (or NULL). + * @param OnChannel Set to true if the originator is member of the channel. + * @param AdminOk Set to true if the client is allowed to do + * administrative tasks on this channel. + * @param UseServerMode Set to true if ngIRCd should emulate "server mode", + * that is send commands as if originating from a server + * and not the originator of the command. + */ +GLOBAL void +Channel_CheckAdminRights(CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, + bool *OnChannel, bool *AdminOk, bool *UseServerMode) +{ + assert (Chan != NULL); + assert (Client != NULL); + assert (OnChannel != NULL); + assert (AdminOk != NULL); + assert (UseServerMode != NULL); + + /* Use the client as origin, if no origin has been given (no prefix?) */ + if (!Origin) + Origin = Client; + + *OnChannel = false; + *AdminOk = false; + *UseServerMode = false; + if (Client_Type(Client) != CLIENT_USER + && Client_Type(Client) != CLIENT_SERVER + && Client_Type(Client) != CLIENT_SERVICE) + return; + /* Allow channel administration if the client is a server or service */ + if (Client_Type(Client) != CLIENT_USER) { + *AdminOk = true; + return; + } + + *OnChannel = Channel_IsMemberOf(Chan, Origin); + + if (*OnChannel && strchr(Channel_UserModes(Chan, Origin), 'o')) { + /* User is a channel operator */ + *AdminOk = true; + } else if (Conf_OperCanMode) { + /* IRC operators are allowed to administer channels as well */ + if (Client_OperByMe(Origin)) { + *AdminOk = true; + if (Conf_OperServerMode) + *UseServerMode = true; + } + } +} /* Channel_CheckAdminRights */ + + static CL2CHAN * Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan ) { blob - 030f9109ceff0eb7bbfa42d435ead49740dc29da blob + b912aab4dc5260b7c447e704b3246976741d0d7e --- src/ngircd/channel.h +++ src/ngircd/channel.h @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2008 by Alexander Barton (alex@barton.de) + * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -133,6 +133,10 @@ GLOBAL void Channel_LogServer PARAMS((const char *msg) GLOBAL bool Channel_CheckKey PARAMS((CHANNEL *Chan, CLIENT *Client, const char *Key)); +GLOBAL void Channel_CheckAdminRights PARAMS((CHANNEL *Chan, CLIENT *Client, + CLIENT *Origin, bool *OnChannel, + bool *AdminOk, bool *UseServerMode)); + #define Channel_IsLocal(c) (Channel_Name(c)[0] == '&') #define Channel_IsModeless(c) (Channel_Name(c)[0] == '+') blob - a4c1d89b330ed175bb02ea158c595693a22be11e blob + 1e6772a69e636a6288ecf1393cf8db96eff7df47 --- src/ngircd/irc-mode.c +++ src/ngircd/irc-mode.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2010 Alexander Barton (alex@barton.de) + * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -316,8 +316,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Ori { char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], argadd[CLIENT_PASS_LEN], *mode_ptr; - bool connected, set, skiponce, retval, onchannel; - bool modeok = true, use_servermode = false; + bool connected, set, skiponce, retval, onchannel, modeok, use_servermode; int mode_arg, arg_arg; CLIENT *client; long l; @@ -331,28 +330,13 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Ori if (Req->argc <= 1) return Channel_Mode_Answer_Request(Origin, Channel); - /* Is the user allowed to change modes? */ - if (Client_Type(Client) == CLIENT_USER) { - /* Is the originating user on that channel? */ - onchannel = Channel_IsMemberOf(Channel, Origin); - modeok = false; - /* channel operator? */ - if (onchannel && - strchr(Channel_UserModes(Channel, Origin), 'o')) { - modeok = true; - } else if (Conf_OperCanMode) { - /* IRC-Operators can use MODE as well */ - if (Client_OperByMe(Origin)) { - modeok = true; - if (Conf_OperServerMode) - use_servermode = true; /* Change Origin to Server */ - } - } + Channel_CheckAdminRights(Channel, Client, Origin, + &onchannel, &modeok, &use_servermode); - if (!onchannel && !modeok) - return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG, - Client_ID(Origin), Channel_Name(Channel)); - } + if (!onchannel && !modeok) + return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG, + Client_ID(Origin), + Channel_Name(Channel)); mode_arg = 1; mode_ptr = Req->argv[mode_arg];