New configuration option "Mask" for [Operator] sections to limit OPER command.
[ngircd-alex.git] / src / ngircd / irc-oper.c
1 /*
2  * ngIRCd -- The Next Generation IRC Daemon
3  * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * Please read the file COPYING, README and AUTHORS for more information.
10  *
11  * IRC operator commands
12  */
13
14
15 #include "portab.h"
16
17 static char UNUSED id[] = "$Id: irc-oper.c,v 1.18 2005/03/02 16:07:31 alex Exp $";
18
19 #include "imp.h"
20 #include <assert.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "ngircd.h"
25 #include "resolve.h"
26 #include "conn.h"
27 #include "conf.h"
28 #include "client.h"
29 #include "channel.h"
30 #include "irc-write.h"
31 #include "log.h"
32 #include "messages.h"
33 #include "parse.h"
34
35 #include <exp.h>
36 #include "irc-oper.h"
37
38
39 GLOBAL BOOLEAN
40 IRC_OPER( CLIENT *Client, REQUEST *Req )
41 {
42         INT i;
43
44         assert( Client != NULL );
45         assert( Req != NULL );
46
47         /* Falsche Anzahl Parameter? */
48         if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
49
50         /* Operator suchen */
51         for( i = 0; i < Conf_Oper_Count; i++)
52         {
53                 if( Conf_Oper[i].name[0] && Conf_Oper[i].pwd[0] && ( strcmp( Conf_Oper[i].name, Req->argv[0] ) == 0 )) break;
54         }
55         if( i >= Conf_Oper_Count )
56         {
57                 Log( LOG_WARNING, "Got invalid OPER from \"%s\": Name \"%s\" not configured!", Client_Mask( Client ), Req->argv[0] );
58                 return IRC_WriteStrClient( Client, ERR_PASSWDMISMATCH_MSG, Client_ID( Client ));
59         }
60
61         /* Stimmt das Passwort? */
62         if( strcmp( Conf_Oper[i].pwd, Req->argv[1] ) != 0 )
63         {
64                 Log( LOG_WARNING, "Got invalid OPER from \"%s\": Bad password for \"%s\"!", Client_Mask( Client ), Conf_Oper[i].name );
65                 return IRC_WriteStrClient( Client, ERR_PASSWDMISMATCH_MSG, Client_ID( Client ));
66         }
67
68         /* Authorized Mask? */
69         if( Conf_Oper[i].mask && (! Match( Conf_Oper[i].mask, Client_Mask( Client ) ))) {
70                 Log( LOG_WARNING, "Rejected valid OPER for \"%s\": Mask mismatch (got: \"%s\", want: \"%s\")!", Conf_Oper[i].name, Client_Mask( Client ), Conf_Oper[i].mask );
71                 return IRC_WriteStrClient( Client, ERR_PASSWDMISMATCH_MSG, Client_ID( Client ));
72         }
73
74
75         if( ! Client_HasMode( Client, 'o' ))
76         {
77                 /* noch kein o-Mode gesetzt */
78                 Client_ModeAdd( Client, 'o' );
79                 if( ! IRC_WriteStrClient( Client, "MODE %s :+o", Client_ID( Client ))) return DISCONNECTED;
80                 IRC_WriteStrServersPrefix( NULL, Client, "MODE %s :+o", Client_ID( Client ));
81         }
82
83         if( ! Client_OperByMe( Client )) Log( LOG_NOTICE|LOG_snotice, "Got valid OPER from \"%s\", user is an IRC operator now.", Client_Mask( Client ));
84
85         Client_SetOperByMe( Client, TRUE );
86         return IRC_WriteStrClient( Client, RPL_YOUREOPER_MSG, Client_ID( Client ));
87 } /* IRC_OPER */
88
89
90 GLOBAL BOOLEAN
91 IRC_DIE( CLIENT *Client, REQUEST *Req )
92 {
93         /* Shut down server */
94
95         assert( Client != NULL );
96         assert( Req != NULL );
97
98         /* Not a local IRC operator? */
99         if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
100         
101         /* Bad number of parameters? */
102         if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
103
104         Log( LOG_NOTICE|LOG_snotice, "Got DIE command from \"%s\" ...", Client_Mask( Client ));
105         NGIRCd_SignalQuit = TRUE;
106         return CONNECTED;
107 } /* IRC_DIE */
108
109
110 GLOBAL BOOLEAN
111 IRC_REHASH( CLIENT *Client, REQUEST *Req )
112 {
113         /* Reload configuration file */
114
115         assert( Client != NULL );
116         assert( Req != NULL );
117
118         /* Not a local IRC operator? */
119         if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
120
121         /* Bad number of parameters? */
122         if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
123
124         Log( LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...", Client_Mask( Client ));
125         NGIRCd_SignalRehash = TRUE;
126         
127         return CONNECTED;
128 } /* IRC_REHASH */
129
130
131 GLOBAL BOOLEAN
132 IRC_RESTART( CLIENT *Client, REQUEST *Req )
133 {
134         /* Restart IRC server (fork a new process) */
135
136         assert( Client != NULL );
137         assert( Req != NULL );
138
139         /* Not a local IRC operator? */
140         if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
141
142         /* Bad number of parameters? */
143         if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
144
145         Log( LOG_NOTICE|LOG_snotice, "Got RESTART command from \"%s\" ...", Client_Mask( Client ));
146         NGIRCd_SignalRestart = TRUE;
147         return CONNECTED;
148 } /* IRC_RESTART */
149
150
151 GLOBAL BOOLEAN
152 IRC_CONNECT(CLIENT *Client, REQUEST *Req )
153 {
154         /* Connect configured or new server */
155
156         assert( Client != NULL );
157         assert( Req != NULL );
158
159         /* Not a local IRC operator? */
160         if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
161
162         /* Bad number of parameters? */
163         if(( Req->argc != 2 ) && ( Req->argc != 5 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
164
165         /* Invalid port number? */
166         if( atoi( Req->argv[1] ) < 1 )  return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
167
168         Log( LOG_NOTICE|LOG_snotice, "Got CONNECT command from \"%s\" for \"%s\".", Client_Mask( Client ), Req->argv[0]);
169
170         if( Req->argc == 2 )
171         {
172                 /* Connect configured server */
173                 if( ! Conf_EnableServer( Req->argv[0], atoi( Req->argv[1] ))) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
174         }
175         else
176         {
177                 /* Add server */
178                 if( ! Conf_AddServer( Req->argv[0], atoi( Req->argv[1] ), Req->argv[2], Req->argv[3], Req->argv[4] )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
179         }
180         return CONNECTED;
181 } /* IRC_CONNECT */
182
183
184 GLOBAL BOOLEAN
185 IRC_DISCONNECT(CLIENT *Client, REQUEST *Req )
186 {
187         /* Disconnect and disable configured server */
188
189         CONN_ID my_conn;
190
191         assert( Client != NULL );
192         assert( Req != NULL );
193
194         /* Not a local IRC operator? */
195         if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
196
197         /* Bad number of parameters? */
198         if( Req->argc != 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
199
200         Log( LOG_NOTICE|LOG_snotice, "Got DISCONNECT command from \"%s\" for0 \"%s\".", Client_Mask( Client ), Req->argv[0]);
201
202         /* Save ID of this connection */
203         my_conn = Client_Conn( Client );
204
205         /* Connect configured server */
206         if( ! Conf_DisableServer( Req->argv[0] )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
207
208         /* Are we still connected or were we killed, too? */
209         if( Client_GetFromConn( my_conn )) return CONNECTED;
210         else return DISCONNECTED;
211 } /* IRC_CONNECT */
212
213
214 /* -eof- */