1 /* $NetBSD: dlz_filesystem_dynamic.c,v 1.1.1.3 2014/12/10 03:34:31 christos Exp $ */
4 * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the
8 * above copyright notice and this permission notice appear in all
11 * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
12 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
13 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
14 * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
15 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
16 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
17 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
18 * USE OR PERFORMANCE OF THIS SOFTWARE.
20 * The development of Dynamically Loadable Zones (DLZ) for Bind 9 was
21 * conceived and contributed by Rob Butler.
23 * Permission to use, copy, modify, and distribute this software for any
24 * purpose with or without fee is hereby granted, provided that the
25 * above copyright notice and this permission notice appear in all
28 * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
29 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
31 * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
32 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
33 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
34 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
35 * USE OR PERFORMANCE OF THIS SOFTWARE.
39 * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
40 * Copyright (C) 1999-2001 Internet Software Consortium.
42 * Permission to use, copy, modify, and/or distribute this software for any
43 * purpose with or without fee is hereby granted, provided that the above
44 * copyright notice and this permission notice appear in all copies.
46 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
47 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
48 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
49 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
50 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
51 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
52 * PERFORMANCE OF THIS SOFTWARE.
56 * This provides the externally loadable filesystem DLZ module, without
68 #include "dlz_minimal.h"
72 typedef struct config_data
{
83 /* Helper functions from the dlz_dlopen driver */
85 dns_sdlz_putrr_t
*putrr
;
86 dns_sdlz_putnamedrr_t
*putnamedrr
;
87 dns_dlz_writeablezone_t
*writeable_zone
;
90 typedef struct dir_entry dir_entry_t
;
93 char dirpath
[DIR_PATHMAX
];
94 DLZ_LINK(dir_entry_t
) link
;
97 typedef DLZ_LIST(dir_entry_t
) dlist_t
;
99 /* forward reference */
102 b9_add_helper(struct config_data
*cd
, const char *helper_name
, void *ptr
);
108 is_safe(const char *input
) {
110 unsigned int len
= strlen(input
);
112 /* check that only allowed characters are in the domain name */
113 for (i
= 0; i
< len
; i
++) {
114 /* '.' is allowed, but has special requirements */
115 if (input
[i
] == '.') {
116 /* '.' is not allowed as first char */
119 /* '..', two dots together is not allowed. */
120 else if (input
[i
-1] == '.')
122 /* '.' is not allowed as last char */
125 /* only 1 dot in ok location, continue at next char */
128 /* '-' is allowed, continue at next char */
131 /* 0-9 is allowed, continue at next char */
132 if (input
[i
] >= '0' && input
[i
] <= '9')
134 /* A-Z uppercase is allowed, continue at next char */
135 if (input
[i
] >= 'A' && input
[i
] <= 'Z')
137 /* a-z lowercase is allowed, continue at next char */
138 if (input
[i
] >= 'a' && input
[i
] <= 'z')
142 * colon needs to be allowed for IPV6 client
143 * addresses. Not dangerous in domain names, as not a
150 * '@' needs to be allowed for in zone data. Not
151 * dangerous in domain names, as not a special char.
157 * if we reach this point we have encountered a
167 create_path_helper(char *out
, const char *in
, config_data_t
*cd
) {
172 tmpString
= strdup(in
);
173 if (tmpString
== NULL
)
174 return (ISC_R_NOMEMORY
);
177 * don't forget is_safe guarantees '.' will NOT be the
180 while ((tmpPtr
= strrchr(tmpString
, '.')) != NULL
) {
182 while (tmpPtr
[i
+1] != '\0') {
183 if (cd
->splitcnt
< 1)
184 strcat(out
, (char *) &tmpPtr
[i
+1]);
186 strncat(out
, (char *) &tmpPtr
[i
+1],
188 strncat(out
, (char *) &cd
->pathsep
, 1);
189 if (cd
->splitcnt
== 0)
191 if (strlen((char *) &tmpPtr
[i
+1]) <=
192 (unsigned int) cd
->splitcnt
)
199 /* handle the "first" label properly */
202 while (tmpPtr
[i
] != '\0') {
203 if (cd
->splitcnt
< 1)
204 strcat(out
, (char *) &tmpPtr
[i
]);
206 strncat(out
, (char *) &tmpPtr
[i
], cd
->splitcnt
);
207 strncat(out
, (char *) &cd
->pathsep
, 1);
208 if (cd
->splitcnt
== 0)
210 if (strlen((char *) &tmpPtr
[i
]) <=
211 (unsigned int) cd
->splitcnt
)
217 return (ISC_R_SUCCESS
);
221 * Checks to make sure zone and host are safe. If safe, then
222 * hashes zone and host strings to build a path. If zone / host
223 * are not safe an error is returned.
227 create_path(const char *zone
, const char *host
, const char *client
,
228 config_data_t
*cd
, char **path
)
235 isc_boolean_t isroot
= ISC_FALSE
;
237 /* special case for root zone */
238 if (strcmp(zone
, ".") == 0)
241 /* if the requested zone is "unsafe", return error */
242 if (!isroot
&& !is_safe(zone
))
243 return (ISC_R_FAILURE
);
245 /* if host was passed, verify that it is safe */
246 if (host
!= NULL
&& !is_safe(host
))
247 return (ISC_R_FAILURE
);
249 /* if client was passed, verify that it is safe */
250 if (client
!= NULL
&& !is_safe(client
))
251 return (ISC_R_FAILURE
);
253 /* Determine how much memory the split up string will require */
255 len
= strlen(zone
) + strlen(host
);
256 else if (client
!= NULL
)
257 len
= strlen(zone
) + strlen(client
);
262 * even though datadir and xfrdir will never be in the same
263 * string we only waste a few bytes by allocating for both,
264 * and then we are safe from buffer overruns.
266 pathsize
= len
+ cd
->basedirsize
+
267 cd
->datadirsize
+ cd
->xfrdirsize
+ 4;
269 /* if we are splitting names, we will need extra space. */
270 if (cd
->splitcnt
> 0)
271 pathsize
+= len
/cd
->splitcnt
;
273 tmpPath
= malloc(pathsize
* sizeof(char));
274 if (tmpPath
== NULL
) {
275 /* write error message */
276 cd
->log(ISC_LOG_ERROR
,
277 "Filesystem driver unable to "
278 "allocate memory in create_path().");
279 result
= ISC_R_NOMEMORY
;
285 * start out with base directory.
287 strcpy(tmpPath
, cd
->basedir
);
289 /* add zone name - parsed properly */
291 result
= create_path_helper(tmpPath
, zone
, cd
);
292 if (result
!= ISC_R_SUCCESS
)
297 * When neither client or host is passed we are building a
298 * path to see if a zone is supported. We require that a zone
299 * path have the "data dir" directory contained within it so
300 * that we know this zone is really supported. Otherwise,
301 * this zone may not really be supported because we are
302 * supporting a delagated sub zone.
306 * We are supporting long.domain.com and using a splitcnt of
307 * 0. the base dir is "/base-dir/" and the data dir is
308 * "/.datadir" We want to see if we are authoritative for
309 * domain.com. Path /base-dir/com/domain/.datadir since
310 * /base-dir/com/domain/.datadir does not exist, we are not
311 * authoritative for the domain "domain.com". However we are
312 * authoritative for the domain "long.domain.com" because the
313 * path /base-dir/com/domain/long/.datadir does exist!
316 /* if client is passed append xfr dir, otherwise append data dir */
317 if (client
!= NULL
) {
318 strcat(tmpPath
, cd
->xfrdir
);
319 strncat(tmpPath
, (char *) &cd
->pathsep
, 1);
320 strcat(tmpPath
, client
);
322 strcat(tmpPath
, cd
->datadir
);
324 /* if host not null, add it. */
326 strncat(tmpPath
, (char *) &cd
->pathsep
, 1);
327 result
= create_path_helper(tmpPath
, host
, cd
);
328 if (result
!= ISC_R_SUCCESS
)
332 /* return the path we built. */
336 result
= ISC_R_SUCCESS
;
341 /* free tmpPath memory */
342 if (tmpPath
!= NULL
&& result
!= ISC_R_SUCCESS
)
349 process_dir(dir_t
*dir
, void *passback
, config_data_t
*cd
,
350 dlist_t
*dir_list
, unsigned int basedirlen
)
353 char tmp
[DIR_PATHMAX
+ DIR_NAMEMAX
];
356 isc_result_t result
= ISC_R_FAILURE
;
361 char host
[DIR_NAMEMAX
];
367 dir_entry_t
*direntry
;
368 isc_boolean_t foundHost
;
370 tmp
[0] = '\0'; /* set 1st byte to '\0' so strcpy works right. */
372 foundHost
= ISC_FALSE
;
374 /* copy base directory name to tmp. */
375 strcpy(tmp
, dir
->dirname
);
377 /* dir->dirname will always have '*' as the last char. */
378 astPos
= strlen(dir
->dirname
) - 1;
380 /* if dir_list != NULL, were are performing a zone xfr */
381 if (dir_list
!= NULL
) {
382 /* if splitcnt == 0, determine host from path. */
383 if (cd
->splitcnt
== 0) {
384 if (strlen(tmp
) - 3 > basedirlen
) {
385 tmp
[astPos
-1] = '\0';
386 tmpString
= (char *) &tmp
[basedirlen
+1];
387 /* handle filesystem's special wildcard "-" */
388 if (strcmp(tmpString
, "-") == 0) {
392 * not special wildcard -- normal name
394 while ((tmpPtr
= strrchr(tmpString
,
399 strlen(tmpPtr
+ 1) + 2)
402 strcat(host
, tmpPtr
+ 1);
407 strlen(tmpString
) + 1)
409 strcat(host
, tmpString
);
412 foundHost
= ISC_TRUE
;
413 /* set tmp again for use later */
414 strcpy(tmp
, dir
->dirname
);
418 * if splitcnt != 0 determine host from
419 * ".host" directory entry
421 while (dir_read(dir
) == ISC_R_SUCCESS
) {
422 if (strncasecmp(".host",
423 dir
->entry
.name
, 5) == 0) {
425 * handle filesystem's special
428 if (strcmp((char *) &dir
->entry
.name
[6],
433 (char *) &dir
->entry
.name
[6],
437 foundHost
= ISC_TRUE
;
441 /* reset dir list for use later */
446 while (dir_read(dir
) == ISC_R_SUCCESS
) {
447 cd
->log(ISC_LOG_DEBUG(1),
448 "Filesystem driver Dir name:"
449 " '%s' Dir entry: '%s'\n",
450 dir
->dirname
, dir
->entry
.name
);
452 /* skip any entries starting with "." */
453 if (dir
->entry
.name
[0] == '.')
457 * get rid of '*', set to NULL. Effectively trims
458 * string from previous loop to base directory only
459 * while still leaving memory for concat to be
465 /* add name to base directory name. */
466 strcat(tmp
, dir
->entry
.name
);
468 /* make sure we can stat entry */
469 if (stat(tmp
, &sb
) == 0 ) {
470 /* if entry is a directory */
471 if ((sb
.st_mode
& S_IFDIR
) != 0) {
473 * if dir list is NOT NULL, add dir to
476 if (dir_list
!= NULL
) {
477 direntry
= malloc(sizeof(dir_entry_t
));
478 if (direntry
== NULL
)
479 return (ISC_R_NOMEMORY
);
480 strcpy(direntry
->dirpath
, tmp
);
481 DLZ_LINK_INIT(direntry
, link
);
482 DLZ_LIST_APPEND(*dir_list
, direntry
,
484 result
= ISC_R_SUCCESS
;
489 * if entry is a file be sure we do
490 * not add entry to DNS results if we
491 * are performing a zone xfr and we
492 * could not find a host entry.
495 } else if (dir_list
!= NULL
&&
496 foundHost
== ISC_FALSE
) {
499 } else /* if we cannot stat entry, skip it. */
502 type
= dir
->entry
.name
;
503 ttlStr
= strchr(type
, cd
->separator
);
504 if (ttlStr
== NULL
) {
505 cd
->log(ISC_LOG_ERROR
,
506 "Filesystem driver: "
507 "%s could not be parsed properly", tmp
);
508 return (ISC_R_FAILURE
);
511 /* replace separator char with NULL to split string */
513 /* start string after NULL of previous string */
514 ttlStr
= (char *) &ttlStr
[1];
516 data
= strchr(ttlStr
, cd
->separator
);
518 cd
->log(ISC_LOG_ERROR
,
519 "Filesystem driver: "
520 "%s could not be parsed properly", tmp
);
521 return (ISC_R_FAILURE
);
524 /* replace separator char with NULL to split string */
527 /* start string after NULL of previous string */
528 data
= (char *) &data
[1];
530 /* replace all cd->separator chars with a space. */
533 for (i
=0; i
< len
; i
++) {
534 if (data
[i
] == cd
->separator
)
538 /* convert text to int, make sure it worked right */
539 ttl
= strtol(ttlStr
, &endp
, 10);
540 if (*endp
!= '\0' || ttl
< 0)
541 cd
->log(ISC_LOG_ERROR
,
543 "ttl must be a postive number");
545 /* pass data back to Bind */
546 if (dir_list
== NULL
)
547 result
= cd
->putrr((dns_sdlzlookup_t
*) passback
,
550 result
= cd
->putnamedrr((dns_sdlzallnodes_t
*) passback
,
554 /* if error, return error right away */
555 if (result
!= ISC_R_SUCCESS
)
557 } /* end of while loop */
566 dlz_allowzonexfr(void *dbdata
, const char *name
, const char *client
) {
573 cd
= (config_data_t
*) dbdata
;
575 if (create_path(name
, NULL
, client
, cd
, &path
) != ISC_R_SUCCESS
) {
576 return (ISC_R_NOTFOUND
);
579 if (stat(path
, &sb
) != 0) {
580 result
= ISC_R_NOTFOUND
;
584 if ((sb
.st_mode
& S_IFREG
) != 0) {
585 result
= ISC_R_SUCCESS
;
589 result
= ISC_R_NOTFOUND
;
597 dlz_allnodes(const char *zone
, void *dbdata
, dns_sdlzallnodes_t
*allnodes
) {
600 config_data_t
*cd
= (config_data_t
*) dbdata
;
602 unsigned int basepathlen
;
605 dir_entry_t
*dir_entry
;
606 dir_entry_t
*next_de
;
611 /* allocate memory for list */
612 dir_list
= malloc(sizeof(dlist_t
));
613 if (dir_list
== NULL
) {
614 result
= ISC_R_NOTFOUND
;
615 goto complete_allnds
;
618 /* initialize list */
619 DLZ_LIST_INIT(*dir_list
);
621 if (create_path(zone
, NULL
, NULL
, cd
, &basepath
) != ISC_R_SUCCESS
) {
622 return (ISC_R_NOTFOUND
);
625 /* remove path separator at end of path so stat works properly */
626 basepathlen
= strlen(basepath
);
628 if (stat(basepath
, &sb
) != 0) {
629 result
= ISC_R_NOTFOUND
;
630 goto complete_allnds
;
633 if ((sb
.st_mode
& S_IFDIR
) == 0) {
634 result
= ISC_R_NOTFOUND
;
635 goto complete_allnds
;
638 /* initialize and open directory */
640 result
= dir_open(&dir
, basepath
);
642 /* if directory open failed, return error. */
643 if (result
!= ISC_R_SUCCESS
) {
644 cd
->log(ISC_LOG_ERROR
,
645 "Unable to open %s directory to read entries.",
647 result
= ISC_R_FAILURE
;
648 goto complete_allnds
;
651 /* process the directory */
652 result
= process_dir(&dir
, allnodes
, cd
, dir_list
, basepathlen
);
654 /* close the directory */
657 if (result
!= ISC_R_SUCCESS
)
658 goto complete_allnds
;
660 /* get first dir entry from list. */
661 dir_entry
= DLZ_LIST_HEAD(*dir_list
);
662 while (dir_entry
!= NULL
) {
663 result
= dir_open(&dir
, dir_entry
->dirpath
);
664 /* if directory open failed, return error. */
665 if (result
!= ISC_R_SUCCESS
) {
666 cd
->log(ISC_LOG_ERROR
,
668 "directory to read entries.", basepath
);
669 result
= ISC_R_FAILURE
;
670 goto complete_allnds
;
673 /* process the directory */
674 result
= process_dir(&dir
, allnodes
, cd
, dir_list
, basepathlen
);
676 /* close the directory */
679 if (result
!= ISC_R_SUCCESS
)
680 goto complete_allnds
;
682 dir_entry
= DLZ_LIST_NEXT(dir_entry
, link
);
686 if (dir_list
!= NULL
) {
687 /* clean up entries from list. */
688 dir_entry
= DLZ_LIST_HEAD(*dir_list
);
689 while (dir_entry
!= NULL
) {
690 next_de
= DLZ_LIST_NEXT(dir_entry
, link
);
697 if (basepath
!= NULL
)
703 #if DLZ_DLOPEN_VERSION < 3
705 dlz_findzonedb(void *dbdata
, const char *name
)
708 dlz_findzonedb(void *dbdata
, const char *name
,
709 dns_clientinfomethods_t
*methods
,
710 dns_clientinfo_t
*clientinfo
)
715 config_data_t
*cd
= (config_data_t
*) dbdata
;
720 #if DLZ_DLOPEN_VERSION >= 3
725 if (create_path(name
, NULL
, NULL
, cd
, &path
) != ISC_R_SUCCESS
)
726 return (ISC_R_NOTFOUND
);
728 cd
->log(ISC_LOG_DEBUG(1),
729 "Filesystem driver Findzone() Checking for path: '%s'\n", path
);
731 if (stat(path
, &sb
) != 0) {
732 result
= ISC_R_NOTFOUND
;
736 if ((sb
.st_mode
& S_IFDIR
) != 0) {
737 result
= ISC_R_SUCCESS
;
741 result
= ISC_R_NOTFOUND
;
749 #if DLZ_DLOPEN_VERSION == 1
751 dlz_lookup(const char *zone
, const char *name
,
752 void *dbdata
, dns_sdlzlookup_t
*lookup
)
755 dlz_lookup(const char *zone
, const char *name
,
756 void *dbdata
, dns_sdlzlookup_t
*lookup
,
757 dns_clientinfomethods_t
*methods
,
758 dns_clientinfo_t
*clientinfo
)
761 isc_result_t result
= ISC_R_NOTFOUND
;
762 config_data_t
*cd
= (config_data_t
*) dbdata
;
769 #if DLZ_DLOPEN_VERSION >= 2
774 if (strcmp(name
, "*") == 0)
776 * handle filesystem's special wildcard "-"
778 result
= create_path(zone
, "-", NULL
, cd
, &path
);
780 result
= create_path(zone
, name
, NULL
, cd
, &path
);
782 if (result
!= ISC_R_SUCCESS
)
783 return (ISC_R_NOTFOUND
);
785 /* remove path separator at end of path so stat works properly */
786 path
[strlen(path
)-1] = '\0';
788 cd
->log(ISC_LOG_DEBUG(1),
789 "Filesystem driver lookup() Checking for path: '%s'\n", path
);
791 if (stat(path
, &sb
) != 0) {
792 result
= ISC_R_NOTFOUND
;
796 if ((sb
.st_mode
& S_IFDIR
) == 0) {
797 result
= ISC_R_NOTFOUND
;
801 /* initialize and open directory */
803 result
= dir_open(&dir
, path
);
805 /* if directory open failed, return error. */
806 if (result
!= ISC_R_SUCCESS
) {
807 cd
->log(ISC_LOG_ERROR
,
808 "Unable to open %s directory to read entries.", path
);
809 result
= ISC_R_FAILURE
;
813 /* process any records in the directory */
814 result
= process_dir(&dir
, lookup
, cd
, NULL
, 0);
816 /* close the directory */
826 dlz_create(const char *dlzname
, unsigned int argc
, char *argv
[],
833 const char *helper_name
;
838 /* allocate memory for our config data and helper functions */
839 cd
= calloc(1, sizeof(config_data_t
));
843 /* zero the memory */
844 memset(cd
, 0, sizeof(config_data_t
));
846 /* Fill in the helper functions */
847 va_start(ap
, dbdata
);
848 while ((helper_name
= va_arg(ap
, const char*)) != NULL
)
849 b9_add_helper(cd
, helper_name
, va_arg(ap
, void*));
852 /* we require 5 command line args. */
854 cd
->log(ISC_LOG_ERROR
,
855 "Filesystem driver requires "
856 "6 command line args.");
857 return (ISC_R_FAILURE
);
860 if (strlen(argv
[5]) > 1) {
861 cd
->log(ISC_LOG_ERROR
,
862 "Filesystem driver can only "
863 "accept a single character for separator.");
864 return (ISC_R_FAILURE
);
867 /* verify base dir ends with '/' or '\' */
868 len
= strlen(argv
[1]);
869 if (argv
[1][len
-1] != '\\' && argv
[1][len
-1] != '/') {
870 cd
->log(ISC_LOG_ERROR
,
871 "Base dir parameter for filesystem driver "
872 "should end with %s",
873 "either '/' or '\\' ");
874 return (ISC_R_FAILURE
);
877 /* determine and save path separator for later */
878 if (argv
[1][len
-1] == '\\')
883 cd
->pathsep
= pathsep
;
885 /* get and store our base directory */
886 cd
->basedir
= strdup(argv
[1]);
887 if (cd
->basedir
== NULL
)
889 cd
->basedirsize
= strlen(cd
->basedir
);
891 /* get and store our data sub-dir */
892 cd
->datadir
= strdup(argv
[2]);
893 if (cd
->datadir
== NULL
)
895 cd
->datadirsize
= strlen(cd
->datadir
);
897 /* get and store our zone xfr sub-dir */
898 cd
->xfrdir
= strdup(argv
[3]);
899 if (cd
->xfrdir
== NULL
)
901 cd
->xfrdirsize
= strlen(cd
->xfrdir
);
903 /* get and store our directory split count */
904 cd
->splitcnt
= strtol(argv
[4], &endp
, 10);
905 if (*endp
!= '\0' || cd
->splitcnt
< 0)
906 cd
->log(ISC_LOG_ERROR
,
907 "Directory split count must be zero (0) "
908 "or a postive number");
910 /* get and store our separator character */
911 cd
->separator
= *argv
[5];
913 /* pass back config data */
917 return (ISC_R_SUCCESS
);
919 /* handle no memory error */
922 /* write error message */
923 if (cd
!= NULL
&& cd
->log
!= NULL
)
924 cd
->log(ISC_LOG_ERROR
,
925 "filesystem_dynamic: Filesystem driver unable to "
926 "allocate memory for config data.");
928 /* if we allocated a config data object clean it up */
933 return (ISC_R_NOMEMORY
);
937 dlz_destroy(void *dbdata
) {
940 cd
= (config_data_t
*) dbdata
;
943 * free memory for each section of config data that was
946 if (cd
->basedir
!= NULL
)
949 if (cd
->datadir
!= NULL
)
952 if (cd
->xfrdir
!= NULL
)
955 /* free config data memory */
960 * Return the version of the API
963 dlz_version(unsigned int *flags
) {
965 return (DLZ_DLOPEN_VERSION
);
969 * Register a helper function from the bind9 dlz_dlopen driver
972 b9_add_helper(struct config_data
*cd
, const char *helper_name
, void *ptr
) {
973 if (strcmp(helper_name
, "log") == 0)
974 cd
->log
= (log_t
*)ptr
;
975 if (strcmp(helper_name
, "putrr") == 0)
976 cd
->putrr
= (dns_sdlz_putrr_t
*)ptr
;
977 if (strcmp(helper_name
, "putnamedrr") == 0)
978 cd
->putnamedrr
= (dns_sdlz_putnamedrr_t
*)ptr
;
979 if (strcmp(helper_name
, "writeable_zone") == 0)
980 cd
->writeable_zone
= (dns_dlz_writeablezone_t
*)ptr
;