ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/conf.c
Revision: 9917
Committed: Sat Jan 30 21:20:07 2021 UTC (3 years, 1 month ago) by michael
Content type: text/x-csrc
File size: 37115 byte(s)
Log Message:
- conf.c:attach_iline(): just let the client silently in if their class is full and they are exempted from limits. No point
  in explicitely telling them that their class is full and they have exceed_limit = yes

File Contents

# User Rev Content
1 adx 30 /*
2 michael 2916 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 adx 30 *
4 michael 9857 * Copyright (c) 1997-2021 ircd-hybrid development team
5 adx 30 *
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 michael 4565 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 adx 30 * USA
20     */
21    
22 michael 2916 /*! \file conf.c
23     * \brief Configuration file functions.
24     * \version $Id$
25     */
26    
27 adx 30 #include "stdinc.h"
28 michael 1011 #include "list.h"
29 adx 30 #include "ircd_defs.h"
30 michael 8458 #include "parse.h"
31 michael 1309 #include "conf.h"
32 michael 7217 #include "conf_cluster.h"
33 michael 7304 #include "conf_gecos.h"
34 michael 4545 #include "conf_pseudo.h"
35 michael 7234 #include "conf_resv.h"
36 michael 7248 #include "conf_service.h"
37 michael 7209 #include "conf_shared.h"
38 michael 3347 #include "server.h"
39 adx 30 #include "channel.h"
40     #include "client.h"
41     #include "event.h"
42     #include "irc_string.h"
43     #include "s_bsd.h"
44     #include "ircd.h"
45     #include "listener.h"
46     #include "hostmask.h"
47     #include "modules.h"
48     #include "numeric.h"
49     #include "fdlist.h"
50 michael 1309 #include "log.h"
51 adx 30 #include "send.h"
52     #include "memory.h"
53 michael 3322 #include "res.h"
54 michael 3347 #include "user.h"
55 adx 30 #include "channel_mode.h"
56 michael 3347 #include "misc.h"
57 michael 1622 #include "conf_db.h"
58 michael 1632 #include "conf_class.h"
59 michael 2150 #include "motd.h"
60 michael 4325 #include "ipcache.h"
61 michael 6185 #include "isupport.h"
62 michael 7437 #include "whowas.h"
63 adx 30
64 michael 2872
65 michael 5602 struct config_channel_entry ConfigChannel;
66 michael 5644 struct config_serverhide_entry ConfigServerHide;
67 michael 5602 struct config_general_entry ConfigGeneral;
68 michael 5644 struct config_log_entry ConfigLog = { .use_logging = 1 };
69     struct config_serverinfo_entry ConfigServerInfo;
70     struct config_admin_entry ConfigAdminInfo;
71 michael 5602 struct conf_parser_context conf_parser_ctx;
72    
73 adx 30 /* general conf items link list root, other than k lines etc. */
74 michael 7401 dlink_list connect_items;
75 michael 6628 dlink_list operator_items;
76 adx 30
77     extern unsigned int lineno;
78     extern char linebuf[];
79     extern char conffilebuf[IRCD_BUFSIZE];
80     extern int yyparse(); /* defined in y.tab.c */
81    
82    
83     /* conf_dns_callback()
84     *
85 michael 1632 * inputs - pointer to struct MaskItem
86 adx 30 * - pointer to DNSReply reply
87     * output - none
88     * side effects - called when resolver query finishes
89     * if the query resulted in a successful search, hp will contain
90     * a non-null pointer, otherwise hp will be null.
91     * if successful save hp in the conf item it was called with
92     */
93     static void
94 michael 4408 conf_dns_callback(void *vptr, const struct irc_ssaddr *addr, const char *name, size_t namelength)
95 adx 30 {
96 michael 4874 struct MaskItem *const conf = vptr;
97 adx 30
98 michael 8658 conf->dns_pending = false;
99 adx 30
100 michael 3235 if (addr)
101 michael 9116 *conf->addr = *addr;
102 michael 992 else
103 michael 8658 conf->dns_failed = true;
104 adx 30 }
105    
106 michael 9114 /* conf_resolve_host()
107 adx 30 *
108 michael 9114 * start DNS lookups of all hostnames in the conf
109     * line and convert an IP addresses in a.b.c.d number for to IP#s.
110 adx 30 */
111 michael 9114 void
112 michael 1632 conf_dns_lookup(struct MaskItem *conf)
113 adx 30 {
114 michael 9114 struct addrinfo hints, *res;
115    
116     /*
117     * Do name lookup now on hostnames given and store the
118     * ip numbers in conf structure.
119     */
120     memset(&hints, 0, sizeof(hints));
121    
122     hints.ai_family = AF_UNSPEC;
123     hints.ai_socktype = SOCK_STREAM;
124    
125     /* Get us ready for a bind() and don't bother doing dns lookup */
126     hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
127    
128     if (getaddrinfo(conf->host, NULL, &hints, &res))
129     {
130     /*
131     * By this point conf->host possibly is not a numerical network address. Do a nameserver
132     * lookup of the conf host. If the conf entry is currently doing a ns lookup do nothing.
133     */
134     if (conf->dns_pending == true)
135     return;
136    
137     conf->dns_pending = true;
138    
139     if (conf->aftype == AF_INET)
140     gethost_byname_type(conf_dns_callback, conf, conf->host, T_A);
141     else
142     gethost_byname_type(conf_dns_callback, conf, conf->host, T_AAAA);
143 michael 4982 return;
144 michael 9114 }
145 michael 4982
146 michael 9114 assert(res);
147 michael 4982
148 michael 9114 memcpy(conf->addr, res->ai_addr, res->ai_addrlen);
149     conf->addr->ss_len = res->ai_addrlen;
150    
151     freeaddrinfo(res);
152 michael 4982 }
153    
154     /* map_to_list()
155     *
156     * inputs - ConfType conf
157     * output - pointer to dlink_list to use
158     * side effects - none
159     */
160     static dlink_list *
161     map_to_list(enum maskitem_type type)
162     {
163     switch (type)
164 adx 30 {
165 michael 4982 case CONF_OPER:
166 michael 6628 return &operator_items;
167 michael 4982 break;
168     case CONF_SERVER:
169 michael 7401 return &connect_items;
170 michael 4982 break;
171     default:
172     return NULL;
173 adx 30 }
174     }
175    
176 michael 1632 struct MaskItem *
177     conf_make(enum maskitem_type type)
178     {
179 michael 7032 struct MaskItem *const conf = xcalloc(sizeof(*conf));
180 michael 1632 dlink_list *list = NULL;
181    
182     conf->type = type;
183 michael 8658 conf->active = true;
184 michael 1632 conf->aftype = AF_INET;
185    
186     if ((list = map_to_list(type)))
187     dlinkAdd(conf, &conf->node, list);
188     return conf;
189     }
190    
191     void
192     conf_free(struct MaskItem *conf)
193     {
194 michael 4815 dlink_node *node = NULL, *node_next = NULL;
195 michael 1636 dlink_list *list = NULL;
196    
197 michael 4511 if ((list = map_to_list(conf->type)))
198 michael 4523 dlinkFindDelete(list, conf);
199 michael 4511
200 michael 7032 xfree(conf->name);
201 michael 1632
202 michael 8658 if (conf->dns_pending == true)
203 michael 1632 delete_resolver_queries(conf);
204 michael 3235 if (conf->passwd)
205 michael 1632 memset(conf->passwd, 0, strlen(conf->passwd));
206 michael 3235 if (conf->spasswd)
207 michael 1632 memset(conf->spasswd, 0, strlen(conf->spasswd));
208    
209     conf->class = NULL;
210    
211 michael 7032 xfree(conf->passwd);
212     xfree(conf->spasswd);
213     xfree(conf->reason);
214     xfree(conf->certfp);
215     xfree(conf->whois);
216     xfree(conf->user);
217     xfree(conf->host);
218 michael 8872 xfree(conf->addr);
219     xfree(conf->bind);
220 michael 7032 xfree(conf->cipher_list);
221 michael 1632
222 michael 4815 DLINK_FOREACH_SAFE(node, node_next, conf->hub_list.head)
223 michael 1632 {
224 michael 7032 xfree(node->data);
225 michael 4815 dlinkDelete(node, &conf->hub_list);
226     free_dlink_node(node);
227 michael 1632 }
228    
229 michael 4815 DLINK_FOREACH_SAFE(node, node_next, conf->leaf_list.head)
230 michael 1632 {
231 michael 7032 xfree(node->data);
232 michael 4815 dlinkDelete(node, &conf->leaf_list);
233     free_dlink_node(node);
234 michael 1632 }
235 adx 30
236 michael 7032 xfree(conf);
237 adx 30 }
238    
239 michael 4982 /* attach_iline()
240 adx 30 *
241 michael 4982 * inputs - client pointer
242     * - conf pointer
243     * output -
244     * side effects - do actual attach
245 adx 30 */
246 michael 4982 static int
247 michael 9250 attach_iline(struct Client *client, struct MaskItem *conf)
248 adx 30 {
249 michael 4982 const struct ClassItem *const class = conf->class;
250 michael 8658 bool a_limit_reached = false;
251 michael 2916
252 michael 9250 struct ip_entry *ipcache = ipcache_record_find_or_add(&client->ip);
253 michael 8496 ++ipcache->count_local;
254 michael 9250 AddFlag(client, FLAGS_IPHASH);
255 adx 30
256 michael 4982 if (class->max_total && class->ref_count >= class->max_total)
257 michael 8658 a_limit_reached = true;
258 michael 8496 else if (class->max_perip_local && ipcache->count_local > class->max_perip_local)
259 michael 8658 a_limit_reached = true;
260 michael 8496 else if (class->max_perip_global &&
261     (ipcache->count_local + ipcache->count_remote) > class->max_perip_global)
262 michael 8658 a_limit_reached = true;
263 michael 9881 else if (class_ip_limit_add(conf->class, &client->ip, IsConfExemptLimits(conf)) == true)
264     a_limit_reached = true;
265 adx 30
266 michael 8658 if (a_limit_reached == true)
267 michael 4982 if (!IsConfExemptLimits(conf))
268     return TOO_MANY; /* Already at maximum allowed */
269 adx 30
270 michael 9250 return conf_attach(client, conf);
271 adx 30 }
272    
273     /* verify_access()
274     *
275 michael 4982 * inputs - pointer to client to verify
276     * output - 0 if success -'ve if not
277     * side effect - find the first (best) I line to attach.
278 adx 30 */
279     static int
280 michael 9250 verify_access(struct Client *client)
281 adx 30 {
282 michael 8727 struct MaskItem *conf;
283 adx 30
284 michael 9250 if (HasFlag(client, FLAGS_GOTID))
285     conf = find_address_conf(client->host, client->username, &client->ip,
286     client->connection->password);
287 adx 30 else
288     {
289 michael 5583 char non_ident[USERLEN + 1] = "~";
290    
291 michael 9250 strlcpy(non_ident + 1, client->username, sizeof(non_ident) - 1);
292     conf = find_address_conf(client->host, non_ident, &client->ip,
293     client->connection->password);
294 adx 30 }
295    
296 michael 8727 if (conf == NULL)
297 michael 5805 return NOT_AUTHORIZED;
298    
299     assert(IsConfClient(conf) || IsConfKill(conf));
300    
301 michael 8727 if (IsConfKill(conf))
302 adx 30 {
303 michael 9250 sendto_one_notice(client, &me, ":*** Banned: %s", conf->reason);
304 michael 8727 return BANNED_CLIENT;
305     }
306 adx 30
307 michael 8727 if (IsConfRedir(conf))
308     {
309 michael 9250 sendto_one_numeric(client, &me, RPL_REDIR,
310 michael 8727 conf->name ? conf->name : "",
311     conf->port);
312     return NOT_AUTHORIZED;
313     }
314 michael 4982
315 michael 9427 /* Preserve x->host in x->realhost before it gets overwritten. */
316     strlcpy(client->realhost, client->host, sizeof(client->realhost));
317    
318 michael 8727 if (IsConfDoSpoofIp(conf))
319 michael 9250 strlcpy(client->host, conf->name, sizeof(client->host));
320 adx 30
321 michael 9250 return attach_iline(client, conf);
322 adx 30 }
323    
324 michael 4982 /* check_client()
325 adx 30 *
326 michael 4982 * inputs - pointer to client
327     * output - 0 = Success
328     * NOT_AUTHORIZED (-1) = Access denied (no I line match)
329     * IRCD_SOCKET_ERROR (-2) = Bad socket.
330     * I_LINE_FULL (-3) = I-line is full
331     * TOO_MANY (-4) = Too many connections from hostname
332     * BANNED_CLIENT (-5) = K-lined
333     * side effects - Ordinary client access check.
334     * Look for conf lines which have the same
335     * status as the flags passed.
336 adx 30 */
337 michael 9107 bool
338 michael 9250 conf_check_client(struct Client *client)
339 adx 30 {
340 michael 9880 const char *error = NULL;
341     bool warn = true;
342 adx 30
343 michael 9880 switch (verify_access(client))
344 michael 4982 {
345     case TOO_MANY:
346 michael 9880 error = "too many connections on IP";
347 michael 4982 break;
348     case I_LINE_FULL:
349 michael 9880 error = "connection class is full";
350 michael 4982 break;
351     case NOT_AUTHORIZED:
352 michael 9880 error = "not authorized";
353 michael 4982 break;
354     case BANNED_CLIENT:
355 michael 9880 error = "banned from server";
356     warn = false;
357 michael 4982 break;
358 michael 9880 }
359 michael 4982
360 michael 9880 if (error)
361     {
362     char buf[REASONLEN + 1];
363     snprintf(buf, sizeof(buf), "Connection rejected - %s", error);
364    
365     ++ServerStats.is_ref;
366    
367     if (warn == true)
368     sendto_realops_flags(UMODE_REJ, L_ALL, SEND_NOTICE, "Rejecting client connection from %s: %s",
369     client_get_name(client, SHOW_IP), error);
370    
371     ilog(LOG_TYPE_IRCD, "Rejecting client connection from %s: %s",
372     client_get_name(client, SHOW_IP), error);
373     exit_client(client, buf);
374     return false;
375 adx 30 }
376    
377 michael 9107 return true;
378 adx 30 }
379    
380 michael 8395 /*! \brief Disassociate configuration from the client. Also removes a class
381     * from the list if marked for deleting.
382 michael 9250 * \param client Client to operate on
383 michael 8395 * \param type Type of conf to detach
384 adx 30 */
385 michael 1632 void
386 michael 9250 conf_detach(struct Client *client, enum maskitem_type type)
387 adx 30 {
388 michael 8395 dlink_node *node, *node_next;
389 adx 30
390 michael 9250 DLINK_FOREACH_SAFE(node, node_next, client->connection->confs.head)
391 adx 30 {
392 michael 4815 struct MaskItem *conf = node->data;
393 adx 30
394 michael 1645 assert(conf->type & (CONF_CLIENT | CONF_OPER | CONF_SERVER));
395     assert(conf->ref_count > 0);
396     assert(conf->class->ref_count > 0);
397 adx 30
398 michael 1645 if (!(conf->type & type))
399     continue;
400 michael 671
401 michael 9250 dlinkDelete(node, &client->connection->confs);
402 michael 4815 free_dlink_node(node);
403 michael 1644
404 michael 2278 if (conf->type == CONF_CLIENT)
405 michael 9250 class_ip_limit_remove(conf->class, &client->ip);
406 adx 30
407 michael 8658 if (--conf->class->ref_count == 0 && conf->class->active == false)
408 michael 1645 {
409     class_free(conf->class);
410     conf->class = NULL;
411 adx 30 }
412 michael 1645
413 michael 8658 if (--conf->ref_count == 0 && conf->active == false)
414 michael 1645 conf_free(conf);
415 adx 30 }
416     }
417    
418 michael 8395 /*! \brief Associate a specific configuration entry to a *local* client (this
419     * is the one which used in accepting the connection). Note, that this
420     * automatically changes the attachment if there was an old one.
421 michael 9250 * \param client Client to attach the conf to
422 michael 8395 * \param conf Configuration record to attach
423 adx 30 */
424     int
425 michael 9250 conf_attach(struct Client *client, struct MaskItem *conf)
426 adx 30 {
427 michael 9250 if (dlinkFind(&client->connection->confs, conf))
428 adx 30 return 1;
429    
430 michael 1632 conf->class->ref_count++;
431 michael 1644 conf->ref_count++;
432 adx 30
433 michael 9250 dlinkAdd(conf, make_dlink_node(), &client->connection->confs);
434 adx 30
435     return 0;
436     }
437    
438     /* find_conf_name()
439     *
440     * inputs - pointer to conf link list to search
441     * - pointer to name to find
442     * - int mask of type of conf to find
443     * output - NULL or pointer to conf found
444     * side effects - find a conf entry which matches the name
445     * and has the given mask.
446     */
447 michael 1632 struct MaskItem *
448     find_conf_name(dlink_list *list, const char *name, enum maskitem_type type)
449 adx 30 {
450 michael 4815 dlink_node *node = NULL;
451 adx 30
452 michael 4815 DLINK_FOREACH(node, list->head)
453 adx 30 {
454 michael 4815 struct MaskItem *conf = node->data;
455 michael 2916
456 adx 30 if (conf->type == type)
457     {
458 michael 4596 if (conf->name && !irccmp(conf->name, name))
459     return conf;
460 adx 30 }
461     }
462    
463     return NULL;
464     }
465    
466 michael 8391 /*! \brief Find a connect {} conf that has a name that matches \a name.
467     * \param name Name to match
468     * \param compare Pointer to function to be used for string matching
469 adx 30 */
470 michael 1632 struct MaskItem *
471 michael 8391 connect_find(const char *name, int (*compare)(const char *, const char *))
472 adx 30 {
473 michael 8391 dlink_node *node;
474 adx 30
475 michael 7401 DLINK_FOREACH(node, connect_items.head)
476 adx 30 {
477 michael 7401 struct MaskItem *conf = node->data;
478 adx 30
479 michael 9202 if (compare(name, conf->name) == 0)
480 michael 7401 return conf;
481     }
482 michael 2916
483 adx 30 return NULL;
484     }
485    
486     /* find_exact_name_conf()
487     *
488     * inputs - type of link list to look in
489     * - pointer to name string to find
490     * - pointer to user
491     * - pointer to host
492 michael 1632 * output - NULL or pointer to found struct MaskItem
493 adx 30 * side effects - looks for an exact match on name field
494     */
495 michael 1632 struct MaskItem *
496 michael 9594 operator_find(const struct Client *client, const char *name)
497 adx 30 {
498 michael 9202 dlink_node *node;
499 adx 30
500 michael 7401 DLINK_FOREACH(node, operator_items.head)
501 adx 30 {
502 michael 7401 struct MaskItem *conf = node->data;
503    
504 michael 9202 if (irccmp(conf->name, name) == 0)
505 adx 30 {
506 michael 9594 if (client == NULL)
507 michael 7401 return conf;
508 michael 1285
509 michael 9594 if (conf->class->max_total &&
510     conf->class->max_total <= conf->class->ref_count)
511     continue;
512    
513     if (match(conf->user, client->username) == 0)
514 adx 30 {
515 michael 7401 switch (conf->htype)
516 michael 1285 {
517 michael 7401 case HM_HOST:
518 michael 9594 if (match(conf->host, client->realhost) == 0 ||
519     match(conf->host, client->sockhost) == 0 || match(conf->host, client->host) == 0)
520     return conf;
521 michael 7401 break;
522 michael 9596 case HM_IPV6:
523 michael 7401 case HM_IPV4:
524 michael 9608 if (address_compare(&client->ip, conf->addr, false, false, conf->bits) == true)
525 michael 9596 return conf;
526 michael 7401 break;
527     default:
528     assert(0);
529 michael 1285 }
530 adx 30 }
531     }
532     }
533 michael 2182
534     return NULL;
535 adx 30 }
536    
537 michael 9110 /* conf_set_defaults()
538 adx 30 *
539     * inputs - NONE
540     * output - NONE
541     * side effects - Set default values here.
542     * This is called **PRIOR** to parsing the
543     * configuration file. If you want to do some validation
544     * of values later, put them in validate_conf().
545     */
546     static void
547 michael 9110 conf_set_defaults(void)
548 adx 30 {
549 michael 9202 /*
550     * Verify init_class() ran, this should be an unnecessary check
551     * but it's not much work.
552 adx 30 */
553 michael 1644 assert(class_default == class_get_list()->tail->data);
554 adx 30
555 michael 4340 ConfigServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
556 michael 9692 ConfigServerInfo.network_description = xstrdup(NETWORK_DESCRIPTION_DEFAULT);
557 michael 5489 ConfigServerInfo.default_max_clients = MAXCLIENTS_MAX;
558 michael 4340 ConfigServerInfo.max_nick_length = 9;
559     ConfigServerInfo.max_topic_length = 80;
560     ConfigServerInfo.hub = 0;
561 michael 4313
562 michael 8510 log_iterate(log_free);
563 michael 1247
564 michael 4340 ConfigLog.use_logging = 1;
565 adx 30
566 michael 9234 ConfigChannel.enable_extbans = 0;
567 michael 1243 ConfigChannel.disable_fake_channels = 0;
568 michael 3860 ConfigChannel.invite_client_count = 10;
569     ConfigChannel.invite_client_time = 300;
570 michael 6792 ConfigChannel.invite_delay_channel = 5;
571 michael 7793 ConfigChannel.invite_expire_time = 1800;
572 michael 3860 ConfigChannel.knock_client_count = 1;
573     ConfigChannel.knock_client_time = 300;
574 adx 30 ConfigChannel.knock_delay_channel = 60;
575 michael 3933 ConfigChannel.max_channels = 25;
576 michael 7766 ConfigChannel.max_invites = 20;
577 michael 8046 ConfigChannel.max_bans = 100;
578     ConfigChannel.max_bans_large = 500;
579 michael 5489 ConfigChannel.default_join_flood_count = 18;
580     ConfigChannel.default_join_flood_time = 6;
581 adx 30
582 michael 1243 ConfigServerHide.flatten_links = 0;
583 michael 6597 ConfigServerHide.flatten_links_delay = 300;
584 michael 1243 ConfigServerHide.hidden = 0;
585     ConfigServerHide.hide_servers = 0;
586 michael 1851 ConfigServerHide.hide_services = 0;
587 michael 1646 ConfigServerHide.hidden_name = xstrdup(NETWORK_NAME_DEFAULT);
588 michael 1243 ConfigServerHide.hide_server_ips = 0;
589 michael 2196 ConfigServerHide.disable_remote_commands = 0;
590 adx 30
591 michael 4340 ConfigGeneral.away_count = 2;
592     ConfigGeneral.away_time = 10;
593 michael 9750 ConfigGeneral.max_monitor = 50;
594 michael 7437 ConfigGeneral.whowas_history_length = 15000;
595 michael 4340 ConfigGeneral.cycle_on_host_change = 1;
596 michael 5805 ConfigGeneral.dline_min_cidr = 16;
597     ConfigGeneral.dline_min_cidr6 = 48;
598     ConfigGeneral.kline_min_cidr = 16;
599     ConfigGeneral.kline_min_cidr6 = 48;
600 michael 4340 ConfigGeneral.invisible_on_connect = 1;
601     ConfigGeneral.disable_auth = 0;
602     ConfigGeneral.kill_chase_time_limit = 90;
603     ConfigGeneral.default_floodcount = 8;
604 michael 7858 ConfigGeneral.default_floodtime = 1;
605 michael 4340 ConfigGeneral.failed_oper_notice = 1;
606 michael 9898 ConfigGeneral.specials_in_ident = 0;
607 michael 4340 ConfigGeneral.min_nonwildcard = 4;
608     ConfigGeneral.min_nonwildcard_simple = 3;
609 michael 6740 ConfigGeneral.max_accept = 50;
610 michael 4340 ConfigGeneral.anti_nick_flood = 0;
611     ConfigGeneral.max_nick_time = 20;
612     ConfigGeneral.max_nick_changes = 5;
613     ConfigGeneral.anti_spam_exit_message_time = 0;
614 michael 6956 ConfigGeneral.ts_warn_delta = 30;
615     ConfigGeneral.ts_max_delta = 600;
616 michael 4340 ConfigGeneral.warn_no_connect_block = 1;
617     ConfigGeneral.stats_e_disabled = 0;
618 michael 5025 ConfigGeneral.stats_i_oper_only = 1; /* 1 = masked */
619 michael 4340 ConfigGeneral.stats_k_oper_only = 1; /* 1 = masked */
620 michael 5025 ConfigGeneral.stats_o_oper_only = 1;
621     ConfigGeneral.stats_m_oper_only = 1;
622 michael 4340 ConfigGeneral.stats_P_oper_only = 0;
623     ConfigGeneral.stats_u_oper_only = 0;
624     ConfigGeneral.caller_id_wait = 60;
625 michael 7949 ConfigGeneral.opers_bypass_callerid = 1;
626 michael 4340 ConfigGeneral.pace_wait = 10;
627     ConfigGeneral.pace_wait_simple = 1;
628     ConfigGeneral.short_motd = 0;
629     ConfigGeneral.ping_cookie = 0;
630     ConfigGeneral.no_oper_flood = 0;
631     ConfigGeneral.max_targets = MAX_TARGETS_DEFAULT;
632 michael 5506 ConfigGeneral.oper_only_umodes = UMODE_DEBUG | UMODE_LOCOPS | UMODE_HIDDEN | UMODE_FARCONNECT |
633 michael 9638 UMODE_EXTERNAL | UMODE_FLOOD | UMODE_NCHANGE |
634     UMODE_SPY | UMODE_SKILL | UMODE_REJ | UMODE_CCONN;
635     ConfigGeneral.oper_umodes = UMODE_FLOOD | UMODE_LOCOPS | UMODE_SERVNOTICE | UMODE_WALLOP;
636 michael 4340 ConfigGeneral.throttle_count = 1;
637     ConfigGeneral.throttle_time = 1;
638 adx 30 }
639    
640     static void
641 michael 9110 conf_validate(void)
642 adx 30 {
643 michael 5039 if (EmptyString(ConfigServerInfo.network_name))
644 michael 4340 ConfigServerInfo.network_name = xstrdup(NETWORK_NAME_DEFAULT);
645 adx 30
646 michael 9692 if (EmptyString(ConfigServerInfo.network_description))
647     ConfigServerInfo.network_description = xstrdup(NETWORK_DESCRIPTION_DEFAULT);
648 adx 30 }
649    
650 michael 9110 /* conf_read()
651 michael 1363 *
652     * inputs - file descriptor pointing to config file to use
653     * output - None
654     * side effects - Read configuration file.
655     */
656     static void
657 michael 9110 conf_read(FILE *file)
658 michael 1363 {
659 michael 7746 lineno = 1;
660 michael 1363
661 michael 9110 conf_set_defaults(); /* Set default values prior to conf parsing */
662 michael 1363 conf_parser_ctx.pass = 1;
663 michael 3375 yyparse(); /* Pick up the classes first */
664 michael 1363
665     rewind(file);
666    
667     conf_parser_ctx.pass = 2;
668 michael 3375 yyparse(); /* Load the values from the conf */
669 michael 9110 conf_validate(); /* Check to make sure some values are still okay. */
670 michael 3375 /* Some global values are also loaded here. */
671 michael 7437 whowas_trim(); /* Attempt to trim whowas list if necessary */
672 michael 3375 class_delete_marked(); /* Delete unused classes that are marked for deletion */
673 michael 1363 }
674    
675 michael 4982 /* conf_rehash()
676     *
677     * Actual REHASH service routine. Called with sig == 0 if it has been called
678     * as a result of an operator issuing this command, else assume it has been
679     * called as a result of the server receiving a HUP signal.
680     */
681 michael 5776 void
682 michael 8658 conf_rehash(bool sig)
683 michael 4982 {
684 michael 8658 if (sig == true)
685 michael 7639 {
686 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
687 michael 4982 "Got signal SIGHUP, reloading configuration file(s)");
688 michael 7639 ilog(LOG_TYPE_IRCD, "Got signal SIGHUP, reloading configuration file(s)");
689     }
690 michael 4982
691     restart_resolver();
692    
693     /* don't close listeners until we know we can go ahead with the rehash */
694    
695 michael 9110 conf_read_files(false);
696 michael 4982
697     load_conf_modules();
698     check_conf_klines();
699     }
700    
701 adx 30 /* conf_connect_allowed()
702     *
703     * inputs - pointer to inaddr
704     * - int type ipv4 or ipv6
705     * output - BANNED or accepted
706     * side effects - none
707     */
708     int
709 michael 8829 conf_connect_allowed(struct irc_ssaddr *addr)
710 adx 30 {
711 michael 8829 const struct MaskItem *conf = find_dline_conf(addr);
712 adx 30
713 michael 3235 if (conf)
714 michael 6549 {
715     /* DLINE exempt also gets you out of static limits/pacing... */
716     if (conf->type == CONF_EXEMPT)
717     return 0;
718 adx 30 return BANNED_CLIENT;
719 michael 6549 }
720 adx 30
721 michael 9202 struct ip_entry *ip_found = ipcache_record_find_or_add(addr);
722 michael 8903 if ((event_base->time.sec_monotonic - ip_found->last_attempt) < ConfigGeneral.throttle_time)
723 adx 30 {
724 michael 4340 if (ip_found->connection_count >= ConfigGeneral.throttle_count)
725 michael 3877 return TOO_FAST;
726 michael 4055
727     ++ip_found->connection_count;
728 adx 30 }
729 michael 3877 else
730     ip_found->connection_count = 1;
731 adx 30
732 michael 8903 ip_found->last_attempt = event_base->time.sec_monotonic;
733 adx 30 return 0;
734     }
735    
736 michael 4982 /* cleanup_tklines()
737     *
738     * inputs - NONE
739     * output - NONE
740     * side effects - call function to expire temporary k/d lines
741     * This is an event started off in ircd.c
742     */
743     void
744     cleanup_tklines(void *unused)
745     {
746     hostmask_expire_temporary();
747 michael 7304 gecos_expire();
748 michael 7282 resv_expire();
749 michael 4982 }
750    
751 adx 30 /*
752 michael 4298 * Input: A client to find the active operator {} name for.
753 adx 30 * Output: The nick!user@host{oper} of the oper.
754     * "oper" is server name for remote opers
755     * Side effects: None.
756     */
757 michael 1364 const char *
758 michael 9250 get_oper_name(const struct Client *client)
759 adx 30 {
760 michael 9762 static char buf[IRCD_BUFSIZE];
761 adx 30
762 michael 9250 if (IsServer(client))
763     return client->name;
764 michael 4628
765 michael 9250 if (MyConnect(client))
766 adx 30 {
767 michael 9250 const dlink_node *const node = client->connection->confs.head;
768 michael 4977
769     if (node)
770 adx 30 {
771 michael 4937 const struct MaskItem *const conf = node->data;
772 adx 30
773 michael 4937 if (conf->type == CONF_OPER)
774 adx 30 {
775 michael 9762 snprintf(buf, sizeof(buf), "%s!%s@%s{%s}", client->name,
776 michael 9250 client->username, client->host, conf->name);
777 michael 9762 return buf;
778 adx 30 }
779     }
780    
781 michael 4298 /*
782     * Probably should assert here for now. If there is an oper out there
783     * with no operator {} conf attached, it would be good for us to know...
784 adx 30 */
785 michael 4298 assert(0); /* Oper without oper conf! */
786 adx 30 }
787    
788 michael 9762 snprintf(buf, sizeof(buf), "%s!%s@%s{%s}", client->name,
789 michael 9250 client->username, client->host, client->servptr->name);
790 michael 9762 return buf;
791 adx 30 }
792    
793 michael 9110 /* conf_clear()
794 adx 30 *
795     * inputs - none
796     * output - none
797     * side effects - Clear out the old configuration
798     */
799     static void
800 michael 9110 conf_clear(void)
801 adx 30 {
802 michael 4815 dlink_node *node = NULL, *node_next = NULL;
803 adx 30 dlink_list *free_items [] = {
804 michael 7401 &connect_items, &operator_items, NULL
805 adx 30 };
806    
807     dlink_list ** iterator = free_items; /* C is dumb */
808    
809     /* We only need to free anything allocated by yyparse() here.
810 michael 9110 * Resetting structs, etc, is taken care of by conf_set_defaults().
811 adx 30 */
812 michael 2916
813 michael 5003 for (; *iterator; iterator++)
814 adx 30 {
815 michael 4815 DLINK_FOREACH_SAFE(node, node_next, (*iterator)->head)
816 adx 30 {
817 michael 4815 struct MaskItem *conf = node->data;
818 michael 1632
819 michael 8658 conf->active = false;
820 michael 7304 dlinkDelete(&conf->node, *iterator);
821 michael 1632
822 michael 7304 if (!conf->ref_count)
823     conf_free(conf);
824 adx 30 }
825     }
826    
827 michael 671 /*
828 michael 5583 * Don't delete the class table, rather mark all entries for deletion.
829     * The table is cleaned up by class_delete_marked. - avalon
830 adx 30 */
831 michael 1632 class_mark_for_deletion();
832 michael 671
833 adx 30 clear_out_address_conf();
834    
835 michael 7245 modules_conf_clear(); /* Clear modules {} items */
836 adx 30
837 michael 7229 motd_clear(); /* Clear motd {} items and re-cache default motd */
838    
839 michael 7217 cluster_clear(); /* Clear cluster {} items */
840 michael 4545
841 michael 7304 gecos_clear(); /* Clear gecos {} items */
842    
843 michael 7282 resv_clear(); /* Clear resv {} items */
844    
845 michael 7248 service_clear(); /* Clear service {} items */
846    
847 michael 7209 shared_clear(); /* Clear shared {} items */
848    
849 michael 7217 pseudo_clear(); /* Clear pseudo {} items */
850    
851 michael 5583 /* Clean out ConfigServerInfo */
852 michael 7032 xfree(ConfigServerInfo.description);
853 michael 4340 ConfigServerInfo.description = NULL;
854 michael 7032 xfree(ConfigServerInfo.network_name);
855 michael 4340 ConfigServerInfo.network_name = NULL;
856 michael 9692 xfree(ConfigServerInfo.network_description);
857     ConfigServerInfo.network_description = NULL;
858 michael 7032 xfree(ConfigServerInfo.rsa_private_key_file);
859 michael 4340 ConfigServerInfo.rsa_private_key_file = NULL;
860 michael 9145 xfree(ConfigServerInfo.tls_certificate_file);
861     ConfigServerInfo.tls_certificate_file = NULL;
862     xfree(ConfigServerInfo.tls_dh_param_file);
863     ConfigServerInfo.tls_dh_param_file = NULL;
864     xfree(ConfigServerInfo.tls_supported_groups);
865     ConfigServerInfo.tls_supported_groups = NULL;
866     xfree(ConfigServerInfo.tls_cipher_list);
867     ConfigServerInfo.tls_cipher_list = NULL;
868 michael 9139 xfree(ConfigServerInfo.tls_cipher_suites);
869     ConfigServerInfo.tls_cipher_suites = NULL;
870 michael 9145 xfree(ConfigServerInfo.tls_message_digest_algorithm);
871     ConfigServerInfo.tls_message_digest_algorithm = NULL;
872 adx 30
873 michael 5583 /* Clean out ConfigAdminInfo */
874 michael 7032 xfree(ConfigAdminInfo.name);
875 michael 4340 ConfigAdminInfo.name = NULL;
876 michael 7032 xfree(ConfigAdminInfo.email);
877 michael 4340 ConfigAdminInfo.email = NULL;
878 michael 7032 xfree(ConfigAdminInfo.description);
879 michael 4340 ConfigAdminInfo.description = NULL;
880 adx 30
881 michael 8451 /* Clean out ConfigServerHide */
882 michael 7032 xfree(ConfigServerHide.flatten_links_file);
883 michael 6599 ConfigServerHide.flatten_links_file = NULL;
884 michael 8451 xfree(ConfigServerHide.hidden_name);
885     ConfigServerHide.hidden_name = NULL;
886 michael 6599
887 michael 5583 /* Clean out listeners */
888 michael 6367 listener_close_marked();
889 adx 30 }
890    
891 michael 7105 static void
892 michael 8656 conf_handle_tls(bool cold)
893 michael 7105 {
894 michael 9224 if (tls_new_credentials() == false)
895 michael 7105 {
896 michael 8656 if (cold == true)
897 michael 7105 {
898     ilog(LOG_TYPE_IRCD, "Error while initializing TLS");
899 michael 7230 exit(EXIT_FAILURE);
900 michael 7105 }
901     else
902     {
903     /* Failed to load new settings/certs, old ones remain active */
904     sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
905     "Error reloading TLS settings, check the ircd log"); // report_crypto_errors logs this
906     }
907     }
908     }
909    
910 michael 4982 /* read_conf_files()
911     *
912     * inputs - cold start YES or NO
913     * output - none
914     * side effects - read all conf files needed, ircd.conf kline.conf etc.
915     */
916     void
917 michael 9110 conf_read_files(bool cold)
918 michael 4982 {
919 michael 9220 char buf[IRCD_BUFSIZE];
920 michael 4982
921     conf_parser_ctx.boot = cold;
922 michael 9222 conf_parser_ctx.conf_file = fopen(ConfigGeneral.configfile, "r");
923 michael 4982
924 michael 9222 if (conf_parser_ctx.conf_file == NULL)
925 michael 4982 {
926 michael 8656 if (cold == true)
927 michael 4982 {
928     ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s",
929 michael 9222 ConfigGeneral.configfile, strerror(errno));
930 michael 6645 exit(EXIT_FAILURE);
931 michael 4982 }
932     else
933     {
934 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
935 michael 4982 "Unable to read configuration file '%s': %s",
936 michael 9222 ConfigGeneral.configfile, strerror(errno));
937 michael 4982 return;
938     }
939     }
940    
941 michael 9222 /*
942     * We need to know the initial filename for the yyerror() to report
943     *
944     * FIXME: The full path is in conffilenamebuf first time since we
945     * don't know anything else
946     *
947     * - Gozem 2002-07-21
948     */
949     strlcpy(conffilebuf, ConfigGeneral.configfile, sizeof(conffilebuf));
950    
951 michael 8656 if (cold == false)
952 michael 9110 conf_clear();
953 michael 4982
954 michael 9110 conf_read(conf_parser_ctx.conf_file);
955 michael 4982 fclose(conf_parser_ctx.conf_file);
956    
957 michael 8510 log_iterate(log_reopen);
958 michael 7105 conf_handle_tls(cold);
959 michael 4982
960 michael 6185 isupport_add("NICKLEN", NULL, ConfigServerInfo.max_nick_length);
961     isupport_add("NETWORK", ConfigServerInfo.network_name, -1);
962 michael 4982
963 michael 9220 snprintf(buf, sizeof(buf), "beI:%u", ConfigChannel.max_bans);
964     isupport_add("MAXLIST", buf, -1);
965 michael 9202
966 michael 6185 isupport_add("MAXTARGETS", NULL, ConfigGeneral.max_targets);
967     isupport_add("CHANTYPES", "#", -1);
968 michael 4982
969 michael 9220 snprintf(buf, sizeof(buf), "#:%u", ConfigChannel.max_channels);
970     isupport_add("CHANLIMIT", buf, -1);
971 michael 9202
972 michael 6185 isupport_add("CHANNELLEN", NULL, CHANNELLEN);
973     isupport_add("TOPICLEN", NULL, ConfigServerInfo.max_topic_length);
974 michael 9202
975 michael 9553 snprintf(buf, sizeof(buf), "%s", "beI,k,l,cimnprstuCKLMNORST");
976 michael 9220 isupport_add("CHANMODES", buf, -1);
977 michael 4982 }
978    
979 adx 30 /* conf_add_class_to_conf()
980     *
981     * inputs - pointer to config item
982     * output - NONE
983 michael 2916 * side effects - Add a class pointer to a conf
984 adx 30 */
985     void
986 michael 5797 conf_add_class_to_conf(struct MaskItem *conf, const char *name)
987 adx 30 {
988 michael 8660 if (EmptyString(name) || (conf->class = class_find(name, true)) == NULL)
989 adx 30 {
990 michael 1632 conf->class = class_default;
991 michael 671
992 michael 4941 if (conf->type == CONF_CLIENT || conf->type == CONF_OPER)
993 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
994 michael 2182 "Warning *** Defaulting to default class for %s@%s",
995     conf->user, conf->host);
996 adx 30 else
997 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
998 michael 2182 "Warning *** Defaulting to default class for %s",
999     conf->name);
1000 adx 30 }
1001     }
1002    
1003     /* yyerror()
1004     *
1005     * inputs - message from parser
1006     * output - NONE
1007     * side effects - message to opers and log file entry is made
1008     */
1009     void
1010     yyerror(const char *msg)
1011     {
1012 michael 967 if (conf_parser_ctx.pass != 1)
1013 adx 30 return;
1014    
1015 michael 7789 const char *p = stripws(linebuf);
1016 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
1017 michael 1618 "\"%s\", line %u: %s: %s",
1018 michael 7746 conffilebuf, lineno, msg, p);
1019 michael 1247 ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1020 michael 7746 conffilebuf, lineno, msg, p);
1021 adx 30 }
1022    
1023 michael 1751 void
1024     conf_error_report(const char *msg)
1025     {
1026 michael 7789 const char *p = stripws(linebuf);
1027 michael 6318 sendto_realops_flags(UMODE_SERVNOTICE, L_ADMIN, SEND_NOTICE,
1028 michael 1751 "\"%s\", line %u: %s: %s",
1029 michael 7777 conffilebuf, lineno, msg, p);
1030 michael 1751 ilog(LOG_TYPE_IRCD, "\"%s\", line %u: %s: %s",
1031 michael 7777 conffilebuf, lineno, msg, p);
1032 michael 1751 }
1033    
1034 adx 30 /*
1035     * valid_tkline()
1036 michael 2916 *
1037 adx 30 * inputs - pointer to ascii string to check
1038     * - whether the specified time is in seconds or minutes
1039     * output - -1 not enough parameters
1040     * - 0 if not an integer number, else the number
1041     * side effects - none
1042     * Originally written by Dianora (Diane, db@db.net)
1043     */
1044 michael 7330 uintmax_t
1045 michael 2313 valid_tkline(const char *data, const int minutes)
1046 adx 30 {
1047 michael 2313 const unsigned char *p = (const unsigned char *)data;
1048     unsigned char tmpch = '\0';
1049 michael 7330 uintmax_t result = 0;
1050 adx 30
1051 michael 2313 while ((tmpch = *p++))
1052 adx 30 {
1053 michael 2313 if (!IsDigit(tmpch))
1054 michael 1121 return 0;
1055 michael 1120
1056     result *= 10;
1057 michael 2313 result += (tmpch & 0xF);
1058 adx 30 }
1059    
1060 michael 1120 /*
1061 michael 2916 * In the degenerate case where oper does a /quote kline 0 user@host :reason
1062 michael 5583 * i.e. they specifically use 0, I am going to return 1 instead as a return
1063     * value of non-zero is used to flag it as a temporary kline
1064 adx 30 */
1065     if (result == 0)
1066     result = 1;
1067    
1068 michael 2916 /*
1069 adx 30 * If the incoming time is in seconds convert it to minutes for the purpose
1070     * of this calculation
1071     */
1072 michael 8522 if (minutes == 0)
1073 michael 2916 result = result / 60;
1074 adx 30
1075     if (result > MAX_TDKLINE_TIME)
1076     result = MAX_TDKLINE_TIME;
1077    
1078 michael 5583 result = result * 60; /* Turn it into seconds */
1079 adx 30
1080     return result;
1081     }
1082    
1083 michael 2130 /* valid_wild_card_simple()
1084     *
1085     * inputs - data to check for sufficient non-wildcard characters
1086     * outputs - 1 if valid, else 0
1087     * side effects - none
1088     */
1089 michael 8660 bool
1090 michael 2130 valid_wild_card_simple(const char *data)
1091     {
1092     const unsigned char *p = (const unsigned char *)data;
1093     unsigned char tmpch = '\0';
1094 michael 6332 unsigned int nonwild = 0, wild = 0;
1095 michael 2130
1096     while ((tmpch = *p++))
1097     {
1098 michael 4265 if (tmpch == '\\' && *p)
1099 michael 2130 {
1100     ++p;
1101 michael 4340 if (++nonwild >= ConfigGeneral.min_nonwildcard_simple)
1102 michael 8660 return true;
1103 michael 2130 }
1104     else if (!IsMWildChar(tmpch))
1105     {
1106 michael 4340 if (++nonwild >= ConfigGeneral.min_nonwildcard_simple)
1107 michael 8660 return true;
1108 michael 2130 }
1109 michael 6332 else
1110     ++wild;
1111 michael 2130 }
1112    
1113 michael 8660 return wild == 0;
1114 michael 2130 }
1115    
1116 adx 30 /* valid_wild_card()
1117     *
1118     * input - pointer to client
1119     * - int flag, 0 for no warning oper 1 for warning oper
1120     * - count of following varargs to check
1121     * output - 0 if not valid, 1 if valid
1122 michael 9250 * side effects - NOTICE is given to client if warn is 1
1123 adx 30 */
1124 michael 8660 bool
1125 michael 7429 valid_wild_card(int count, ...)
1126 adx 30 {
1127 michael 3931 unsigned char tmpch = '\0';
1128 michael 3870 unsigned int nonwild = 0;
1129 adx 30 va_list args;
1130    
1131     /*
1132     * Now we must check the user and host to make sure there
1133     * are at least NONWILDCHARS non-wildcard characters in
1134     * them, otherwise assume they are attempting to kline
1135     * *@* or some variant of that. This code will also catch
1136     * people attempting to kline *@*.tld, as long as NONWILDCHARS
1137     * is greater than 3. In that case, there are only 3 non-wild
1138     * characters (tld), so if NONWILDCHARS is 4, the kline will
1139     * be disallowed.
1140     * -wnder
1141     */
1142    
1143     va_start(args, count);
1144    
1145     while (count--)
1146     {
1147 michael 3931 const unsigned char *p = va_arg(args, const unsigned char *);
1148 adx 30 if (p == NULL)
1149     continue;
1150    
1151     while ((tmpch = *p++))
1152     {
1153     if (!IsKWildChar(tmpch))
1154     {
1155     /*
1156     * If we find enough non-wild characters, we can
1157     * break - no point in searching further.
1158     */
1159 michael 4340 if (++nonwild >= ConfigGeneral.min_nonwildcard)
1160 michael 2659 {
1161     va_end(args);
1162 michael 8660 return true;
1163 michael 2659 }
1164 adx 30 }
1165     }
1166     }
1167    
1168 michael 2659 va_end(args);
1169 michael 8660 return false;
1170 adx 30 }
1171    
1172     /* XXX should this go into a separate file ? -Dianora */
1173     /* parse_aline
1174     *
1175     * input - pointer to cmd name being used
1176     * - pointer to client using cmd
1177     * - parc parameter count
1178     * - parv[] list of parameters to parse
1179     * - parse_flags bit map of things to test
1180     * - pointer to user or string to parse into
1181     * - pointer to host or NULL to parse into if non NULL
1182 michael 2916 * - pointer to optional tkline time or NULL
1183 adx 30 * - pointer to target_server to parse into if non NULL
1184     * - pointer to reason to parse into
1185     *
1186 michael 5776 * output - 1 if valid, 0 if not valid
1187 adx 30 * side effects - A generalised k/d/x etc. line parser,
1188     * "ALINE [time] user@host|string [ON] target :reason"
1189     * will parse returning a parsed user, host if
1190     * h_p pointer is non NULL, string otherwise.
1191     * if tkline_time pointer is non NULL a tk line will be set
1192     * to non zero if found.
1193     * if tkline_time pointer is NULL and tk line is found,
1194     * error is reported.
1195     * if target_server is NULL and an "ON" is found error
1196     * is reported.
1197     * if reason pointer is NULL ignore pointer,
1198 db 936 * this allows use of parse_a_line in unkline etc.
1199 adx 30 *
1200     * - Dianora
1201     */
1202 michael 8664 bool
1203 michael 9250 parse_aline(const char *cmd, struct Client *client, int parc, char **parv, struct aline_ctx *aline)
1204 adx 30 {
1205 michael 5823 static char default_reason[] = CONF_NOREASON;
1206 michael 8676 static char user[USERLEN * 2 + 1];
1207     static char host[HOSTLEN * 2 + 1];
1208 adx 30
1209 michael 8670 ++parv;
1210     --parc;
1211 adx 30
1212 michael 8670 if (aline->add == true && (aline->duration = valid_tkline(*parv, TK_MINUTES)))
1213 adx 30 {
1214 michael 8670 ++parv;
1215     --parc;
1216 adx 30 }
1217    
1218     if (parc == 0)
1219     {
1220 michael 9250 sendto_one_numeric(client, &me, ERR_NEEDMOREPARAMS, cmd);
1221 michael 8664 return false;
1222 adx 30 }
1223    
1224 michael 8680 if (aline->simple_mask == true)
1225     {
1226     aline->mask = *parv;
1227     aline->user = NULL;
1228     aline->host = NULL;
1229     }
1230 adx 30 else
1231     {
1232 michael 8676 struct split_nuh_item nuh;
1233 michael 8682
1234 michael 8676 nuh.nuhmask = *parv;
1235 michael 8682 nuh.nickptr = NULL;
1236 michael 8676 nuh.userptr = user;
1237     nuh.hostptr = host;
1238 adx 30
1239 michael 8682 nuh.nicksize = 0;
1240 michael 8676 nuh.usersize = sizeof(user);
1241     nuh.hostsize = sizeof(host);
1242    
1243     split_nuh(&nuh);
1244    
1245 michael 8680 aline->mask = NULL;
1246 michael 8670 aline->user = user;
1247     aline->host = host;
1248 adx 30 }
1249 michael 2916
1250 michael 8670 ++parv;
1251     --parc;
1252 adx 30
1253 michael 4982 if (parc)
1254 adx 30 {
1255     if (irccmp(*parv, "ON") == 0)
1256     {
1257 michael 8670 ++parv;
1258     --parc;
1259 adx 30
1260 michael 9250 if (!HasOFlag(client, OPER_FLAG_REMOTEBAN))
1261 adx 30 {
1262 michael 9250 sendto_one_numeric(client, &me, ERR_NOPRIVS, "remoteban");
1263 michael 8664 return false;
1264 adx 30 }
1265    
1266     if (parc == 0 || EmptyString(*parv))
1267     {
1268 michael 9250 sendto_one_numeric(client, &me, ERR_NEEDMOREPARAMS, cmd);
1269 michael 8664 return false;
1270 adx 30 }
1271    
1272 michael 8670 aline->server = *parv;
1273     ++parv;
1274     --parc;
1275 adx 30 }
1276     else
1277 michael 8670 aline->server = NULL;
1278 adx 30 }
1279    
1280 michael 8670 if (aline->add == true)
1281 adx 30 {
1282 michael 8676 if (parc == 0 || EmptyString(*parv))
1283     aline->reason = default_reason;
1284     else
1285 michael 8670 aline->reason = *parv;
1286 adx 30 }
1287    
1288 michael 8664 return true;
1289 adx 30 }
1290    
1291     /* match_conf_password()
1292     *
1293     * inputs - pointer to given password
1294     * - pointer to Conf
1295     * output - 1 or 0 if match
1296     * side effects - none
1297     */
1298 michael 8660 bool
1299 michael 1632 match_conf_password(const char *password, const struct MaskItem *conf)
1300 adx 30 {
1301     const char *encr = NULL;
1302    
1303 michael 1632 if (EmptyString(password) || EmptyString(conf->passwd))
1304 michael 8660 return false;
1305 adx 30
1306 michael 1632 if (conf->flags & CONF_FLAGS_ENCRYPTED)
1307     encr = crypt(password, conf->passwd);
1308 adx 30 else
1309     encr = password;
1310    
1311 michael 8660 return encr && strcmp(encr, conf->passwd) == 0;
1312 adx 30 }
1313    
1314     /*
1315     * split_nuh
1316     *
1317     * inputs - pointer to original mask (modified in place)
1318     * - pointer to pointer where nick should go
1319     * - pointer to pointer where user should go
1320     * - pointer to pointer where host should go
1321     * output - NONE
1322     * side effects - mask is modified in place
1323     * If nick pointer is NULL, ignore writing to it
1324     * this allows us to use this function elsewhere.
1325     *
1326     * mask nick user host
1327     * ---------------------- ------- ------- ------
1328     * Dianora!db@db.net Dianora db db.net
1329     * Dianora Dianora * *
1330     * db.net * * db.net
1331     * OR if nick pointer is NULL
1332     * Dianora - * Dianora
1333     * Dianora! Dianora * *
1334     * Dianora!@ Dianora * *
1335     * Dianora!db Dianora db *
1336     * Dianora!@db.net Dianora * db.net
1337     * db@db.net * db db.net
1338     * !@ * * *
1339     * @ * * *
1340     * ! * * *
1341     */
1342     void
1343 michael 593 split_nuh(struct split_nuh_item *const iptr)
1344 adx 30 {
1345     char *p = NULL, *q = NULL;
1346    
1347 michael 593 if (iptr->nickptr)
1348     strlcpy(iptr->nickptr, "*", iptr->nicksize);
1349 michael 4982
1350 michael 593 if (iptr->userptr)
1351     strlcpy(iptr->userptr, "*", iptr->usersize);
1352 michael 4982
1353 michael 593 if (iptr->hostptr)
1354     strlcpy(iptr->hostptr, "*", iptr->hostsize);
1355    
1356     if ((p = strchr(iptr->nuhmask, '!')))
1357 adx 30 {
1358     *p = '\0';
1359    
1360 michael 3375 if (iptr->nickptr && *iptr->nuhmask)
1361 michael 593 strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);
1362 adx 30
1363 michael 2525 if ((q = strchr(++p, '@')))
1364     {
1365 michael 593 *q++ = '\0';
1366    
1367 michael 3375 if (*p)
1368 michael 593 strlcpy(iptr->userptr, p, iptr->usersize);
1369 adx 30
1370 michael 3375 if (*q)
1371 michael 593 strlcpy(iptr->hostptr, q, iptr->hostsize);
1372 adx 30 }
1373     else
1374     {
1375 michael 3375 if (*p)
1376 michael 593 strlcpy(iptr->userptr, p, iptr->usersize);
1377 adx 30 }
1378     }
1379 michael 593 else
1380 adx 30 {
1381 michael 593 /* No ! found so lets look for a user@host */
1382     if ((p = strchr(iptr->nuhmask, '@')))
1383 adx 30 {
1384 michael 593 /* if found a @ */
1385     *p++ = '\0';
1386 adx 30
1387 michael 3375 if (*iptr->nuhmask)
1388 michael 593 strlcpy(iptr->userptr, iptr->nuhmask, iptr->usersize);
1389 adx 30
1390 michael 3375 if (*p)
1391 michael 593 strlcpy(iptr->hostptr, p, iptr->hostsize);
1392 adx 30 }
1393 michael 593 else
1394 adx 30 {
1395 michael 5583 /* No @ found */
1396 michael 8702 if (iptr->nickptr == NULL || strpbrk(iptr->nuhmask, ".:"))
1397 michael 593 strlcpy(iptr->hostptr, iptr->nuhmask, iptr->hostsize);
1398 adx 30 else
1399 michael 593 strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize);
1400 adx 30 }
1401     }
1402     }

Properties

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