/***************************************************************************
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 <poslib/server/server.h>
#include <poslib/server/configuration.h>
#include "configuration.h"
#include "lib.h"
#include "zonefile.h"
#include "primary.h"
#include "masterfile.h"
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
/* ---- 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.<zone>, <zone>.znf, db.<zone> or <zone>.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;
}
syntax highlighted by Code2HTML, v. 0.9.1