1 /*
2  *  ircd-ratbox: A slightly useful ircd.
3  *  m_admin.c: Sends administrative information to a user.
4  *
5  *  Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6  *  Copyright (C) 1996-2002 Hybrid Development Team
7  *  Copyright (C) 2002-2012 ircd-ratbox development team
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
22  *  USA
23  *
24  *  $Id: m_admin.c 27371 2012-03-16 05:33:15Z dubkat $
25  */
26 
27 #include "stdinc.h"
28 #include "struct.h"
29 #include "client.h"
30 #include "ircd.h"
31 #include "numeric.h"
32 #include "s_conf.h"
33 #include "s_serv.h"
34 #include "send.h"
35 #include "parse.h"
36 #include "hook.h"
37 #include "modules.h"
38 #include "match.h"
39 
40 static int m_admin(struct Client *, struct Client *, int, const char **);
41 static int mr_admin(struct Client *, struct Client *, int, const char **);
42 static int ms_admin(struct Client *, struct Client *, int, const char **);
43 static void do_admin(struct Client *source_p);
44 
45 static void admin_spy(struct Client *);
46 
47 struct Message admin_msgtab = {
48 	"ADMIN", 0, 0, 0, MFLG_SLOW | MFLG_UNREG,
49 	{{mr_admin, 0}, {m_admin, 0}, {ms_admin, 0}, mg_ignore, mg_ignore, {ms_admin, 0}}
50 };
51 
52 int doing_admin_hook;
53 
54 mapi_clist_av1 admin_clist[] = { &admin_msgtab, NULL };
55 
56 mapi_hlist_av1 admin_hlist[] = {
57 	{"doing_admin", &doing_admin_hook},
58 	{NULL, NULL}
59 };
60 
61 DECLARE_MODULE_AV1(admin, NULL, NULL, admin_clist, admin_hlist, NULL, "$Revision: 27371 $");
62 
63 /*
64  * mr_admin - ADMIN command handler
65  *      parv[0] = sender prefix
66  *      parv[1] = servername
67  */
68 static int
mr_admin(struct Client * client_p,struct Client * source_p,int parc,const char * parv[])69 mr_admin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
70 {
71 	static time_t last_used = 0L;
72 
73 	if((last_used + ConfigFileEntry.pace_wait) > rb_current_time())
74 	{
75 		sendto_one(source_p, form_str(RPL_LOAD2HI),
76 			   me.name, EmptyString(source_p->name) ? "*" : source_p->name, "ADMIN");
77 		return 0;
78 	}
79 	else
80 		last_used = rb_current_time();
81 
82 	do_admin(source_p);
83 
84 	return 0;
85 }
86 
87 /*
88  * m_admin - ADMIN command handler
89  *      parv[0] = sender prefix
90  *      parv[1] = servername
91  */
92 static int
m_admin(struct Client * client_p,struct Client * source_p,int parc,const char * parv[])93 m_admin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
94 {
95 	static time_t last_used = 0L;
96 
97 	if(parc > 1)
98 	{
99 		if((last_used + ConfigFileEntry.pace_wait) > rb_current_time())
100 		{
101 			sendto_one(source_p, form_str(RPL_LOAD2HI),
102 				   me.name, source_p->name, "ADMIN");
103 			return 0;
104 		}
105 		else
106 			last_used = rb_current_time();
107 
108 		if(hunt_server(client_p, source_p, ":%s ADMIN :%s", 1, parc, parv) != HUNTED_ISME)
109 			return 0;
110 	}
111 
112 	do_admin(source_p);
113 
114 	return 0;
115 }
116 
117 
118 /*
119  * ms_admin - ADMIN command handler, used for OPERS as well
120  *      parv[0] = sender prefix
121  *      parv[1] = servername
122  */
123 static int
ms_admin(struct Client * client_p,struct Client * source_p,int parc,const char * parv[])124 ms_admin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
125 {
126 	if(hunt_server(client_p, source_p, ":%s ADMIN :%s", 1, parc, parv) != HUNTED_ISME)
127 		return 0;
128 
129 	do_admin(source_p);
130 
131 	return 0;
132 }
133 
134 
135 /*
136  * do_admin
137  *
138  * inputs	- pointer to client to report to
139  * output	- none
140  * side effects	- admin info is sent to client given
141  */
142 static void
do_admin(struct Client * source_p)143 do_admin(struct Client *source_p)
144 {
145 	const char *myname;
146 	const char *nick;
147 
148 	if(IsClient(source_p))
149 		admin_spy(source_p);
150 
151 	myname = get_id(&me, source_p);
152 	nick = EmptyString(source_p->name) ? "*" : get_id(source_p, source_p);
153 	SetCork(source_p);
154 	sendto_one(source_p, form_str(RPL_ADMINME), myname, nick, me.name);
155 	if(AdminInfo.name != NULL)
156 		sendto_one(source_p, form_str(RPL_ADMINLOC1), myname, nick, AdminInfo.name);
157 	if(AdminInfo.description != NULL)
158 		sendto_one(source_p, form_str(RPL_ADMINLOC2), myname, nick, AdminInfo.description);
159 	if(AdminInfo.email != NULL)
160 		sendto_one(source_p, form_str(RPL_ADMINEMAIL), myname, nick, AdminInfo.email);
161 	ClearCork(source_p);
162 	send_pop_queue(source_p);
163 }
164 
165 /* admin_spy()
166  *
167  * input	- pointer to client
168  * output	- none
169  * side effects - event doing_admin is called
170  */
171 static void
admin_spy(struct Client * source_p)172 admin_spy(struct Client *source_p)
173 {
174 	hook_data hd;
175 
176 	hd.client = source_p;
177 	hd.arg1 = hd.arg2 = NULL;
178 
179 	call_hook(doing_admin_hook, &hd);
180 }
181