/* * $Id: config.c,v 1.25 2002/10/17 20:02:29 ljb Exp $ * originally Id: config.c,v 1.50 1998/07/20 01:22:03 labovit Exp */ #include #include #include "mrt.h" #include "trace.h" #include #include #include #include #include "config_file.h" #include "irrd.h" extern trace_t *default_trace; find_filter_t o_filter[] = { {"unused", XXX_F }, {"autnum", AUTNUM_F }, {"asmacro", ASMACRO_F }, {"community", COMMUNITY_F }, {"domain", DOMAIN_F }, {"inetnum", INETNUM_F }, {"inet6num", INET6NUM_F }, {"person", PERSON_F }, {"dom-prefix", DOMAIN_PREFIX_F}, {"inet-rtr", INET_RTR_F }, {"limerick", LIMERICK_F }, {"mntner", MNTNER_F }, {"route", ROUTE_F }, {"role", ROLE_F }, {"ipv6-site", IPV6_SITE_F }, {"as-set", AS_SET_F }, {"route-set", ROUTE_SET_F }, {"filter-set", FILTER_SET_F }, {"rtr-set", RTR_SET_F }, {"peering-set", PEERING_SET_F }, {"dictionary", DICTIONARY_F }, {"key-cert", KEY_CERT_F }, {"repository", REPOSITORY_F }, }; u_int as_lookup_fn (u_short *as1, u_short *as2) { return ((!((*as1) - (*as2)))); } u_int as_hash_fn (u_short *as, u_int size) { u_int value; value = *as % size; return (value); } #ifdef HJHJHH void config_create_default () { char *tmp; CONFIG.ll_modules = LL_Create (0); tmp = strdup ("#####################################################################"); config_add_module (0, "comment", get_comment_config, tmp); tmp = malloc (512); sprintf (tmp, "# IRRd -- version %s ", IRRD_VERSION); config_add_module (0, "comment", get_comment_config, tmp); tmp = strdup ("#####################################################################"); config_add_module (0, "comment", get_comment_config, tmp); config_add_module (0, "comment", get_comment_config, strdup ("!")); config_add_module (0, "comment", get_comment_config, strdup ("!")); /*config_add_module (0, "irr_port", get_config_irr_port, NULL); config_add_module (0, "irr_directory", get_config_irr_directory, NULL); */ } #endif void get_config_irr_max_connections () { config_add_output ("irr_max_connections %d\r\n", IRR.max_connections); } /* irr_max_con %d * maximum number of silumtaneous open TCP connections to our whois port */ int config_irr_max_con (uii_connection_t *uii, int max) { if ((max <= 0) || (max >= 10000)) { config_notice (NORM, uii, "CONFIG Error -- usage: irr_max_connections <1-1000>\n", max); return (-1); } IRR.max_connections = max; config_add_module (0, "irr_max_connections", get_config_irr_max_connections, NULL); return (1); } /* return the irr_port (whois) on which we are listening */ void get_config_irr_port () { if (IRR.irr_port_access == 0) config_add_output ("irr_port %d\r\n", IRR.irr_port); else config_add_output ("irr_port %d access %d\r\n", IRR.irr_port, IRR.irr_port_access); } /* irr_port %d * The port we listen on for RAWhoisd style machine queries */ void config_irr_port (uii_connection_t *uii, int port, int access_list) { if ((port <= 0) || (port > 60000)) { config_notice (NORM, uii, "CONFIG Error -- usage: irr_port [access ]\n"); return; } IRR.irr_port = port; if ((access_list < 1) || (access_list > 101)) { config_notice (NORM, uii, "CONFIG Error -- usage: irr_port [access ]\n"); return; } IRR.irr_port_access = access_list; config_add_module (0, "irr_port", get_config_irr_port, NULL); } /* irr_port %d * The port we listen on for RAWhoisd style machine queries */ void config_irr_port_2 (uii_connection_t *uii, int port) { if ((port <= 0) || (port > 60000)) { config_notice (NORM, uii, "CONFIG Error -- usage: irr_port [access ]\n"); return; } IRR.irr_port = port; /* reset to no access list filtering */ IRR.irr_port_access = 0; config_add_module (0, "irr_port", get_config_irr_port, NULL); } void get_config_irr_mirror_interval () { config_add_output ("irr_mirror_interval %d\r\n", IRR.mirror_interval); } void config_irr_mirror_interval (uii_connection_t *uii, int interval) { IRR.mirror_interval = interval; config_add_module (0, "irr_mirror_interval", get_config_irr_mirror_interval, NULL); } void get_config_irr_directory () { config_add_output ("irr_directory %s\r\n", IRR.database_dir); } int config_irr_directory (uii_connection_t *uii, char *directory) { char status_filename[BUFSIZE]; if (IRR.database_dir != NULL) Delete (IRR.database_dir); IRR.database_dir = directory; config_add_module (0, "irr_directory", get_config_irr_directory, NULL); sprintf(status_filename, "%s/IRRD_STATUS", directory); if (IRR.statusfile) { CloseStatusFile(IRR.statusfile); Delete(IRR.statusfile); } IRR.statusfile = InitStatusFile(status_filename); return (1); } void get_config_irr_database (irr_database_t *database) { int atts = 0; if (database->flags & IRR_AUTHORITATIVE) { config_add_output ("irr_database %s authoritative\r\n", database->name); atts = 1; } if (database->mirror_prefix != NULL) { config_add_output ("irr_database %s mirror_host %s %d\r\n", database->name, prefix_toa (database->mirror_prefix), database->mirror_port); atts =1; } if (database->access_list != 0) { config_add_output ("irr_database %s access %d\r\n", database->name, database->access_list); atts =1; } if (database->write_access_list != 0) { config_add_output ("irr_database %s write-access %d\r\n", database->name, database->write_access_list); atts =1; } if (database->mirror_access_list != 0) { config_add_output ("irr_database %s mirror-access %d\r\n", database->name, database->mirror_access_list); atts =1; } if (database->export_timer != NULL) { config_add_output ("irr_database %s export %d\r\n", database->name, database->export_timer->time_interval_base); atts =1; } if ((database->clean_timer != NULL) && (!database->no_dbclean)) { config_add_output ("irr_database %s clean %d\r\n", database->name, database->clean_timer->time_interval_base); atts =1; } if (database->no_dbclean) { config_add_output ("irr_database %s no-clean\r\n", database->name); atts =1; } if (database->flags & IRR_NODEFAULT) { config_add_output ("irr_database %s no-default\r\n", database->name); atts = 1; } if (atts == 0) config_add_output ("irr_database %s\r\n", database->name); } int config_irr_database_nodefault (uii_connection_t *uii, char *name) { irr_database_t *database = NULL; if ((database = find_database (name)) == NULL) { config_notice (ERROR, uii, "Database %s not found!\r\n", name); Delete (name); return (-1); } Delete (name); database->flags |= IRR_NODEFAULT; return (1); } /* irr_database %s export %d [%s] */ int config_irr_database_export (uii_connection_t *uii, char *name, int interval, int num, char *filename) { irr_database_t *database = NULL; if ((database = find_database (name)) == NULL) { config_notice (ERROR, uii, "Database %s not found!\r\n", name); Delete (name); if (num == 1) Delete(filename); return (-1); } /* once a day */ database->export_timer = (mtimer_t *) New_Timer (irr_export_timer, interval, "IRR export", database); timer_set_jitter (database->export_timer, (int) (interval / 3.0)); Timer_Turn_ON ((mtimer_t *) database->export_timer); if (num == 1) { database->export_filename = filename; } Delete(name); return (1); } /* Parse the irrd.conf command 'irr_path %s' and save the specified * path component (which can be used to find irrdcacher, wget, * ripe2rpsl ...). The specified path component is added to the * users PATH environment variable when external binaries are invoked. * * irrd.conf command: * irr_path %s * * eg, 'irr_path :/irr/bin:/usr/local/joe/mybin * * Input: * -data struct for communicating with UII users (uii) * -a path component (path) * * Return: * -void * * set's 'IRR.path' to (path) */ int config_irr_path (uii_connection_t *uii, char *path) { char buf[BUFSIZE+2]; if (path == NULL) { config_notice (ERROR, uii, "NULL irr path component!\r\n"); return -1; } else if (strlen (path) > BUFSIZE) { config_notice (ERROR, uii, "path component too large! MAX(%d)\r\n", BUFSIZE); Delete (path); return -1; } Delete (IRR.path); /* make sure path component begin's with a ':' */ if (*path != ':') sprintf (buf, ":%s", path); else strcpy (buf, path); IRR.path = strdup (buf); Delete (path); /* let the user know we have updated the path */ config_notice (NORM, uii, "path component set to (%s)\r\n", IRR.path); return 1; } #ifndef NT /* Reset the ftp URL for DB (name) * * URL to be used by irrdcacher for remote DB retrievel. * * (name) must not be an authoritative DB. * * irrd.conf command: * irr_database %s remote_ftp_url %s * * eg, 'irr_database ripe remote_ftp_url ftp://ftp.ripe.net/ripe/dbase * * Input: * -data struct for communicating with UII users (uii) * -DB name to associate the ftp URL with (name) * -ftp URL to use for remote DB refreshes (dir) * * Return: * -1 if there were no errors in the command * --1 otherwise * * set's the 'remote_ftp_url' irr_database_t member with (dir) */ int config_irr_remote_ftp_url (uii_connection_t *uii, char *name, char *dir) { int ret_code = 1; irr_database_t *db; regex_t url_re; char *ftp_url = "^ftp://[^ \t/]+/[[:graph:]]+$"; /* Do we know about this DB? */ if ((db = find_database (name)) == NULL) { config_notice (ERROR, uii, "Database %s not found!\r\n", name); ret_code = -1; goto INPUT_ERROR; } /* make sure this DB is not authoritative */ if (db->flags & IRR_AUTHORITATIVE) { config_notice (ERROR, uii, "*ERROR* database %s is authoritative !\r\n", name); ret_code = -1; goto INPUT_ERROR; } /* make sure the remote url is in valid URL format */ /* compile our reg ex */ regcomp (&url_re, ftp_url, REG_EXTENDED|REG_NOSUB); /* check the URL format */ if (regexec (&url_re, dir, 0, NULL, 0)) { config_notice (ERROR, uii, "Invalid URL format (%s)! (ftp:///)\r\n", dir); ret_code = -1; } else { /* make purify happy */ Delete (db->remote_ftp_url); db->remote_ftp_url = strdup (dir); config_notice (NORM, uii, "Remote ftp URL (%s) set for (%s)\r\n", dir, name); } regfree (&url_re); INPUT_ERROR: Delete (dir); Delete (name); return ret_code; } /* Set the repository signature hex ID for DB (name) to (hexid). * * The hexid can be in "[[:xdigit:]]{8}" format or "0x[[:xdigit:]]{8}". * Internally the hexid will be stored as "0x[[:xdigit:]]{8}". * * Input: * -data struct for communicating with UII users (uii) * -DB to set the repository hex ID (name) * -hex ID of the repository signature (hexid) * * Return: * -1 if the operation was successful * --1 otherwise */ int config_irr_repos_hexid (uii_connection_t *uii, char *name, char *hexid) { char hex_out[16]; int ret_code = -1; irr_database_t *db; regex_t re; char *hex_num = "^(0x)?[[:xdigit:]]{8}$"; /* Do we know about this DB? */ if ((db = find_database (name)) == NULL) { config_notice (ERROR, uii, "Database %s not found!\r\n", name); goto INPUT_ERROR; } /* compile the regex */ regcomp (&re, hex_num, REG_EXTENDED|REG_NOSUB); /* see if the (hexid) is well-formed */ if (regexec (&re, hexid, 0, NULL, 0) == 0) { if (*hexid == '0') strcpy (hex_out, hexid); /* perfect! */ else sprintf (hex_out, "0x%s", hexid); /* need to add a leading '0x' */ /* replace the old repos hexid with the new */ Delete (db->repos_hexid); db->repos_hexid = strdup (hex_out); ret_code = 1; config_notice (NORM, uii, "Repository hex ID (%s) set for (%s)\r\n", hexid, name); } else config_notice (NORM, uii, "Malformed hex ID (%s) expecting \"[[:xdigit:]]{8}\"\r\n", hexid); regfree (&re); INPUT_ERROR: Delete (hexid); Delete (name); return ret_code; } /* Set the PGP password for DB (name)'s repository object. * * (passwd) can have spaces and may be enclosed in "'s. The * enclosing "'s (if any) are not considered part of the password. * * Input: * -data struct for communicating with UII users (uii) * -DB to set pgp password (name) * -password for the repository object (passwd) * * Return: * -1 if the operation was successful * --1 otherwise */ int config_irr_pgppass (uii_connection_t *uii, char *name, char *passwd) { char pgppass[BUFSIZE+1]; int ret_code = -1, n, offset; irr_database_t *db; regmatch_t rm[5]; regex_t re; char *pass = "^((\"(.*)\")|([^\" \t\n]*))[ \t]*\n?$"; /* Do we know about this DB? */ if ((db = find_database (name)) == NULL) { config_notice (ERROR, uii, "Database %s not found!\r\n", name); goto INPUT_ERROR; } /* compile the regex */ regcomp (&re, pass, REG_EXTENDED); /* see if the (password) is well-formed */ if (regexec (&re, passwd, 5, rm, 0) == 0) { if (rm[3].rm_so != -1) offset = 3; else offset = 4; if ((n = (rm[offset].rm_eo - rm[offset].rm_so)) <= BUFSIZE) { strncpy (pgppass, (char *) (passwd + rm[offset].rm_so), n); pgppass[n] = '\0'; Delete (db->pgppass); db->pgppass = strdup (pgppass); ret_code = 1; config_notice (NORM, uii, "PGP password (%s) set for (%s)\r\n", pgppass, name); } else config_notice (ERROR, uii, "PGP password is too long! MAX(%d)\r\n", BUFSIZE); } else config_notice (ERROR, uii, "Malformed PGP password\r\n"); regfree (&re); INPUT_ERROR: Delete (passwd); Delete (name); return ret_code; } #endif /* NT */ /* Add (dbname) to the list of rpsdist managed DB's. * * sample irrd.conf entry: * rpsdist_database bell * rpsdist does not trust DB's defined this way. DB's * will normally be added this way dynamically from the * !C command. * * A corresponding entry is made to irrd so that it will know * about the DB and will accept !ms...!me commands from rpsdist. * * Input: * -name of the DB to add to the rpsdist list of DB's * * Return: * -1 if no errors * --1 otherwise */ int config_rpsdist_database (uii_connection_t *uii, char *dbname) { int ret_code = -1; irr_database_t *db; /* look up the DB */ db = find_database (dbname); /* mis-configuration checking */ if (db != NULL && db->mirror_prefix != NULL) { config_notice (NORM, uii, "CONFIG Error -- conflicting " "\"irr_database/rpsdist_database\" configurations " "for DB %s\r\n", dbname); goto CLEAN_UP; } if ((ret_code = config_irr_database_authoritative (uii, strdup (dbname))) < 0) goto CLEAN_UP; /* look up the DB */ if (db == NULL) db = find_database (dbname); db->rpsdist_flag = 1; CLEAN_UP: /* clean-up */ Delete (dbname); return ret_code; } /* Accept rpsdist connections from (host). * * sample irrd.conf entry: * rpsdist accept 198.108.60.1 * * Allows mirror-only hosts to connect to us and get * transaction updates from us. (eg, a router. any host * that does not have an DB but wishes to have a local * copy of the IRR) * * Input: * -host to accept connections from which we will send * transactions but not accept updates. * * Return: * -1 if no errors * --1 otherwise */ int config_rpsdist_accept (uii_connection_t *uii, char *host) { int ret_code = 1; /* host */ if (string_toprefix (host, default_trace) == NULL) { config_notice (NORM, uii, "CONFIG Error -- could not resolve %s\r\n", host); ret_code = -1; } Delete (host); return ret_code; } /* Accept rpsdist connections from (host) and also * accept poll requests and unicasted transactions. * * sample irrd.conf entry: * rpsdist ripe accept 198.108.60.1 * * Allows a remote host to send us rpsdist updates * from more than 1 host or from a remote host that * we don't trust. * * Input: * -host to accept connections from which we will send * transactions and accept updates. * -name of the DB to add to the rpsdist list of DB's * * Return: * -1 if no errors * --1 otherwise */ int config_rpsdist_accept_database (uii_connection_t *uii, char *dbname, char *host) { int ret_code = -1; irr_database_t *db; /* look up the DB */ db = find_database (dbname); /* mis-configuration checking */ if (db != NULL && db->mirror_prefix != NULL) { config_notice (NORM, uii, "CONFIG Error -- conflicting " "\"irr_database/rpsdist_database\" configurations " "for DB %s\r\n", dbname); goto CLEAN_UP; } /* host and port */ if (string_toprefix (host, default_trace) == NULL) { config_notice (NORM, uii, "CONFIG Error -- could not resolve %s\r\n", host); goto CLEAN_UP; } if ((ret_code = config_irr_database_authoritative (uii, strdup (dbname))) < 0) goto CLEAN_UP; /* look up the DB */ if (db == NULL) db = find_database (dbname); /* if we get here all is well */ db->rpsdist_flag = 1; db->rpsdist_accept_host = strdup (host); CLEAN_UP: /* clean-up */ Delete (dbname); Delete (host); return ret_code; } /* Parse the conf command line for "rpsdist_database %s trusted %s %d". * * eg, rpsdist_database ripe trusted whois.ripe.net 43 * * The DB becomes trusted for ripe which allows rpsdist to accept * signed updates to be accepted without auth checking. The host * and port tell rpsdist where to connect for floods/polls. * * Input: * -data struct for communicating with UII users (uii) * -DB to associate the information to (dbname) * -host and port to connect to for floods/polls (host, port) * * Return: * -1 if there were no errors * --1 otherwise */ int config_rpsdist_database_trusted (uii_connection_t *uii, char *dbname, char *host, int port) { int ret_code = -1; irr_database_t *db; /* look up the DB */ db = find_database (dbname); /* mis-configuration checking */ if (db != NULL && (db->rpsdist_trusted || db->rpsdist_auth || db->mirror_prefix != NULL)) { config_notice (NORM, uii, "CONFIG Error -- conflicting " "\"irr_database/rpsdist_database\" configurations " "for DB %s\r\n", dbname); goto CLEAN_UP; } /* host */ if (string_toprefix (host, default_trace) == NULL) { config_notice (NORM, uii, "CONFIG Error -- could not resolve %s\r\n", host); goto CLEAN_UP; } /* if we get here there were no errors */ config_notice (NORM, uii, "rpsdist DB (%s) set values: (host, port)=" "(%s, %d)\r\n", dbname, host, port); /* let irrd know about this DB */ if ((ret_code = config_irr_database_authoritative (uii, strdup (dbname))) < 0) goto CLEAN_UP; /* look up the DB */ if (db == NULL) db = find_database (dbname); /* set the values */ db->rpsdist_flag = 1; db->rpsdist_trusted = 1; db->rpsdist_host = strdup (host); db->rpsdist_port = port; CLEAN_UP: /* clean-up */ Delete (dbname); Delete (host); return ret_code; } /* Parse the conf command line for "rpsdist_database %s authoritative %s". * * eg, rpsdist_database radb authoritative "Iftdpa!" * * radb becomes authoritative which allows rpsdist to accept * updates. The password is for the signing key which * is needed by rpsdist when flooding. * * Input: * -data struct for communicating with UII users (uii) * -DB to associate the information to (dbname) * -pgp password for the signing key (passwd) * * Return: * -1 if there were no errors * --1 otherwise */ int config_rpsdist_database_authoritative (uii_connection_t *uii, char *dbname, char *passwd) { int ret_code = -1, n, offset; irr_database_t *db; char pgppass[BUFSIZE+1]; regmatch_t rm[5]; regex_t re_pass; char *pass = "^((\"(.*)\")|([^\" \t\n]*))[ \t]*\n?$"; /* look up the DB */ db = find_database (dbname); /* mis-configuration checking */ if (db != NULL && (db->rpsdist_trusted || db->mirror_prefix != NULL)) { config_notice (NORM, uii, "CONFIG Error -- conflicting " "\"irr_database/rpsdist_database\" configurations " "for DB %s\r\n", dbname); goto CLEAN_UP; } /* PGP password */ regcomp (&re_pass, pass, REG_EXTENDED); /* see if the (password) is well-formed */ if (regexec (&re_pass, passwd, 5, rm, 0) == 0) { if (rm[3].rm_so != -1) offset = 3; else offset = 4; if ((n = (rm[offset].rm_eo - rm[offset].rm_so)) <= BUFSIZE) { strncpy (pgppass, (char *) (passwd + rm[offset].rm_so), n); pgppass[n] = '\0'; ret_code = 1; } else config_notice (ERROR, uii, "PGP password is too long! MAX(%d)\r\n", BUFSIZE); } else config_notice (ERROR, uii, "Malformed PGP password\r\n"); regfree (&re_pass); if (ret_code < 0) goto CLEAN_UP; /* if we get here there were no errors */ config_notice (NORM, uii, "rpsdist DB (%s) set values: (PGPPASS)=" "(%s)\r\n", dbname, pgppass); /* let irrd know about this DB */ if ((ret_code = config_irr_database_authoritative (NULL, strdup (dbname))) < 0) goto CLEAN_UP; /* look up the DB */ if (db == NULL) db = find_database (dbname); /* set the values */ db->rpsdist_flag = 1; db->rpsdist_auth = 1; db->pgppass = strdup (pgppass); CLEAN_UP: /* clean-up */ Delete (dbname); Delete (passwd); return ret_code; } /* config no irr_database %s authoritative */ int no_config_irr_database_authoritative (uii_connection_t *uii, char *name) { irr_database_t *database = NULL; if ((database = find_database (name)) == NULL) { config_notice (ERROR, uii, "Database %s not found!\r\n", name); Delete (name); return (-1); } trace (NORM, default_trace, "CONFIG %s no authoritative\n", name); database->flags = 0; Delete (name); return (1); } /* config irr database %s authoritative */ int config_irr_database_authoritative (uii_connection_t *uii, char *name) { irr_database_t *database = NULL; if ((database = find_database (name)) == NULL) config_irr_database (uii, strdup (name)); if ((database = find_database (name)) == NULL) { Delete (name); return (-1); } /* can't be authoritative and mirror at the same time! */ if (database->mirror_prefix != NULL) { config_notice (ERROR, uii, "*ERROR* database %s is configured for mirroring!\r\n", name); Delete (name); return (-1); } /* since we're authoritative, turn on cleaning by default */ if ((database->clean_timer == NULL) && (!database->no_dbclean)) { database->clean_timer = (mtimer_t *) New_Timer (irr_clean_timer, 60*60*24*2, "IRR dbclean", database); timer_set_jitter (database->clean_timer, 60*60*1); Timer_Turn_ON ((mtimer_t *) database->clean_timer); } trace (NORM, default_trace, "CONFIG %s authoritative\n", name); database->flags |= IRR_AUTHORITATIVE; config_add_module (0, "irr_database", get_config_irr_database, database); Delete (name); return (1); } /* config irr_database %s mirror %s %d */ int config_irr_database_mirror (uii_connection_t *uii, char *name, char *host, int port) { irr_database_t *database = NULL; if ((database = find_database (name)) == NULL) config_irr_database (uii, strdup (name)); if ((database = find_database (name)) == NULL) { Delete (name); Delete (host); return (-1); } if (database->flags &= IRR_AUTHORITATIVE) { config_notice (ERROR, uii, "*ERROR* database %s is authoritative!\r\n", name); Delete (name); Delete (host); return (-1); } trace (NORM, default_trace, "CONFIG %s mirror\n", name); if ((database->mirror_prefix = string_toprefix (host, default_trace)) == NULL) { config_notice (NORM, uii, "CONFIG Error -- could not resolve %s\r\n", host); Delete (name); Delete (host); return (-1); } database->mirror_port = port; database->mirror_timer = (mtimer_t *) New_Timer (irr_mirror_timer, IRR.mirror_interval, "IRR Mirror", database); timer_set_jitter (database->mirror_timer, 40); Timer_Turn_ON ((mtimer_t *) database->mirror_timer); /* since we're mirroring, turn on cleaning by default */ if ((database->clean_timer == NULL) && (!database->no_dbclean)) { database->clean_timer = (mtimer_t *) New_Timer (irr_clean_timer, 60*60*24*2, "IRR dbclean", database); timer_set_jitter (database->clean_timer, 60*60*1); Timer_Turn_ON ((mtimer_t *) database->clean_timer); } Delete (name); Delete (host); return (1); } /* config irr_database %s access %d * Control access to database */ int config_irr_database_access (uii_connection_t *uii, char *name, int num) { irr_database_t *database = NULL; if ((database = find_database (name)) == NULL) config_irr_database (uii, strdup (name)); if ((database = find_database (name)) == NULL) { Delete (name); return (-1); } trace (NORM, default_trace, "CONFIG %s access-list %d\n", name, num); config_add_module (0, "access", get_config_irr_database, database); database->access_list = num; Delete (name); return (1); } /* config irr_database %s mirror-access %d */ int config_irr_database_mirror_access (uii_connection_t *uii, char *name, int num) { irr_database_t *database = NULL; if ((database = find_database (name)) == NULL) { config_notice (ERROR, uii, "Database %s not found!\r\n", name); Delete (name); return (-1); } trace (NORM, default_trace, "CONFIG %s access-list write %d\n", name, num); config_add_module (0, "sychronization", get_config_irr_database, database); database->mirror_access_list = num; Delete (name); return (1); } /* config irr_database %s write-access %d */ int config_irr_database_access_write (uii_connection_t *uii, char *name, int num) { irr_database_t *database = NULL; if ((database = find_database (name)) == NULL) { config_notice (ERROR, uii, "Database %s not found!\r\n", name); Delete (name); return (-1); } trace (NORM, default_trace, "CONFIG %s access-list write %d\n", name, num); config_add_module (0, "database access", get_config_irr_database, database); database->write_access_list = num; Delete (name); return (1); } /* no config irr_database %s */ int no_config_irr_database (uii_connection_t *uii, char *name) { irr_database_t *db; if ((db = find_database (name)) == NULL) { Delete (name); config_notice (NORM, uii, "CONFIG no database %s -- database not found!\r\n", db->name); return (-1); } config_notice (NORM, uii, "CONFIG database %s deleted\r\n", db->name); LL_Remove (IRR.ll_database, db); irr_update_lock (db); radix_flush(db->radix); HASH_Destroy(db->hash); HASH_Destroy(db->hash_spec); Delete(db->name); irr_update_unlock (db); pthread_mutex_destroy(&db->mutex_lock); pthread_mutex_destroy(&db->mutex_clean_lock); Delete (db); Delete (name); return (1); } /* config irr_database xxxx */ int config_irr_database (uii_connection_t *uii, char *name) { irr_database_t *database; database = find_database (name); if (database == NULL) { database = new_database (name); LL_Add (IRR.ll_database, database); } config_add_module (0, "irr_database", get_config_irr_database, database); Delete (name); return (1); } void get_config_server_debug () { config_add_output ("debug server file-name %s\r\n", default_trace->logfile->logfile_name); if ((strcmp ("stdout", default_trace->logfile->logfile_name) != 0) && (default_trace->logfile->max_filesize > 0)) config_add_output ("debug server file-max-size %d\r\n", default_trace->logfile->max_filesize); if (default_trace->syslog_flag) config_add_output ("debug server syslog\r\n"); } /* no debug server */ int no_config_debug_server (uii_connection_t *uii) { /* need to do something here !!! */ return (1); } /* debug server verbose */ int config_debug_server_verbose (uii_connection_t *uii) { set_trace (default_trace, TRACE_FLAGS, TR_ALL, NULL); config_add_module (0, "debug", get_config_server_debug, NULL); return (1); } /* no debug server verbose */ int config_no_debug_server_verbose (uii_connection_t *uii) { set_trace (default_trace, TRACE_FLAGS, NORM, NULL); config_add_module (0, "debug", get_config_server_debug, NULL); return (1); } /* debug server file-name %s */ int config_debug_server_file (uii_connection_t *uii, char *filename) { set_trace (default_trace, TRACE_LOGFILE, filename, NULL); config_add_module (0, "debug", get_config_server_debug, NULL); Delete (filename); return (1); } /* debug server syslog */ int config_debug_server_syslog (uii_connection_t *uii) { set_trace (default_trace, TRACE_USE_SYSLOG, 1, 0); config_add_module (0, "syslog trace", get_config_server_debug, IRR.submit_trace); return (1); } /* debug server size %d */ int config_debug_server_size (uii_connection_t *uii, int bytes) { set_trace (default_trace, TRACE_MAX_FILESIZE, bytes, NULL); config_add_module (0, "debug", get_config_server_debug, IRR.submit_trace); return (1); } void get_config_submission_debug () { config_add_output ("debug submission file-name %s\r\n", IRR.submit_trace->logfile->logfile_name); /* also add verbose and syslog here */ } /* no debug submission */ int no_config_debug_submission (uii_connection_t *uii) { /* do something !!! */ return (1); } /* debug submission file-name %s */ int config_debug_submission_file (uii_connection_t *uii, char *filename) { set_trace (IRR.submit_trace, TRACE_LOGFILE, filename, NULL); config_add_module (0, "debug", get_config_submission_debug, IRR.submit_trace); Delete (filename); return (1); } /* debug submission verbose */ int config_debug_submission_verbose (uii_connection_t *uii) { set_trace (IRR.submit_trace, TRACE_FLAGS, TR_ALL, NULL); config_add_module (0, "debug", get_config_submission_debug, NULL); return (1); } /* debug submission file-max-size %d */ int config_debug_submission_maxsize (uii_connection_t *uii, int size) { set_trace (IRR.submit_trace, TRACE_MAX_FILESIZE, size, NULL); config_add_module (0, "debug", get_config_submission_debug, NULL); return (1); } /* debug submission syslog */ int config_debug_submission_syslog (uii_connection_t *uii) { set_trace (IRR.submit_trace, TRACE_USE_SYSLOG, 1, NULL); config_add_module (0, "debug", get_config_submission_debug, NULL); return (1); } /* db_admin % s */ void get_config_dbadmin () { config_add_output ("db_admin %s\r\n", IRR.db_admin); } int config_dbadmin (uii_connection_t *uii, char *email) { IRR.db_admin = email; config_add_module (0, "dbadmin", get_config_dbadmin, NULL); return (1); } void get_config_responsefooter () { char *st; LL_Iterate (IRR.ll_response_footer, st) { config_add_output ("response_footer %s\r\n", st); } } /* response_footer %s */ int config_response_footer (uii_connection_t *uii, char *st) { if (IRR.ll_response_footer == NULL) IRR.ll_response_footer = LL_Create (0); if (st == NULL) st = " "; LL_Add (IRR.ll_response_footer, strdup (st)); config_add_module (0, "responsefooter", get_config_responsefooter, NULL); return (1); } void get_config_responsenotifyheader () { char *st; LL_Iterate (IRR.ll_response_notify_header, st) { config_add_output ("response_notify_header %s\r\n", st); } } /* response_notify_header %s */ int config_response_notify_header (uii_connection_t *uii, char *st) { if (IRR.ll_response_notify_header == NULL) IRR.ll_response_notify_header = LL_Create (0); if (st == NULL) st = " "; LL_Add (IRR.ll_response_notify_header, strdup (st)); config_add_module (0, "responsenotifyheader", get_config_responsenotifyheader, NULL); return (1); } void get_config_responseforwardheader () { char *st; LL_Iterate (IRR.ll_response_forward_header, st) { config_add_output ("response_forward_header %s\r\n", st); } } /* response_foward_header %s */ int config_response_forward_header (uii_connection_t *uii, char *st) { if (IRR.ll_response_forward_header == NULL) IRR.ll_response_forward_header = LL_Create (0); if (st == NULL) st = " "; LL_Add (IRR.ll_response_forward_header, strdup (st)); config_add_module (0, "responseforwardheader", get_config_responseforwardheader, NULL); return (1); } /* pgp_dir %s */ void get_config_pgpdir () { config_add_output ("pgp_dir %s\r\n", IRR.pgp_dir); } int config_pgpdir (uii_connection_t *uii, char *pgpdir) { IRR.pgp_dir = pgpdir; config_add_module (0, "pipe_line configuration", get_config_pgpdir, NULL); return (1); } /* override_cryptpw %s */ void get_config_override () { config_add_output ("override_cryptpw %s\r\n", IRR.override_password); } int config_override (uii_connection_t *uii, char *override) { IRR.override_password = override; config_add_module (0, "override onfiguration", get_config_override, NULL); return (1); } /* irr_server %s */ void get_config_irr_host () { config_add_output ("irr_server %s \r\n", IRR.irr_host); } int config_irr_host (uii_connection_t *uii, char *host) { IRR.irr_host = host; config_add_module (0, "pipe_line configuration", get_config_irr_host, NULL); return (1); } void get_irr_ftp_dir () { config_add_output ("ftp directory %s \r\n", IRR.ftp_dir); } /* ftp directory %s */ int config_export_directory (uii_connection_t *uii, char *dir) { IRR.ftp_dir = dir; config_add_module (0, "ftp directory", get_irr_ftp_dir, NULL); return (1); } void get_tmp_directory () { config_add_output ("tmp directory %s\r\n", IRR.tmp_dir); } /* tmp directory %s */ int config_tmp_directory (uii_connection_t *uii, char *dir) { IRR.tmp_dir = dir; config_add_module (0, "tmp directory", get_tmp_directory, NULL); return (1); } /* irr_database %s no-clean */ int config_irr_database_no_clean (uii_connection_t *uii, char *name) { irr_database_t *database; if ((database = find_database (name)) == NULL) { config_notice (ERROR, uii, "Database %s not found!\r\n", name); Delete (name); return (-1); } database->no_dbclean = 1; if (database->clean_timer) { Timer_Turn_OFF (database->clean_timer); } Delete (name); return (1); } /* irr_database %s clean %d */ int config_irr_database_clean (uii_connection_t *uii, char *name, int seconds) { irr_database_t *database; if ((database = find_database (name)) == NULL) { config_notice (ERROR, uii, "Database %s not found!\r\n", name); Delete (name); return (-1); } database->no_dbclean = 0; if (database->clean_timer == NULL) { database->clean_timer = (mtimer_t *) New_Timer (irr_clean_timer, seconds, "IRR dbclean", database); timer_set_jitter (database->clean_timer, (int) (seconds/ 3.0)); Timer_Turn_ON ((mtimer_t *) database->clean_timer); } else { Timer_Turn_OFF ((mtimer_t *) database->clean_timer); Timer_Set_Time (database->clean_timer, seconds); timer_set_jitter (database->clean_timer, (int) (seconds/ 3.0)); Timer_Turn_ON ((mtimer_t *) database->clean_timer); } Delete (name); return (1); } /* Look for input of the form ~(...) and remove the '~(' and ')'. * * Return: * 1 if the above form is found in the input string * 0 otherwise * * If ~(...) is found in the input then remove it from the input * string and reset the input string. */ int remove_tilda (char **t) { char *q, *r, *s = *t; /* Find the first printable character */ for (; isspace ((int) *s); s++); /* Look for a string like this: ~(...). * Remove the opening '~(' and closing ')' */ if (*s == '~' && (q = strchr (s, '(')) != NULL && (r = strrchr (++q, ')')) != NULL && r > q) { *r = '\0'; s = strdup (q); free (*t); *t = s; return 1; } return 0; } /* Search all known object types and check for a match * with the input string, "name". * * Return: * The corresponding 'enum OBJECT_FILTERS' value that * matches the input string (see scan.h for 'enum OBJECT_FILTERS' types). * XXX_F otherwise (ie, if no match is found). */ enum OBJECT_FILTERS find_object_type (char *name) { int i; for (i = 0; i < MAX_OBJECT_FILTERS; i++) if (!strcasecmp (o_filter[i].name, name)) return o_filter[i].filter_f; return XXX_F; } /* Set the bit field data structure, "database->obj_filter", which * controls which objects are used/accepted/kept in the database. * This is useful when we are dealing with VERY large databases like RIPE * that have lots of objects that we do NOT want to index or return queries * for. "database->obj_filter" affects all loading operations, ie, mirroring, * updates/submissions, bootstrap loads and reloads. * * The filter is defined by the user in irrd.conf. Filters define objects to keep in * the DB. The filter should be constructed as so: * * irr_database radb filter route|autnum|mntner * (allow only routes, autnum's and maintainer objects) * * irr_database radb filter ~(route|autnum) * (allow all objects except routes and autnums) * * Also recognized are the keywords "routing-registry-objects" and "non-critical" * which filter on the routing registry objects only (see scan.h). * * irr_database radb filter non-critical * (use all routing registry objects) * * Return: * 1 if a valid filter is found * -1 if a non-valid filter is found * * "database->obj_filter" is set to the new filter is a valid filter is found. * Otherwise "database->obj_filter" is left unchanged. */ int config_irr_database_filter (uii_connection_t *uii, char *name, char *object) { irr_database_t *database; char *last, *filter, *s; enum OBJECT_FILTERS F; u_long filter_bak; int ret_val = 1, tilda; if ((database = find_database (name)) == NULL) { config_notice (ERROR, uii, "Database %s not found!\r\n", name); Delete (name); if (object != NULL) Delete (object); return (-1); } if (object == NULL) { trace (TR_ERROR, default_trace, "config_irr_database_filter (): NULL object input filter: ABORT! \n"); Delete (name); return -1; } s = strdup (object); filter_bak = database->obj_filter; database->obj_filter = ~0; tilda = remove_tilda (&s); filter = strtok_r (s, "|", &last); while (filter != NULL) { /* put a '0' in proper bit position ==> use/keep/accept this object type */ if ((F = find_object_type (filter)) != XXX_F) database->obj_filter &= ~F; else if (!strcasecmp (filter, "routing-registry-objects") || !strcasecmp (filter, "non-critical")) database->obj_filter &= ~ROUTING_REGISTRY_OBJECTS; else { database->obj_filter = filter_bak; trace (TR_ERROR, default_trace, "Unknown filter %s\n", filter); ret_val = -1; break; } filter = strtok_r (NULL, "|", &last); } if (ret_val != -1) { /* Check to make sure at least one filter was applied */ if (!(~database->obj_filter)) { database->obj_filter = filter_bak; trace (TR_ERROR, default_trace, "DB object filter unchanged!\n"); trace (TR_ERROR, default_trace, "Did not recognize any object types: (%s)\n", object); ret_val = -1; } else { /* If a ~(...) was given we need to reverse the filter logic */ if (tilda) database->obj_filter = ~database->obj_filter; trace (NORM, default_trace, "Config filter %s (%s)\n", database->name, object); } } Delete (name); Delete (object); free (s); return ret_val; }