X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Firc-oper.c;h=237107f69b8f56c828f212122da415cee247ba1b;hp=8492603dcbc42b710b5c10771e3021787e893484;hb=48326e061aacd954e24f76c53ded10448cbc28eb;hpb=28ca31e5761c0f5e746fcd0f4cdfac98e344bdb7 diff --git a/src/ngircd/irc-oper.c b/src/ngircd/irc-oper.c index 8492603d..237107f6 100644 --- a/src/ngircd/irc-oper.c +++ b/src/ngircd/irc-oper.c @@ -1,31 +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 "resolve.h" #include "conn-func.h" #include "conf.h" -#include "client.h" #include "channel.h" +#include "class.h" #include "irc-write.h" #include "log.h" #include "match.h" @@ -36,7 +38,6 @@ #include #include "irc-oper.h" - /** * Handle invalid received OPER command. * Log OPER attempt and send error message to client. @@ -51,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 ) { @@ -61,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); @@ -76,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) { @@ -132,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 ) { @@ -145,15 +177,28 @@ 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)); + IRC_WriteStrClient(Client, RPL_REHASHING_MSG, Client_ID(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 ) { @@ -166,16 +211,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) @@ -271,9 +325,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) @@ -314,7 +374,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 ) { @@ -324,12 +392,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: @@ -340,11 +410,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- */