ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/modules/core/m_server.c
Revision: 3156
Committed: Fri Mar 14 19:57:38 2014 UTC (10 years, 1 month ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/trunk/modules/core/m_server.c
File size: 15798 byte(s)
Log Message:
- Removed client_p pointers from everywhere

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 1997-2014 ircd-hybrid development team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 */
21
22 /*! \file m_server.c
23 * \brief Includes required functions for processing the SERVER/SID command.
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #include "list.h"
29 #include "client.h"
30 #include "event.h"
31 #include "hash.h"
32 #include "irc_string.h"
33 #include "ircd.h"
34 #include "numeric.h"
35 #include "conf.h"
36 #include "log.h"
37 #include "s_serv.h"
38 #include "s_user.h"
39 #include "send.h"
40 #include "parse.h"
41 #include "modules.h"
42
43
44 /* set_server_gecos()
45 *
46 * input - pointer to client
47 * output - NONE
48 * side effects - servers gecos field is set
49 */
50 static void
51 set_server_gecos(struct Client *client_p, const char *info)
52 {
53 const char *s = info;
54
55 /* check for (H) which is a hidden server */
56 if (!strncmp(s, "(H) ", 4))
57 {
58 SetHidden(client_p);
59 s = s + 4;
60 }
61
62 if (!EmptyString(s))
63 strlcpy(client_p->info, s, sizeof(client_p->info));
64 else
65 strlcpy(client_p->info, "(Unknown Location)", sizeof(client_p->info));
66 }
67
68 /* mr_server()
69 * parv[0] = command
70 * parv[1] = servername
71 * parv[2] = hopcount
72 * parv[3] = serverinfo
73 */
74 static int
75 mr_server(struct Client *source_p, int parc, char *parv[])
76 {
77 char *name;
78 struct Client *target_p;
79 int hop;
80
81 if (EmptyString(parv[3]))
82 {
83 sendto_one(source_p, "ERROR :No servername");
84 exit_client(source_p, source_p, "Wrong number of args");
85 return 0;
86 }
87
88 name = parv[1];
89 hop = atoi(parv[2]);
90
91 /*
92 * Reject a direct nonTS server connection if we're TS_ONLY -orabidoo
93 */
94 if (!DoesTS(source_p))
95 {
96 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
97 "Unauthorized server connection attempt from %s: Non-TS server "
98 "for server %s", get_client_name(source_p, HIDE_IP), name);
99 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
100 "Unauthorized server connection attempt from %s: Non-TS server "
101 "for server %s", get_client_name(source_p, MASK_IP), name);
102 exit_client(source_p, source_p, "Non-TS server");
103 return 0;
104 }
105
106 if (!valid_servname(name))
107 {
108 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
109 "Unauthorized server connection attempt from %s: Bogus server name "
110 "for server %s", get_client_name(source_p, HIDE_IP), name);
111 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
112 "Unauthorized server connection attempt from %s: Bogus server name "
113 "for server %s", get_client_name(source_p, MASK_IP), name);
114 exit_client(source_p, source_p, "Bogus server name");
115 return 0;
116 }
117
118 if (!valid_sid(source_p->id))
119 {
120 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
121 "Link %s introduced server with bogus server ID %s",
122 get_client_name(source_p, SHOW_IP), source_p->id);
123 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
124 "Link %s introduced server with bogus server ID %s",
125 get_client_name(source_p, MASK_IP), source_p->id);
126 sendto_one(source_p, "ERROR :Bogus server ID introduced");
127 exit_client(source_p, &me, "Bogus server ID intoduced");
128 return 0;
129 }
130
131 /* Now we just have to call check_server and everything should
132 * be check for us... -A1kmm.
133 */
134 switch (check_server(name, source_p))
135 {
136 case -1:
137 if (ConfigFileEntry.warn_no_nline)
138 {
139 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
140 "Unauthorized server connection attempt from %s: No entry for "
141 "servername %s", get_client_name(source_p, HIDE_IP), name);
142
143 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
144 "Unauthorized server connection attempt from %s: No entry for "
145 "servername %s", get_client_name(source_p, MASK_IP), name);
146 }
147
148 exit_client(source_p, source_p, "No connect{} block.");
149 return 0;
150 /* NOT REACHED */
151 break;
152
153 case -2:
154 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
155 "Unauthorized server connection attempt from %s: Bad password "
156 "for server %s", get_client_name(source_p, HIDE_IP), name);
157
158 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
159 "Unauthorized server connection attempt from %s: Bad password "
160 "for server %s", get_client_name(source_p, MASK_IP), name);
161
162 exit_client(source_p, source_p, "Invalid password.");
163 return 0;
164 /* NOT REACHED */
165 break;
166
167 case -3:
168 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
169 "Unauthorized server connection attempt from %s: Invalid host "
170 "for server %s", get_client_name(source_p, HIDE_IP), name);
171
172 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
173 "Unauthorized server connection attempt from %s: Invalid host "
174 "for server %s", get_client_name(source_p, MASK_IP), name);
175
176 exit_client(source_p, source_p, "Invalid host.");
177 return 0;
178 case -4:
179 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
180 "Unauthorized server connection attempt from %s: Invalid certificate fingerprint "
181 "for server %s", get_client_name(source_p, HIDE_IP), name);
182
183 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
184 "Unauthorized server connection attempt from %s: Invalid certificate fingerprint "
185 "for server %s", get_client_name(source_p, MASK_IP), name);
186
187 exit_client(source_p, source_p, "Invalid certificate fingerprint.");
188 return 0;
189 /* NOT REACHED */
190 break;
191 }
192
193 if ((target_p = hash_find_server(name)))
194 {
195 /* This link is trying feed me a server that I already have
196 * access through another path -- multiple paths not accepted
197 * currently, kill this link immediately!!
198 *
199 * Rather than KILL the link which introduced it, KILL the
200 * youngest of the two links. -avalon
201 *
202 * Definitely don't do that here. This is from an unregistered
203 * connect - A1kmm.
204 */
205 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
206 "Attempt to re-introduce server %s from %s",
207 name, get_client_name(source_p, HIDE_IP));
208 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
209 "Attempt to re-introduce server %s from %s",
210 name, get_client_name(source_p, MASK_IP));
211 sendto_one(source_p, "ERROR :Server already exists.");
212 exit_client(source_p, source_p, "Server already exists");
213 return 0;
214 }
215
216 if ((target_p = hash_find_id(source_p->id)))
217 {
218 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
219 "Attempt to re-introduce server %s SID %s from %s",
220 name, source_p->id,
221 get_client_name(source_p, HIDE_IP));
222 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
223 "Attempt to re-introduce server %s SID %s from %s",
224 name, source_p->id,
225 get_client_name(source_p, MASK_IP));
226 sendto_one(source_p, "ERROR :Server ID already exists.");
227 exit_client(source_p, source_p, "Server ID already exists");
228 return 0;
229 }
230
231 /* XXX If somehow there is a connect in progress and
232 * a connect comes in with same name toss the pending one,
233 * but only if it's not the same client! - Dianora
234 */
235 if ((target_p = find_servconn_in_progress(name)))
236 if (target_p != source_p)
237 exit_client(target_p, &me, "Overridden");
238
239 /* if we are connecting (Handshake), we already have the name from the
240 * connect{} block in source_p->name
241 */
242 strlcpy(source_p->name, name, sizeof(source_p->name));
243 set_server_gecos(source_p, parv[3]);
244 source_p->hopcount = hop;
245 server_estab(source_p);
246 return 0;
247 }
248
249 /* ms_sid()
250 * parv[0] = command
251 * parv[1] = servername
252 * parv[2] = hopcount
253 * parv[3] = sid of new server
254 * parv[4] = serverinfo
255 */
256 static int
257 ms_sid(struct Client *source_p, int parc, char *parv[])
258 {
259 dlink_node *ptr = NULL;
260 struct Client *target_p = NULL;
261 struct Client *client_p = source_p->from; /* XXX */
262 const struct MaskItem *conf = NULL;
263 int hlined = 0;
264 int llined = 0;
265 int hop = 0;
266
267 /* Just to be sure -A1kmm. */
268 if (!IsServer(source_p))
269 return 0;
270
271 if (EmptyString(parv[4]))
272 {
273 sendto_one(client_p, "ERROR :No servername");
274 return 0;
275 }
276
277 hop = atoi(parv[2]);
278
279 if (!valid_servname(parv[1]))
280 {
281 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
282 "Link %s introduced server with bogus server name %s",
283 get_client_name(client_p, SHOW_IP), parv[1]);
284 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
285 "Link %s introduced server with bogus server name %s",
286 get_client_name(client_p, MASK_IP), parv[1]);
287 sendto_one(client_p, "ERROR :Bogus server name introduced");
288 exit_client(client_p, &me, "Bogus server name intoduced");
289 return 0;
290 }
291
292 if (!valid_sid(parv[3]))
293 {
294 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
295 "Link %s introduced server with bogus server ID %s",
296 get_client_name(client_p, SHOW_IP), parv[3]);
297 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
298 "Link %s introduced server with bogus server ID %s",
299 get_client_name(client_p, MASK_IP), parv[3]);
300 sendto_one(client_p, "ERROR :Bogus server ID introduced");
301 exit_client(client_p, &me, "Bogus server ID intoduced");
302 return 0;
303 }
304
305 /* collision on SID? */
306 if ((target_p = hash_find_id(parv[3])))
307 {
308 sendto_one(client_p, "ERROR :SID %s already exists", parv[3]);
309 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
310 "Link %s cancelled, SID %s already exists",
311 get_client_name(client_p, SHOW_IP), parv[3]);
312 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
313 "Link %s cancelled, SID %s already exists",
314 client_p->name, parv[3]);
315 exit_client(client_p, &me, "SID Exists");
316 return 0;
317 }
318
319 /* collision on name? */
320 if ((target_p = hash_find_server(parv[1])))
321 {
322 sendto_one(client_p, "ERROR :Server %s already exists", parv[1]);
323 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
324 "Link %s cancelled, server %s already exists",
325 get_client_name(client_p, SHOW_IP), parv[1]);
326 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
327 "Link %s cancelled, server %s already exists",
328 client_p->name, parv[1]);
329 exit_client(client_p, &me, "Server Exists");
330 return 0;
331 }
332
333 /* XXX If somehow there is a connect in progress and
334 * a connect comes in with same name toss the pending one,
335 * but only if it's not the same client! - Dianora
336 */
337 if ((target_p = find_servconn_in_progress(parv[1])))
338 if (target_p != client_p)
339 exit_client(target_p, &me, "Overridden");
340
341 conf = client_p->localClient->confs.head->data;
342
343 /* See if the newly found server is behind a guaranteed
344 * leaf. If so, close the link.
345 */
346 DLINK_FOREACH(ptr, conf->leaf_list.head)
347 {
348 if (!match(ptr->data, parv[1]))
349 {
350 llined = 1;
351 break;
352 }
353 }
354
355 DLINK_FOREACH(ptr, conf->hub_list.head)
356 {
357 if (!match(ptr->data, parv[1]))
358 {
359 hlined = 1;
360 break;
361 }
362 }
363
364 /* Ok, this way this works is
365 *
366 * A server can have a CONF_HUB allowing it to introduce servers
367 * behind it.
368 *
369 * connect {
370 * name = "irc.bighub.net";
371 * hub_mask="*";
372 * ...
373 *
374 * That would allow "irc.bighub.net" to introduce anything it wanted..
375 *
376 * However
377 *
378 * connect {
379 * name = "irc.somehub.fi";
380 * hub_mask="*";
381 * leaf_mask="*.edu";
382 *...
383 * Would allow this server in finland to hub anything but
384 * .edu's
385 */
386
387 /* Ok, check client_p can hub the new server, and make sure it's not a LL */
388 if (!hlined)
389 {
390 /* OOOPs nope can't HUB */
391 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
392 "Non-Hub link %s introduced %s.",
393 get_client_name(client_p, SHOW_IP), parv[1]);
394 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
395 "Non-Hub link %s introduced %s.",
396 get_client_name(client_p, MASK_IP), parv[1]);
397 exit_client(source_p, &me, "No matching hub_mask.");
398 return 0;
399 }
400
401 /* Check for the new server being leafed behind this HUB */
402 if (llined)
403 {
404 /* OOOPs nope can't HUB this leaf */
405 sendto_realops_flags(UMODE_ALL, L_ADMIN, SEND_NOTICE,
406 "Link %s introduced leafed server %s.",
407 get_client_name(client_p, SHOW_IP), parv[1]);
408 sendto_realops_flags(UMODE_ALL, L_OPER, SEND_NOTICE,
409 "Link %s introduced leafed server %s.",
410 get_client_name(client_p, MASK_IP), parv[1]);
411 exit_client(client_p, &me, "Leafed Server.");
412 return 0;
413 }
414
415 target_p = make_client(client_p);
416 make_server(target_p);
417 target_p->hopcount = hop;
418 target_p->servptr = source_p;
419
420 strlcpy(target_p->name, parv[1], sizeof(target_p->name));
421 strlcpy(target_p->id, parv[3], sizeof(target_p->id));
422
423 set_server_gecos(target_p, parv[4]);
424 SetServer(target_p);
425
426 if (HasFlag(source_p, FLAGS_SERVICE) || find_matching_name_conf(CONF_SERVICE, target_p->name, NULL, NULL, 0))
427 AddFlag(target_p, FLAGS_SERVICE);
428
429 dlinkAdd(target_p, &target_p->node, &global_client_list);
430 dlinkAdd(target_p, make_dlink_node(), &global_serv_list);
431 dlinkAdd(target_p, &target_p->lnode, &target_p->servptr->serv->server_list);
432
433 hash_add_client(target_p);
434 hash_add_id(target_p);
435
436 sendto_server(client_p, NOCAPS, NOCAPS, ":%s SID %s %d %s :%s%s",
437 ID_or_name(source_p, client_p), target_p->name, hop + 1,
438 target_p->id, IsHidden(target_p) ? "(H) " : "", target_p->info);
439 sendto_realops_flags(UMODE_EXTERNAL, L_ALL, SEND_NOTICE,
440 "Server %s being introduced by %s",
441 target_p->name, source_p->name);
442 return 0;
443 }
444
445 static struct Message server_msgtab =
446 {
447 "SERVER", 0, 0, 4, MAXPARA, MFLG_SLOW, 0,
448 { mr_server, m_registered, m_ignore, m_ignore, m_registered, m_ignore }
449 };
450
451 static struct Message sid_msgtab =
452 {
453 "SID", 0, 0, 5, MAXPARA, MFLG_SLOW, 0,
454 { m_ignore, m_ignore, ms_sid, m_ignore, m_ignore, m_ignore }
455 };
456
457 static void
458 module_init(void)
459 {
460 mod_add_cmd(&sid_msgtab);
461 mod_add_cmd(&server_msgtab);
462 }
463
464 static void
465 module_exit(void)
466 {
467 mod_del_cmd(&sid_msgtab);
468 mod_del_cmd(&server_msgtab);
469 }
470
471 struct module module_entry =
472 {
473 .node = { NULL, NULL, NULL },
474 .name = NULL,
475 .version = "$Revision$",
476 .handle = NULL,
477 .modinit = module_init,
478 .modexit = module_exit,
479 .flags = MODULE_FLAG_CORE
480 };

Properties

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