conf.c
来自「此dns服务器是在mydns基础上改写」· C语言 代码 · 共 465 行
C
465 行
/************************************************************************************************** $Id: conf.c,v 1.59 2006/01/18 20:46:46 bboy Exp $ Copyright (C) 2002-2005 Don Moore <bboy@bboy.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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA**************************************************************************************************/#include "named.h"/* Make this nonzero to enable debugging for this source file */#define DEBUG_CONF 1#include <pwd.h>#include <grp.h>CONF *Conf = (CONF *)NULL; /* Config options */int opt_daemon = 0; /* Run in background? (-d, --daemon) */char *opt_conf = MYDNS_CONF; /* Location of config file (-c, --conf) */uid_t perms_uid = 0; /* User permissions */gid_t perms_gid = 0; /* Group permissions */time_t task_timeout; /* Task timeout */int axfr_enabled = 0; /* Enable AXFR? */int tcp_enabled = 0; /* Enable TCP? */int dns_update_enabled = 0; /* Enable DNS UPDATE? */int ignore_minimum = 0; /* Ignore minimum TTL? */int forward_recursive = 0; /* Forward recursive queries? */char *recursive_fwd_server = NULL; /* Name of server for recursive forwarding */int recursive_family = AF_INET; /* Protocol family for recursion */#if HAVE_IPV6struct sockaddr_in6 recursive_sa6; /* Recursive server (IPv6) */#endifstruct sockaddr_in recursive_sa; /* Recursive server (IPv4) */#ifdef DN_COLUMN_NAMESchar *dn_default_ns = NULL; /* Default NS for directNIC */#endif/*** Default config values**** If the 'name' is "-", the --dump-config option treats 'desc' as a header field.*/static CONF defConfig[] = {/* name value desc */{ "-", NULL, N_("DATABASE INFORMATION")},{ "db-host", "localhost", N_("SQL server hostname")},{ "db-user", "username", N_("SQL server username")},{ "db-password", "password", N_("SQL server password")},{ "database", PACKAGE_NAME, N_("MyDNS database name")},{ "-", NULL, N_("GENERAL OPTIONS")},{ "user", "nobody", N_("Run with the permissions of this user")},{ "group", "nobody", N_("Run with the permissions of this group")},{ "listen", "*", N_("Listen on these addresses ('*' for all)"), "bind"},{ "no-listen", "", N_("Do not listen on these addresses")},{ "-", NULL, N_("CACHE OPTIONS")},{ "cache-size", "1024", N_("Maximum number of elements stored in the data/reply cache")},{ "cache-expire", "60", N_("Number of seconds after which cached data/replies expire")},{ "zone-cache-size", "1024", N_("Maximum number of elements stored in the zone cache")},{ "zone-cache-expire", "60", N_("Number of seconds after which cached zones expires")},{ "reply-cache-size", "1024", N_("Maximum number of elements stored in the reply cache")},{ "reply-cache-expire","30", N_("Number of seconds after which cached replies expire")},{ "-", NULL, N_("ESOTERICA")},{ "log", "LOG_DAEMON", N_("Facility to use for program output (LOG_*/stdout/stderr)")},{ "pidfile", "/var/run/"PACKAGE_NAME".pid", N_("Path to PID file")},{ "timeout", "120", N_("Number of seconds after which queries time out")},{ "multicpu", "1", N_("Number of CPUs installed on your system")},{ "recursive", "", N_("Location of recursive resolver")},{ "allow-axfr", "no", N_("Should AXFR be enabled?")},{ "allow-tcp", "no", N_("Should TCP be enabled?")},{ "allow-update", "no", N_("Should DNS UPDATE be enabled?")},{ "ignore-minimum", "no", N_("Ignore minimum TTL for zone?")},{ "soa-table", MYDNS_SOA_TABLE, N_("Name of table containing SOA records")},{ "rr-table", MYDNS_RR_TABLE, N_("Name of table containing RR data")},#ifdef DN_COLUMN_NAMES{ "default-ns", "ns0.example.com.", N_("Default nameserver for all zones")},#endif{ "soa-where", "", N_("Extra WHERE clause for SOA queries")},{ "rr-where", "", N_("Extra WHERE clause for RR queries")},{ NULL, NULL, NULL}};/************************************************************************************************** DUMP_CONFIG Output configuration info (in a sort of config-file format).**************************************************************************************************/voiddump_config(void){ time_t time_now = time(NULL); int len = 0, w = 0, n, defaulted; char pair[512], buf[80]; CONF *c; /* ** Pretty header */ puts("##"); puts("## "MYDNS_CONF); printf("## %.24s\n", ctime(&time_now)); printf("## %s\n", _("For more information, see mydns.conf(5).")); puts("##"); /* ** Get longest words */ for (n = 0; defConfig[n].name; n++) { char *value = conf_get(&Conf, defConfig[n].name, &defaulted); c = &defConfig[n]; if (!c->value || !c->value[0]) continue; if (!value) { if ((len = strlen(c->name) + (c->value ? strlen(c->value) : 0)) > w) w = len; } else { char *cp, *vbuf, *v; if (!strcasecmp(c->name, "listen") || !strcasecmp(c->name, "no-listen")) { while ((cp = strchr(value, ','))) *cp = CONF_FS_CHAR; } if (!(vbuf = strdup(value))) Err("strdup"); for (cp = vbuf; (v = strsep(&cp, CONF_FS_STR));) if ((len = strlen(c->name) + strlen(v)) > w) w = len; Free(vbuf); } } w += strlen(" = "); /* ** Output name/value pairs */ for (n = 0; defConfig[n].name; n++) { char *value = conf_get(&Conf, defConfig[n].name, &defaulted); c = &defConfig[n]; if (c->name[0] == '-') { printf("\n\n%-*.*s\t# %s\n\n", w, w, " ", _(c->desc)); continue; } if (!value) { if (!c->value || !c->value[0]) continue; value = c->value; defaulted = 1; } /* Pick between "nobody" and "nogroup" for default group */ if (!strcasecmp(c->name, "group") && getgrnam("nogroup")) c->value = "nogroup"; /* If cache-size/cache-expire are set, copy values into data/reply-cache-size */ if (!strcasecmp(c->name, "cache-size")) { if (defaulted) continue; else { snprintf(buf, sizeof(buf), "%d", atou(value) - (atou(value)/3)); conf_clobber(&Conf, "zone-cache-size", buf); snprintf(buf, sizeof(buf), "%d", atou(value)/3); conf_clobber(&Conf, "reply-cache-size", buf); } } else if (!strcasecmp(c->name, "cache-expire")) { if (defaulted) continue; else { snprintf(buf, sizeof(buf), "%d", atou(value)); conf_clobber(&Conf, "zone-cache-expire", buf); snprintf(buf, sizeof(buf), "%d", atou(value)/2); conf_clobber(&Conf, "reply-cache-expire", buf); } } else if (!strcasecmp(c->name, "listen") || !strcasecmp(c->name, "no-listen")) { char *cp, *vbuf, *v; while ((cp = strchr(value, ','))) *cp = CONF_FS_CHAR; if (!(vbuf = strdup(value))) Err("strdup"); for (cp = vbuf; (v = strsep(&cp, CONF_FS_STR));) { if (v == vbuf) { snprintf(pair, sizeof(pair), "%s = %s", c->name, v); printf("%-*.*s\t# %s\n", w, w, pair, _(c->desc)); } else printf("%s = %s\n", c->name, v); } Free(vbuf); } else { snprintf(pair, sizeof(pair), "%s = %s", c->name, value); printf("%-*.*s\t# %s\n", w, w, pair, _(c->desc)); } } printf("\n");}/*--- dump_config() -----------------------------------------------------------------------------*//************************************************************************************************** CONF_SET_LOGGING Sets the logging type and opens the syslog connection if necessary.**************************************************************************************************/voidconf_set_logging(void){ char logtype[80]; strncpy(logtype, conf_get(&Conf, "log", NULL), sizeof(logtype)-1); strtolower(logtype); if (!err_file) closelog(); if (!strcmp(logtype, "stderr")) { err_file = stderr; closelog(); } else if (!strcmp(logtype, "stdout")) { err_file = stdout; closelog(); } else if (!strcmp(logtype, "log_daemon")) error_init(NULL, LOG_DAEMON); else if (!strcmp(logtype, "log_local0")) error_init(NULL, LOG_LOCAL0); else if (!strcmp(logtype, "log_local1")) error_init(NULL, LOG_LOCAL1); else if (!strcmp(logtype, "log_local2")) error_init(NULL, LOG_LOCAL2); else if (!strcmp(logtype, "log_local3")) error_init(NULL, LOG_LOCAL3); else if (!strcmp(logtype, "log_local4")) error_init(NULL, LOG_LOCAL4); else if (!strcmp(logtype, "log_local5")) error_init(NULL, LOG_LOCAL5); else if (!strcmp(logtype, "log_local6")) error_init(NULL, LOG_LOCAL6); else if (!strcmp(logtype, "log_local7")) error_init(NULL, LOG_LOCAL7); else { FILE *fp; if (!(fp = fopen(logtype, "a"))) Warn("%s: %s: %s", opt_conf, logtype, _("Error opening log file")); err_file = fp; closelog(); }}/*--- conf_set_logging() ------------------------------------------------------------------------*//************************************************************************************************** CHECK_CONFIG_FILE_PERMS**************************************************************************************************/voidcheck_config_file_perms(void){ FILE *fp; if ((fp = fopen(opt_conf, "r"))) { Warnx("%s: %s", opt_conf, _("WARNING: config file is readable by unprivileged user")); fclose(fp); }}/*--- check_config_file_perms() -----------------------------------------------------------------*//************************************************************************************************** CONF_SET_RECURSIVE If the 'recursive' configuration option was specified, set the recursive server.**************************************************************************************************/voidconf_set_recursive(void){ char *c, *address = conf_get(&Conf, "recursive", NULL), addr[512]; int port = 53; if (!address || !address[0]) return; strncpy(addr, address, sizeof(addr)-1);#if HAVE_IPV6 if (is_ipv6(addr)) /* IPv6 - treat '+' as port separator */ { recursive_family = AF_INET6; if ((c = strchr(addr, '+'))) { *c++ = '\0'; if (!(port = atoi(c))) port = 53; } if (inet_pton(AF_INET6, addr, &recursive_sa6.sin6_addr) <= 0) { Warnx("%s: %s", address, _("invalid network address for recursive server")); return; } recursive_sa6.sin6_family = AF_INET6; recursive_sa6.sin6_port = htons(port); forward_recursive = 1;#if DEBUG_ENABLED Debug(_("recursive forwarding service through %s:%u"), ipaddr(AF_INET6, &recursive_sa6.sin6_addr), port);#endif if (!(recursive_fwd_server = strdup(address))) recursive_fwd_server = _("forwarder"); } else /* IPv4 - treat '+' or ':' as port separator */#endif { recursive_family = AF_INET; if ((c = strchr(addr, '+')) || (c = strchr(addr, ':'))) { *c++ = '\0'; if (!(port = atoi(c))) port = 53; } if (inet_pton(AF_INET, addr, &recursive_sa.sin_addr) <= 0) { Warnx("%s: %s", address, _("invalid network address for recursive server")); return; } recursive_sa.sin_family = AF_INET; recursive_sa.sin_port = htons(port);#if DEBUG_ENABLED Debug(_("recursive forwarding service through %s:%u"), ipaddr(AF_INET, &recursive_sa.sin_addr), port);#endif forward_recursive = 1; if (!(recursive_fwd_server = strdup(address))) recursive_fwd_server = _("forwarder"); }}/*--- conf_set_recursive() ----------------------------------------------------------------------*//************************************************************************************************** LOAD_CONFIG Load the configuration file.**************************************************************************************************/voidload_config(void){ int n; struct passwd *pwd = NULL; struct group *grp = NULL; /* Load config */ conf_load(&Conf, opt_conf); /* Set defaults */ for (n = 0; defConfig[n].name; n++) { if (defConfig[n].name[0] == '-' || !defConfig[n].value) continue; if (!conf_get(&Conf, defConfig[n].name, NULL)) conf_set(&Conf, defConfig[n].name, defConfig[n].value, 1); } /* Support "mysql-user" etc. for backwards compatibility */ if (conf_get(&Conf, "mysql-host", NULL)) conf_set(&Conf, "db-host", conf_get(&Conf, "mysql-host", NULL), 0); if (conf_get(&Conf, "mysql-user", NULL)) conf_set(&Conf, "db-user", conf_get(&Conf, "mysql-user", NULL), 0); if (conf_get(&Conf, "mysql-pass", NULL)) conf_set(&Conf, "db-password", conf_get(&Conf, "mysql-pass", NULL), 0); if (conf_get(&Conf, "mysql-password", NULL)) conf_set(&Conf, "db-password", conf_get(&Conf, "mysql-password", NULL), 0);#if HAVE_GETPWUID /* Set default for database username to real username if none was provided */ if (!conf_get(&Conf, "db-user", NULL)) { struct passwd *pwd2; if ((pwd2 = getpwuid(getuid())) && pwd2->pw_name) { conf_set(&Conf, "db-user", pwd2->pw_name, 0); memset(pwd2, 0, sizeof(struct passwd)); } }#endif /* Load user/group perms */ if (!(pwd = getpwnam(conf_get(&Conf, "user", NULL)))) Err(_("error loading uid for user `%s'"), conf_get(&Conf, "user", NULL)); perms_uid = pwd->pw_uid; perms_gid = pwd->pw_gid; memset(pwd, 0, sizeof(struct passwd)); if (!(grp = getgrnam(conf_get(&Conf, "group", NULL))) && !(grp = getgrnam("nobody"))) { Warnx(_("error loading gid for group `%s'"), conf_get(&Conf, "group", NULL)); Warnx(_("using gid %lu from user `%s'"), (unsigned long)perms_gid, conf_get(&Conf, "user", NULL)); } else { perms_gid = grp->gr_gid; memset(grp, 0, sizeof(struct group)); } /* We call conf_set_logging() again after moving into background, but it's called here to report on errors. */ conf_set_logging(); /* Set global options */ task_timeout = atou(conf_get(&Conf, "timeout", NULL)); axfr_enabled = GETBOOL(conf_get(&Conf, "allow-axfr", NULL)); tcp_enabled = GETBOOL(conf_get(&Conf, "allow-tcp", NULL)); dns_update_enabled = GETBOOL(conf_get(&Conf, "allow-update", NULL)); ignore_minimum = GETBOOL(conf_get(&Conf, "ignore-minimum", NULL)); /* Set table names if provided */ mydns_set_soa_table_name(conf_get(&Conf, "soa-table", NULL)); mydns_set_rr_table_name(conf_get(&Conf, "rr-table", NULL)); /* Set additional where clauses if provided */ mydns_set_soa_where_clause(conf_get(&Conf, "soa-where", NULL)); mydns_set_rr_where_clause(conf_get(&Conf, "rr-where", NULL)); /* Set recursive server if specified */ conf_set_recursive();#ifdef DN_COLUMN_NAMES dn_default_ns = conf_get(&Conf, "default-ns", NULL);#endif}/*--- load_config() -----------------------------------------------------------------------------*//* vi:set ts=3: *//* NEED_PO */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?