OpenDNSSEC-signer 1.2.1

/build/buildd-opendnssec_1.2.1.dfsg-1-ia64-j6OroR/opendnssec-1.2.1.dfsg/signer/src/parser/confparser.c

Go to the documentation of this file.
00001 /*
00002  * $Id: confparser.c 4294 2011-01-13 19:58:29Z jakob $
00003  *
00004  * Copyright (c) 2009 NLNet Labs. All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00016  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00019  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00020  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00021  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00023  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00024  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00025  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  */
00028 
00034 #include "parser/confparser.h"
00035 #include "util/log.h"
00036 #include "util/se_malloc.h"
00037 
00038 #include <libxml/xpath.h> /* xmlXPath*() */
00039 #include <libxml/relaxng.h> /* xmlRelaxNG*() */
00040 #include <libxml/xmlreader.h> /* xmlParseFile(), xmlFreeDoc() */
00041 #include <string.h> /* strlen() */
00042 #include <stdlib.h> /* atoi() */
00043 
00044 
00049 int
00050 parse_file_check(const char* cfgfile, const char* rngfile)
00051 {
00052     xmlDocPtr doc = NULL;
00053     xmlDocPtr rngdoc = NULL;
00054     xmlRelaxNGParserCtxtPtr rngpctx = NULL;
00055     xmlRelaxNGValidCtxtPtr rngctx = NULL;
00056     xmlRelaxNGPtr schema = NULL;
00057     int status = 0;
00058 
00059     se_log_assert(cfgfile);
00060     se_log_assert(rngfile);
00061     se_log_debug("check config file: %s, use rng file: %s",
00062         cfgfile?cfgfile:"(null)", rngfile?rngfile:"(null)");
00063 
00064     /* Load XML document */
00065     doc = xmlParseFile(cfgfile);
00066     if (doc == NULL) {
00067         se_log_error("unable to read config file %s",
00068             cfgfile?cfgfile:"(null)");
00069         return 1;
00070     }
00071     /* Load rng document */
00072     rngdoc = xmlParseFile(rngfile);
00073     if (rngdoc == NULL) {
00074         se_log_error("unable to read conf rng file %s",
00075             rngfile?rngfile:"(null)");
00076         xmlFreeDoc(doc);
00077         return 1;
00078     }
00079     /* Create an XML RelaxNGs parser context for the relax-ng document. */
00080     rngpctx = xmlRelaxNGNewDocParserCtxt(rngdoc);
00081     if (rngpctx == NULL) {
00082         xmlFreeDoc(rngdoc);
00083         xmlFreeDoc(doc);
00084         se_log_error("unable to create XML RelaxNGs parser context");
00085         return 1;
00086     }
00087     /* Parse a schema definition resource and
00088      * build an internal XML schema structure.
00089      */
00090     schema = xmlRelaxNGParse(rngpctx);
00091     if (schema == NULL) {
00092         se_log_error("unable to parse a schema definition resource");
00093         xmlRelaxNGFreeParserCtxt(rngpctx);
00094         xmlFreeDoc(rngdoc);
00095         xmlFreeDoc(doc);
00096         return 1;
00097     }
00098     /* Create an XML RelaxNGs validation context. */
00099     rngctx = xmlRelaxNGNewValidCtxt(schema);
00100     if (rngctx == NULL) {
00101         se_log_error("unable to create RelaxNGs validation context");
00102         xmlRelaxNGFree(schema);
00103         xmlRelaxNGFreeParserCtxt(rngpctx);
00104         xmlFreeDoc(rngdoc);
00105         xmlFreeDoc(doc);
00106         return 1;
00107     }
00108     /* Validate a document tree in memory. */
00109     status = xmlRelaxNGValidateDoc(rngctx,doc);
00110     if (status != 0) {
00111         se_log_error("configuration file validation failed %s",
00112             cfgfile?cfgfile:"(null)");
00113         xmlRelaxNGFreeValidCtxt(rngctx);
00114         xmlRelaxNGFree(schema);
00115         xmlRelaxNGFreeParserCtxt(rngpctx);
00116         xmlFreeDoc(rngdoc);
00117         xmlFreeDoc(doc);
00118         return 1;
00119     }
00120 
00121     xmlRelaxNGFreeValidCtxt(rngctx);
00122     xmlRelaxNGFree(schema);
00123     xmlRelaxNGFreeParserCtxt(rngpctx);
00124     xmlFreeDoc(rngdoc);
00125     xmlFreeDoc(doc);
00126 
00127     return 0;
00128 }
00129 
00130 /* TODO: look how the enforcer reads this now */
00131 
00136 const char*
00137 parse_conf_string(const char* cfgfile, const char* expr, int required)
00138 {
00139     xmlDocPtr doc = NULL;
00140     xmlXPathContextPtr xpathCtx = NULL;
00141     xmlXPathObjectPtr xpathObj = NULL;
00142     xmlChar *xexpr = NULL;
00143     const char* string = NULL;
00144 
00145     se_log_assert(expr);
00146     se_log_assert(cfgfile);
00147 
00148     /* Load XML document */
00149     doc = xmlParseFile(cfgfile);
00150     if (doc == NULL) {
00151         return NULL;
00152     }
00153     /* Create xpath evaluation context */
00154     xpathCtx = xmlXPathNewContext(doc);
00155     if (xpathCtx == NULL) {
00156         se_log_error("unable to create new XPath context for cfgile %s expr %s",
00157             cfgfile?cfgfile:"(null)",
00158             expr?(char *)expr:"(null)");
00159         xmlFreeDoc(doc);
00160         return NULL;
00161     }
00162     /* Get string */
00163     xexpr = (unsigned char*) expr;
00164     xpathObj = xmlXPathEvalExpression(xexpr, xpathCtx);
00165     if (xpathObj == NULL || xpathObj->nodesetval == NULL ||
00166         xpathObj->nodesetval->nodeNr <= 0) {
00167         if (required) {
00168             se_log_error("unable to evaluate required element %s in cfgfile %s",
00169                 xexpr?(char *)xexpr:"(null)",
00170                 cfgfile?cfgfile:"(null)");
00171         }
00172         xmlXPathFreeContext(xpathCtx);
00173         if (xpathObj) {
00174             xmlXPathFreeObject(xpathObj);
00175         }
00176         xmlFreeDoc(doc);
00177         return NULL;
00178     }
00179     if (xpathObj->nodesetval != NULL &&
00180         xpathObj->nodesetval->nodeNr > 0) {
00181         string = (const char*) xmlXPathCastToString(xpathObj);
00182         xmlXPathFreeContext(xpathCtx);
00183         xmlXPathFreeObject(xpathObj);
00184         xmlFreeDoc(doc);
00185         return string;
00186     }
00187     xmlXPathFreeContext(xpathCtx);
00188     xmlXPathFreeObject(xpathObj);
00189     xmlFreeDoc(doc);
00190     return NULL;
00191 }
00192 
00193 
00194 const char*
00195 parse_conf_zonelist_filename(const char* cfgfile)
00196 {
00197     return parse_conf_string(cfgfile,
00198         "//Configuration/Common/ZoneListFile",
00199         1);
00200 }
00201 
00202 
00203 const char*
00204 parse_conf_zonefetch_filename(const char* cfgfile)
00205 {
00206     return parse_conf_string(cfgfile,
00207         "//Configuration/Common/ZoneFetchFile",
00208         0);
00209 }
00210 
00211 
00212 const char*
00213 parse_conf_log_filename(const char* cfgfile)
00214 {
00215     const char* str = parse_conf_string(cfgfile,
00216         "//Configuration/Common/Logging/Syslog/Facility",
00217         0);
00218     if (!str) {
00219         str = parse_conf_string(cfgfile,
00220             "//Configuration/Common/Logging/File/Filename",
00221             0);
00222     }
00223     return str; /* NULL, Facility or Filename */
00224 }
00225 
00226 
00227 const char*
00228 parse_conf_pid_filename(const char* cfgfile)
00229 {
00230     const char* str = parse_conf_string(cfgfile,
00231         "//Configuration/Signer/PidFile",
00232         0);
00233     if (!str) {
00234         return se_strdup(ODS_SE_PIDFILE);
00235     }
00236     return str;
00237 }
00238 
00239 
00240 const char*
00241 parse_conf_notify_command(const char* cfgfile)
00242 {
00243     return parse_conf_string(cfgfile,
00244         "//Configuration/Signer/NotifyCommand",
00245         0);
00246 }
00247 
00248 
00249 const char*
00250 parse_conf_clisock_filename(const char* cfgfile)
00251 {
00252     const char* str = parse_conf_string(cfgfile,
00253         "//Configuration/Signer/SocketFile",
00254         0);
00255     if (!str) {
00256         return se_strdup(ODS_SE_SOCKFILE);
00257     }
00258     return str;
00259 }
00260 
00261 
00262 const char* parse_conf_working_dir(const char* cfgfile)
00263 {
00264     const char* str = parse_conf_string(cfgfile,
00265         "//Configuration/Signer/WorkingDirectory",
00266         0);
00267     if (!str) {
00268         return se_strdup(ODS_SE_WORKDIR);
00269     }
00270     return str;
00271 }
00272 
00273 
00274 const char*
00275 parse_conf_username(const char* cfgfile)
00276 {
00277    return parse_conf_string(cfgfile,
00278         "//Configuration/Signer/Privileges/User",
00279         0);
00280 }
00281 
00282 
00283 const char* parse_conf_group(const char* cfgfile)
00284 {
00285    return parse_conf_string(cfgfile,
00286         "//Configuration/Signer/Privileges/Group",
00287         0);
00288 }
00289 
00290 
00291 const char* parse_conf_chroot(const char* cfgfile)
00292 {
00293    return parse_conf_string(cfgfile,
00294         "//Configuration/Signer/Privileges/Directory",
00295         0);
00296 }
00297 
00298 
00303 int
00304 parse_conf_use_syslog(const char* cfgfile)
00305 {
00306     const char* str = parse_conf_string(cfgfile,
00307         "//Configuration/Common/Logging/Syslog/Facility",
00308         0);
00309     if (str) {
00310         se_free((void*)str);
00311         return 1;
00312     }
00313     return 0;
00314 }
00315 
00316 
00317 int
00318 parse_conf_worker_threads(const char* cfgfile)
00319 {
00320     int numwt = ODS_SE_WORKERTHREADS;
00321     const char* str = parse_conf_string(cfgfile,
00322         "//Configuration/Signer/WorkerThreads",
00323         0);
00324     if (str) {
00325         if (strlen(str) > 0) {
00326             numwt = atoi(str);
00327         }
00328         se_free((void*)str);
00329     }
00330     return numwt;
00331 }
00332 
00333 
00334 int
00335 parse_conf_signer_threads(const char* cfgfile)
00336 {
00337     int numwt = ODS_SE_SIGNERTHREADS;
00338     const char* str = parse_conf_string(cfgfile,
00339         "//Configuration/Signer/SignerThreads",
00340         0);
00341     if (str) {
00342         if (strlen(str) > 0) {
00343             numwt = atoi(str);
00344         }
00345         se_free((void*)str);
00346     }
00347     return numwt;
00348 }