• Main Page
  • Data Structures
  • Files
  • File List
  • Globals

/build/buildd-opendnssec_1.3.2-1~bpo60+1-s390-eF9Mr1/opendnssec-1.3.2/signer/src/parser/confparser.c

Go to the documentation of this file.
00001 /*
00002  * $Id: confparser.c 4979 2011-04-19 12:49:53Z rb $
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 "parser/zonelistparser.h"
00036 #include "shared/allocator.h"
00037 #include "shared/file.h"
00038 #include "shared/log.h"
00039 #include "shared/status.h"
00040 
00041 #include <libxml/xpath.h>
00042 #include <libxml/relaxng.h>
00043 #include <libxml/xmlreader.h>
00044 #include <string.h>
00045 #include <stdlib.h>
00046 
00047 static const char* parser_str = "parser";
00048 
00049 
00054 ods_status
00055 parse_file_check(const char* cfgfile, const char* rngfile)
00056 {
00057     xmlDocPtr doc = NULL;
00058     xmlDocPtr rngdoc = NULL;
00059     xmlRelaxNGParserCtxtPtr rngpctx = NULL;
00060     xmlRelaxNGValidCtxtPtr rngctx = NULL;
00061     xmlRelaxNGPtr schema = NULL;
00062 
00063     if (!cfgfile || !rngfile) {
00064         ods_log_error("[%s] no cfgfile or rngfile", parser_str);
00065         return ODS_STATUS_ASSERT_ERR;
00066     }
00067     ods_log_assert(cfgfile);
00068     ods_log_assert(rngfile);
00069     ods_log_debug("[%s] check cfgfile %s with rngfile %s", parser_str,
00070         cfgfile, rngfile);
00071 
00072     /* Load XML document */
00073     doc = xmlParseFile(cfgfile);
00074     if (doc == NULL) {
00075         ods_log_error("[%s] unable to read cfgfile %s", parser_str,
00076             cfgfile);
00077         return ODS_STATUS_XML_ERR;
00078     }
00079     /* Load rng document */
00080     rngdoc = xmlParseFile(rngfile);
00081     if (rngdoc == NULL) {
00082         ods_log_error("[%s] unable to read rngfile %s", parser_str,
00083             rngfile);
00084         xmlFreeDoc(doc);
00085         return ODS_STATUS_XML_ERR;
00086     }
00087     /* Create an XML RelaxNGs parser context for the relax-ng document. */
00088     rngpctx = xmlRelaxNGNewDocParserCtxt(rngdoc);
00089     if (rngpctx == NULL) {
00090         xmlFreeDoc(rngdoc);
00091         xmlFreeDoc(doc);
00092         ods_log_error("[%s] unable to create XML RelaxNGs parser context",
00093            parser_str);
00094         return ODS_STATUS_XML_ERR;
00095     }
00096     /* Parse a schema definition resource and
00097      * build an internal XML schema structure.
00098      */
00099     schema = xmlRelaxNGParse(rngpctx);
00100     if (schema == NULL) {
00101         ods_log_error("[%s] unable to parse a schema definition resource",
00102             parser_str);
00103         xmlRelaxNGFreeParserCtxt(rngpctx);
00104         xmlFreeDoc(rngdoc);
00105         xmlFreeDoc(doc);
00106         return ODS_STATUS_PARSE_ERR;
00107     }
00108     /* Create an XML RelaxNGs validation context. */
00109     rngctx = xmlRelaxNGNewValidCtxt(schema);
00110     if (rngctx == NULL) {
00111         ods_log_error("[%s] unable to create RelaxNGs validation context",
00112             parser_str);
00113         xmlRelaxNGFree(schema);
00114         xmlRelaxNGFreeParserCtxt(rngpctx);
00115         xmlFreeDoc(rngdoc);
00116         xmlFreeDoc(doc);
00117         return ODS_STATUS_RNG_ERR;
00118     }
00119     /* Validate a document tree in memory. */
00120 /*
00121     better not check: if not correct, this will segfault.
00122     status = xmlRelaxNGValidateDoc(rngctx,doc);
00123     if (status != 0) {
00124         ods_log_error("[%s] cfgfile validation failed %s", parser_str,
00125             cfgfile);
00126         xmlRelaxNGFreeValidCtxt(rngctx);
00127         xmlRelaxNGFree(schema);
00128         xmlRelaxNGFreeParserCtxt(rngpctx);
00129         xmlFreeDoc(rngdoc);
00130         xmlFreeDoc(doc);
00131         return ODS_STATUS_RNG_ERR;
00132     }
00133 */
00134     xmlRelaxNGFreeValidCtxt(rngctx);
00135     xmlRelaxNGFree(schema);
00136     xmlRelaxNGFreeParserCtxt(rngpctx);
00137     xmlFreeDoc(rngdoc);
00138     xmlFreeDoc(doc);
00139     return ODS_STATUS_OK;
00140 }
00141 
00142 /* TODO: look how the enforcer reads this now */
00143 
00144 
00149 adapter_type**
00150 parse_conf_adapters(allocator_type* allocator, const char* cfgfile,
00151     int* count)
00152 {
00153     char* tag_name = NULL;
00154     adapter_type** adapters = NULL;
00155     int ret = 0;
00156     size_t adcount = 0;
00157 
00158     xmlTextReaderPtr reader = NULL;
00159     xmlDocPtr doc = NULL;
00160     xmlXPathContextPtr xpathCtx = NULL;
00161 
00162     xmlChar* expr = (xmlChar*) "//Adapter";
00163 
00164     ods_log_assert(allocator);
00165     ods_log_assert(cfgfile);
00166 
00167     reader = xmlNewTextReaderFilename(cfgfile);
00168     if (!reader) {
00169         ods_log_error("[%s] unable to open file %s", parser_str, cfgfile);
00170         return NULL;
00171     }
00172 
00173     ret = xmlTextReaderRead(reader);
00174     adapters = (adapter_type**) allocator_alloc(allocator,
00175         ADMAX * sizeof(adapter_type*));
00176     while (ret == XML_READER_TYPE_ELEMENT) {
00177         if (adcount >= ADMAX) {
00178             ods_log_warning("[%s] too many adapters in config file %s, "
00179                 "skipping additional adapters", parser_str, cfgfile);
00180             break;
00181         }
00182 
00183         tag_name = (char*) xmlTextReaderLocalName(reader);
00184 
00185         /* This assumes that there is no other <Adapters> element in
00186          * conf.xml
00187          */
00188         if (ods_strcmp(tag_name, "Adapter") == 0 &&
00189             ods_strcmp(tag_name, "Adapters") != 0 &&
00190             xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) {
00191             /* Found an adapter */
00192 
00193             /* Expand this node to get the rest of the info */
00194             xmlTextReaderExpand(reader);
00195             doc = xmlTextReaderCurrentDoc(reader);
00196             if (doc) {
00197                 xpathCtx = xmlXPathNewContext(doc);
00198             }
00199             if (doc == NULL || xpathCtx == NULL) {
00200                 ods_log_error("[%s] unable to read adapter; skipping",
00201                     parser_str);
00202                 ret = xmlTextReaderRead(reader);
00203                 free((void*) tag_name);
00204                 continue;
00205             }
00206             /* That worked, reuse the parse_zonelist_adapter() function */
00207             adapters[adcount] = parse_zonelist_adapter(xpathCtx, expr, 1);
00208             adcount++;
00209             ods_log_debug("[%s] adapter added", parser_str);
00210             xmlXPathFreeContext(xpathCtx);
00211         }
00212         free((void*) tag_name);
00213         ret = xmlTextReaderRead(reader);
00214     }
00215 
00216     /* no more adapters */
00217     ods_log_debug("[%s] no more adapters", parser_str);
00218     xmlFreeTextReader(reader);
00219     if (doc) {
00220         xmlFreeDoc(doc);
00221     }
00222     if (ret != 0) {
00223         ods_log_error("[%s] error parsing file %s", parser_str, cfgfile);
00224         return NULL;
00225     }
00226     *count = (int) adcount;
00227     return adapters;
00228 }
00229 
00230 
00235 const char*
00236 parse_conf_string(const char* cfgfile, const char* expr, int required)
00237 {
00238     xmlDocPtr doc = NULL;
00239     xmlXPathContextPtr xpathCtx = NULL;
00240     xmlXPathObjectPtr xpathObj = NULL;
00241     xmlChar *xexpr = NULL;
00242     const char* string = NULL;
00243 
00244     ods_log_assert(expr);
00245     ods_log_assert(cfgfile);
00246 
00247     /* Load XML document */
00248     doc = xmlParseFile(cfgfile);
00249     if (doc == NULL) {
00250         return NULL;
00251     }
00252     /* Create xpath evaluation context */
00253     xpathCtx = xmlXPathNewContext(doc);
00254     if (xpathCtx == NULL) {
00255         ods_log_error("[%s] unable to create new XPath context for cfgile "
00256             "%s expr %s", parser_str, cfgfile, (char*) expr);
00257         xmlFreeDoc(doc);
00258         return NULL;
00259     }
00260     /* Get string */
00261     xexpr = (unsigned char*) expr;
00262     xpathObj = xmlXPathEvalExpression(xexpr, xpathCtx);
00263     if (xpathObj == NULL || xpathObj->nodesetval == NULL ||
00264         xpathObj->nodesetval->nodeNr <= 0) {
00265         if (required) {
00266             ods_log_error("[%s] unable to evaluate required element %s in "
00267                 "cfgfile %s", parser_str, (char*) xexpr, cfgfile);
00268         }
00269         xmlXPathFreeContext(xpathCtx);
00270         if (xpathObj) {
00271             xmlXPathFreeObject(xpathObj);
00272         }
00273         xmlFreeDoc(doc);
00274         return NULL;
00275     }
00276     if (xpathObj->nodesetval != NULL &&
00277         xpathObj->nodesetval->nodeNr > 0) {
00278         string = (const char*) xmlXPathCastToString(xpathObj);
00279         xmlXPathFreeContext(xpathCtx);
00280         xmlXPathFreeObject(xpathObj);
00281         xmlFreeDoc(doc);
00282         return string;
00283     }
00284     xmlXPathFreeContext(xpathCtx);
00285     xmlXPathFreeObject(xpathObj);
00286     xmlFreeDoc(doc);
00287     return NULL;
00288 }
00289 
00290 
00291 const char*
00292 parse_conf_zonelist_filename(allocator_type* allocator, const char* cfgfile)
00293 {
00294     const char* dup = NULL;
00295     const char* str = parse_conf_string(
00296         cfgfile,
00297         "//Configuration/Common/ZoneListFile",
00298         1);
00299 
00300     if (str) {
00301         dup = allocator_strdup(allocator, str);
00302         free((void*)str);
00303     }
00304     return dup;
00305 }
00306 
00307 
00308 const char*
00309 parse_conf_zonefetch_filename(allocator_type* allocator, const char* cfgfile)
00310 {
00311     const char* dup = NULL;
00312     const char* str = parse_conf_string(
00313         cfgfile,
00314         "//Configuration/Common/ZoneFetchFile",
00315         0);
00316 
00317     if (str) {
00318         dup = allocator_strdup(allocator, str);
00319         free((void*)str);
00320     }
00321     return dup;
00322 }
00323 
00324 
00325 const char*
00326 parse_conf_log_filename(allocator_type* allocator, const char* cfgfile)
00327 {
00328     const char* dup = NULL;
00329     const char* str = parse_conf_string(cfgfile,
00330         "//Configuration/Common/Logging/Syslog/Facility",
00331         0);
00332     if (!str) {
00333         str = parse_conf_string(cfgfile,
00334             "//Configuration/Common/Logging/File/Filename",
00335             0);
00336     }
00337     if (str) {
00338         dup = allocator_strdup(allocator, str);
00339         free((void*)str);
00340     }
00341     return dup; /* NULL, Facility or Filename */
00342 }
00343 
00344 
00345 const char*
00346 parse_conf_pid_filename(allocator_type* allocator, const char* cfgfile)
00347 {
00348     const char* dup = NULL;
00349     const char* str = parse_conf_string(
00350         cfgfile,
00351         "//Configuration/Signer/PidFile",
00352         0);
00353 
00354     if (str) {
00355         dup = allocator_strdup(allocator, str);
00356         free((void*)str);
00357     } else {
00358         dup = allocator_strdup(allocator, ODS_SE_PIDFILE);
00359     }
00360     return dup;
00361 }
00362 
00363 
00364 const char*
00365 parse_conf_notify_command(allocator_type* allocator, const char* cfgfile)
00366 {
00367     const char* dup = NULL;
00368     const char* str = parse_conf_string(
00369         cfgfile,
00370         "//Configuration/Signer/NotifyCommand",
00371         0);
00372 
00373     if (str) {
00374         dup = allocator_strdup(allocator, str);
00375         free((void*)str);
00376     }
00377     return dup;
00378 }
00379 
00380 
00381 const char*
00382 parse_conf_clisock_filename(allocator_type* allocator, const char* cfgfile)
00383 {
00384     const char* dup = NULL;
00385     const char* str = parse_conf_string(
00386         cfgfile,
00387         "//Configuration/Signer/SocketFile",
00388         0);
00389 
00390     if (str) {
00391         dup = allocator_strdup(allocator, str);
00392         free((void*)str);
00393     } else {
00394         dup = allocator_strdup(allocator, ODS_SE_SOCKFILE);
00395     }
00396     return dup;
00397 }
00398 
00399 
00400 const char*
00401 parse_conf_working_dir(allocator_type* allocator, const char* cfgfile)
00402 {
00403     const char* dup = NULL;
00404     const char* str = parse_conf_string(
00405         cfgfile,
00406         "//Configuration/Signer/WorkingDirectory",
00407         0);
00408 
00409     if (str) {
00410         dup = allocator_strdup(allocator, str);
00411         free((void*)str);
00412     } else {
00413         dup = allocator_strdup(allocator, ODS_SE_WORKDIR);
00414     }
00415     return dup;
00416 }
00417 
00418 
00419 const char*
00420 parse_conf_username(allocator_type* allocator, const char* cfgfile)
00421 {
00422     const char* dup = NULL;
00423     const char* str = parse_conf_string(
00424         cfgfile,
00425         "//Configuration/Signer/Privileges/User",
00426         0);
00427 
00428     if (str) {
00429         dup = allocator_strdup(allocator, str);
00430         free((void*)str);
00431     }
00432     return dup;
00433 }
00434 
00435 
00436 const char*
00437 parse_conf_group(allocator_type* allocator, const char* cfgfile)
00438 {
00439     const char* dup = NULL;
00440     const char* str = parse_conf_string(
00441         cfgfile,
00442         "//Configuration/Signer/Privileges/Group",
00443         0);
00444 
00445     if (str) {
00446         dup = allocator_strdup(allocator, str);
00447         free((void*)str);
00448     }
00449     return dup;
00450 }
00451 
00452 
00453 const char*
00454 parse_conf_chroot(allocator_type* allocator, const char* cfgfile)
00455 {
00456     const char* dup = NULL;
00457     const char* str = parse_conf_string(
00458         cfgfile,
00459         "//Configuration/Signer/Privileges/Directory",
00460         0);
00461 
00462     if (str) {
00463         dup = allocator_strdup(allocator, str);
00464         free((void*)str);
00465     }
00466     return dup;
00467 }
00468 
00469 
00474 int
00475 parse_conf_use_syslog(const char* cfgfile)
00476 {
00477     const char* str = parse_conf_string(cfgfile,
00478         "//Configuration/Common/Logging/Syslog/Facility",
00479         0);
00480     if (str) {
00481         free((void*)str);
00482         return 1;
00483     }
00484     return 0;
00485 }
00486 
00487 
00488 int
00489 parse_conf_worker_threads(const char* cfgfile)
00490 {
00491     int numwt = ODS_SE_WORKERTHREADS;
00492     const char* str = parse_conf_string(cfgfile,
00493         "//Configuration/Signer/WorkerThreads",
00494         0);
00495     if (str) {
00496         if (strlen(str) > 0) {
00497             numwt = atoi(str);
00498         }
00499         free((void*)str);
00500     }
00501     return numwt;
00502 }
00503 
00504 
00505 int
00506 parse_conf_signer_threads(const char* cfgfile)
00507 {
00508     int numwt = ODS_SE_WORKERTHREADS;
00509     const char* str = parse_conf_string(cfgfile,
00510         "//Configuration/Signer/SignerThreads",
00511         0);
00512     if (str) {
00513         if (strlen(str) > 0) {
00514             numwt = atoi(str);
00515         }
00516         free((void*)str);
00517         return numwt;
00518     }
00519     /* no SignerThreads value configured, look at WorkerThreads */
00520     return parse_conf_worker_threads(cfgfile);
00521 }

Generated on Sat Dec 17 2011 09:57:56 for OpenDNSSEC-signer by  doxygen 1.7.1