xref: /minix3/external/bsd/bind/dist/contrib/sdb/dir/dirdb.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: dirdb.c,v 1.4 2014/12/10 04:37:57 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004, 2007, 2011, 2014  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 2000, 2001  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: dirdb.c,v 1.14 2011/10/11 23:46:45 tbox Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek /*
23*00b67f09SDavid van Moolenbroek  * A simple database driver that returns basic information about
24*00b67f09SDavid van Moolenbroek  * files and directories in the Unix file system as DNS data.
25*00b67f09SDavid van Moolenbroek  */
26*00b67f09SDavid van Moolenbroek 
27*00b67f09SDavid van Moolenbroek #include <config.h>
28*00b67f09SDavid van Moolenbroek 
29*00b67f09SDavid van Moolenbroek #include <stdio.h>
30*00b67f09SDavid van Moolenbroek #include <string.h>
31*00b67f09SDavid van Moolenbroek #include <unistd.h>
32*00b67f09SDavid van Moolenbroek #include <sys/stat.h>
33*00b67f09SDavid van Moolenbroek #include <sys/sysmacros.h>
34*00b67f09SDavid van Moolenbroek 
35*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
36*00b67f09SDavid van Moolenbroek #include <isc/print.h>
37*00b67f09SDavid van Moolenbroek #include <isc/result.h>
38*00b67f09SDavid van Moolenbroek #include <isc/util.h>
39*00b67f09SDavid van Moolenbroek 
40*00b67f09SDavid van Moolenbroek #include <dns/sdb.h>
41*00b67f09SDavid van Moolenbroek 
42*00b67f09SDavid van Moolenbroek #include <named/globals.h>
43*00b67f09SDavid van Moolenbroek 
44*00b67f09SDavid van Moolenbroek #include "dirdb.h"
45*00b67f09SDavid van Moolenbroek 
46*00b67f09SDavid van Moolenbroek static dns_sdbimplementation_t *dirdb = NULL;
47*00b67f09SDavid van Moolenbroek 
48*00b67f09SDavid van Moolenbroek #define CHECK(op)						\
49*00b67f09SDavid van Moolenbroek 	do { result = (op);					\
50*00b67f09SDavid van Moolenbroek 		if (result != ISC_R_SUCCESS) return (result);	\
51*00b67f09SDavid van Moolenbroek 	} while (/*CONSTCOND*/0)
52*00b67f09SDavid van Moolenbroek 
53*00b67f09SDavid van Moolenbroek #define CHECKN(op)						\
54*00b67f09SDavid van Moolenbroek 	do { n = (op);						\
55*00b67f09SDavid van Moolenbroek 		if (n < 0) return (ISC_R_FAILURE);		\
56*00b67f09SDavid van Moolenbroek 	} while (/*CONSTCOND*/0)
57*00b67f09SDavid van Moolenbroek 
58*00b67f09SDavid van Moolenbroek 
59*00b67f09SDavid van Moolenbroek /*
60*00b67f09SDavid van Moolenbroek  * This database operates on relative names.
61*00b67f09SDavid van Moolenbroek  *
62*00b67f09SDavid van Moolenbroek  * Any name will be interpreted as a pathname offset from the directory
63*00b67f09SDavid van Moolenbroek  * specified in the configuration file.
64*00b67f09SDavid van Moolenbroek  */
65*00b67f09SDavid van Moolenbroek #ifdef DNS_CLIENTINFO_VERSION
66*00b67f09SDavid van Moolenbroek static isc_result_t
dirdb_lookup(const char * zone,const char * name,void * dbdata,dns_sdblookup_t * lookup,dns_clientinfomethods_t * methods,dns_clientinfo_t * clientinfo)67*00b67f09SDavid van Moolenbroek dirdb_lookup(const char *zone, const char *name, void *dbdata,
68*00b67f09SDavid van Moolenbroek 	      dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods,
69*00b67f09SDavid van Moolenbroek 	      dns_clientinfo_t *clientinfo)
70*00b67f09SDavid van Moolenbroek #else
71*00b67f09SDavid van Moolenbroek static isc_result_t
72*00b67f09SDavid van Moolenbroek dirdb_lookup(const char *zone, const char *name, void *dbdata,
73*00b67f09SDavid van Moolenbroek 	      dns_sdblookup_t *lookup)
74*00b67f09SDavid van Moolenbroek #endif /* DNS_CLIENTINFO_VERSION */
75*00b67f09SDavid van Moolenbroek {
76*00b67f09SDavid van Moolenbroek 	char filename[255];
77*00b67f09SDavid van Moolenbroek 	char filename2[255];
78*00b67f09SDavid van Moolenbroek 	char buf[1024];
79*00b67f09SDavid van Moolenbroek 	struct stat statbuf;
80*00b67f09SDavid van Moolenbroek 	isc_result_t result;
81*00b67f09SDavid van Moolenbroek 	int n;
82*00b67f09SDavid van Moolenbroek 
83*00b67f09SDavid van Moolenbroek 	UNUSED(zone);
84*00b67f09SDavid van Moolenbroek 	UNUSED(dbdata);
85*00b67f09SDavid van Moolenbroek #ifdef DNS_CLIENTINFO_VERSION
86*00b67f09SDavid van Moolenbroek 	UNUSED(methods);
87*00b67f09SDavid van Moolenbroek 	UNUSED(clientinfo);
88*00b67f09SDavid van Moolenbroek #endif /* DNS_CLIENTINFO_VERSION */
89*00b67f09SDavid van Moolenbroek 
90*00b67f09SDavid van Moolenbroek 	if (strcmp(name, "@") == 0)
91*00b67f09SDavid van Moolenbroek 		snprintf(filename, sizeof(filename), "%s", (char *)dbdata);
92*00b67f09SDavid van Moolenbroek 	else
93*00b67f09SDavid van Moolenbroek 		snprintf(filename, sizeof(filename), "%s/%s",
94*00b67f09SDavid van Moolenbroek 			 (char *)dbdata, name);
95*00b67f09SDavid van Moolenbroek 	CHECKN(lstat(filename, &statbuf));
96*00b67f09SDavid van Moolenbroek 
97*00b67f09SDavid van Moolenbroek 	if (S_ISDIR(statbuf.st_mode))
98*00b67f09SDavid van Moolenbroek 		CHECK(dns_sdb_putrr(lookup, "txt", 3600, "dir"));
99*00b67f09SDavid van Moolenbroek 	else if (S_ISCHR(statbuf.st_mode) || S_ISBLK(statbuf.st_mode)) {
100*00b67f09SDavid van Moolenbroek 		CHECKN(snprintf(buf, sizeof(buf),
101*00b67f09SDavid van Moolenbroek 				"\"%sdev\" \"major %d\" \"minor %d\"",
102*00b67f09SDavid van Moolenbroek 				S_ISCHR(statbuf.st_mode) ? "chr" : "blk",
103*00b67f09SDavid van Moolenbroek 				major(statbuf.st_rdev),
104*00b67f09SDavid van Moolenbroek 				minor(statbuf.st_rdev)));
105*00b67f09SDavid van Moolenbroek 		CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf));
106*00b67f09SDavid van Moolenbroek 	} else if (S_ISFIFO(statbuf.st_mode))
107*00b67f09SDavid van Moolenbroek 		CHECK(dns_sdb_putrr(lookup, "txt", 3600, "pipe"));
108*00b67f09SDavid van Moolenbroek 	else if (S_ISSOCK(statbuf.st_mode))
109*00b67f09SDavid van Moolenbroek 		CHECK(dns_sdb_putrr(lookup, "txt", 3600, "socket"));
110*00b67f09SDavid van Moolenbroek 	else if (S_ISLNK(statbuf.st_mode)) {
111*00b67f09SDavid van Moolenbroek 		CHECKN(readlink(filename, filename2, sizeof(filename2) - 1));
112*00b67f09SDavid van Moolenbroek 		buf[n] = 0;
113*00b67f09SDavid van Moolenbroek 		CHECKN(snprintf(buf, sizeof(buf), "\"symlink\" \"%s\"",
114*00b67f09SDavid van Moolenbroek 				filename2));
115*00b67f09SDavid van Moolenbroek 		CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf));
116*00b67f09SDavid van Moolenbroek 	} else if (!S_ISREG(statbuf.st_mode))
117*00b67f09SDavid van Moolenbroek 		CHECK(dns_sdb_putrr(lookup, "txt", 3600, "unknown"));
118*00b67f09SDavid van Moolenbroek 	else {
119*00b67f09SDavid van Moolenbroek 		CHECKN(snprintf(buf, sizeof(buf), "\"file\" \"size = %u\"",
120*00b67f09SDavid van Moolenbroek 			 (unsigned int)statbuf.st_size));
121*00b67f09SDavid van Moolenbroek 		CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf));
122*00b67f09SDavid van Moolenbroek 	}
123*00b67f09SDavid van Moolenbroek 
124*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
125*00b67f09SDavid van Moolenbroek }
126*00b67f09SDavid van Moolenbroek 
127*00b67f09SDavid van Moolenbroek /*
128*00b67f09SDavid van Moolenbroek  * lookup () does not return SOA or NS records, so authority() must be defined.
129*00b67f09SDavid van Moolenbroek  */
130*00b67f09SDavid van Moolenbroek static isc_result_t
dirdb_authority(const char * zone,void * dbdata,dns_sdblookup_t * lookup)131*00b67f09SDavid van Moolenbroek dirdb_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) {
132*00b67f09SDavid van Moolenbroek 	isc_result_t result;
133*00b67f09SDavid van Moolenbroek 
134*00b67f09SDavid van Moolenbroek 	UNUSED(zone);
135*00b67f09SDavid van Moolenbroek 	UNUSED(dbdata);
136*00b67f09SDavid van Moolenbroek 
137*00b67f09SDavid van Moolenbroek 	result = dns_sdb_putsoa(lookup, "ns", "hostmaster", 0);
138*00b67f09SDavid van Moolenbroek 	INSIST(result == ISC_R_SUCCESS);
139*00b67f09SDavid van Moolenbroek 	result = dns_sdb_putrr(lookup, "ns", 86400, "ns1");
140*00b67f09SDavid van Moolenbroek 	INSIST(result == ISC_R_SUCCESS);
141*00b67f09SDavid van Moolenbroek 	result = dns_sdb_putrr(lookup, "ns", 86400, "ns2");
142*00b67f09SDavid van Moolenbroek 	INSIST(result == ISC_R_SUCCESS);
143*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
144*00b67f09SDavid van Moolenbroek }
145*00b67f09SDavid van Moolenbroek 
146*00b67f09SDavid van Moolenbroek /*
147*00b67f09SDavid van Moolenbroek  * Each database stores the top-level directory as the dbdata opaque
148*00b67f09SDavid van Moolenbroek  * object.  The create() function allocates it.  argv[0] holds the top
149*00b67f09SDavid van Moolenbroek  * level directory.
150*00b67f09SDavid van Moolenbroek  */
151*00b67f09SDavid van Moolenbroek static isc_result_t
dirdb_create(const char * zone,int argc,char ** argv,void * driverdata,void ** dbdata)152*00b67f09SDavid van Moolenbroek dirdb_create(const char *zone, int argc, char **argv,
153*00b67f09SDavid van Moolenbroek 	     void *driverdata, void **dbdata)
154*00b67f09SDavid van Moolenbroek {
155*00b67f09SDavid van Moolenbroek 	UNUSED(zone);
156*00b67f09SDavid van Moolenbroek 	UNUSED(driverdata);
157*00b67f09SDavid van Moolenbroek 
158*00b67f09SDavid van Moolenbroek 	if (argc < 1)
159*00b67f09SDavid van Moolenbroek 		return (ISC_R_FAILURE);
160*00b67f09SDavid van Moolenbroek 	*dbdata = isc_mem_strdup((isc_mem_t *)driverdata, argv[0]);
161*00b67f09SDavid van Moolenbroek 	if (*dbdata == NULL)
162*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
163*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
164*00b67f09SDavid van Moolenbroek }
165*00b67f09SDavid van Moolenbroek 
166*00b67f09SDavid van Moolenbroek /*
167*00b67f09SDavid van Moolenbroek  * The destroy() function frees the memory allocated by create().
168*00b67f09SDavid van Moolenbroek  */
169*00b67f09SDavid van Moolenbroek static void
dirdb_destroy(const char * zone,void * driverdata,void ** dbdata)170*00b67f09SDavid van Moolenbroek dirdb_destroy(const char *zone, void *driverdata, void **dbdata) {
171*00b67f09SDavid van Moolenbroek 	UNUSED(zone);
172*00b67f09SDavid van Moolenbroek 	UNUSED(driverdata);
173*00b67f09SDavid van Moolenbroek 	isc_mem_free((isc_mem_t *)driverdata, *dbdata);
174*00b67f09SDavid van Moolenbroek }
175*00b67f09SDavid van Moolenbroek 
176*00b67f09SDavid van Moolenbroek /*
177*00b67f09SDavid van Moolenbroek  * This zone does not support zone transfer, so allnodes() is NULL.
178*00b67f09SDavid van Moolenbroek  */
179*00b67f09SDavid van Moolenbroek static dns_sdbmethods_t dirdb_methods = {
180*00b67f09SDavid van Moolenbroek 	dirdb_lookup,
181*00b67f09SDavid van Moolenbroek 	dirdb_authority,
182*00b67f09SDavid van Moolenbroek 	NULL, /* allnodes */
183*00b67f09SDavid van Moolenbroek 	dirdb_create,
184*00b67f09SDavid van Moolenbroek 	dirdb_destroy,
185*00b67f09SDavid van Moolenbroek 	NULL /* lookup2 */
186*00b67f09SDavid van Moolenbroek };
187*00b67f09SDavid van Moolenbroek 
188*00b67f09SDavid van Moolenbroek /*
189*00b67f09SDavid van Moolenbroek  * Wrapper around dns_sdb_register().  Note that the first ns_g_mctx is
190*00b67f09SDavid van Moolenbroek  * being passed as the "driverdata" parameter, so that will it will be
191*00b67f09SDavid van Moolenbroek  * passed to create() and destroy().
192*00b67f09SDavid van Moolenbroek  */
193*00b67f09SDavid van Moolenbroek isc_result_t
dirdb_init(void)194*00b67f09SDavid van Moolenbroek dirdb_init(void) {
195*00b67f09SDavid van Moolenbroek 	unsigned int flags;
196*00b67f09SDavid van Moolenbroek 	flags = DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA |
197*00b67f09SDavid van Moolenbroek 		DNS_SDBFLAG_THREADSAFE;
198*00b67f09SDavid van Moolenbroek 	return (dns_sdb_register("dir", &dirdb_methods, ns_g_mctx, flags,
199*00b67f09SDavid van Moolenbroek 				 ns_g_mctx, &dirdb));
200*00b67f09SDavid van Moolenbroek }
201*00b67f09SDavid van Moolenbroek 
202*00b67f09SDavid van Moolenbroek /*
203*00b67f09SDavid van Moolenbroek  * Wrapper around dns_sdb_unregister().
204*00b67f09SDavid van Moolenbroek  */
205*00b67f09SDavid van Moolenbroek void
dirdb_clear(void)206*00b67f09SDavid van Moolenbroek dirdb_clear(void) {
207*00b67f09SDavid van Moolenbroek 	if (dirdb != NULL)
208*00b67f09SDavid van Moolenbroek 		dns_sdb_unregister(&dirdb);
209*00b67f09SDavid van Moolenbroek }
210