dirdb.c revision 499b34cea04a46823d003d4c0520c8b03e8513cb
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt/*
c19f42a378f76af272166f9cababe7bfbc1cf6abTinderbox User * Copyright (C) 2000, 2001 Internet Software Consortium.
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Permission to use, copy, modify, and distribute this software for any
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * purpose with or without fee is hereby granted, provided that the above
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * copyright notice and this permission notice appear in all copies.
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt *
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
28a8f5b0de57d269cf2845c69cb6abe18cbd3b3aMark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt */
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
e7008e7007f440490174a52b7117f3c6d121d303Mark Andrews/* $Id: dirdb.c,v 1.9 2001/01/09 21:46:22 bwelling Exp $ */
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt/*
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * A simple database driver that returns basic information about
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * files and directories in the Unix file system as DNS data.
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt */
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include <config.h>
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include <stdio.h>
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include <string.h>
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include <unistd.h>
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include <sys/stat.h>
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include <sys/sysmacros.h>
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include <isc/mem.h>
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include <isc/print.h>
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include <isc/result.h>
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include <isc/util.h>
6f7abb89ec22aef5eda40ed60fcf605a42b78d4dMark Andrews
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include <dns/sdb.h>
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include <named/globals.h>
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#include "dirdb.h"
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Huntstatic dns_sdbimplementation_t *dirdb = NULL;
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#define CHECK(op) \
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt do { result = (op); \
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt if (result != ISC_R_SUCCESS) return (result); \
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt } while (0)
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt#define CHECKN(op) \
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt do { n = (op); \
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt if (n < 0) return (ISC_R_FAILURE); \
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt } while (0)
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
de52784e45e3a7a92c0d8ad843eb4db313bbfd97Mark Andrews
de52784e45e3a7a92c0d8ad843eb4db313bbfd97Mark Andrews/*
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * This database operates on relative names.
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt *
5e965459a66e9e83e56091d5366c17f1953ab3ceAutomatic Updater * Any name will be interpreted as a pathname offset from the directory
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * specified in the configuration file.
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt */
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Huntstatic isc_result_t
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Huntdirdb_lookup(const char *zone, const char *name, void *dbdata,
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt dns_sdblookup_t *lookup)
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt{
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt char filename[255];
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt char filename2[255];
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt char buf[1024];
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt struct stat statbuf;
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt isc_result_t result;
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt int n;
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt UNUSED(zone);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt UNUSED(dbdata);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt if (strcmp(name, "@") == 0)
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt snprintf(filename, sizeof(filename), "%s", (char *)dbdata);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt else
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt snprintf(filename, sizeof(filename), "%s/%s",
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt (char *)dbdata, name);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt CHECKN(lstat(filename, &statbuf));
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt if (S_ISDIR(statbuf.st_mode))
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt CHECK(dns_sdb_putrr(lookup, "txt", 3600, "dir"));
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt else if (S_ISCHR(statbuf.st_mode) || S_ISBLK(statbuf.st_mode)) {
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt CHECKN(snprintf(buf, sizeof(buf),
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt "\"%sdev\" \"major %d\" \"minor %d\"",
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt S_ISCHR(statbuf.st_mode) ? "chr" : "blk",
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt major(statbuf.st_rdev),
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt minor(statbuf.st_rdev)));
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf));
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt } else if (S_ISFIFO(statbuf.st_mode))
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt CHECK(dns_sdb_putrr(lookup, "txt", 3600, "pipe"));
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt else if (S_ISSOCK(statbuf.st_mode))
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt CHECK(dns_sdb_putrr(lookup, "txt", 3600, "socket"));
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt else if (S_ISLNK(statbuf.st_mode)) {
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt CHECKN(readlink(filename, filename2, sizeof(filename2) - 1));
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt buf[n] = 0;
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt CHECKN(snprintf(buf, sizeof(buf), "\"symlink\" \"%s\"",
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt filename2));
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf));
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt } else if (!S_ISREG(statbuf.st_mode))
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt CHECK(dns_sdb_putrr(lookup, "txt", 3600, "unknown"));
de52784e45e3a7a92c0d8ad843eb4db313bbfd97Mark Andrews else {
de52784e45e3a7a92c0d8ad843eb4db313bbfd97Mark Andrews CHECKN(snprintf(buf, sizeof(buf), "\"file\" \"size = %u\"",
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt (unsigned int)statbuf.st_size));
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt CHECK(dns_sdb_putrr(lookup, "txt", 3600, buf));
5e965459a66e9e83e56091d5366c17f1953ab3ceAutomatic Updater }
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt return (ISC_R_SUCCESS);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt}
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt/*
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * lookup () does not return SOA or NS records, so authority() must be defined.
d64e3b29bd1b66a4bc80b60ef87a5bafe741d7caMark Andrews */
d64e3b29bd1b66a4bc80b60ef87a5bafe741d7caMark Andrewsstatic isc_result_t
d64e3b29bd1b66a4bc80b60ef87a5bafe741d7caMark Andrewsdirdb_authority(const char *zone, void *dbdata, dns_sdblookup_t *lookup) {
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt isc_result_t result;
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt UNUSED(zone);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt UNUSED(dbdata);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt result = dns_sdb_putsoa(lookup, "ns", "hostmaster", 0);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt INSIST(result == ISC_R_SUCCESS);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt result = dns_sdb_putrr(lookup, "ns", 86400, "ns1");
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt INSIST(result == ISC_R_SUCCESS);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt result = dns_sdb_putrr(lookup, "ns", 86400, "ns2");
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt INSIST(result == ISC_R_SUCCESS);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt return (ISC_R_SUCCESS);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt}
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt/*
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * Each database stores the top-level directory as the dbdata opaque
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * object. The create() function allocates it. argv[0] holds the top
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * level directory.
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt */
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Huntstatic isc_result_t
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Huntdirdb_create(const char *zone, int argc, char **argv,
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt void *driverdata, void **dbdata)
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt{
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt UNUSED(zone);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt UNUSED(driverdata);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt if (argc < 1)
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt return (ISC_R_FAILURE);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt *dbdata = isc_mem_strdup((isc_mem_t *)driverdata, argv[0]);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt if (*dbdata == NULL)
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt return (ISC_R_NOMEMORY);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt return (ISC_R_SUCCESS);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt}
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt/*
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * The destroy() function frees the memory allocated by create().
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt */
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Huntstatic void
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Huntdirdb_destroy(const char *zone, void *driverdata, void **dbdata) {
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt UNUSED(zone);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt UNUSED(driverdata);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt isc_mem_free((isc_mem_t *)driverdata, *dbdata);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt}
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt/*
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * This zone does not support zone transfer, so allnodes() is NULL.
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt */
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Huntstatic dns_sdbmethods_t dirdb_methods = {
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt dirdb_lookup,
de52784e45e3a7a92c0d8ad843eb4db313bbfd97Mark Andrews dirdb_authority,
de52784e45e3a7a92c0d8ad843eb4db313bbfd97Mark Andrews NULL, /* allnodes */
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt dirdb_create,
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt dirdb_destroy
5e965459a66e9e83e56091d5366c17f1953ab3ceAutomatic Updater};
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt/*
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * Wrapper around dns_sdb_register(). Note that the first ns_g_mctx is
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * being passed as the "driverdata" parameter, so that will it will be
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * passed to create() and destroy().
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt */
d64e3b29bd1b66a4bc80b60ef87a5bafe741d7caMark Andrewsisc_result_t
d64e3b29bd1b66a4bc80b60ef87a5bafe741d7caMark Andrewsdirdb_init(void) {
d64e3b29bd1b66a4bc80b60ef87a5bafe741d7caMark Andrews unsigned int flags;
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt flags = DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA |
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt DNS_SDBFLAG_THREADSAFE;
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt return (dns_sdb_register("dir", &dirdb_methods, ns_g_mctx, flags,
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt ns_g_mctx, &dirdb));
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt}
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt/*
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt * Wrapper around dns_sdb_unregister().
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt */
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Huntvoid
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Huntdirdb_clear(void) {
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt if (dirdb != NULL)
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt dns_sdb_unregister(&dirdb);
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt}
5a75f61dd413720c16d229b24ebba6bd6ecdb738Evan Hunt