1 /*
2  * Copyright (c) 2014 Jerry Lundström <lundstrom.jerry@gmail.com>
3  * Copyright (c) 2014 .SE (The Internet Infrastructure Foundation).
4  * Copyright (c) 2014 OpenDNSSEC AB (svb)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #include "zone_db.h"
31 
32 #include "db_error.h"
33 #include "log.h"
34 #include "policy.h"
35 
36 #include <string.h>
37 
38 char *
zone_db_ext_zonename_from_id(const db_connection_t * connection,const db_value_t * id)39 zone_db_ext_zonename_from_id(const db_connection_t* connection,
40     const db_value_t* id)
41 {
42     zone_db_t *zone;
43     char *zonename = NULL;
44 
45     if (!connection || !id) {
46         return NULL;
47     }
48 
49     if ((zone = zone_db_new(connection)) && !zone_db_get_by_id(zone, id)) {
50         zonename = strdup(zone_db_name(zone));
51     }
52     zone_db_free(zone);
53     return zonename;
54 }
55 
zone_db_get_keys(const zone_db_t * zone)56 key_data_list_t* zone_db_get_keys(const zone_db_t* zone) {
57     if (!zone) {
58         return NULL;
59     }
60     if (!zone->dbo) {
61         return NULL;
62     }
63     if (db_value_not_empty(&(zone->id))) {
64         return NULL;
65     }
66 
67     return key_data_list_new_get_by_zone_id(db_object_connection(zone->dbo),
68         &(zone->id));
69 
70     /*
71      * TODO: associated
72     return key_data_list_new_copy(zone_key_data_list(zone));
73      */
74 }
75 
zone_db_get_key_dependencies(const zone_db_t * zone)76 key_dependency_list_t* zone_db_get_key_dependencies(const zone_db_t* zone) {
77     if (!zone) {
78         return NULL;
79     }
80     if (!zone->dbo) {
81         return NULL;
82     }
83     if (db_value_not_empty(&(zone->id))) {
84         return NULL;
85     }
86 
87     return key_dependency_list_new_get_by_zone_id(db_object_connection(zone->dbo),
88         &(zone->id));
89 
90     /*
91      * TODO: associated
92     return key_dependency_list_new_copy(zone_key_dependency_list(zone));
93     */
94 }
95 
__xmlNode2zone(zone_db_t * zone,xmlNodePtr zone_node,int * updated)96 static int __xmlNode2zone(zone_db_t* zone, xmlNodePtr zone_node, int* updated) {
97     xmlNodePtr node;
98     xmlNodePtr node2;
99     xmlNodePtr node3;
100     xmlChar* xml_text = NULL;
101     int check_if_updated = 0;
102     int update_this = 1;
103     policy_t* policy = NULL;
104     int ret;
105 
106     if (!zone) {
107         return DB_ERROR_UNKNOWN;
108     }
109     if (!zone_node) {
110         return DB_ERROR_UNKNOWN;
111     }
112 
113     /*
114      * If updated is set we will check if the content is changed and set the
115      * integer pointed by updated to non-zero.
116      */
117     if (updated) {
118         *updated = 0;
119         check_if_updated = 1;
120     }
121 
122     if (!(xml_text = xmlGetProp(zone_node, (xmlChar*)"name"))) {
123         return DB_ERROR_UNKNOWN;
124     }
125     ods_log_deeebug("[zone_*_from_xml] zone %s", (char*)xml_text);
126     if (check_if_updated) {
127         update_this = 0;
128         if (!zone_db_name(zone)) {
129             *updated = 1;
130             update_this = 1;
131         }
132         else if (strcmp(zone_db_name(zone), (char*)xml_text)) {
133             *updated = 1;
134             update_this = 1;
135         }
136     }
137     if (update_this) {
138         if (zone_db_set_name(zone, (char*)xml_text)) {
139             if (xml_text) {
140                 xmlFree(xml_text);
141             }
142             return DB_ERROR_UNKNOWN;
143         }
144     }
145     if (xml_text) {
146         xmlFree(xml_text);
147         xml_text = NULL;
148     }
149 
150     for (node = zone_node->children; node; node = node->next) {
151         if (node->type != XML_ELEMENT_NODE) {
152             continue;
153         }
154 
155         if (!strcmp((char*)node->name, "Policy")) {
156             if (!(xml_text = xmlNodeGetContent(node))) {
157                 policy_free(policy);
158                 return DB_ERROR_UNKNOWN;
159             }
160             if (policy) {
161                 if (strcmp(policy_name(policy), (char*)xml_text)
162                     && policy_get_by_name(policy, (char*)xml_text))
163                 {
164                     policy_free(policy);
165                     if (xml_text) {
166                         xmlFree(xml_text);
167                     }
168                     return DB_ERROR_UNKNOWN;
169                 }
170             }
171             else {
172                 if (!(policy = policy_new(db_object_connection(zone->dbo)))
173                     || policy_get_by_name(policy, (char*)xml_text))
174                 {
175                     policy_free(policy);
176                     if (xml_text) {
177                         xmlFree(xml_text);
178                     }
179                     return DB_ERROR_UNKNOWN;
180                 }
181             }
182             ods_log_deeebug("[zone_*_from_xml] policy %s", (char*)xml_text);
183             if (check_if_updated) {
184                 update_this = 0;
185                 if (db_value_cmp(zone_db_policy_id(zone), policy_id(policy), &ret)) {
186                     policy_free(policy);
187                     if (xml_text) {
188                         xmlFree(xml_text);
189                     }
190                     return DB_ERROR_UNKNOWN;
191                 }
192                 if (ret) {
193                     *updated = 1;
194                     update_this = 1;
195                 }
196             }
197             if (update_this) {
198                 if (zone_db_set_policy_id(zone, policy_id(policy))) {
199                     policy_free(policy);
200                     if (xml_text) {
201                         xmlFree(xml_text);
202                     }
203                     return DB_ERROR_UNKNOWN;
204                 }
205             }
206             if (xml_text) {
207                 xmlFree(xml_text);
208                 xml_text = NULL;
209             }
210         }
211         else if (!strcmp((char*)node->name, "SignerConfiguration")) {
212             if (!(xml_text = xmlNodeGetContent(node))) {
213                 policy_free(policy);
214                 return DB_ERROR_UNKNOWN;
215             }
216             ods_log_deeebug("[zone_*_from_xml] signconf path %s", (char*)xml_text);
217             if (check_if_updated) {
218                 update_this = 0;
219                 if (!zone_db_signconf_path(zone)) {
220                     *updated = 1;
221                     update_this = 1;
222                 }
223                 else if (strcmp(zone_db_signconf_path(zone), (char*)xml_text)) {
224                     *updated = 1;
225                     update_this = 1;
226                 }
227             }
228             if (update_this) {
229                 if (zone_db_set_signconf_path(zone, (char*)xml_text)) {
230                     if (xml_text) {
231                         xmlFree(xml_text);
232                     }
233                     policy_free(policy);
234                     return DB_ERROR_UNKNOWN;
235                 }
236             }
237             if (xml_text) {
238                 xmlFree(xml_text);
239                 xml_text = NULL;
240             }
241         }
242         else if (!strcmp((char*)node->name, "Adapters")) {
243             for (node2 = node->children; node2; node2 = node2->next) {
244                 if (node2->type != XML_ELEMENT_NODE) {
245                     continue;
246                 }
247 
248                 if (!strcmp((char*)node2->name, "Input")) {
249                     for (node3 = node2->children; node3; node3 = node3->next) {
250                         if (node3->type != XML_ELEMENT_NODE) {
251                             continue;
252                         }
253 
254                         if (!strcmp((char*)node3->name, "File")) {
255                             ods_log_deeebug("[zone_*_from_xml] input adapter type File");
256                             if (check_if_updated) {
257                                 update_this = 0;
258                                 if (!zone_db_input_adapter_type(zone)) {
259                                     *updated = 1;
260                                     update_this = 1;
261                                 }
262                                 else if (strcmp(zone_db_input_adapter_type(zone), "File")) {
263                                     *updated = 1;
264                                     update_this = 1;
265                                 }
266                             }
267                             if (update_this) {
268                                 if (zone_db_set_input_adapter_type(zone, "File")) {
269                                     if (xml_text) {
270                                         xmlFree(xml_text);
271                                     }
272                                     policy_free(policy);
273                                     return DB_ERROR_UNKNOWN;
274                                 }
275                             }
276                             if (xml_text) {
277                                 xmlFree(xml_text);
278                                 xml_text = NULL;
279                             }
280 
281                             if (!(xml_text = xmlNodeGetContent(node3))) {
282                                 policy_free(policy);
283                                 return DB_ERROR_UNKNOWN;
284                             }
285                             ods_log_deeebug("[zone_*_from_xml] input adapter uri %s", (char*)xml_text);
286                             if (check_if_updated) {
287                                 update_this = 0;
288                                 if (!zone_db_input_adapter_uri(zone)) {
289                                     *updated = 1;
290                                     update_this = 1;
291                                 }
292                                 else if (strcmp(zone_db_input_adapter_uri(zone), (char*)xml_text)) {
293                                     *updated = 1;
294                                     update_this = 1;
295                                 }
296                             }
297                             if (update_this) {
298                                 if (zone_db_set_input_adapter_uri(zone, (char*)xml_text)) {
299                                     if (xml_text) {
300                                         xmlFree(xml_text);
301                                     }
302                                     policy_free(policy);
303                                     return DB_ERROR_UNKNOWN;
304                                 }
305                             }
306                             if (xml_text) {
307                                 xmlFree(xml_text);
308                                 xml_text = NULL;
309                             }
310                         }
311                         else if (!strcmp((char*)node3->name, "Adapter")) {
312                             if (!(xml_text = xmlGetProp(node3, (xmlChar*)"type"))) {
313                                 policy_free(policy);
314                                 return DB_ERROR_UNKNOWN;
315                             }
316                             ods_log_deeebug("[zone_*_from_xml] input adapter type %s", (char*)xml_text);
317                             if (check_if_updated) {
318                                 update_this = 0;
319                                 if (!zone_db_input_adapter_type(zone)) {
320                                     *updated = 1;
321                                     update_this = 1;
322                                 }
323                                 else if (strcmp(zone_db_input_adapter_type(zone), (char*)xml_text)) {
324                                     *updated = 1;
325                                     update_this = 1;
326                                 }
327                             }
328                             if (update_this) {
329                                 if (zone_db_set_input_adapter_type(zone, (char*)xml_text)) {
330                                     if (xml_text) {
331                                         xmlFree(xml_text);
332                                     }
333                                     policy_free(policy);
334                                     return DB_ERROR_UNKNOWN;
335                                 }
336                             }
337                             if (xml_text) {
338                                 xmlFree(xml_text);
339                                 xml_text = NULL;
340                             }
341 
342                             if (!(xml_text = xmlNodeGetContent(node3))) {
343                                 policy_free(policy);
344                                 return DB_ERROR_UNKNOWN;
345                             }
346                             ods_log_deeebug("[zone_*_from_xml] input adapter uri %s", (char*)xml_text);
347                             if (check_if_updated) {
348                                 update_this = 0;
349                                 if (!zone_db_input_adapter_uri(zone)) {
350                                     *updated = 1;
351                                     update_this = 1;
352                                 }
353                                 else if (strcmp(zone_db_input_adapter_uri(zone), (char*)xml_text)) {
354                                     *updated = 1;
355                                     update_this = 1;
356                                 }
357                             }
358                             if (update_this) {
359                                 if (zone_db_set_input_adapter_uri(zone, (char*)xml_text)) {
360                                     if (xml_text) {
361                                         xmlFree(xml_text);
362                                     }
363                                     policy_free(policy);
364                                     return DB_ERROR_UNKNOWN;
365                                 }
366                             }
367                             if (xml_text) {
368                                 xmlFree(xml_text);
369                                 xml_text = NULL;
370                             }
371                         }
372                         else {
373                             ods_log_deeebug("[zone_*_from_xml] unknown %s", (char*)node3->name);
374                             policy_free(policy);
375                             return DB_ERROR_UNKNOWN;
376                         }
377                     }
378                 }
379                 else if (!strcmp((char*)node2->name, "Output")) {
380                     for (node3 = node2->children; node3; node3 = node3->next) {
381                         if (node3->type != XML_ELEMENT_NODE) {
382                             continue;
383                         }
384 
385                         if (!strcmp((char*)node3->name, "File")) {
386                             ods_log_deeebug("[zone_*_from_xml] output adapter type File");
387                             if (check_if_updated) {
388                                 update_this = 0;
389                                 if (!zone_db_output_adapter_type(zone)) {
390                                     *updated = 1;
391                                     update_this = 1;
392                                 }
393                                 else if (strcmp(zone_db_output_adapter_type(zone), "File")) {
394                                     *updated = 1;
395                                     update_this = 1;
396                                 }
397                             }
398                             if (update_this) {
399                                 if (zone_db_set_output_adapter_type(zone, "File")) {
400                                     if (xml_text) {
401                                         xmlFree(xml_text);
402                                     }
403                                     policy_free(policy);
404                                     return DB_ERROR_UNKNOWN;
405                                 }
406                             }
407                             if (xml_text) {
408                                 xmlFree(xml_text);
409                                 xml_text = NULL;
410                             }
411 
412                             if (!(xml_text = xmlNodeGetContent(node3))) {
413                                 policy_free(policy);
414                                 return DB_ERROR_UNKNOWN;
415                             }
416                             ods_log_deeebug("[zone_*_from_xml] output adapter uri %s", (char*)xml_text);
417                             if (check_if_updated) {
418                                 update_this = 0;
419                                 if (!zone_db_output_adapter_uri(zone)) {
420                                     *updated = 1;
421                                     update_this = 1;
422                                 }
423                                 else if (strcmp(zone_db_output_adapter_uri(zone), (char*)xml_text)) {
424                                     *updated = 1;
425                                     update_this = 1;
426                                 }
427                             }
428                             if (update_this) {
429                                 if (zone_db_set_output_adapter_uri(zone, (char*)xml_text)) {
430                                     if (xml_text) {
431                                         xmlFree(xml_text);
432                                     }
433                                     policy_free(policy);
434                                     return DB_ERROR_UNKNOWN;
435                                 }
436                             }
437                             if (xml_text) {
438                                 xmlFree(xml_text);
439                                 xml_text = NULL;
440                             }
441                         }
442                         else if (!strcmp((char*)node3->name, "Adapter")) {
443                             if (!(xml_text = xmlGetProp(node3, (xmlChar*)"type"))) {
444                                 policy_free(policy);
445                                 return DB_ERROR_UNKNOWN;
446                             }
447                             ods_log_deeebug("[zone_*_from_xml] output adapter type %s", (char*)xml_text);
448                             if (check_if_updated) {
449                                 update_this = 0;
450                                 if (!zone_db_output_adapter_type(zone)) {
451                                     *updated = 1;
452                                     update_this = 1;
453                                 }
454                                 else if (strcmp(zone_db_output_adapter_type(zone), (char*)xml_text)) {
455                                     *updated = 1;
456                                     update_this = 1;
457                                 }
458                             }
459                             if (update_this) {
460                                 if (zone_db_set_output_adapter_type(zone, (char*)xml_text)) {
461                                     if (xml_text) {
462                                         xmlFree(xml_text);
463                                     }
464                                     policy_free(policy);
465                                     return DB_ERROR_UNKNOWN;
466                                 }
467                             }
468                             if (xml_text) {
469                                 xmlFree(xml_text);
470                                 xml_text = NULL;
471                             }
472 
473                             if (!(xml_text = xmlNodeGetContent(node3))) {
474                                 policy_free(policy);
475                                 return DB_ERROR_UNKNOWN;
476                             }
477                             ods_log_deeebug("[zone_*_from_xml] output adapter uri %s", (char*)xml_text);
478                             if (check_if_updated) {
479                                 update_this = 0;
480                                 if (!zone_db_output_adapter_uri(zone)) {
481                                     *updated = 1;
482                                     update_this = 1;
483                                 }
484                                 else if (strcmp(zone_db_output_adapter_uri(zone), (char*)xml_text)) {
485                                     *updated = 1;
486                                     update_this = 1;
487                                 }
488                             }
489                             if (update_this) {
490                                 if (zone_db_set_output_adapter_uri(zone, (char*)xml_text)) {
491                                     if (xml_text) {
492                                         xmlFree(xml_text);
493                                     }
494                                     policy_free(policy);
495                                     return DB_ERROR_UNKNOWN;
496                                 }
497                             }
498                             if (xml_text) {
499                                 xmlFree(xml_text);
500                                 xml_text = NULL;
501                             }
502                         }
503                         else {
504                             ods_log_deeebug("[zone_*_from_xml] unknown %s", (char*)node3->name);
505                             policy_free(policy);
506                             return DB_ERROR_UNKNOWN;
507                         }
508                     }
509                 }
510                 else {
511                     ods_log_deeebug("[zone_*_from_xml] unknown %s", (char*)node2->name);
512                     policy_free(policy);
513                     return DB_ERROR_UNKNOWN;
514                 }
515             }
516         }
517         else {
518             ods_log_deeebug("[zone_*_from_xml] unknown %s", (char*)node->name);
519             policy_free(policy);
520             return DB_ERROR_UNKNOWN;
521         }
522     }
523 
524     if (xml_text) {
525         xmlFree(xml_text);
526         xml_text = NULL;
527     }
528     policy_free(policy);
529     return DB_OK;
530 }
531 
zone_db_create_from_xml(zone_db_t * zone,xmlNodePtr zone_node)532 int zone_db_create_from_xml(zone_db_t* zone, xmlNodePtr zone_node) {
533     if (!zone) {
534         return DB_ERROR_UNKNOWN;
535     }
536     if (!zone_node) {
537         return DB_ERROR_UNKNOWN;
538     }
539 
540     return __xmlNode2zone(zone, zone_node, NULL);
541 }
542 
zone_db_update_from_xml(zone_db_t * zone,xmlNodePtr zone_node,int * updated)543 int zone_db_update_from_xml(zone_db_t* zone, xmlNodePtr zone_node, int* updated) {
544     if (!zone) {
545         return DB_ERROR_UNKNOWN;
546     }
547     if (!zone_node) {
548         return DB_ERROR_UNKNOWN;
549     }
550     if (!updated) {
551         return DB_ERROR_UNKNOWN;
552     }
553 
554     return __xmlNode2zone(zone, zone_node, updated);
555 }
556