Import bind 9.5.2 vendor sources.
[dragonfly.git] / contrib / bind-9.5.2 / bin / named / builtin.c
blob7927737d684d8dd12997f1004a7532906e10cbc5
1 /*
2 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2001-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or 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.12 2007/06/19 23:46:59 tbox Exp $ */
20 /*! \file
21 * \brief
22 * The built-in "version", "hostname", "id", "authors" and "empty" databases.
25 #include <config.h>
27 #include <string.h>
28 #include <stdio.h>
30 #include <isc/mem.h>
31 #include <isc/print.h>
32 #include <isc/result.h>
33 #include <isc/util.h>
35 #include <dns/result.h>
36 #include <dns/sdb.h>
38 #include <named/builtin.h>
39 #include <named/globals.h>
40 #include <named/server.h>
41 #include <named/os.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.
57 struct builtin {
58 isc_result_t (*do_lookup)(dns_sdblookup_t *lookup);
59 char *server;
60 char *contact;
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;
71 static isc_result_t
72 builtin_lookup(const char *zone, const char *name, void *dbdata,
73 dns_sdblookup_t *lookup)
75 builtin_t *b = (builtin_t *) dbdata;
77 UNUSED(zone);
79 if (strcmp(name, "@") == 0)
80 return (b->do_lookup(lookup));
81 else
82 return (ISC_R_NOTFOUND);
85 static isc_result_t
86 put_txt(dns_sdblookup_t *lookup, const char *text) {
87 unsigned char buf[256];
88 unsigned int len = strlen(text);
89 if (len > 255)
90 len = 255; /* Silently truncate */
91 buf[0] = len;
92 memcpy(&buf[1], text, len);
93 return (dns_sdb_putrdata(lookup, dns_rdatatype_txt, 0, buf, len + 1));
96 static isc_result_t
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);
101 else
102 return (put_txt(lookup, ns_g_server->version));
103 } else {
104 return (put_txt(lookup, ns_g_version));
108 static isc_result_t
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);
113 else
114 return (put_txt(lookup, ns_g_server->hostname));
115 } else {
116 char buf[256];
117 isc_result_t result = ns_os_gethostname(buf, sizeof(buf));
118 if (result != ISC_R_SUCCESS)
119 return (result);
120 return (put_txt(lookup, buf));
124 static isc_result_t
125 do_authors_lookup(dns_sdblookup_t *lookup) {
126 isc_result_t result;
127 const char **p;
128 static const char *authors[] = {
129 "Mark Andrews",
130 "James Brister",
131 "Ben Cottrell",
132 "Michael Graff",
133 "Andreas Gustafsson",
134 "Bob Halley",
135 "David Lawrence",
136 "Danny Mayer",
137 "Damien Neil",
138 "Matt Nelson",
139 "Michael Sawyer",
140 "Brian Wellington",
141 NULL
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)
153 return (result);
155 return (ISC_R_SUCCESS);
158 static isc_result_t
159 do_id_lookup(dns_sdblookup_t *lookup) {
161 if (ns_g_server->server_usehostname) {
162 char buf[256];
163 isc_result_t result = ns_os_gethostname(buf, sizeof(buf));
164 if (result != ISC_R_SUCCESS)
165 return (result);
166 return (put_txt(lookup, buf));
169 if (ns_g_server->server_id == NULL)
170 return (ISC_R_SUCCESS);
171 else
172 return (put_txt(lookup, ns_g_server->server_id));
175 static isc_result_t
176 do_empty_lookup(dns_sdblookup_t *lookup) {
178 UNUSED(lookup);
179 return (ISC_R_SUCCESS);
182 static isc_result_t
183 builtin_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) {
184 isc_result_t result;
185 const char *contact = "hostmaster";
186 const char *server = "@";
187 builtin_t *b = (builtin_t *) dbdata;
189 UNUSED(zone);
190 UNUSED(dbdata);
192 if (b == &empty_builtin) {
193 server = ".";
194 contact = ".";
195 } else {
196 if (b->server != NULL)
197 server = b->server;
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);
213 static isc_result_t
214 builtin_create(const char *zone, int argc, char **argv,
215 void *driverdata, void **dbdata)
217 REQUIRE(argc >= 1);
219 UNUSED(zone);
220 UNUSED(driverdata);
222 if (strcmp(argv[0], "empty") == 0) {
223 if (argc != 3)
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) {
237 builtin_t *empty;
238 char *server;
239 char *contact;
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;
249 if (server != NULL)
250 isc_mem_free(ns_g_mctx, server);
251 if (contact != NULL)
252 isc_mem_free(ns_g_mctx, contact);
253 if (empty != NULL)
254 isc_mem_put(ns_g_mctx, empty, sizeof (*empty));
255 } else {
256 memcpy(empty, &empty_builtin, sizeof (empty_builtin));
257 empty->server = server;
258 empty->contact = contact;
259 *dbdata = empty;
261 } else
262 return (ISC_R_NOTIMPLEMENTED);
263 return (ISC_R_SUCCESS);
266 static void
267 builtin_destroy(const char *zone, void *driverdata, void **dbdata) {
268 builtin_t *b = (builtin_t *) *dbdata;
270 UNUSED(zone);
271 UNUSED(driverdata);
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)
279 return;
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 = {
287 builtin_lookup,
288 builtin_authority,
289 NULL, /* allnodes */
290 builtin_create,
291 builtin_destroy
294 isc_result_t
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)
300 == ISC_R_SUCCESS);
301 return (ISC_R_SUCCESS);
304 void
305 ns_builtin_deinit(void) {
306 dns_sdb_unregister(&builtin_impl);