]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - contrib/bind9/bin/named/builtin.c
Update to version 9.6-ESV-R6, the latest from ISC, which contains numerous
[FreeBSD/stable/8.git] / contrib / bind9 / bin / named / builtin.c
1 /*
2  * Copyright (C) 2004, 2005, 2007, 2010, 2012  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 2001-2003  Internet Software Consortium.
4  *
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.
8  *
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.
16  */
17
18 /* $Id$ */
19
20 /*! \file
21  * \brief
22  * The built-in "version", "hostname", "id", "authors" and "empty" databases.
23  */
24
25 #include <config.h>
26
27 #include <string.h>
28 #include <stdio.h>
29
30 #include <isc/mem.h>
31 #include <isc/print.h>
32 #include <isc/result.h>
33 #include <isc/util.h>
34
35 #include <dns/result.h>
36 #include <dns/sdb.h>
37
38 #include <named/builtin.h>
39 #include <named/globals.h>
40 #include <named/server.h>
41 #include <named/os.h>
42
43 typedef struct builtin builtin_t;
44
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);
50
51 /*
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.
55  */
56
57 struct builtin {
58         isc_result_t (*do_lookup)(dns_sdblookup_t *lookup);
59         char *server;
60         char *contact;
61 };
62
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 };
68
69 static dns_sdbimplementation_t *builtin_impl;
70
71 static isc_result_t
72 builtin_lookup(const char *zone, const char *name, void *dbdata,
73                dns_sdblookup_t *lookup)
74 {
75         builtin_t *b = (builtin_t *) dbdata;
76
77         UNUSED(zone);
78
79         if (strcmp(name, "@") == 0)
80                 return (b->do_lookup(lookup));
81         else
82                 return (ISC_R_NOTFOUND);
83 }
84
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));
94 }
95
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));
105         }
106 }
107
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));
121         }
122 }
123
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                 "Curtis Blackburn",
131                 "James Brister",
132                 "Ben Cottrell",
133                 "Michael Graff",
134                 "Andreas Gustafsson",
135                 "Bob Halley",
136                 "Evan Hunt",
137                 "JINMEI Tatuya",
138                 "David Lawrence",
139                 "Scott Mann",
140                 "Danny Mayer",
141                 "Damien Neil",
142                 "Matt Nelson",
143                 "Michael Sawyer",
144                 "Brian Wellington",
145                 NULL
146         };
147
148         /*
149          * If a version string is specified, disable the authors.bind zone.
150          */
151         if (ns_g_server->version_set)
152                 return (ISC_R_SUCCESS);
153
154         for (p = authors; *p != NULL; p++) {
155                 result = put_txt(lookup, *p);
156                 if (result != ISC_R_SUCCESS)
157                         return (result);
158         }
159         return (ISC_R_SUCCESS);
160 }
161
162 static isc_result_t
163 do_id_lookup(dns_sdblookup_t *lookup) {
164
165         if (ns_g_server->server_usehostname) {
166                 char buf[256];
167                 isc_result_t result = ns_os_gethostname(buf, sizeof(buf));
168                 if (result != ISC_R_SUCCESS)
169                         return (result);
170                 return (put_txt(lookup, buf));
171         }
172
173         if (ns_g_server->server_id == NULL)
174                 return (ISC_R_SUCCESS);
175         else
176                 return (put_txt(lookup, ns_g_server->server_id));
177 }
178
179 static isc_result_t
180 do_empty_lookup(dns_sdblookup_t *lookup) {
181
182         UNUSED(lookup);
183         return (ISC_R_SUCCESS);
184 }
185
186 static isc_result_t
187 builtin_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) {
188         isc_result_t result;
189         const char *contact = "hostmaster";
190         const char *server = "@";
191         builtin_t *b = (builtin_t *) dbdata;
192
193         UNUSED(zone);
194         UNUSED(dbdata);
195
196         if (b == &empty_builtin) {
197                 server = ".";
198                 contact = ".";
199         } else {
200                 if (b->server != NULL)
201                         server = b->server;
202                 if (b->contact != NULL)
203                         contact = b->contact;
204         }
205
206         result = dns_sdb_putsoa(lookup, server, contact, 0);
207         if (result != ISC_R_SUCCESS)
208                 return (ISC_R_FAILURE);
209
210         result = dns_sdb_putrr(lookup, "ns", 0, server);
211         if (result != ISC_R_SUCCESS)
212                 return (ISC_R_FAILURE);
213
214         return (ISC_R_SUCCESS);
215 }
216
217 static isc_result_t
218 builtin_create(const char *zone, int argc, char **argv,
219                void *driverdata, void **dbdata)
220 {
221         REQUIRE(argc >= 1);
222
223         UNUSED(zone);
224         UNUSED(driverdata);
225
226         if (strcmp(argv[0], "empty") == 0) {
227                 if (argc != 3)
228                         return (DNS_R_SYNTAX);
229         } else if (argc != 1)
230                 return (DNS_R_SYNTAX);
231
232         if (strcmp(argv[0], "version") == 0)
233                 *dbdata = &version_builtin;
234         else if (strcmp(argv[0], "hostname") == 0)
235                 *dbdata = &hostname_builtin;
236         else if (strcmp(argv[0], "authors") == 0)
237                 *dbdata = &authors_builtin;
238         else if (strcmp(argv[0], "id") == 0)
239                 *dbdata = &id_builtin;
240         else if (strcmp(argv[0], "empty") == 0) {
241                 builtin_t *empty;
242                 char *server;
243                 char *contact;
244                 /*
245                  * We don't want built-in zones to fail.  Fallback to
246                  * the static configuration if memory allocation fails.
247                  */
248                 empty = isc_mem_get(ns_g_mctx, sizeof(*empty));
249                 server = isc_mem_strdup(ns_g_mctx, argv[1]);
250                 contact = isc_mem_strdup(ns_g_mctx, argv[2]);
251                 if (empty == NULL || server == NULL || contact == NULL) {
252                         *dbdata = &empty_builtin;
253                         if (server != NULL)
254                                 isc_mem_free(ns_g_mctx, server);
255                         if (contact != NULL)
256                                 isc_mem_free(ns_g_mctx, contact);
257                         if (empty != NULL)
258                                 isc_mem_put(ns_g_mctx, empty, sizeof (*empty));
259                 } else {
260                         memcpy(empty, &empty_builtin, sizeof (empty_builtin));
261                         empty->server = server;
262                         empty->contact = contact;
263                         *dbdata = empty;
264                 }
265         } else
266                 return (ISC_R_NOTIMPLEMENTED);
267         return (ISC_R_SUCCESS);
268 }
269
270 static void
271 builtin_destroy(const char *zone, void *driverdata, void **dbdata) {
272         builtin_t *b = (builtin_t *) *dbdata;
273
274         UNUSED(zone);
275         UNUSED(driverdata);
276
277         /*
278          * Don't free the static versions.
279          */
280         if (*dbdata == &version_builtin || *dbdata == &hostname_builtin ||
281             *dbdata == &authors_builtin || *dbdata == &id_builtin ||
282             *dbdata == &empty_builtin)
283                 return;
284
285         isc_mem_free(ns_g_mctx, b->server);
286         isc_mem_free(ns_g_mctx, b->contact);
287         isc_mem_put(ns_g_mctx, b, sizeof (*b));
288 }
289
290 static dns_sdbmethods_t builtin_methods = {
291         builtin_lookup,
292         builtin_authority,
293         NULL,           /* allnodes */
294         builtin_create,
295         builtin_destroy
296 };
297
298 isc_result_t
299 ns_builtin_init(void) {
300         RUNTIME_CHECK(dns_sdb_register("_builtin", &builtin_methods, NULL,
301                                        DNS_SDBFLAG_RELATIVEOWNER |
302                                        DNS_SDBFLAG_RELATIVERDATA,
303                                        ns_g_mctx, &builtin_impl)
304                       == ISC_R_SUCCESS);
305         return (ISC_R_SUCCESS);
306 }
307
308 void
309 ns_builtin_deinit(void) {
310         dns_sdb_unregister(&builtin_impl);
311 }