ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_trace.c
Revision: 1618
Committed: Tue Oct 30 21:04:38 2012 UTC (11 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 12479 byte(s)
Log Message:
- Made m_globops() and ms_globops() use sendto_realops_flags()
- Added message-type parameter to sendto_realops_flags() which can be one of
  SEND_NOTICE, SEND_GLOBAL, SEND_LOCOPS
- Forward-port -r1617

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_trace.c: Traces a path to a client/server.
4 *
5 * Copyright (C) 2002 by the past and present ircd coders, and others.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "list.h"
27 #include "client.h"
28 #include "hash.h"
29 #include "irc_string.h"
30 #include "ircd.h"
31 #include "numeric.h"
32 #include "s_bsd.h"
33 #include "s_serv.h"
34 #include "send.h"
35 #include "parse.h"
36 #include "modules.h"
37 #include "conf.h"
38
39
40 static void do_actual_trace(struct Client *, int, char *[]);
41 static void report_this_status(struct Client *, struct Client *, int);
42
43 static void
44 trace_get_dependent(int *const server,
45 int *const client, const struct Client *target_p)
46 {
47 const dlink_node *ptr = NULL;
48
49 (*server)++;
50 (*client) += dlink_list_length(&target_p->serv->client_list);
51
52 DLINK_FOREACH(ptr, target_p->serv->server_list.head)
53 trace_get_dependent(server, client, ptr->data);
54 }
55
56 /*
57 * m_trace()
58 *
59 * parv[0] = sender prefix
60 * parv[1] = target client/server to trace
61 */
62 static void
63 m_trace(struct Client *client_p, struct Client *source_p,
64 int parc, char *parv[])
65 {
66 const char *tname;
67
68 if (parc > 1)
69 tname = parv[1];
70 else
71 tname = me.name;
72
73 sendto_one(source_p, form_str(RPL_ENDOFTRACE),
74 me.name, source_p->name, tname);
75 }
76
77
78 /* mo_trace()
79 * parv[0] = sender prefix
80 * parv[1] = servername
81 */
82 static void
83 mo_trace(struct Client *client_p, struct Client *source_p,
84 int parc, char *parv[])
85 {
86 dlink_node *ptr;
87 const char *tname;
88 const char *from, *to;
89
90 if (parc > 2)
91 if (hunt_server(client_p, source_p, ":%s TRACE %s :%s", 2, parc, parv))
92 return;
93
94 if (parc > 1)
95 tname = parv[1];
96 else
97 tname = me.name;
98
99 if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
100 {
101 from = me.id;
102 to = source_p->id;
103 }
104 else
105 {
106 from = me.name;
107 to = source_p->name;
108 }
109
110 switch (hunt_server(client_p, source_p, ":%s TRACE :%s", 1, parc, parv))
111 {
112 case HUNTED_PASS: /* note: gets here only if parv[1] exists */
113 {
114 struct Client *ac2ptr = NULL;
115
116 if ((ac2ptr = hash_find_client(tname)) == NULL)
117 {
118 DLINK_FOREACH(ptr, global_client_list.head)
119 {
120 ac2ptr = ptr->data;
121
122 if (match(tname, ac2ptr->name))
123 break;
124 else
125 ac2ptr = NULL;
126 }
127 }
128
129 if (ac2ptr != NULL)
130 sendto_one(source_p, form_str(RPL_TRACELINK), from, to,
131 ircd_version, tname, ac2ptr->from->name);
132 else
133 sendto_one(source_p, form_str(RPL_TRACELINK), from, to,
134 ircd_version, tname, "ac2ptr_is_NULL!!");
135 return;
136 }
137
138 case HUNTED_ISME:
139 do_actual_trace(source_p, parc, parv);
140 break;
141 default:
142 return;
143 }
144 }
145
146 /*
147 ** ms_trace
148 ** parv[0] = sender prefix
149 ** parv[1] = servername
150 */
151 static void
152 ms_trace(struct Client *client_p, struct Client *source_p,
153 int parc, char *parv[])
154 {
155 if (hunt_server(client_p, source_p, ":%s TRACE %s :%s", 2, parc, parv))
156 return;
157
158 if (HasUMode(source_p, UMODE_OPER))
159 mo_trace(client_p, source_p, parc, parv);
160 }
161
162 static void
163 do_actual_trace(struct Client *source_p, int parc, char *parv[])
164 {
165 struct Client *target_p = NULL;
166 struct ConfItem *conf;
167 struct ClassItem *cltmp;
168 int doall = 0;
169 int wilds, dow;
170 dlink_node *ptr;
171 const char *from, *to, *tname;
172
173 if (parc > 1)
174 tname = parv[1];
175 else
176 tname = me.name;
177
178 if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
179 {
180 from = me.id;
181 to = source_p->id;
182 }
183 else
184 {
185 from = me.name;
186 to = source_p->name;
187 }
188
189 sendto_realops_flags(UMODE_SPY, L_ALL, SEND_NOTICE,
190 "TRACE requested by %s (%s@%s) [%s]",
191 source_p->name, source_p->username,
192 source_p->host, source_p->servptr->name);
193
194 if (match(tname, me.name))
195 doall = 1;
196 else if (!MyClient(source_p) && !strcmp(tname, me.id))
197 {
198 doall = 1;
199 tname = me.name;
200 }
201
202 wilds = !parv[1] || has_wildcards(tname);
203 dow = wilds || doall;
204
205 set_time();
206 if (!HasUMode(source_p, UMODE_OPER) || !dow) /* non-oper traces must be full nicks */
207 /* lets also do this for opers tracing nicks */
208 {
209 const char *name;
210 const char *class_name;
211
212 target_p = hash_find_client(tname);
213
214 if (target_p && IsClient(target_p))
215 {
216 name = get_client_name(target_p, HIDE_IP);
217 class_name = get_client_class(target_p);
218
219 if (HasUMode(target_p, UMODE_OPER))
220 {
221 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
222 from, to, class_name, name,
223 IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost,
224 CurrentTime - target_p->localClient->lasttime,
225 CurrentTime - target_p->localClient->last_privmsg);
226 }
227 else
228 {
229 sendto_one(source_p,form_str(RPL_TRACEUSER),
230 from, to, class_name, name,
231 IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost,
232 CurrentTime - target_p->localClient->lasttime,
233 CurrentTime - target_p->localClient->last_privmsg);
234 }
235 }
236
237 sendto_one(source_p, form_str(RPL_ENDOFTRACE),
238 from, to, tname);
239 return;
240 }
241
242 /* report all direct connections */
243 DLINK_FOREACH(ptr, local_client_list.head)
244 {
245 target_p = ptr->data;
246
247 if (HasUMode(target_p, UMODE_INVISIBLE) && dow &&
248 !(MyConnect(source_p) && HasUMode(source_p, UMODE_OPER)) &&
249 !HasUMode(target_p, UMODE_OPER) && (target_p != source_p))
250 continue;
251 if (!doall && wilds && !match(tname, target_p->name))
252 continue;
253 if (!dow && irccmp(tname, target_p->name))
254 continue;
255
256 report_this_status(source_p, target_p, dow);
257 }
258
259 DLINK_FOREACH(ptr, serv_list.head)
260 {
261 target_p = ptr->data;
262
263 if (!doall && wilds && !match(tname, target_p->name))
264 continue;
265 if (!dow && irccmp(tname, target_p->name))
266 continue;
267
268 report_this_status(source_p, target_p, dow);
269 }
270
271 /* This section is to report the unknowns */
272 DLINK_FOREACH(ptr, unknown_list.head)
273 {
274 target_p = ptr->data;
275
276 if (!doall && wilds && !match(tname, target_p->name))
277 continue;
278 if (!dow && irccmp(tname, target_p->name))
279 continue;
280
281 report_this_status(source_p, target_p, dow);
282 }
283
284 DLINK_FOREACH(ptr, class_items.head)
285 {
286 conf = ptr->data;
287 cltmp = map_to_conf(conf);
288
289 if (cltmp->curr_user_count > 0)
290 sendto_one(source_p, form_str(RPL_TRACECLASS),
291 from, to, conf->name, cltmp->curr_user_count);
292 }
293
294 sendto_one(source_p, form_str(RPL_ENDOFTRACE), from, to, tname);
295 }
296
297 /* report_this_status()
298 *
299 * inputs - pointer to client to report to
300 * - pointer to client to report about
301 * output - counter of number of hits
302 * side effects - NONE
303 */
304 static void
305 report_this_status(struct Client *source_p, struct Client *target_p, int dow)
306 {
307 const char *name;
308 const char *class_name;
309 const char *from, *to;
310
311 if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
312 {
313 from = me.id;
314 to = source_p->id;
315 }
316 else
317 {
318 from = me.name;
319 to = source_p->name;
320 }
321
322 name = get_client_name(target_p, HIDE_IP);
323 class_name = get_client_class(target_p);
324
325 set_time();
326
327 switch (target_p->status)
328 {
329 case STAT_CONNECTING:
330 sendto_one(source_p, form_str(RPL_TRACECONNECTING),
331 from, to, class_name,
332 HasUMode(source_p, UMODE_ADMIN) ? name : target_p->name);
333 break;
334 case STAT_HANDSHAKE:
335 sendto_one(source_p, form_str(RPL_TRACEHANDSHAKE),
336 from, to, class_name,
337 HasUMode(source_p, UMODE_ADMIN) ? name : target_p->name);
338 break;
339 case STAT_ME:
340 break;
341 case STAT_UNKNOWN:
342 /* added time -Taner */
343 sendto_one(source_p, form_str(RPL_TRACEUNKNOWN),
344 from, to, class_name, name, target_p->sockhost,
345 target_p->localClient->firsttime ? /* TBD: can't be 0 */
346 CurrentTime - target_p->localClient->firsttime : -1);
347 break;
348 case STAT_CLIENT:
349 /*
350 * Only opers see users if there is a wildcard
351 * but anyone can see all the opers.
352 */
353 if ((HasUMode(source_p, UMODE_OPER) &&
354 (MyClient(source_p) || !(dow && HasUMode(target_p, UMODE_INVISIBLE))))
355 || !dow || HasUMode(target_p, UMODE_OPER))
356 {
357 if (HasUMode(target_p, UMODE_ADMIN) && !ConfigFileEntry.hide_spoof_ips)
358 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
359 from, to, class_name, name,
360 HasUMode(source_p, UMODE_ADMIN) ? target_p->sockhost : "255.255.255.255",
361 CurrentTime - target_p->localClient->lasttime,
362 CurrentTime - target_p->localClient->last_privmsg);
363
364 else if (HasUMode(target_p, UMODE_OPER))
365 {
366 if (ConfigFileEntry.hide_spoof_ips)
367 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
368 from, to, class_name, name,
369 IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost,
370 CurrentTime - target_p->localClient->lasttime,
371 CurrentTime - target_p->localClient->last_privmsg);
372 else
373 sendto_one(source_p, form_str(RPL_TRACEOPERATOR),
374 from, to, class_name, name,
375 MyOper(source_p) ? target_p->sockhost :
376 (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost),
377 CurrentTime - target_p->localClient->lasttime,
378 CurrentTime - target_p->localClient->last_privmsg);
379 }
380 else
381 {
382 if (ConfigFileEntry.hide_spoof_ips)
383 sendto_one(source_p, form_str(RPL_TRACEUSER),
384 from, to, class_name, name,
385 IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost,
386 CurrentTime - target_p->localClient->lasttime,
387 CurrentTime - target_p->localClient->last_privmsg);
388 else
389 sendto_one(source_p, form_str(RPL_TRACEUSER),
390 from, to, class_name, name,
391 MyOper(source_p) ? target_p->sockhost :
392 (IsIPSpoof(target_p) ? "255.255.255.255" : target_p->sockhost),
393 CurrentTime - target_p->localClient->lasttime,
394 CurrentTime - target_p->localClient->last_privmsg);
395 }
396 }
397 break;
398 case STAT_SERVER:
399 {
400 int clients = 0;
401 int servers = 0;
402
403 trace_get_dependent(&servers, &clients, target_p);
404
405 if (!HasUMode(source_p, UMODE_ADMIN))
406 name = get_client_name(target_p, MASK_IP);
407
408 sendto_one(source_p, form_str(RPL_TRACESERVER),
409 from, to, class_name, servers,
410 clients, name, *(target_p->serv->by) ?
411 target_p->serv->by : "*", "*",
412 me.name, CurrentTime - target_p->localClient->lasttime);
413 break;
414 }
415
416 default: /* ...we actually shouldn't come here... --msa */
417 sendto_one(source_p, form_str(RPL_TRACENEWTYPE),
418 from, to, name);
419 break;
420 }
421 }
422
423 static struct Message trace_msgtab = {
424 "TRACE", 0, 0, 0, MAXPARA, MFLG_SLOW, 0,
425 { m_unregistered, m_trace, ms_trace, m_ignore, mo_trace, m_ignore }
426 };
427
428 static void
429 module_init(void)
430 {
431 mod_add_cmd(&trace_msgtab);
432 }
433
434 static void
435 module_exit(void)
436 {
437 mod_del_cmd(&trace_msgtab);
438 }
439
440 struct module module_entry = {
441 .node = { NULL, NULL, NULL },
442 .name = NULL,
443 .version = "$Revision$",
444 .handle = NULL,
445 .modinit = module_init,
446 .modexit = module_exit,
447 .flags = 0
448 };

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision