138494Sobrien/* 2174294Sobrien * Copyright (c) 1997-2006 Erez Zadok 338494Sobrien * Copyright (c) 1989 Jan-Simon Pendry 438494Sobrien * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 538494Sobrien * Copyright (c) 1989 The Regents of the University of California. 638494Sobrien * All rights reserved. 738494Sobrien * 838494Sobrien * This code is derived from software contributed to Berkeley by 938494Sobrien * Jan-Simon Pendry at Imperial College, London. 1038494Sobrien * 1138494Sobrien * Redistribution and use in source and binary forms, with or without 1238494Sobrien * modification, are permitted provided that the following conditions 1338494Sobrien * are met: 1438494Sobrien * 1. Redistributions of source code must retain the above copyright 1538494Sobrien * notice, this list of conditions and the following disclaimer. 1638494Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1738494Sobrien * notice, this list of conditions and the following disclaimer in the 1838494Sobrien * documentation and/or other materials provided with the distribution. 1938494Sobrien * 3. All advertising materials mentioning features or use of this software 2042629Sobrien * must display the following acknowledgment: 2138494Sobrien * This product includes software developed by the University of 2238494Sobrien * California, Berkeley and its contributors. 2338494Sobrien * 4. Neither the name of the University nor the names of its contributors 2438494Sobrien * may be used to endorse or promote products derived from this software 2538494Sobrien * without specific prior written permission. 2638494Sobrien * 2738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2838494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2938494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3038494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3138494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3238494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3338494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3438494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3538494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3638494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3738494Sobrien * SUCH DAMAGE. 3838494Sobrien * 3938494Sobrien * 40174294Sobrien * File: am-utils/amd/info_hesiod.c 4138494Sobrien * 4238494Sobrien */ 4338494Sobrien 4438494Sobrien/* 4538494Sobrien * Get info from Hesiod 4638494Sobrien */ 4738494Sobrien 4838494Sobrien#ifdef HAVE_CONFIG_H 4938494Sobrien# include <config.h> 5038494Sobrien#endif /* HAVE_CONFIG_H */ 5138494Sobrien#include <am_defs.h> 5238494Sobrien#include <amd.h> 5338494Sobrien 5438494Sobrien#define HES_PREFIX "hesiod." 5538494Sobrien#define HES_PREFLEN 7 5638494Sobrien 5738494Sobrien#ifdef HAVE_HESIOD_INIT 5838494Sobrien/* bsdi3 does not define this extern in any header file */ 5938494Sobrienextern char **hesiod_resolve(void *context, const char *name, const char *type); 6051292Sobrienextern int hesiod_init(void **context); 6138494Sobrienstatic voidp hesiod_context; 6238494Sobrien#endif /* HAVE_HESIOD_INIT */ 6338494Sobrien 6451292Sobrien/* forward declarations */ 6551292Sobrienint amu_hesiod_init(mnt_map *m, char *map, time_t *tp); 6651292Sobrienint hesiod_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp); 6751292Sobrienint hesiod_isup(mnt_map *m, char *map); 6851292Sobrien 6938494Sobrien/* 7038494Sobrien * No easy way to probe the server - check the map name begins with "hesiod." 7138494Sobrien * Note: this name includes 'amu_' so as to not conflict with libhesiod's 7238494Sobrien * hesiod_init() function. 7338494Sobrien */ 7438494Sobrienint 7538494Sobrienamu_hesiod_init(mnt_map *m, char *map, time_t *tp) 7638494Sobrien{ 7738494Sobrien dlog("amu_hesiod_init(%s)", map); 7838494Sobrien *tp = 0; 7938494Sobrien 8038494Sobrien#ifdef HAVE_HESIOD_INIT 81174294Sobrien if (!hesiod_context && hesiod_init(&hesiod_context) != 0) 8238494Sobrien return ENOENT; 8338494Sobrien#endif /* HAVE_HESIOD_INIT */ 8438494Sobrien 8538494Sobrien return NSTREQ(map, HES_PREFIX, HES_PREFLEN) ? 0 : ENOENT; 8638494Sobrien} 8738494Sobrien 8838494Sobrien 8938494Sobrien/* 9038494Sobrien * Do a Hesiod nameserver call. 9138494Sobrien * Modify time is ignored by Hesiod - XXX 9238494Sobrien */ 9338494Sobrienint 9438494Sobrienhesiod_search(mnt_map *m, char *map, char *key, char **pval, time_t *tp) 9538494Sobrien{ 9638494Sobrien char hes_key[MAXPATHLEN]; 9738494Sobrien char **rvec; 9838494Sobrien#ifndef HAVE_HESIOD_INIT 9938494Sobrien int error; 10038494Sobrien#endif /* not HAVE_HESIOD_INIT */ 10138494Sobrien 10251292Sobrien dlog("hesiod_search(m=%lx, map=%s, key=%s, pval=%lx tp=%lx)", 10351292Sobrien (unsigned long) m, map, key, (unsigned long) pval, (unsigned long) tp); 10438494Sobrien 105174294Sobrien if (key[0] == '.') 106174294Sobrien return ENOENT; 10738494Sobrien 108174294Sobrien xsnprintf(hes_key, sizeof(hes_key), "%s.%s", key, map + HES_PREFLEN); 109174294Sobrien 11038494Sobrien /* 11138494Sobrien * Call the resolver 11238494Sobrien */ 11338494Sobrien dlog("Hesiod base is: %s\n", gopt.hesiod_base); 11438494Sobrien dlog("hesiod_search: hes_resolve(%s, %s)", hes_key, gopt.hesiod_base); 115174294Sobrien if (amuDebug(D_INFO)) 11638494Sobrien _res.options |= RES_DEBUG; 11738494Sobrien 11838494Sobrien#ifdef HAVE_HESIOD_INIT 11938494Sobrien /* new style hesiod */ 12038494Sobrien rvec = hesiod_resolve(hesiod_context, hes_key, gopt.hesiod_base); 12138494Sobrien#else /* not HAVE_HESIOD_INIT */ 12238494Sobrien rvec = hes_resolve(hes_key, gopt.hesiod_base); 12338494Sobrien#endif /* not HAVE_HESIOD_INIT */ 12438494Sobrien 12538494Sobrien /* 12638494Sobrien * If a reply was forthcoming then return 12738494Sobrien * it (and free subsequent replies) 12838494Sobrien */ 12938494Sobrien if (rvec && *rvec) { 13038494Sobrien *pval = *rvec; 13138494Sobrien while (*++rvec) 13238494Sobrien XFREE(*rvec); 13338494Sobrien return 0; 13438494Sobrien } 13538494Sobrien 13638494Sobrien#ifdef HAVE_HESIOD_INIT 13738494Sobrien /* new style hesiod */ 13838494Sobrien return errno; 13938494Sobrien#else /* not HAVE_HESIOD_INIT */ 14038494Sobrien /* 14138494Sobrien * Otherwise reflect the hesiod error into a Un*x error 14238494Sobrien */ 14338494Sobrien dlog("hesiod_search: Error: %d", hes_error()); 14438494Sobrien switch (hes_error()) { 14538494Sobrien case HES_ER_NOTFOUND: 14638494Sobrien error = ENOENT; 14738494Sobrien break; 14838494Sobrien case HES_ER_CONFIG: 14938494Sobrien error = EIO; 15038494Sobrien break; 15138494Sobrien case HES_ER_NET: 15238494Sobrien error = ETIMEDOUT; 15338494Sobrien break; 15438494Sobrien default: 15538494Sobrien error = EINVAL; 15638494Sobrien break; 15738494Sobrien } 15838494Sobrien dlog("hesiod_search: Returning: %d", error); 15938494Sobrien return error; 16038494Sobrien#endif /* not HAVE_HESIOD_INIT */ 16138494Sobrien} 16251292Sobrien 16351292Sobrien 16451292Sobrien/* 16551292Sobrien * Check if Hesiod is up, so we can determine if to clear the map or not. 16651292Sobrien * Test it by querying for /defaults. 16751292Sobrien * Returns: 0 if Hesiod is down, 1 if it is up. 16851292Sobrien */ 16951292Sobrienint 17051292Sobrienhesiod_isup(mnt_map *m, char *map) 17151292Sobrien{ 17251292Sobrien int error; 17351292Sobrien char *val; 17451292Sobrien time_t mtime; 17551292Sobrien static int last_status = 1; /* assume up by default */ 17651292Sobrien 17751292Sobrien error = hesiod_search(m, map, "/defaults", &val, &mtime); 17851292Sobrien dlog("hesiod_isup(%s): %s", map, strerror(error)); 17951292Sobrien if (error != 0 && error != ENOENT) { 18051292Sobrien plog(XLOG_ERROR, 18151292Sobrien "hesiod_isup: error getting `/defaults' entry in map %s: %m", map); 18251292Sobrien last_status = 0; 18351292Sobrien return 0; /* Hesiod is down */ 18451292Sobrien } 18551292Sobrien if (last_status == 0) { /* if was down before */ 18651292Sobrien plog(XLOG_INFO, "hesiod_isup: Hesiod came back up for map %s", map); 18751292Sobrien last_status = 1; 18851292Sobrien } 18951292Sobrien return 1; /* Hesiod is up */ 19051292Sobrien} 191