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

/build/buildd-opendnssec_1.3.2-1~bpo60+1-armel-4stS1W/opendnssec-1.3.2/signer/src/adapter/adfile.c

Go to the documentation of this file.
00001 /*
00002  * $Id: adfile.c 5485 2011-08-25 14:04:41Z matthijs $
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 "config.h"
00035 #include "adapter/adapi.h"
00036 #include "adapter/adfile.h"
00037 #include "adapter/adutil.h"
00038 #include "shared/duration.h"
00039 #include "shared/file.h"
00040 #include "shared/log.h"
00041 #include "shared/status.h"
00042 #include "shared/util.h"
00043 #include "signer/zone.h"
00044 
00045 #include <ldns/ldns.h>
00046 #include <stdio.h>
00047 #include <stdlib.h>
00048 
00049 static const char* adapter_str = "adapter";
00050 static ods_status adfile_read_file(FILE* fd, zone_type* zone);
00051 
00052 
00057 ods_status
00058 adfile_init(void)
00059 {
00060     /* nothing to initialize */
00061     return ODS_STATUS_OK;
00062 }
00063 
00064 
00069 static ldns_rr*
00070 adfile_read_rr(FILE* fd, zone_type* zone, char* line, ldns_rdf** orig,
00071     ldns_rdf** prev, uint32_t* ttl, ldns_status* status, unsigned int* l)
00072 {
00073     ldns_rr* rr = NULL;
00074     ldns_rdf* tmp = NULL;
00075     FILE* fd_include = NULL;
00076     int len = 0;
00077     ods_status s = ODS_STATUS_OK;
00078     uint32_t new_ttl = 0;
00079     const char *endptr;  /* unused */
00080     int offset = 0;
00081 
00082 adfile_read_line:
00083     if (ttl) {
00084         new_ttl = *ttl;
00085     }
00086 
00087     len = adutil_readline_frm_file(fd, line, l);
00088     adutil_rtrim_line(line, &len);
00089 
00090     if (len >= 0) {
00091         switch (line[0]) {
00092             /* directive */
00093             case '$':
00094                 if (strncmp(line, "$ORIGIN", 7) == 0 && isspace(line[7])) {
00095                     /* copy from ldns */
00096                     if (*orig) {
00097                         ldns_rdf_deep_free(*orig);
00098                         *orig = NULL;
00099                     }
00100                     offset = 8;
00101                     while (isspace(line[offset])) {
00102                         offset++;
00103                     }
00104                     tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME,
00105                         line + offset);
00106                     if (!tmp) {
00107                         /* could not parse what next to $ORIGIN */
00108                         *status = LDNS_STATUS_SYNTAX_DNAME_ERR;
00109                         return NULL;
00110                     }
00111                     *orig = tmp;
00112                     /* end copy from ldns */
00113                     goto adfile_read_line; /* perhaps next line is rr */
00114                     break;
00115                 } else if (strncmp(line, "$TTL", 4) == 0 &&
00116                     isspace(line[4])) {
00117                     /* override default ttl */
00118                     offset = 5;
00119                     while (isspace(line[offset])) {
00120                         offset++;
00121                     }
00122                     if (ttl) {
00123                         *ttl = ldns_str2period(line + offset, &endptr);
00124                         new_ttl = *ttl;
00125                     }
00126                     goto adfile_read_line; /* perhaps next line is rr */
00127                     break;
00128                 } else if (strncmp(line, "$INCLUDE", 8) == 0 &&
00129                     isspace(line[8])) {
00130                     /* dive into this file */
00131                     offset = 9;
00132                     while (isspace(line[offset])) {
00133                         offset++;
00134                     }
00135                     fd_include = ods_fopen(line + offset, NULL, "r");
00136                     if (fd_include) {
00137                         s = adfile_read_file(fd_include, zone);
00138                         ods_fclose(fd_include);
00139                     } else {
00140                         ods_log_error("[%s] unable to open include file %s",
00141                             adapter_str, (line+offset));
00142                         *status = LDNS_STATUS_SYNTAX_ERR;
00143                         return NULL;
00144                     }
00145                     if (s != ODS_STATUS_OK) {
00146                         *status = LDNS_STATUS_SYNTAX_ERR;
00147                         ods_log_error("[%s] error in include file %s",
00148                             adapter_str, (line+offset));
00149                         return NULL;
00150                     }
00151                     /* restore current ttl */
00152                     if (ttl) {
00153                         *ttl = new_ttl;
00154                     }
00155                     goto adfile_read_line; /* perhaps next line is rr */
00156                     break;
00157                 }
00158                 goto adfile_read_rr; /* this can be an owner name */
00159                 break;
00160             /* comments, empty lines */
00161             case ';':
00162             case '\n':
00163                 goto adfile_read_line; /* perhaps next line is rr */
00164                 break;
00165             /* let's hope its a RR */
00166             default:
00167 adfile_read_rr:
00168                 if (adutil_whitespace_line(line, len)) {
00169                     goto adfile_read_line; /* perhaps next line is rr */
00170                     break;
00171                 }
00172 
00173                 *status = ldns_rr_new_frm_str(&rr, line, new_ttl, *orig, prev);
00174                 if (*status == LDNS_STATUS_OK) {
00175                     ldns_rr2canonical(rr); /* TODO: canonicalize or not? */
00176                     return rr;
00177                 } else if (*status == LDNS_STATUS_SYNTAX_EMPTY) {
00178                     if (rr) {
00179                         ldns_rr_free(rr);
00180                         rr = NULL;
00181                     }
00182                     *status = LDNS_STATUS_OK;
00183                     goto adfile_read_line; /* perhaps next line is rr */
00184                     break;
00185                 } else {
00186                     ods_log_error("[%s] error parsing RR at line %i (%s): %s",
00187                         adapter_str, l&&*l?*l:0,
00188                         ldns_get_errorstr_by_id(*status), line);
00189                     while (len >= 0) {
00190                         len = adutil_readline_frm_file(fd, line, l);
00191                     }
00192                     if (rr) {
00193                         ldns_rr_free(rr);
00194                         rr = NULL;
00195                     }
00196                     return NULL;
00197                 }
00198                 break;
00199         }
00200     }
00201 
00202     /* -1, EOF */
00203     *status = LDNS_STATUS_OK;
00204     return NULL;
00205 }
00206 
00207 
00212 static ods_status
00213 adfile_read_file(FILE* fd, zone_type* zone)
00214 {
00215     ods_status result = ODS_STATUS_OK;
00216     ldns_rr* rr = NULL;
00217     ldns_rdf* prev = NULL;
00218     ldns_rdf* orig = NULL;
00219     ldns_rdf* dname = NULL;
00220     uint32_t ttl = 0;
00221     ldns_status status = LDNS_STATUS_OK;
00222     char line[SE_ADFILE_MAXLINE];
00223     unsigned int line_update_interval = 100000;
00224     unsigned int line_update = line_update_interval;
00225     unsigned int l = 0;
00226 
00227     ods_log_assert(fd);
00228     ods_log_assert(zone);
00229 
00230     /* $ORIGIN <zone name> */
00231     dname = adapi_get_origin(zone);
00232     if (!dname) {
00233         ods_log_error("[%s] error getting default value for $ORIGIN",
00234             adapter_str);
00235         return ODS_STATUS_ERR;
00236     }
00237     orig = ldns_rdf_clone(dname);
00238     if (!orig) {
00239         ods_log_error("[%s] error setting default value for $ORIGIN",
00240             adapter_str);
00241         return ODS_STATUS_ERR;
00242     }
00243 
00244     /* $TTL <default ttl> */
00245     ttl = adapi_get_ttl(zone);
00246 
00247     /* read RRs */
00248     while ((rr = adfile_read_rr(fd, zone, line, &orig, &prev, &ttl,
00249         &status, &l)) != NULL) {
00250 
00251         if (status != LDNS_STATUS_OK) {
00252             ods_log_error("[%s] error reading RR at line %i (%s): %s",
00253                 adapter_str, l, ldns_get_errorstr_by_id(status), line);
00254             result = ODS_STATUS_ERR;
00255             break;
00256         }
00257 
00258         if (l > line_update) {
00259             ods_log_debug("[%s] ...at line %i: %s", adapter_str, l, line);
00260             line_update += line_update_interval;
00261         }
00262 
00263         /* filter out DNSSEC RRs (except DNSKEY) from the Input File Adapter */
00264         if (util_is_dnssec_rr(rr)) {
00265             ldns_rr_free(rr);
00266             rr = NULL;
00267             continue;
00268         }
00269 
00270         /* add to the zonedata */
00271         result = adapi_add_rr(zone, rr);
00272         if (result != ODS_STATUS_OK) {
00273             ods_log_error("[%s] error adding RR at line %i: %s",
00274                 adapter_str, l, line);
00275             break;
00276         }
00277     }
00278 
00279     /* and done */
00280     if (orig) {
00281         ldns_rdf_deep_free(orig);
00282         orig = NULL;
00283     }
00284     if (prev) {
00285         ldns_rdf_deep_free(prev);
00286         prev = NULL;
00287     }
00288 
00289     if (result == ODS_STATUS_OK && status != LDNS_STATUS_OK) {
00290         ods_log_error("[%s] error reading RR at line %i (%s): %s",
00291             adapter_str, l, ldns_get_errorstr_by_id(status), line);
00292         result = ODS_STATUS_ERR;
00293     }
00294     return result;
00295 }
00296 
00297 
00302 ods_status
00303 adfile_read(struct zone_struct* zone, const char* filename)
00304 {
00305     FILE* fd = NULL;
00306     zone_type* adzone = (zone_type*) zone;
00307     ods_status status = ODS_STATUS_OK;
00308     uint32_t new_serial = 0;
00309     ldns_rr* rr = NULL;
00310 
00311     /* [start] sanity parameter checking */
00312     if (!adzone) {
00313         ods_log_error("[%s] unable to read file: no zone (or no name given)",
00314             adapter_str);
00315         return ODS_STATUS_ASSERT_ERR;
00316     }
00317     ods_log_assert(adzone);
00318     if (!filename) {
00319         ods_log_error("[%s] unable to read file: no filename given",
00320             adapter_str);
00321         return ODS_STATUS_ASSERT_ERR;
00322     }
00323     ods_log_assert(filename);
00324     /* [end] sanity parameter checking */
00325 
00326     /* [start] read zone */
00327     fd = ods_fopen(filename, NULL, "r");
00328     if (fd) {
00329         /* serial */
00330         rr = adutil_lookup_soa_rr(fd);
00331         if (rr) {
00332             new_serial =
00333                 ldns_rdf2native_int32(ldns_rr_rdf(rr, SE_SOA_RDATA_SERIAL));
00334         }
00335         ldns_rr_free(rr);
00336         rewind(fd);
00337 
00338         status = adfile_read_file(fd, adzone);
00339         ods_fclose(fd);
00340     } else {
00341         status = ODS_STATUS_FOPEN_ERR;
00342     }
00343     if (status != ODS_STATUS_OK) {
00344         ods_log_error("[%s] unable to read file %s: %s", adapter_str,
00345             filename, ods_status2str(status));
00346         return status;
00347     }
00348     /* [end] read zone */
00349 
00350     /* [start] full transaction */
00351     status = adapi_trans_full(adzone);
00352     if (status != ODS_STATUS_OK) {
00353         ods_log_error("[%s] unable to read file: start transaction failed",
00354             adapter_str);
00355         return status;
00356     }
00357     /* [end] full transaction */
00358 
00359     /* [start] validate updates */
00360     status = zone_examine(adzone);
00361     if (status != ODS_STATUS_OK) {
00362         ods_log_error("[%s] unable to read file: zonefile contains errors",
00363             adapter_str);
00364         return status;
00365     }
00366     /* [end] validate updates */
00367     adapi_set_serial(adzone, new_serial);
00368     return ODS_STATUS_OK;
00369 }
00370 
00371 
00376 ods_status
00377 adbackup_read(struct zone_struct* zone, const char* filename)
00378 {
00379     FILE* fd = NULL;
00380     zone_type* adzone = (zone_type*) zone;
00381     ods_status status = ODS_STATUS_OK;
00382 
00383     /* [start] sanity parameter checking */
00384     if (!adzone) {
00385         ods_log_error("[%s] unable to read file: no zone (or no name given)",
00386             adapter_str);
00387         return ODS_STATUS_ASSERT_ERR;
00388     }
00389     ods_log_assert(adzone);
00390     if (!filename) {
00391         ods_log_error("[%s] unable to read file: no filename given",
00392             adapter_str);
00393         return ODS_STATUS_ASSERT_ERR;
00394     }
00395     ods_log_assert(filename);
00396     /* [end] sanity parameter checking */
00397 
00398     /* [start] read zone */
00399     fd = ods_fopen(filename, NULL, "r");
00400     if (fd) {
00401         status = adfile_read_file(fd, adzone);
00402         ods_fclose(fd);
00403     } else {
00404         status = ODS_STATUS_FOPEN_ERR;
00405     }
00406     if (status != ODS_STATUS_OK) {
00407         ods_log_error("[%s] unable to recover file: %s", adapter_str,
00408             ods_status2str(status));
00409         return status;
00410     }
00411     /* [end] read zone */
00412 
00413     /* [start] full transaction */
00414     status = adapi_trans_full(adzone);
00415     if (status != ODS_STATUS_OK) {
00416         ods_log_error("[%s] unable to recover file: start transaction failed",
00417             adapter_str);
00418         return status;
00419     }
00420     /* [end] full transaction */
00421     return ODS_STATUS_OK;
00422 }
00423 
00424 
00429 ods_status
00430 adfile_write(struct zone_struct* zone, const char* filename)
00431 {
00432     FILE* fd = NULL;
00433     zone_type* adzone = (zone_type*) zone;
00434     ods_status status = ODS_STATUS_OK;
00435 
00436     /* [start] sanity parameter checking */
00437     if (!adzone) {
00438         ods_log_error("[%s] unable to write file: no zone (or no "
00439             "name given)", adapter_str);
00440         return ODS_STATUS_ASSERT_ERR;
00441     }
00442     ods_log_assert(adzone);
00443     if (!filename) {
00444         ods_log_error("[%s] unable to write file: no filename given",
00445             adapter_str);
00446         return ODS_STATUS_ERR;
00447     }
00448     ods_log_assert(filename);
00449     /* [end] sanity parameter checking */
00450 
00451     /* [start] write zone */
00452     fd = ods_fopen(filename, NULL, "w");
00453     if (fd) {
00454         status = zone_print(fd, adzone);
00455         ods_fclose(fd);
00456     } else {
00457         status = ODS_STATUS_FOPEN_ERR;
00458     }
00459     /* [end] write zone */
00460 
00461     return status;
00462 }

Generated on Sat Dec 17 2011 10:09:48 for OpenDNSSEC-signer by  doxygen 1.7.1