/*************************************************************************** configuration.cpp - description ------------------- begin : wo dec 25 2002 copyright : (C) 2002 by Meilof email : meilof@users.sourceforge.net ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include "configuration.h" #include "lib.h" #include "zonefile.h" #include "primary.h" #include "masterfile.h" #include #include #include #include /* ---- configuration settings --------------------------------------------- */ bool cmd_logfile; char i_logfile[PATH_MAX]; char *logfile = i_logfile; bool logfile_per_day; char i_confdir[PATH_MAX]; char *confdir = i_confdir; //char *mfdir = i_mfdir; char i_datadir[PATH_MAX]; char *datadir = i_datadir; int max_cache_items; int resolv_patience; int max_cname_recursion; int update_ttl; bool do_query_logging; bool omit_ns_records; bool cache_statistics; #ifndef _WIN32 bool cmd_username, cmd_groupname; char username[128], groupname[128]; #endif stl_slist(addrrange) recursive_allow; stl_slist(addrrange) recursive_refuse; int maxtcp; stl_slist(addrrange) tcp_priority; stl_list(stl_string) cachefiles; /* ---- end: configuration settings ----------------------------------------- */ void config_init() { poslib_config_init(); cmd_logfile = false; i_logfile[0] = 0; logfile_per_day = false; i_confdir[0] = 0; i_datadir[0] = 0; max_cache_items = 1000; resolv_patience = 15; max_cname_recursion = 10; do_query_logging = false; omit_ns_records = false; cache_statistics = false; update_ttl = 600; #ifndef _WIN32 cmd_username = false; cmd_groupname = false; username[0] = 0; groupname[0] = 0; #endif recursive_allow.clear(); recursive_refuse.clear(); maxtcp = -1; tcp_priority.clear(); cachefiles.clear(); } bool provide_recursion(_addr *a) { if (in_addrrange_list(recursive_allow, a) && !in_addrrange_list(recursive_refuse, a)) return true; else return false; } bool our_allow_tcp_connection(_addr *a, int ntcp) { return ( (maxtcp == -1 || ntcp < maxtcp) && n_threads < max_threads ) || in_addrrange_list(tcp_priority, a); } void load_all_zone_files() { if (confdir[0] == 0) throw PException("You should specify a configdir before setting AllZoneFiles"); DIR *dir; struct dirent *ent; stl_string path; domainname dom; if ((dir = opendir(confdir)) == NULL) throw PException("Could not open configdir for reading"); while ( (ent = readdir(dir)) != NULL ) { path = stl_string(confdir) + ent->d_name; try { if (is_zonefile(ent->d_name, dom)) { load_zone_file(dom, path.c_str(), false); } else if (is_masterfile(ent->d_name, dom)) { PrimaryZone *z = new PrimaryZone(); add_authoritative_zone(dom, z); z->feed_setting("file", path.c_str()); } } catch (PException p) { throw PException(true, "Zonefile %s: %s", ent->d_name, p.message); } } closedir(dir); } bool conf_feed_setting(const char *set, const char *value) { int l; _addr a; addrrange range; domainname dom; stl_string path; if (strcmpi(set, "mfdir") == 0) { pos_log(context_conf, log_warning, "The mfdir command is obsolete. Use configdir instead."); goto _confdir; } else if (strcmpi(set, "confdir") == 0 || strcmpi(set, "configdir") == 0) { _confdir: if (strlen(value) + 2 >= PATH_MAX) printf("Master file path too long"); strcpy(confdir, value); l = strlen(confdir) - 1; if (confdir[l] != SEP) { confdir[l+1] = SEP; confdir[l+2] = '\0'; } } else if (strcmpi(set, "max_cache_items") == 0) { max_cache_items = txt_to_int(value); } else if (strcmpi(set, "resolv_patience") == 0) { resolv_patience = txt_to_int(value); } else if (strcmpi(set, "max_cname_recursion") == 0) { max_cname_recursion = txt_to_int(value); } else if (strcmpi(set, "max_threads") == 0) { max_threads = txt_to_int(value); } else if (strcmpi(set, "max_tcp_connections") == 0) { maxtcp = txt_to_negint(value); } else if (strcmpi(set, "tcp_priority") == 0) { txt_to_addrrange(range.range, value); tcp_priority.push_front(range); } else if (strcmpi(set, "loadmodule") == 0) { load_library(value); } else if (strcmpi(set, "allow_recursion") == 0) { txt_to_addrrange(range.range, value); recursive_allow.push_front(range); } else if (strcmpi(set, "refuse_recursion") == 0) { txt_to_addrrange(range.range, value); recursive_refuse.push_front(range); } else if (strcmpi(set, "datadir") == 0) { if (strlen(value) + 1 >= PATH_MAX) throw PException("Data dir name too long"); strcpy(datadir, value); if (datadir[strlen(datadir)-1] != SEP) { datadir[strlen(datadir)+1] = '\0'; datadir[strlen(datadir)] = SEP; } } else if (strcmpi(set, "logfile") == 0) { if (cmd_logfile) return true; if (strlen(value) >= PATH_MAX) throw PException("Log file name too long"); strcpy(logfile, value); } else if (strcmpi(set, "logfile_per_day") == 0) { logfile_per_day = txt_to_bool(value); #ifndef _WIN32 } else if (strcmpi(set, "user") == 0) { if (cmd_username) return true; if (strlen(value) >= 127) throw PException("User name too long"); strcpy(username, value); } else if (strcmpi(set, "group") == 0) { if (cmd_groupname) return true; if (strlen(value) >= 127) throw PException("User name too long"); strcpy(groupname, value); #endif } else if (strcmpi(set, "listen") == 0) { try { if (strncmpi(value, "tcp/", 4) == 0) { txt_to_addr(&a, value + 4, DNS_PORT, false); servers.push_front(ServerSocket(ss_tcp, tcpcreateserver(&a))); } else if (strncmpi(value, "udp/", 4) == 0) { txt_to_addr(&a, value + 4, DNS_PORT, false); servers.push_front(ServerSocket(ss_udp, udpcreateserver(&a))); } else if (strncmpi(value, "both/", 5) == 0) { txt_to_addr(&a, value + 5, DNS_PORT, false); servers.push_front(ServerSocket(ss_udp, udpcreateserver(&a))); servers.push_front(ServerSocket(ss_tcp, tcpcreateserver(&a))); } else { txt_to_addr(&a, value, DNS_PORT, false); servers.push_front(ServerSocket(ss_udp, udpcreateserver(&a))); servers.push_front(ServerSocket(ss_tcp, tcpcreateserver(&a))); } } catch (PException p) { throw PException(true, "Could not listen to network interface %s: %s", value, p.message); } } else if (strcmpi(set, "libdir") == 0) { add_libdir(value); } else if (strcmpi(set, "do_query_logging") == 0) { do_query_logging = txt_to_bool(value); } else if (strcmpi(set, "omit_ns_records") == 0) { omit_ns_records = txt_to_bool(value); } else if (strcmpi(set, "cache_statistics") == 0) { cache_statistics = txt_to_bool(value); } else if (strcmpi(set, "zone_file") == 0 || strcmpi(set, "zonefile") == 0) { if (confdir[0] == 0) throw PException("You should specify a configdir before loading any zone files"); path = stl_string(confdir) + value; if (is_zonefile(value, dom)) { load_zone_file(dom, path.c_str(), false); } else if (is_masterfile(value, dom)) { PrimaryZone *z = new PrimaryZone(); add_authoritative_zone(dom, z); z->feed_setting("file", path.c_str()); } else { throw PException(true, "%s cannot be recognized as a zone or master file. Make sure it is either in zn., .znf, db. or .znf format.", value); } } else if (strcmpi(set, "all_zone_files") == 0 || strcmpi(set, "allzonefiles") == 0) { if (txt_to_bool(value) == true) { load_all_zone_files(); } } else if (strcmpi(set, "update_ttl") == 0) { update_ttl = txt_to_int(value); } else if (strcmpi(set, "initial_cache_file") == 0) { cachefiles.push_back(value); } else { return false; } return true; } void conf_end_setting() { addrrange range; if (recursive_allow.empty()) { txt_to_addrrange(range.range, "any"); recursive_allow.push_front(range); } /* load the zone files */ stl_list(stl_string)::iterator it = cachefiles.begin(); while (it != cachefiles.end()) { if (!strchr(it->c_str(), SEP)) load_initial_cache((stl_string(confdir) + it->c_str()).c_str()); else load_initial_cache(it->c_str()); it++; } add_libdir(plugin_dir); } bool recursive_zone_end_setting(void *data, char *name, Zone *z) { if (!z->is_placeholder) z->end_setting(); z->subitems.iterate((iteratorfn)recursive_zone_end_setting, NULL); return true; }