X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Firc-oper.c;h=21577f00438956992141cf6c255767763fcdd409;hb=384f965fba126c4724bffb6f7e2d30d8b7fb50cb;hp=a927b1951035aa5b34c0524c263cb6df2cda8c2c;hpb=5462c6c50fd01fd516e29a42ee0b15c946c11d27;p=ngircd-alex.git diff --git a/src/ngircd/irc-oper.c b/src/ngircd/irc-oper.c index a927b195..21577f00 100644 --- a/src/ngircd/irc-oper.c +++ b/src/ngircd/irc-oper.c @@ -1,29 +1,33 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2008 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. - * - * IRC operator commands */ - #include "portab.h" +/** + * @file + * IRC operator commands + */ + #include "imp.h" #include #include #include #include +#include #include "ngircd.h" #include "conn-func.h" #include "conf.h" #include "channel.h" +#include "class.h" #include "irc-write.h" #include "log.h" #include "match.h" @@ -34,7 +38,6 @@ #include #include "irc-oper.h" - /** * Handle invalid received OPER command. * Log OPER attempt and send error message to client. @@ -49,7 +52,15 @@ Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg) Client_ID(Client)); } /* Bad_OperPass */ - +/** + * Handler for the IRC "OPER" command. + * + * See RFC 2812, 3.1.4 "Oper message". + * + * @param Client The client from which this command has been received. + * @param Req Request structure with prefix and all parameters. + * @return CONNECTED or DISCONNECTED. + */ GLOBAL bool IRC_OPER( CLIENT *Client, REQUEST *Req ) { @@ -59,7 +70,9 @@ IRC_OPER( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + if (Req->argc != 2) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); len = array_length(&Conf_Opers, sizeof(*op)); op = array_start(&Conf_Opers); @@ -74,20 +87,33 @@ IRC_OPER( CLIENT *Client, REQUEST *Req ) if (op[i].mask && (!Match(op[i].mask, Client_Mask(Client)))) return Bad_OperPass(Client, op[i].mask, "hostmask check failed"); - if( ! Client_HasMode( Client, 'o' )) - { - Client_ModeAdd( Client, 'o' ); - if( ! IRC_WriteStrClient( Client, "MODE %s :+o", Client_ID( Client ))) return DISCONNECTED; - IRC_WriteStrServersPrefix( NULL, Client, "MODE %s :+o", Client_ID( Client )); + if (!Client_HasMode(Client, 'o')) { + Client_ModeAdd(Client, 'o'); + if (!IRC_WriteStrClient(Client, "MODE %s :+o", + Client_ID(Client))) + return DISCONNECTED; + IRC_WriteStrServersPrefix(NULL, Client, "MODE %s :+o", + Client_ID(Client)); } - if( ! Client_OperByMe( Client )) Log( LOG_NOTICE|LOG_snotice, "Got valid OPER from \"%s\", user is an IRC operator now.", Client_Mask( Client )); + if (!Client_OperByMe(Client)) + Log(LOG_NOTICE|LOG_snotice, + "Got valid OPER from \"%s\", user is an IRC operator now.", + Client_Mask(Client)); - Client_SetOperByMe( Client, true); - return IRC_WriteStrClient( Client, RPL_YOUREOPER_MSG, Client_ID( Client )); + Client_SetOperByMe(Client, true); + return IRC_WriteStrClient(Client, RPL_YOUREOPER_MSG, Client_ID(Client)); } /* IRC_OPER */ - +/** + * Handler for the IRC "DIE" command. + * + * See RFC 2812, 4.3 "Die message". + * + * @param Client The client from which this command has been received. + * @param Req Request structure with prefix and all parameters. + * @return CONNECTED or DISCONNECTED. + */ GLOBAL bool IRC_DIE(CLIENT * Client, REQUEST * Req) { @@ -130,7 +156,15 @@ IRC_DIE(CLIENT * Client, REQUEST * Req) return CONNECTED; } /* IRC_DIE */ - +/** + * Handler for the IRC "REHASH" command. + * + * See RFC 2812, 4.2 "Rehash message". + * + * @param Client The client from which this command has been received. + * @param Req Request structure with prefix and all parameters. + * @return CONNECTED or DISCONNECTED. + */ GLOBAL bool IRC_REHASH( CLIENT *Client, REQUEST *Req ) { @@ -143,15 +177,26 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req ) return Op_NoPrivileges(Client, Req); /* Bad number of parameters? */ - if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + if (Req->argc != 0) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command ); + + Log(LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...", + Client_Mask(Client)); + raise(SIGHUP); - Log( LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...", Client_Mask( Client )); - NGIRCd_SignalRehash = true; - return CONNECTED; } /* IRC_REHASH */ - +/** + * Handler for the IRC "RESTART" command. + * + * See RFC 2812, 4.4 "Restart message". + * + * @param Client The client from which this command has been received. + * @param Req Request structure with prefix and all parameters. + * @return CONNECTED or DISCONNECTED. + */ GLOBAL bool IRC_RESTART( CLIENT *Client, REQUEST *Req ) { @@ -164,16 +209,25 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req ) return Op_NoPrivileges(Client, Req); /* Bad number of parameters? */ - if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + if (Req->argc != 0) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); - Log( LOG_NOTICE|LOG_snotice, "Got RESTART command from \"%s\" ...", Client_Mask( Client )); + Log(LOG_NOTICE|LOG_snotice, "Got RESTART command from \"%s\" ...", + Client_Mask(Client)); NGIRCd_SignalRestart = true; + return CONNECTED; } /* IRC_RESTART */ - /** - * Connect configured or new server. + * Handler for the IRC "CONNECT" command. + * + * See RFC 2812, 3.4.7 "Connect message". + * + * @param Client The client from which this command has been received. + * @param Req Request structure with prefix and all parameters. + * @return CONNECTED or DISCONNECTED. */ GLOBAL bool IRC_CONNECT(CLIENT * Client, REQUEST * Req) @@ -269,9 +323,15 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req) return CONNECTED; } /* IRC_CONNECT */ - /** - * Disconnect (and disable) configured server. + * Handler for the IRC "DISCONNECT" command. + * + * This command is not specified in the IRC RFCs, it is an extension + * of ngIRCd: it shuts down and disables a configured server connection. + * + * @param Client The client from which this command has been received. + * @param Req Request structure with prefix and all parameters. + * @return CONNECTED or DISCONNECTED. */ GLOBAL bool IRC_DISCONNECT(CLIENT * Client, REQUEST * Req) @@ -312,7 +372,15 @@ IRC_DISCONNECT(CLIENT * Client, REQUEST * Req) return DISCONNECTED; } /* IRC_DISCONNECT */ - +/** + * Handler for the IRC "WALLOPS" command. + * + * See RFC 2812, 4.7 "Operwall message". + * + * @param Client The client from which this command has been received. + * @param Req Request structure with prefix and all parameters. + * @return CONNECTED or DISCONNECTED. + */ GLOBAL bool IRC_WALLOPS( CLIENT *Client, REQUEST *Req ) { @@ -322,12 +390,14 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req ) assert( Req != NULL ); if (Req->argc != 1) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); switch (Client_Type(Client)) { case CLIENT_USER: if (!Client_OperByMe(Client)) - return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, Client_ID(Client)); + return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, + Client_ID(Client)); from = Client; break; case CLIENT_SERVER: @@ -338,11 +408,87 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req ) } if (!from) - return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix); + return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + Client_ID(Client), Req->prefix); IRC_SendWallops(Client, from, "%s", Req->argv[0]); return CONNECTED; } /* IRC_WALLOPS */ +/** + * Handle LINE commands (GLINE, KLINE). + * + * @param Client The client from which this command has been received. + * @param Req Request structure with prefix and all parameters. + * @return CONNECTED or DISCONNECTED. + */ +GLOBAL bool +IRC_xLINE(CLIENT *Client, REQUEST *Req) +{ + CLIENT *from; + int class; + char class_c; + + assert(Client != NULL); + assert(Req != NULL); + + from = Op_Check(Client, Req); + if (!from) + return Op_NoPrivileges(Client, Req); + + /* Bad number of parameters? */ + if (Req->argc != 1 && Req->argc != 3) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); + + switch(Req->command[0]) { + case 'g': + case 'G': + class = CLASS_GLINE; class_c = 'G'; + break; + case 'k': + case 'K': + class = CLASS_KLINE; class_c = 'K'; + break; + default: + Log(LOG_CRIT, + "IRC_xLINE() called for unknown line: %c!? Ignored.", + Req->command[0]); + return CONNECTED; + } + + if (Req->argc == 1) { + /* Delete mask from list */ + Class_DeleteMask(class, Req->argv[0]); + Log(LOG_NOTICE|LOG_snotice, + "\"%s\" deleted \"%s\" from %c-Line list.", + Client_Mask(from), Req->argv[0], class_c); + if (class == CLASS_GLINE) { + /* Inform other servers */ + IRC_WriteStrServersPrefix(Client, from, "%s %s", + Req->command, Req->argv[0]); + + } + } else { + /* Add new mask to list */ + if (Class_AddMask(class, Req->argv[0], + time(NULL) + atol(Req->argv[1]), + Req->argv[2])) { + Log(LOG_NOTICE|LOG_snotice, + "\"%s\" added \"%s\" to %c-Line list: \"%s\" (%ld seconds).", + Client_Mask(from), Req->argv[0], class_c, + Req->argv[2], atol(Req->argv[1])); + if (class == CLASS_GLINE) { + /* Inform other servers */ + IRC_WriteStrServersPrefix(Client, from, + "%s %s %s :%s", Req->command, + Req->argv[0], Req->argv[1], + Req->argv[2]); + } + } + } + + return CONNECTED; +} /* -eof- */