/[svn]/ircd-hybrid/trunk/modules/core/m_server.c
ViewVC logotype

Contents of /ircd-hybrid/trunk/modules/core/m_server.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1624 - (show annotations)
Thu Nov 1 13:27:04 2012 UTC (7 years, 9 months ago) by michael
File MIME type: text/x-chdr
File size: 20435 byte(s)
- Fixed compile warnings due to missing arguments to sendto_realops_flags()

1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_server.c: Introduces a 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" /* client struct */
28 #include "event.h"
29 #include "hash.h" /* add_to_client_hash_table */
30 #include "irc_string.h"
31 #include "ircd.h" /* me */
32 #include "numeric.h" /* ERR_xxx */
33 #include "conf.h" /* struct AccessItem */
34 #include "log.h" /* log level defines */
35 #include "s_serv.h" /* server_estab, check_server */
36 #include "s_user.h"
37 #include "send.h" /* sendto_one */
38 #include "parse.h"
39 #include "modules.h"
40
41
42 static void set_server_gecos(struct Client *, const char *);
43
44 /* mr_server()
45 * parv[0] = sender prefix
46 * parv[1] = servername
47 * parv[2] = serverinfo/hopcount
48 * parv[3] = serverinfo
49 */
50 static void
51 mr_server(struct Client *client_p, struct Client *source_p,
52 int parc, char *parv[])
53 {
54 char *name;
55 struct Client *target_p;
56 int hop;
57
58 if (EmptyString(parv[3]))
59 {
60 sendto_one(client_p, "ERROR :No servername");
61 exit_client(client_p, client_p, "Wrong number of args");
62 return;
63 }
64
65 name = parv[1];
66 hop = atoi(parv[2]);
67
68 /*
69 * Reject a direct nonTS server connection if we're TS_ONLY -orabidoo
70 */
71 if (!DoesTS(client_p))
72 {
73 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
74 "Unauthorized server connection attempt from %s: Non-TS server "
75 "for server %s", get_client_name(client_p, HIDE_IP), name);
76 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
77 "Unauthorized server connection attempt from %s: Non-TS server "
78 "for server %s", get_client_name(client_p, MASK_IP), name);
79 exit_client(client_p, client_p, "Non-TS server");
80 return;
81 }
82
83 if (!valid_servname(name))
84 {
85 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
86 "Unauthorized server connection attempt from %s: Bogus server name "
87 "for server %s", get_client_name(client_p, HIDE_IP), name);
88 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
89 "Unauthorized server connection attempt from %s: Bogus server name "
90 "for server %s", get_client_name(client_p, MASK_IP), name);
91 exit_client(client_p, client_p, "Bogus server name");
92 return;
93 }
94
95 /* Now we just have to call check_server and everything should
96 * be check for us... -A1kmm.
97 */
98 switch (check_server(name, client_p))
99 {
100 case -1:
101 if (ConfigFileEntry.warn_no_nline)
102 {
103 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
104 "Unauthorized server connection attempt from %s: No entry for "
105 "servername %s", get_client_name(client_p, HIDE_IP), name);
106
107 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
108 "Unauthorized server connection attempt from %s: No entry for "
109 "servername %s", get_client_name(client_p, MASK_IP), name);
110 }
111
112 exit_client(client_p, client_p, "Invalid servername.");
113 return;
114 /* NOT REACHED */
115 break;
116
117 case -2:
118 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
119 "Unauthorized server connection attempt from %s: Bad password "
120 "for server %s", get_client_name(client_p, HIDE_IP), name);
121
122 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
123 "Unauthorized server connection attempt from %s: Bad password "
124 "for server %s", get_client_name(client_p, MASK_IP), name);
125
126 exit_client(client_p, client_p, "Invalid password.");
127 return;
128 /* NOT REACHED */
129 break;
130
131 case -3:
132 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
133 "Unauthorized server connection attempt from %s: Invalid host "
134 "for server %s", get_client_name(client_p, HIDE_IP), name);
135
136 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
137 "Unauthorized server connection attempt from %s: Invalid host "
138 "for server %s", get_client_name(client_p, MASK_IP), name);
139
140 exit_client(client_p, client_p, "Invalid host.");
141 return;
142 /* NOT REACHED */
143 break;
144 }
145
146 if ((client_p->id[0] && (target_p = hash_find_id(client_p->id)))
147 || (target_p = hash_find_server(name)))
148 {
149 /* This link is trying feed me a server that I already have
150 * access through another path -- multiple paths not accepted
151 * currently, kill this link immediately!!
152 *
153 * Rather than KILL the link which introduced it, KILL the
154 * youngest of the two links. -avalon
155 *
156 * Definitely don't do that here. This is from an unregistered
157 * connect - A1kmm.
158 */
159 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
160 "Attempt to re-introduce server %s SID %s from %s",
161 name, client_p->id,
162 get_client_name(client_p, HIDE_IP));
163 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
164 "Attempt to re-introduce server %s SID %s from %s",
165 name, client_p->id,
166 get_client_name(client_p, MASK_IP));
167 sendto_one(client_p, "ERROR :Server ID already exists.");
168 exit_client(client_p, client_p, "Server ID Exists");
169 return;
170 }
171
172 /* XXX If somehow there is a connect in progress and
173 * a connect comes in with same name toss the pending one,
174 * but only if it's not the same client! - Dianora
175 */
176 if ((target_p = find_servconn_in_progress(name)))
177 if (target_p != client_p)
178 exit_client(target_p, &me, "Overridden");
179
180 /* if we are connecting (Handshake), we already have the name from the
181 * connect{} block in client_p->name
182 */
183 strlcpy(client_p->name, name, sizeof(client_p->name));
184 set_server_gecos(client_p, parv[3]);
185 client_p->hopcount = hop;
186 server_estab(client_p);
187 }
188
189 /* ms_server()
190 * parv[0] = sender prefix
191 * parv[1] = servername
192 * parv[2] = serverinfo/hopcount
193 * parv[3] = serverinfo
194 */
195 static void
196 ms_server(struct Client *client_p, struct Client *source_p,
197 int parc, char *parv[])
198 {
199 char *name;
200 struct Client *target_p;
201 struct AccessItem *aconf;
202 int hop;
203 int hlined = 0;
204 int llined = 0;
205 dlink_node *ptr = NULL;
206
207 /* Just to be sure -A1kmm. */
208 if (!IsServer(source_p))
209 return;
210
211 if (EmptyString(parv[3]))
212 {
213 sendto_one(client_p, "ERROR :No servername");
214 return;
215 }
216
217 name = parv[1];
218 hop = atoi(parv[2]);
219
220 if (!valid_servname(name))
221 {
222 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
223 "Link %s introduced server with bogus server name %s",
224 get_client_name(client_p, SHOW_IP), name);
225 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
226 "Link %s introduced server with bogus server name %s",
227 get_client_name(client_p, MASK_IP), name);
228 sendto_one(client_p, "ERROR :Bogus server name introduced");
229 exit_client(client_p, &me, "Bogus server name intoduced");
230 return;
231 }
232
233 if ((target_p = hash_find_server(name)))
234 {
235 /* This link is trying feed me a server that I already have
236 * access through another path -- multiple paths not accepted
237 * currently, kill this link immediately!!
238 *
239 * Rather than KILL the link which introduced it, KILL the
240 * youngest of the two links. -avalon
241 *
242 * I think that we should exit the link itself, not the introducer,
243 * and we should always exit the most recently received(i.e. the
244 * one we are receiving this SERVER for. -A1kmm
245 *
246 * You *cant* do this, if you link somewhere, it bursts you a server
247 * that already exists, then sends you a client burst, you squit the
248 * server, but you keep getting the burst of clients on a server that
249 * doesnt exist, although ircd can handle it, its not a realistic
250 * solution.. --fl_
251 */
252 sendto_one(client_p, "ERROR :Server %s already exists", name);
253 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
254 "Link %s cancelled, server %s already exists",
255 get_client_name(client_p, SHOW_IP), name);
256 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
257 "Link %s cancelled, server %s already exists",
258 client_p->name, name);
259 exit_client(client_p, &me, "Server Exists");
260 return;
261 }
262
263 /* XXX If somehow there is a connect in progress and
264 * a connect comes in with same name toss the pending one,
265 * but only if it's not the same client! - Dianora
266 */
267 if ((target_p = find_servconn_in_progress(name)))
268 if (target_p != client_p)
269 exit_client(target_p, &me, "Overridden");
270
271 aconf = map_to_conf(client_p->localClient->confs.head->data);
272
273 /* See if the newly found server is behind a guaranteed
274 * leaf. If so, close the link.
275 */
276 DLINK_FOREACH(ptr, aconf->leaf_list.head)
277 if (match(ptr->data, name))
278 {
279 llined = 1;
280 break;
281 }
282
283 DLINK_FOREACH(ptr, aconf->hub_list.head)
284 if (match(ptr->data, name))
285 {
286 hlined = 1;
287 break;
288 }
289
290 /* Ok, this way this works is
291 *
292 * A server can have a CONF_HUB allowing it to introduce servers
293 * behind it.
294 *
295 * connect {
296 * name = "irc.bighub.net";
297 * hub_mask="*";
298 * ...
299 *
300 * That would allow "irc.bighub.net" to introduce anything it wanted..
301 *
302 * However
303 *
304 * connect {
305 * name = "irc.somehub.fi";
306 * hub_mask="*";
307 * leaf_mask="*.edu";
308 *...
309 * Would allow this server in finland to hub anything but
310 * .edu's
311 */
312
313 /* Ok, check client_p can hub the new server */
314 if (!hlined)
315 {
316 /* OOOPs nope can't HUB */
317 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
318 "Non-Hub link %s introduced %s.",
319 get_client_name(client_p, HIDE_IP), name);
320 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
321 "Non-Hub link %s introduced %s.",
322 get_client_name(client_p, MASK_IP), name);
323 exit_client(source_p, &me, "No matching hub_mask.");
324 return;
325 }
326
327 /* Check for the new server being leafed behind this HUB */
328 if (llined)
329 {
330 /* OOOPs nope can't HUB this leaf */
331 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
332 "Link %s introduced leafed server %s.",
333 get_client_name(client_p, HIDE_IP), name);
334 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
335 "Link %s introduced leafed server %s.",
336 get_client_name(client_p, MASK_IP), name);
337 /* If it is new, we are probably misconfigured, so split the
338 * non-hub server introducing this. Otherwise, split the new
339 * server. -A1kmm.
340 */
341 /* wastes too much bandwidth, generates too many errors on
342 * larger networks, dont bother. --fl_
343 */
344 exit_client(client_p, &me, "Leafed Server.");
345 return;
346 }
347
348 target_p = make_client(client_p);
349 make_server(target_p);
350 target_p->hopcount = hop;
351 target_p->servptr = source_p;
352
353 strlcpy(target_p->name, name, sizeof(target_p->name));
354
355 set_server_gecos(target_p, parv[3]);
356 SetServer(target_p);
357
358 if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(SERVICE_TYPE, target_p->name, NULL, NULL, 0))
359 AddFlag(target_p, FLAGS_SERVICE);
360
361 dlinkAdd(target_p, &target_p->node, &global_client_list);
362 dlinkAdd(target_p, make_dlink_node(), &global_serv_list);
363 dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list);
364
365 hash_add_client(target_p);
366
367 sendto_server(client_p, NOCAPS, NOCAPS, ":%s SERVER %s %d :%s%s",
368 source_p->name, target_p->name, hop + 1,
369 IsHidden(target_p) ? "(H) " : "", target_p->info);
370
371 sendto_realops_flags(UMODE_EXTERNAL, L_ALL, SEND_NOTICE,
372 "Server %s being introduced by %s",
373 target_p->name, source_p->name);
374 }
375
376 /* ms_sid()
377 * parv[0] = sender prefix
378 * parv[1] = servername
379 * parv[2] = serverinfo/hopcount
380 * parv[3] = sid of new server
381 * parv[4] = serverinfo
382 */
383 static void
384 ms_sid(struct Client *client_p, struct Client *source_p,
385 int parc, char *parv[])
386 {
387 struct Client *target_p;
388 struct AccessItem *aconf = NULL;
389 int hlined = 0;
390 int llined = 0;
391 dlink_node *ptr = NULL;
392 int hop;
393
394 /* Just to be sure -A1kmm. */
395 if (!IsServer(source_p))
396 return;
397
398 if (EmptyString(parv[4]))
399 {
400 sendto_one(client_p, "ERROR :No servername");
401 return;
402 }
403
404 hop = atoi(parv[2]);
405
406 if (!valid_servname(parv[1]))
407 {
408 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
409 "Link %s introduced server with bogus server name %s",
410 get_client_name(client_p, SHOW_IP), parv[1]);
411 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
412 "Link %s introduced server with bogus server name %s",
413 get_client_name(client_p, MASK_IP), parv[1]);
414 sendto_one(client_p, "ERROR :Bogus server name introduced");
415 exit_client(client_p, &me, "Bogus server name intoduced");
416 return;
417 }
418
419 if (!valid_sid(parv[3]))
420 {
421 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
422 "Link %s introduced server with bogus server ID %s",
423 get_client_name(client_p, SHOW_IP), parv[3]);
424 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
425 "Link %s introduced server with bogus server ID %s",
426 get_client_name(client_p, MASK_IP), parv[3]);
427 sendto_one(client_p, "ERROR :Bogus server ID introduced");
428 exit_client(client_p, &me, "Bogus server ID intoduced");
429 return;
430 }
431
432 /* collision on SID? */
433 if ((target_p = hash_find_id(parv[3])))
434 {
435 sendto_one(client_p, "ERROR :SID %s already exists", parv[3]);
436 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
437 "Link %s cancelled, SID %s already exists",
438 get_client_name(client_p, SHOW_IP), parv[3]);
439 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
440 "Link %s cancelled, SID %s already exists",
441 client_p->name, parv[3]);
442 exit_client(client_p, &me, "SID Exists");
443 return;
444 }
445
446 /* collision on name? */
447 if ((target_p = hash_find_server(parv[1])))
448 {
449 sendto_one(client_p, "ERROR :Server %s already exists", parv[1]);
450 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
451 "Link %s cancelled, server %s already exists",
452 get_client_name(client_p, SHOW_IP), parv[1]);
453 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
454 "Link %s cancelled, server %s already exists",
455 client_p->name, parv[1]);
456 exit_client(client_p, &me, "Server Exists");
457 return;
458 }
459
460 /* XXX If somehow there is a connect in progress and
461 * a connect comes in with same name toss the pending one,
462 * but only if it's not the same client! - Dianora
463 */
464 if ((target_p = find_servconn_in_progress(parv[1])))
465 if (target_p != client_p)
466 exit_client(target_p, &me, "Overridden");
467
468 aconf = map_to_conf(client_p->localClient->confs.head->data);
469
470 /* See if the newly found server is behind a guaranteed
471 * leaf. If so, close the link.
472 */
473 DLINK_FOREACH(ptr, aconf->leaf_list.head)
474 if (match(ptr->data, parv[1]))
475 {
476 llined = 1;
477 break;
478 }
479
480 DLINK_FOREACH(ptr, aconf->hub_list.head)
481 if (match(ptr->data, parv[1]))
482 {
483 hlined = 1;
484 break;
485 }
486
487
488 /* Ok, this way this works is
489 *
490 * A server can have a CONF_HUB allowing it to introduce servers
491 * behind it.
492 *
493 * connect {
494 * name = "irc.bighub.net";
495 * hub_mask="*";
496 * ...
497 *
498 * That would allow "irc.bighub.net" to introduce anything it wanted..
499 *
500 * However
501 *
502 * connect {
503 * name = "irc.somehub.fi";
504 * hub_mask="*";
505 * leaf_mask="*.edu";
506 *...
507 * Would allow this server in finland to hub anything but
508 * .edu's
509 */
510
511 /* Ok, check client_p can hub the new server, and make sure it's not a LL */
512 if (!hlined)
513 {
514 /* OOOPs nope can't HUB */
515 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
516 "Non-Hub link %s introduced %s.",
517 get_client_name(client_p, SHOW_IP), parv[1]);
518 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
519 "Non-Hub link %s introduced %s.",
520 get_client_name(client_p, MASK_IP), parv[1]);
521 exit_client(source_p, &me, "No matching hub_mask.");
522 return;
523 }
524
525 /* Check for the new server being leafed behind this HUB */
526 if (llined)
527 {
528 /* OOOPs nope can't HUB this leaf */
529 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
530 "Link %s introduced leafed server %s.",
531 get_client_name(client_p, SHOW_IP), parv[1]);
532 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
533 "Link %s introduced leafed server %s.",
534 get_client_name(client_p, MASK_IP), parv[1]);
535 exit_client(client_p, &me, "Leafed Server.");
536 return;
537 }
538
539 target_p = make_client(client_p);
540 make_server(target_p);
541 target_p->hopcount = hop;
542 target_p->servptr = source_p;
543
544 strlcpy(target_p->name, parv[1], sizeof(target_p->name));
545 strlcpy(target_p->id, parv[3], sizeof(target_p->id));
546
547 set_server_gecos(target_p, parv[4]);
548 SetServer(target_p);
549
550 if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(SERVICE_TYPE, target_p->name, NULL, NULL, 0))
551 AddFlag(target_p, FLAGS_SERVICE);
552
553 dlinkAdd(target_p, &target_p->node, &global_client_list);
554 dlinkAdd(target_p, make_dlink_node(), &global_serv_list);
555 dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list);
556
557 hash_add_client(target_p);
558 hash_add_id(target_p);
559
560 sendto_server(client_p, CAP_TS6, NOCAPS, ":%s SID %s %d %s :%s%s",
561 ID_or_name(source_p, client_p), target_p->name, hop + 1,
562 target_p->id, IsHidden(target_p) ? "(H) " : "", target_p->info);
563 sendto_server(client_p, NOCAPS, CAP_TS6, ":%s SERVER %s %d :%s%s",
564 source_p->name, target_p->name, hop + 1,
565 IsHidden(target_p) ? "(H) " : "", target_p->info);
566
567 sendto_realops_flags(UMODE_EXTERNAL, L_ALL, SEND_NOTICE,
568 "Server %s being introduced by %s",
569 target_p->name, source_p->name);
570 }
571
572 /* set_server_gecos()
573 *
574 * input - pointer to client
575 * output - NONE
576 * side effects - servers gecos field is set
577 */
578 static void
579 set_server_gecos(struct Client *client_p, const char *info)
580 {
581 const char *s = info;
582
583 /* check for (H) which is a hidden server */
584 if (!strncmp(s, "(H) ", 4))
585 {
586 SetHidden(client_p);
587 s = s + 4;
588 }
589
590 if (!EmptyString(s))
591 strlcpy(client_p->info, s, sizeof(client_p->info));
592 else
593 strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
594 }
595
596 static struct Message server_msgtab = {
597 "SERVER", 0, 0, 4, MAXPARA, MFLG_SLOW, 0,
598 {mr_server, m_registered, ms_server, m_ignore, m_registered, m_ignore}
599 };
600
601 static struct Message sid_msgtab = {
602 "SID", 0, 0, 5, MAXPARA, MFLG_SLOW, 0,
603 {rfc1459_command_send_error, m_ignore, ms_sid, m_ignore, m_ignore, m_ignore}
604 };
605
606 static void
607 module_init(void)
608 {
609 mod_add_cmd(&sid_msgtab);
610 mod_add_cmd(&server_msgtab);
611 }
612
613 static void
614 module_exit(void)
615 {
616 mod_del_cmd(&sid_msgtab);
617 mod_del_cmd(&server_msgtab);
618 }
619
620 struct module module_entry = {
621 .node = { NULL, NULL, NULL },
622 .name = NULL,
623 .version = "$Revision$",
624 .handle = NULL,
625 .modinit = module_init,
626 .modexit = module_exit,
627 .flags = MODULE_FLAG_CORE
628 };

Properties

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

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28