ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_trace.c
Revision: 1241
Committed: Thu Sep 29 20:26:09 2011 UTC (15 years ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/m_trace.c
File size: 12765 byte(s)
Log Message:
- move firsttime, since, and lasttime Client struct members to LocalUser struct
- m_watch.c: show_watch() now properly reports signon times. This also fixes
  an invalid signon time of zero for remote clients.

File Contents

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

Properties

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