2 * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2001-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: builtin.c,v 1.5.18.5 2005/08/23 04:12:38 marka Exp $ */
22 * The built-in "version", "hostname", "id", "authors" and "empty" databases.
31 #include <isc/print.h>
32 #include <isc/result.h>
35 #include <dns/result.h>
38 #include <named/builtin.h>
39 #include <named/globals.h>
40 #include <named/server.h>
43 typedef struct builtin builtin_t;
45 static isc_result_t do_version_lookup(dns_sdblookup_t *lookup);
46 static isc_result_t do_hostname_lookup(dns_sdblookup_t *lookup);
47 static isc_result_t do_authors_lookup(dns_sdblookup_t *lookup);
48 static isc_result_t do_id_lookup(dns_sdblookup_t *lookup);
49 static isc_result_t do_empty_lookup(dns_sdblookup_t *lookup);
52 * We can't use function pointers as the db_data directly
53 * because ANSI C does not guarantee that function pointers
54 * can safely be cast to void pointers and back.
58 isc_result_t (*do_lookup)(dns_sdblookup_t *lookup);
63 static builtin_t version_builtin = { do_version_lookup, NULL, NULL };
64 static builtin_t hostname_builtin = { do_hostname_lookup, NULL, NULL };
65 static builtin_t authors_builtin = { do_authors_lookup, NULL, NULL };
66 static builtin_t id_builtin = { do_id_lookup, NULL, NULL };
67 static builtin_t empty_builtin = { do_empty_lookup, NULL, NULL };
69 static dns_sdbimplementation_t *builtin_impl;
72 builtin_lookup(const char *zone, const char *name, void *dbdata,
73 dns_sdblookup_t *lookup)
75 builtin_t *b = (builtin_t *) dbdata;
79 if (strcmp(name, "@") == 0)
80 return (b->do_lookup(lookup));
82 return (ISC_R_NOTFOUND);
86 put_txt(dns_sdblookup_t *lookup, const char *text) {
87 unsigned char buf[256];
88 unsigned int len = strlen(text);
90 len = 255; /* Silently truncate */
92 memcpy(&buf[1], text, len);
93 return (dns_sdb_putrdata(lookup, dns_rdatatype_txt, 0, buf, len + 1));
97 do_version_lookup(dns_sdblookup_t *lookup) {
98 if (ns_g_server->version_set) {
99 if (ns_g_server->version == NULL)
100 return (ISC_R_SUCCESS);
102 return (put_txt(lookup, ns_g_server->version));
104 return (put_txt(lookup, ns_g_version));
109 do_hostname_lookup(dns_sdblookup_t *lookup) {
110 if (ns_g_server->hostname_set) {
111 if (ns_g_server->hostname == NULL)
112 return (ISC_R_SUCCESS);
114 return (put_txt(lookup, ns_g_server->hostname));
117 isc_result_t result = ns_os_gethostname(buf, sizeof(buf));
118 if (result != ISC_R_SUCCESS)
120 return (put_txt(lookup, buf));
125 do_authors_lookup(dns_sdblookup_t *lookup) {
128 static const char *authors[] = {
133 "Andreas Gustafsson",
145 * If a version string is specified, disable the authors.bind zone.
147 if (ns_g_server->version_set)
148 return (ISC_R_SUCCESS);
150 for (p = authors; *p != NULL; p++) {
151 result = put_txt(lookup, *p);
152 if (result != ISC_R_SUCCESS)
155 return (ISC_R_SUCCESS);
159 do_id_lookup(dns_sdblookup_t *lookup) {
161 if (ns_g_server->server_usehostname) {
163 isc_result_t result = ns_os_gethostname(buf, sizeof(buf));
164 if (result != ISC_R_SUCCESS)
166 return (put_txt(lookup, buf));
169 if (ns_g_server->server_id == NULL)
170 return (ISC_R_SUCCESS);
172 return (put_txt(lookup, ns_g_server->server_id));
176 do_empty_lookup(dns_sdblookup_t *lookup) {
179 return (ISC_R_SUCCESS);
183 builtin_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) {
185 const char *contact = "hostmaster";
186 const char *server = "@";
187 builtin_t *b = (builtin_t *) dbdata;
192 if (b == &empty_builtin) {
196 if (b->server != NULL)
198 if (b->contact != NULL)
199 contact = b->contact;
202 result = dns_sdb_putsoa(lookup, server, contact, 0);
203 if (result != ISC_R_SUCCESS)
204 return (ISC_R_FAILURE);
206 result = dns_sdb_putrr(lookup, "ns", 0, server);
207 if (result != ISC_R_SUCCESS)
208 return (ISC_R_FAILURE);
210 return (ISC_R_SUCCESS);
214 builtin_create(const char *zone, int argc, char **argv,
215 void *driverdata, void **dbdata)
222 if (strcmp(argv[0], "empty") == 0) {
224 return (DNS_R_SYNTAX);
225 } else if (argc != 1)
226 return (DNS_R_SYNTAX);
228 if (strcmp(argv[0], "version") == 0)
229 *dbdata = &version_builtin;
230 else if (strcmp(argv[0], "hostname") == 0)
231 *dbdata = &hostname_builtin;
232 else if (strcmp(argv[0], "authors") == 0)
233 *dbdata = &authors_builtin;
234 else if (strcmp(argv[0], "id") == 0)
235 *dbdata = &id_builtin;
236 else if (strcmp(argv[0], "empty") == 0) {
241 * We don't want built-in zones to fail. Fallback to
242 * the static configuration if memory allocation fails.
244 empty = isc_mem_get(ns_g_mctx, sizeof(*empty));
245 server = isc_mem_strdup(ns_g_mctx, argv[1]);
246 contact = isc_mem_strdup(ns_g_mctx, argv[2]);
247 if (empty == NULL || server == NULL || contact == NULL) {
248 *dbdata = &empty_builtin;
250 isc_mem_free(ns_g_mctx, server);
252 isc_mem_free(ns_g_mctx, contact);
254 isc_mem_put(ns_g_mctx, empty, sizeof (*empty));
256 memcpy(empty, &empty_builtin, sizeof (empty_builtin));
257 empty->server = server;
258 empty->contact = contact;
262 return (ISC_R_NOTIMPLEMENTED);
263 return (ISC_R_SUCCESS);
267 builtin_destroy(const char *zone, void *driverdata, void **dbdata) {
268 builtin_t *b = (builtin_t *) *dbdata;
274 * Don't free the static versions.
276 if (*dbdata == &version_builtin || *dbdata == &hostname_builtin ||
277 *dbdata == &authors_builtin || *dbdata == &id_builtin ||
278 *dbdata == &empty_builtin)
281 isc_mem_free(ns_g_mctx, b->server);
282 isc_mem_free(ns_g_mctx, b->contact);
283 isc_mem_put(ns_g_mctx, b, sizeof (*b));
286 static dns_sdbmethods_t builtin_methods = {
295 ns_builtin_init(void) {
296 RUNTIME_CHECK(dns_sdb_register("_builtin", &builtin_methods, NULL,
297 DNS_SDBFLAG_RELATIVEOWNER |
298 DNS_SDBFLAG_RELATIVERDATA,
299 ns_g_mctx, &builtin_impl)
301 return (ISC_R_SUCCESS);
305 ns_builtin_deinit(void) {
306 dns_sdb_unregister(&builtin_impl);