diff options
| author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
|---|---|---|
| committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
| commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
| tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/nsswitch/dns | |
| download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz | |
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/nsswitch/dns')
| -rw-r--r-- | usr/src/lib/nsswitch/dns/Makefile | 47 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/dns/Makefile.com | 49 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/dns/amd64/Makefile | 36 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/dns/common/dns_common.c | 167 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/dns/common/dns_common.h | 88 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/dns/common/dns_mt.c | 312 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/dns/common/gethostent.c | 416 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/dns/common/gethostent6.c | 534 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/dns/common/mapfile-vers | 46 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/dns/i386/Makefile | 36 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/dns/sparc/Makefile | 36 | ||||
| -rw-r--r-- | usr/src/lib/nsswitch/dns/sparcv9/Makefile | 37 |
12 files changed, 1804 insertions, 0 deletions
diff --git a/usr/src/lib/nsswitch/dns/Makefile b/usr/src/lib/nsswitch/dns/Makefile new file mode 100644 index 0000000000..9fc3326ce3 --- /dev/null +++ b/usr/src/lib/nsswitch/dns/Makefile @@ -0,0 +1,47 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright (c) 1991 - 1996, by Sun Microsystems, Inc. +# All rights reserved. +# +# lib/nsswitch/dns/Makefile + +include ../../../Makefile.master + +FILES_SUBDIRS= $(MACH) $(BUILD64) $(MACH64) + +all:= TARGET= all +clean:= TARGET= clean +clobber:= TARGET= clobber +install:= TARGET= install +lint:= TARGET= lint + +.KEEP_STATE: + +all clean clobber install lint: $(FILES_SUBDIRS) + +$(MACH) $(MACH64): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: diff --git a/usr/src/lib/nsswitch/dns/Makefile.com b/usr/src/lib/nsswitch/dns/Makefile.com new file mode 100644 index 0000000000..f4aa3f433c --- /dev/null +++ b/usr/src/lib/nsswitch/dns/Makefile.com @@ -0,0 +1,49 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2003 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# lib/nsswitch/dns/Makefile.com + +LIBRARY = libnss_dns.a +VERS = .1 + +OBJECTS = gethostent.o \ + gethostent6.o \ + dns_mt.o \ + dns_common.o + +# include common nsswitch library definitions. +include ../../Makefile.com + +# install this library in the root filesystem +include ../../../Makefile.rootfs + +# Appropriate libresolv loaded at runtime. This is the default, to be dlopened +# if no libresolv was provided by the application. +CPPFLAGS += -DNSS_DNS_LIBRESOLV=\"libresolv.so.2\" + +LDLIBS += -lnsl +DYNLIB1 = nss_dns.so$(VERS) diff --git a/usr/src/lib/nsswitch/dns/amd64/Makefile b/usr/src/lib/nsswitch/dns/amd64/Makefile new file mode 100644 index 0000000000..1334471b25 --- /dev/null +++ b/usr/src/lib/nsswitch/dns/amd64/Makefile @@ -0,0 +1,36 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +LIBS = $(DYNLIB1) + +include ../../Makefile.targ + +install: all $(ROOT64DYNLIB) diff --git a/usr/src/lib/nsswitch/dns/common/dns_common.c b/usr/src/lib/nsswitch/dns/common/dns_common.c new file mode 100644 index 0000000000..da766c4d12 --- /dev/null +++ b/usr/src/lib/nsswitch/dns/common/dns_common.c @@ -0,0 +1,167 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * dns_common.c + * + * Copyright (c) 1993,1998 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include "dns_common.h" + +#define DNS_ALIASES 0 +#define DNS_ADDRLIST 1 +#define DNS_MAPDLIST 2 + +static int +dns_netdb_aliases(from_list, to_list, aliaspp, type, count, af_type) + char **from_list, **to_list, **aliaspp; + int type, *count, af_type; +{ + char *fstr; + int cnt = 0; + size_t len; + + *count = 0; + if ((char *)to_list >= *aliaspp) + return (NSS_STR_PARSE_ERANGE); + + for (fstr = from_list[cnt]; fstr != NULL; fstr = from_list[cnt]) { + if (type == DNS_ALIASES) + len = strlen(fstr) + 1; + else + len = (af_type == AF_INET) ? sizeof (struct in_addr) + : sizeof (struct in6_addr); + *aliaspp -= len; + to_list[cnt] = *aliaspp; + if (*aliaspp <= (char *)&to_list[cnt+1]) + return (NSS_STR_PARSE_ERANGE); + if (type == DNS_MAPDLIST) { + struct in6_addr *addr6p = (struct in6_addr *) *aliaspp; + + (void) memset(addr6p, '\0', sizeof (struct in6_addr)); + (void) memcpy(&addr6p->s6_addr[12], fstr, + sizeof (struct in_addr)); + addr6p->s6_addr[10] = 0xffU; + addr6p->s6_addr[11] = 0xffU; + ++cnt; + } else { + (void) memcpy (*aliaspp, fstr, len); + ++cnt; + } + } + to_list[cnt] = NULL; + + *count = cnt; + if (cnt == 0) + return (NSS_STR_PARSE_PARSE); + + return (NSS_STR_PARSE_SUCCESS); +} + + +int +ent2result(he, argp, af_type) + struct hostent *he; + nss_XbyY_args_t *argp; + int af_type; +{ + char *buffer, *limit; + int buflen = argp->buf.buflen; + int ret, count; + size_t len; + struct hostent *host; + struct in_addr *addrp; + struct in6_addr *addrp6; + + limit = argp->buf.buffer + buflen; + host = (struct hostent *) argp->buf.result; + buffer = argp->buf.buffer; + + /* h_addrtype and h_length */ + host->h_addrtype = af_type; + host->h_length = (af_type == AF_INET) ? sizeof (struct in_addr) + : sizeof (struct in6_addr); + + /* h_name */ + len = strlen(he->h_name) + 1; + host->h_name = buffer; + if (host->h_name + len >= limit) + return (NSS_STR_PARSE_ERANGE); + (void) memcpy(host->h_name, he->h_name, len); + buffer += len; + + /* h_addr_list */ + if (af_type == AF_INET) { + addrp = (struct in_addr *) ROUND_DOWN(limit, sizeof (*addrp)); + host->h_addr_list = (char **) + ROUND_UP(buffer, sizeof (char **)); + ret = dns_netdb_aliases(he->h_addr_list, host->h_addr_list, + (char **)&addrp, DNS_ADDRLIST, &count, af_type); + if (ret != NSS_STR_PARSE_SUCCESS) + return (ret); + /* h_aliases */ + host->h_aliases = host->h_addr_list + count + 1; + ret = dns_netdb_aliases(he->h_aliases, host->h_aliases, + (char **)&addrp, DNS_ALIASES, &count, af_type); + } else { + addrp6 = (struct in6_addr *) + ROUND_DOWN(limit, sizeof (*addrp6)); + host->h_addr_list = (char **) + ROUND_UP(buffer, sizeof (char **)); + if (he->h_addrtype == AF_INET && af_type == AF_INET6) { + ret = dns_netdb_aliases(he->h_addr_list, + host->h_addr_list, (char **)&addrp6, + DNS_MAPDLIST, &count, af_type); + } else { + ret = dns_netdb_aliases(he->h_addr_list, + host->h_addr_list, (char **)&addrp6, + DNS_ADDRLIST, &count, af_type); + } + if (ret != NSS_STR_PARSE_SUCCESS) + return (ret); + /* h_aliases */ + host->h_aliases = host->h_addr_list + count + 1; + ret = dns_netdb_aliases(he->h_aliases, host->h_aliases, + (char **)&addrp6, DNS_ALIASES, &count, af_type); + } + if (ret == NSS_STR_PARSE_PARSE) + ret = NSS_STR_PARSE_SUCCESS; + + return (ret); +} + + +nss_backend_t * +_nss_dns_constr(dns_backend_op_t ops[], int n_ops) +{ + dns_backend_ptr_t be; + + if ((be = (dns_backend_ptr_t) malloc(sizeof (*be))) == 0) + return (0); + + be->ops = ops; + be->n_ops = n_ops; + return ((nss_backend_t *) be); +} diff --git a/usr/src/lib/nsswitch/dns/common/dns_common.h b/usr/src/lib/nsswitch/dns/common/dns_common.h new file mode 100644 index 0000000000..7861cbb683 --- /dev/null +++ b/usr/src/lib/nsswitch/dns/common/dns_common.h @@ -0,0 +1,88 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1993, 1998-1999 by Sun Microsystems, Inc. + * All rights reserved. + * + * Common code and structures used by name-service-switch "dns" backends. + */ + +#ifndef _DNS_COMMON_H +#define _DNS_COMMON_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <strings.h> +#include <thread.h> +#include <arpa/nameser.h> +#include <resolv.h> +#include <syslog.h> +#include <nsswitch.h> +#include <nss_dbdefs.h> +#include <stdlib.h> +#include <signal.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct dns_backend *dns_backend_ptr_t; +typedef nss_status_t (*dns_backend_op_t)(dns_backend_ptr_t, void *); + +struct dns_backend { + dns_backend_op_t *ops; + nss_dbop_t n_ops; +}; + +/* multithreaded libresolv2 related functions and variables */ +extern void (*set_no_hosts_fallback)(void); +extern void (*unset_no_hosts_fallback)(void); +extern struct __res_state *(*set_res_retry)(); +extern int (*enable_mt)(); +extern int (*disable_mt)(); +extern int *(*get_h_errno)(); +extern int (*override_retry)(int); +extern void switch_resolver_setup(int *, sigset_t *, int *); +extern void switch_resolver_reset(int, sigset_t, int); +extern mutex_t one_lane; + +extern int _thr_sigsetmask(int, const sigset_t *, sigset_t *); +extern int _mutex_lock(mutex_t *); +extern int _mutex_unlock(mutex_t *); +extern const char *inet_ntop(int, const void *, char *, size_t); + +extern int ent2result(struct hostent *, nss_XbyY_args_t *, int); + +nss_backend_t *_nss_dns_constr(dns_backend_op_t *, int); +extern nss_status_t _herrno2nss(int); + +#ifdef __cplusplus +} +#endif + +#endif /* _DNS_COMMON_H */ diff --git a/usr/src/lib/nsswitch/dns/common/dns_mt.c b/usr/src/lib/nsswitch/dns/common/dns_mt.c new file mode 100644 index 0000000000..7e236c40eb --- /dev/null +++ b/usr/src/lib/nsswitch/dns/common/dns_mt.c @@ -0,0 +1,312 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1993, 1998-2001 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * dns_mt.c + * + * This file contains all the MT related routines for the DNS backend. + */ + +#include "dns_common.h" +#include <dlfcn.h> + +/* + * If the DNS name service switch routines are used in a binary that depends + * on an older libresolv (libresolv.so.1, say), then having nss_dns.so.1 or + * libnss_dns.a depend on a newer libresolv (libresolv.so.2) will cause + * relocation problems. In particular, copy relocation of the _res structure + * (which changes in size from libresolv.so.1 to libresolv.so.2) could + * cause corruption, and result in a number of strange problems, including + * core dumps. Hence, we check if a libresolv is already loaded. + */ + +#pragma init(_nss_dns_init) +static void _nss_dns_init(void); + +extern struct hostent *res_gethostbyname(const char *); +#pragma weak res_gethostbyname + +#define RES_SET_NO_HOSTS_FALLBACK "__res_set_no_hosts_fallback" +extern void __res_set_no_hosts_fallback(void); +#pragma weak __res_set_no_hosts_fallback + +#define RES_UNSET_NO_HOSTS_FALLBACK "__res_unset_no_hosts_fallback" +extern void __res_unset_no_hosts_fallback(void); +#pragma weak __res_unset_no_hosts_fallback + +#define RES_GET_RES "__res_get_res" +extern struct __res_state *__res_get_res(void); +#pragma weak __res_get_res + +#define RES_ENABLE_MT "__res_enable_mt" +extern int __res_enable_mt(void); +#pragma weak __res_enable_mt + +#define RES_DISABLE_MT "__res_disable_mt" +extern int __res_disable_mt(void); +#pragma weak __res_disable_mt + +#define RES_GET_H_ERRNO "__res_get_h_errno" +extern int *__res_get_h_errno(); +#pragma weak __res_get_h_errno + +#define __H_ERRNO "__h_errno" +extern int *__h_errno(void); +#pragma weak __h_errno + +#define RES_OVERRIDE_RETRY "__res_override_retry" +extern int __res_override_retry(int); +#pragma weak __res_override_retry + +static void __fallback_set_no_hosts(void); +static int *__fallback_h_errno(void); +static int __fallback_override_retry(int); +static int __is_mt_safe(void); + +void (*set_no_hosts_fallback)(void) = __fallback_set_no_hosts; +void (*unset_no_hosts_fallback)(void) = __fallback_set_no_hosts; +struct __res_state *(*set_res_retry)() = 0; +int (*enable_mt)() = 0; +int (*disable_mt)() = 0; +int *(*get_h_errno)(void) = 0; +int (*override_retry)(int) = 0; + +/* Usually set from the Makefile */ +#ifndef NSS_DNS_LIBRESOLV +#define NSS_DNS_LIBRESOLV "libresolv.so.2" +#endif + +/* From libresolv */ +extern int h_errno; + +mutex_t one_lane = DEFAULTMUTEX; + +void +_nss_dns_init(void) +{ + struct hostent *(*f_hostent_ptr)(); + void *reslib, (*f_void_ptr)(); + + /* If no libresolv library, then load one */ + if ((f_hostent_ptr = res_gethostbyname) == 0) { + if ((reslib = + dlopen(NSS_DNS_LIBRESOLV, RTLD_LAZY|RTLD_GLOBAL)) != 0) { + /* Turn off /etc/hosts fall back in libresolv */ + if ((f_void_ptr = (void (*)(void))dlsym(reslib, + RES_SET_NO_HOSTS_FALLBACK)) != 0) { + set_no_hosts_fallback = f_void_ptr; + } + if ((f_void_ptr = (void (*)(void))dlsym(reslib, + RES_SET_NO_HOSTS_FALLBACK)) != 0) { + unset_no_hosts_fallback = f_void_ptr; + } + /* Set number of resolver retries */ + if ((override_retry = (int (*)(int))dlsym(reslib, + RES_OVERRIDE_RETRY)) == 0) { + set_res_retry = + (struct __res_state *(*)(void))dlsym(reslib, + RES_GET_RES); + override_retry = __fallback_override_retry; + } + /* + * Select h_errno retrieval function. A BIND 8.2.2 + * libresolv.so.2 will have __h_errno, a BIND 8.1.2 + * one will have __res_get_h_errno, and other + * versions may have nothing at all. + * + * Also try to bind to the relevant MT enable/disable + * functions which are also dependent on the version + * of the BIND libresolv.so.2 being used. + */ + if ((get_h_errno = (int *(*)(void))dlsym(reslib, + __H_ERRNO)) != 0) { + /* BIND 8.2.2 libresolv.so.2 is MT safe. */ + enable_mt = __is_mt_safe; + disable_mt = __is_mt_safe; + } else { + if ((get_h_errno = + (int *(*)(void))dlsym(reslib, + RES_GET_H_ERRNO)) == 0) { + get_h_errno = __fallback_h_errno; + } + /* + * Pre-BIND 8.2.2 was not MT safe. Try to + * bind the MT enable/disable functions. + */ + if ((enable_mt = (int (*)(void))dlsym(reslib, + RES_ENABLE_MT)) != 0 && + (disable_mt = (int (*)(void))dlsym(reslib, + RES_DISABLE_MT)) == 0) { + enable_mt = 0; + } + } + } + } else { + /* Libresolv already loaded */ + if ((f_void_ptr = __res_set_no_hosts_fallback) != 0) { + set_no_hosts_fallback = f_void_ptr; + } + if ((f_void_ptr = __res_unset_no_hosts_fallback) != 0) { + unset_no_hosts_fallback = f_void_ptr; + } + if ((override_retry = __res_override_retry) == 0) { + set_res_retry = __res_get_res; + override_retry = __fallback_override_retry; + } + if ((get_h_errno = __h_errno) == 0 && + (get_h_errno = __res_get_h_errno) == 0) { + get_h_errno = __fallback_h_errno; + } + if (get_h_errno == __h_errno) { + enable_mt = __is_mt_safe; + disable_mt = __is_mt_safe; + } else { + if ((enable_mt = __res_enable_mt) != 0 && + (disable_mt = __res_disable_mt) == 0) { + enable_mt = 0; + } + } + } +} + + +/* + * + * Integration of BIND 8.1.2 introduced two new Sun private functions, + * __res_enable_mt() and __res_disable_mt(), that enabled and disabled + * MT mode per-thread. These functions are in the private libresolv.so.2 + * interface, and intended for use by nss_dns.so.1. + * + * BIND 8.2.2 removed the need for those two functions. As similar + * functionality was provided in BIND further up the stack. However the + * functions remain to satisfy any application that directly called upon + * them. Only, __res_enable_mt() was modified to return failure. + * Indicated by a non-zero return value. So that those unconventional + * applications would not then presume that res_send() and friends are + * MT-safe, when in fact they are not. + * + * To prevent nss_dns from locking inappropriately __is_mt_safe() is + * called in place of __res_enable_mt() and __res_disable_mt() if BIND + * 8.2.2 libresolv.so.2 being used. __is_mt_safe() returns success + * indicated by a return code of zero. Signifying that no locking is + * necessary. + * + * MT applications making calls to gethostby*_r() or getipnodeby*() + * linked to libresolv.so.1 or linked statically with pre-BIND 8.2.2 + * libresolv.a, doubtful as we don't ship a static version, would require + * locking within the nsswitch back-end. Hence the mechanism can not + * simply be removed. + * + */ +static int +__is_mt_safe(void) { + return (0); +} + + +/* + * Return pointer to the global h_errno variable + */ +static int * +__fallback_h_errno(void) { + return (&h_errno); +} + + +/* + * This function is called when the resolver library doesn't provide its + * own function to establish an override retry. If we can get a pointer + * to the per-thread _res (i.e., set_res_retry != 0), we set the retries + * directly, and return the previous number of retries. Otherwise, there's + * nothing to do. + */ +static int +__fallback_override_retry(int retry) { + struct __res_state *res; + int old_retry = 0; + + if (set_res_retry != 0) { + res = set_res_retry(); + old_retry = res->retry; + res->retry = retry; + } + return (old_retry); +} + + +static void +__fallback_set_no_hosts(void) { +} + + +/* + * Common code to enable/disable MT mode, set/unset no-/etc/hosts fallback, + * and to set the number of retries. + */ +void +switch_resolver_setup(int *mt_disabled, sigset_t *oldmask, int *old_retry) { + + /* + * Try to enable MT mode. If that isn't possible, mask signals, + * and mutex_lock. + */ + *mt_disabled = 1; + if (enable_mt == 0 || (*mt_disabled = (*enable_mt)()) != 0) { + sigset_t newmask; + (void) sigfillset(&newmask); + _thr_sigsetmask(SIG_SETMASK, &newmask, oldmask); + _mutex_lock(&one_lane); + } + + /* + * Disable any fallback to /etc/hosts (or /etc/inet/ipnodes, when + * libresolv knows about that file). + */ + (*set_no_hosts_fallback)(); + + /* + * The NS switch wants to handle retries on its own. + */ + *old_retry = (*override_retry)(1); +} + + +void +switch_resolver_reset(int mt_disabled, sigset_t oldmask, int old_retry) { + + if (mt_disabled) { + _mutex_unlock(&one_lane); + _thr_sigsetmask(SIG_SETMASK, &oldmask, NULL); + } else { + (void) (*disable_mt)(); + } + + (*unset_no_hosts_fallback)(); + + (void) (*override_retry)(old_retry); +} diff --git a/usr/src/lib/nsswitch/dns/common/gethostent.c b/usr/src/lib/nsswitch/dns/common/gethostent.c new file mode 100644 index 0000000000..38c8a44a3a --- /dev/null +++ b/usr/src/lib/nsswitch/dns/common/gethostent.c @@ -0,0 +1,416 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1993, 1998-2000 by Sun Microsystems, Inc. + * All rights reserved. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * gethostent.c + * + * In order to avoid duplicating libresolv code here, and since libresolv.so.2 + * provides res_-equivalents of the getXbyY and {set,get}Xent, lets call + * re_gethostbyaddr() and so on from this file. Among other things, this + * should help us avoid problems like the one described in bug 1264386, + * where the internal getanswer() acquired new functionality in BIND 4.9.3, + * but the local copy of getanswer() in this file wasn't updated, so that new + * functionality wasn't available to the name service switch. + */ + +#define gethostbyaddr res_gethostbyaddr +#define gethostbyname res_gethostbyname +#define gethostbyname2 res_gethostbyname2 +#define sethostent res_sethostent +#define endhostent res_endhostent + +#include "dns_common.h" + +extern char *inet_ntoa(struct in_addr in); + +struct hostent *_gethostbyname(int *h_errnop, const char *name); +static struct hostent *_gethostbyaddr(int *h_errnop, const char *addr, + int len, int type); +struct hostent *_nss_dns_gethostbyname2(int *h_errnop, const char *name); + +#pragma weak res_gethostbyname +#pragma weak res_gethostbyname2 +#pragma weak res_gethostbyaddr +#pragma weak res_sethostent +#pragma weak res_endhostent + +nss_backend_t *_nss_dns_constr(dns_backend_op_t ops[], int n_ops); +nss_status_t __nss_dns_getbyaddr(dns_backend_ptr_t, void *); + +typedef union { + long al; + char ac; +} align; + +/* + * Internet Name Domain Server (DNS) only implementation. + */ +static struct hostent * +_gethostbyaddr(int *h_errnop, const char *addr, int len, int type) +{ + struct hostent *hp; + + hp = gethostbyaddr(addr, len, type); + *h_errnop = *get_h_errno(); + return (hp); +} + +struct hostent * +_nss_dns_gethostbyname2(int *h_errnop, const char *name) +{ + struct hostent *hp; + + hp = gethostbyname2(name, AF_INET6); + *h_errnop = *get_h_errno(); + return (hp); +} + +struct hostent * +_gethostbyname(int *h_errnop, const char *name) +{ + struct hostent *hp; + + hp = gethostbyname(name); + *h_errnop = *get_h_errno(); + return (hp); +} + +static void +_sethostent(errp, stayopen) + nss_status_t *errp; + int stayopen; +{ + int ret; + + ret = sethostent(stayopen); + if (ret == 0) + *errp = NSS_SUCCESS; + else + *errp = NSS_UNAVAIL; +} + +static void +_endhostent(errp) + nss_status_t *errp; +{ + int ret; + + ret = endhostent(); + if (ret == 0) + *errp = NSS_SUCCESS; + else + *errp = NSS_UNAVAIL; +} + + +/*ARGSUSED*/ +static nss_status_t +getbyname(be, a) + dns_backend_ptr_t be; + void *a; +{ + struct hostent *he; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + int ret, mt_disabled; + int old_retry; + sigset_t oldmask; + + switch_resolver_setup(&mt_disabled, &oldmask, &old_retry); + + he = _gethostbyname(&argp->h_errno, argp->key.name); + if (he != NULL) { + ret = ent2result(he, a, AF_INET); + if (ret == NSS_STR_PARSE_SUCCESS) { + argp->returnval = argp->buf.result; + } else { + argp->h_errno = HOST_NOT_FOUND; + if (ret == NSS_STR_PARSE_ERANGE) { + argp->erange = 1; + } + } + } + + switch_resolver_reset(mt_disabled, oldmask, old_retry); + + return (_herrno2nss(argp->h_errno)); +} + + + +/*ARGSUSED*/ +static nss_status_t +getbyaddr(be, a) + dns_backend_ptr_t be; + void *a; +{ + return (__nss_dns_getbyaddr(be, a)); +} + + +/* + * Exposing a DNS backend specific interface so that it doesn't conflict + * with other getbyaddr() routines from other switch backends. + */ +nss_status_t +__nss_dns_getbyaddr(be, a) + dns_backend_ptr_t be; + void *a; +{ + size_t n; + struct hostent *he, *he2; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + int ret, save_h_errno, mt_disabled; + char **ans, hbuf[MAXHOSTNAMELEN]; + char dst[INET6_ADDRSTRLEN]; + struct in_addr unmapv4; + sigset_t oldmask; + int af, addrlen; + void *addrp; + int old_retry; + + switch_resolver_setup(&mt_disabled, &oldmask, &old_retry); + + if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)argp->key.hostaddr.addr)) { + addrp = &unmapv4; + addrlen = sizeof (unmapv4); + af = AF_INET; + memcpy(addrp, &argp->key.hostaddr.addr[12], addrlen); + } else { + addrp = (void *)argp->key.hostaddr.addr; + addrlen = argp->key.hostaddr.len; + af = argp->key.hostaddr.type; + } + he = _gethostbyaddr(&argp->h_errno, addrp, addrlen, af); + + if (he != NULL) { + if (strlen(he->h_name) >= MAXHOSTNAMELEN) + ret = NSS_STR_PARSE_ERANGE; + else { + /* save a copy of the (alleged) hostname */ + (void) strcpy(hbuf, he->h_name); + n = strlen(hbuf); + if (n < MAXHOSTNAMELEN-1 && hbuf[n-1] != '.') { + (void) strcat(hbuf, "."); + } + ret = ent2result(he, a, argp->key.hostaddr.type); + save_h_errno = argp->h_errno; + } + if (ret == NSS_STR_PARSE_SUCCESS) { + /* + * check to make sure by doing a forward query + * We use _gethostbyname() to avoid the stack, and + * then we throw the result from argp->h_errno away, + * becase we don't care. And besides you want the + * return code from _gethostbyaddr() anyway. + */ + + if (af == AF_INET) + he2 = _gethostbyname(&argp->h_errno, hbuf); + else + he2 = _nss_dns_gethostbyname2(&argp->h_errno, + hbuf); + if (he2 != (struct hostent *)NULL) { + + /* until we prove name and addr match */ + argp->h_errno = HOST_NOT_FOUND; + for (ans = he2->h_addr_list; *ans; ans++) + if (memcmp(*ans, addrp, addrlen) == + 0) { + argp->h_errno = save_h_errno; + argp->returnval = argp->buf.result; + break; + } + } else { + + /* + * What to do if _gethostbyname() fails ??? + * We assume they are doing something stupid + * like registering addresses but not names + * (some people actually think that provides + * some "security", through obscurity). So for + * these poor lost souls, because we can't + * PROVE spoofing and because we did try (and + * we don't want a bug filed on this), we let + * this go. And return the name from byaddr. + */ + argp->h_errno = save_h_errno; + argp->returnval = argp->buf.result; + } + /* we've been spoofed, make sure to log it. */ + if (argp->h_errno == HOST_NOT_FOUND) { + if (argp->key.hostaddr.type == AF_INET) + syslog(LOG_NOTICE, "gethostbyaddr: %s != %s", + hbuf, inet_ntoa(*(struct in_addr *)argp->key.hostaddr.addr)); + else + syslog(LOG_NOTICE, "gethostbyaddr: %s != %s", + hbuf, inet_ntop(AF_INET6, (void *) argp->key.hostaddr.addr, + dst, sizeof (dst))); + } + } else { + argp->h_errno = HOST_NOT_FOUND; + if (ret == NSS_STR_PARSE_ERANGE) { + argp->erange = 1; + } + } + } + + switch_resolver_reset(mt_disabled, oldmask, old_retry); + + return (_herrno2nss(argp->h_errno)); +} + + +/*ARGSUSED*/ +static nss_status_t +_nss_dns_getent(be, args) + dns_backend_ptr_t be; + void *args; +{ + return (NSS_UNAVAIL); +} + + +/*ARGSUSED*/ +static nss_status_t +_nss_dns_setent(be, dummy) + dns_backend_ptr_t be; + void *dummy; +{ + nss_status_t errp; + + sigset_t oldmask, newmask; + int mt_disabled = 1; + + /* + * Try to enable MT; if not, we have to single-thread libresolv + * access + */ + if (enable_mt == 0 || (mt_disabled = (*enable_mt)()) != 0) { + (void) sigfillset(&newmask); + _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); + _mutex_lock(&one_lane); + } + + _sethostent(&errp, 1); + + if (mt_disabled) { + _mutex_unlock(&one_lane); + _thr_sigsetmask(SIG_SETMASK, &oldmask, NULL); + } else { + (void) (*disable_mt)(); + } + + return (errp); +} + + +/*ARGSUSED*/ +static nss_status_t +_nss_dns_endent(be, dummy) + dns_backend_ptr_t be; + void *dummy; +{ + nss_status_t errp; + + sigset_t oldmask, newmask; + int mt_disabled = 1; + + /* + * Try to enable MT; if not, we have to single-thread libresolv + * access + */ + if (enable_mt == 0 || (mt_disabled = (*enable_mt)()) != 0) { + (void) sigfillset(&newmask); + _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); + _mutex_lock(&one_lane); + } + + _endhostent(&errp); + + if (mt_disabled) { + _mutex_unlock(&one_lane); + _thr_sigsetmask(SIG_SETMASK, &oldmask, NULL); + } else { + (void) (*disable_mt)(); + } + + return (errp); +} + + +/*ARGSUSED*/ +static nss_status_t +_nss_dns_destr(be, dummy) + dns_backend_ptr_t be; + void *dummy; +{ + nss_status_t errp; + + if (be != 0) { + /* === Should change to invoke ops[ENDENT] ? */ + sigset_t oldmask, newmask; + int mt_disabled = 1; + + if (enable_mt == 0 || (mt_disabled = (*enable_mt)()) != 0) { + (void) sigfillset(&newmask); + _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); + _mutex_lock(&one_lane); + } + + _endhostent(&errp); + + if (mt_disabled) { + _mutex_unlock(&one_lane); + _thr_sigsetmask(SIG_SETMASK, &oldmask, NULL); + } else { + (void) (*disable_mt)(); + } + + free(be); + } + return (NSS_SUCCESS); /* In case anyone is dumb enough to check */ +} + + +static dns_backend_op_t host_ops[] = { + _nss_dns_destr, + _nss_dns_endent, + _nss_dns_setent, + _nss_dns_getent, + getbyname, + getbyaddr, +}; + +/*ARGSUSED*/ +nss_backend_t * +_nss_dns_hosts_constr(dummy1, dummy2, dummy3) + const char *dummy1, *dummy2, *dummy3; +{ + return (_nss_dns_constr(host_ops, + sizeof (host_ops) / sizeof (host_ops[0]))); +} diff --git a/usr/src/lib/nsswitch/dns/common/gethostent6.c b/usr/src/lib/nsswitch/dns/common/gethostent6.c new file mode 100644 index 0000000000..e92ce6a356 --- /dev/null +++ b/usr/src/lib/nsswitch/dns/common/gethostent6.c @@ -0,0 +1,534 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 1993-2000, 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * + * gethostent6.c + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * This is the DNS backend for IPv6 addresses. + * getbyname() is a local routine, but getbyaddr() actually shares the + * same codes as the one in gethostent.c. + */ + +#define endhostent res_endhostent + +#include <malloc.h> +#include <stddef.h> +#include <string.h> +#include "dns_common.h" + +/* + * If the DNS name service switch routines are used in a binary that depends + * on an older libresolv (libresolv.so.1, say), then having nss_dns.so.1 or + * libnss_dns.a depend on a newer libresolv (libresolv.so.2) will cause + * relocation problems. In particular, copy relocation of the _res structure + * (which changes in size from libresolv.so.1 to libresolv.so.2) could + * cause corruption, and result in a number of strange problems, including + * core dumps. Hence, we check if a libresolv is already loaded. + */ + + +#pragma weak res_endhostent + +extern struct hostent *_gethostbyname(int *, const char *); +extern struct hostent *_nss_dns_gethostbyname2(int *, const char *); + +typedef union { + long al; + char ac; +} align; + + +static void +_endhostent(errp) + nss_status_t *errp; +{ + int ret; + + ret = endhostent(); + if (ret == 0) + *errp = NSS_SUCCESS; + else + *errp = NSS_UNAVAIL; +} + + +#ifdef RNDUP +#undef RNDUP +#endif +#define RNDUP(x) ((1 + (((x)-1)/sizeof (void *))) * sizeof (void *)) + +#ifdef PTROFF +#undef PTROFF +#endif +#define PTROFF(p, o) (((o) == 0) ? 0 : (void *)((char *)(p) + (o))) + + +/* + * Make a copy of h->h_name. + */ +static char * +cloneName(struct hostent *h, int *outerr) { + + char *name; + int len; + int error, *errp; + + if (outerr) + errp = outerr; + else + errp = &error; + + if (h == 0 || h->h_name == 0) { + *errp = 0; + return (0); + } + + len = strlen(h->h_name); + + if ((name = malloc(len+1)) == 0) { + *errp = 1; + return (0); + } + + memcpy(name, h->h_name, len+1); + + *errp = 0; + return (name); +} + + +/* + * Copy the h->h_addr_list[] array to a new array, and append the + * moreAddrs[] list. If h->h_addr_list[] contains IPv4 addresses, + * convert them to v4 mapped IPv6 addresses. + * + * Note: The pointers to the addresses in the moreAddrs[] array are copied, + * but not the IP addresses themselves. + */ +struct in6_addr ** +cloneAddrList(struct hostent *h, struct in6_addr **moreAddrs, int *outerr) { + + struct in6_addr **addrArray, *addrList; + int domap, addrlen, i, j, addrCount, moreAddrCount = 0; + + int error, *errp; + + if (outerr) + errp = outerr; + else + errp = &error; + + if (h == 0 || h->h_addr_list == 0) { + *errp = 0; + return (0); + } + + /* Should we map v4 to IPv6 ? */ + domap = (h->h_length == sizeof (struct in_addr)) && + (h->h_addrtype == AF_INET); + + /* If mapping, make sure we allocate enough memory for addresses */ + addrlen = h->h_length; + if (domap && addrlen < sizeof (struct in6_addr)) + addrlen = sizeof (struct in6_addr); + + for (addrCount = 0; h->h_addr_list[addrCount]; addrCount++); + + if (moreAddrs != 0) { + for (moreAddrCount = 0; moreAddrs[moreAddrCount]; + moreAddrCount++); + } + + if ((addrArray = malloc((addrCount+moreAddrCount+1)*sizeof (addrList) + + addrCount*addrlen)) == 0) { + *errp = 1; + return (0); + } + + addrList = PTROFF(addrArray, (addrCount+moreAddrCount+1) * + sizeof (addrList)); + + for (i = 0; i < addrCount; i++) { + addrArray[i] = addrList; + if (domap) { + IN6_INADDR_TO_V4MAPPED( + (struct in_addr *)h->h_addr_list[i], addrArray[i]); + } else { + memcpy(addrArray[i], h->h_addr_list[i], addrlen); + } + addrList = PTROFF(addrList, addrlen); + } + + for (j = 0; j < moreAddrCount; j++, i++) { + addrArray[i] = moreAddrs[j]; + } + + /* Last pointer should be NULL */ + addrArray[i] = 0; + + *errp = 0; + return (addrArray); +} + + +/* + * Create a new alias array that is is a copy of h->h_aliases[] plus + * the aliases in mergeAliases[] which aren't duplicates of any alias + * in h->h_aliases[]. + * + * Note 1: Only the string pointers (NOT the strings) in the mergeAliases[] + * array are copied. + * + * Note 2: The duplicate aliases in mergeAliases[] are replaced by NULL + * pointers. + */ +static char ** +cloneAliasList(struct hostent *h, char **mergeAliases, int *outerr) { + + char **aliasArray, *aliasList; + int i, j, k, aliasCount, mergeAliasCount = 0, realMac = 0; + int stringSize = 0; + int error, *errp; + + if (outerr) + errp = outerr; + else + errp = &error; + + + if (h == 0 || h->h_aliases == 0) { + *errp = 0; + return (0); + } + + for (aliasCount = 0; h->h_aliases[aliasCount]; aliasCount++) { + stringSize += RNDUP(strlen(h->h_aliases[aliasCount])+1); + } + + if (mergeAliases != 0) { + for (; mergeAliases[mergeAliasCount]; mergeAliasCount++) { + int countThis = 1; + /* Skip duplicates */ + for (j = 0; j < aliasCount; j++) { + if (strcmp(mergeAliases[mergeAliasCount], + h->h_aliases[j]) == 0) { + countThis = 0; + break; + } + } + if (countThis) + realMac++; + else + mergeAliases[mergeAliasCount] = 0; + } + } + + if ((aliasArray = malloc((aliasCount+realMac+1)*sizeof (char **)+ + stringSize)) == 0) { + *errp = 1; + return (0); + } + + aliasList = PTROFF(aliasArray, + (aliasCount+realMac+1)*sizeof (char **)); + for (i = 0; i < aliasCount; i++) { + int len = strlen(h->h_aliases[i]); + aliasArray[i] = aliasList; + memcpy(aliasArray[i], h->h_aliases[i], len+1); + aliasList = PTROFF(aliasList, RNDUP(len+1)); + } + + for (j = 0; j < mergeAliasCount; j++) { + if (mergeAliases[j] != 0) { + aliasArray[i++] = mergeAliases[j]; + } + } + + aliasArray[i] = 0; + + *errp = 0; + return (aliasArray); +} + + +static nss_status_t +getbyname(be, a) + dns_backend_ptr_t be; + void *a; +{ + struct hostent *he = NULL; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + int ret, mt_disabled; + sigset_t oldmask; + int converr = 0, gotv6 = 0; + struct hostent v6he; + char *v6Name = 0; + struct in6_addr **v6Addrs = 0, **mergeAddrs = 0; + char **v6Aliases = 0, **mergeAliases = 0; + int v6_h_errno; + int old_retry; + int af = argp->key.ipnode.af_family; + int flags = argp->key.ipnode.flags; + + switch_resolver_setup(&mt_disabled, &oldmask, &old_retry); + + /* Now get the AAAA records */ + if (af == AF_INET6) + he = _nss_dns_gethostbyname2(&argp->h_errno, + argp->key.ipnode.name); + if (he != NULL) { + /* + * pointer in "he" is part of a static pthread key in libresolv + * It should be treated as read only. + * So clone a copy first. + */ + v6Name = cloneName(he, &converr); + if (converr) { + argp->h_errno = HOST_NOT_FOUND; + argp->erange = 1; + switch_resolver_reset(mt_disabled, oldmask, old_retry); + return (_herrno2nss(argp->h_errno)); + } + v6Addrs = cloneAddrList(he, 0, &converr); + if (converr) { + if (v6Name != 0) + free(v6Name); + argp->h_errno = HOST_NOT_FOUND; + argp->erange = 1; + switch_resolver_reset(mt_disabled, oldmask, old_retry); + return (_herrno2nss(argp->h_errno)); + } + v6Aliases = cloneAliasList(he, 0, &converr); + if (converr) { + if (v6Name != 0) + free(v6Name); + if (v6Addrs != 0) + free(v6Addrs); + argp->h_errno = HOST_NOT_FOUND; + argp->erange = 1; + switch_resolver_reset(mt_disabled, oldmask, old_retry); + return (_herrno2nss(argp->h_errno)); + } + v6_h_errno = argp->h_errno; + gotv6 = 1; + } + + /* + * The conditions to search "A" records: + * 1. af is AF_INET + * 2. if af is AF_INET6 + * then flags are either + * 1) (AI_ALL | AI_V4MAPPED) or + * 2) AI_V4MAPPED and he == NULL + * (No V6 addresses found or no search for V6 at all) + */ + + /* Get the A records, and store the information */ + if ((af == AF_INET) || + ((af == AF_INET6) && + ((flags & (AI_ALL | AI_V4MAPPED)) || + ((flags & AI_V4MAPPED) && he == NULL)))) + he = _gethostbyname(&argp->h_errno, argp->key.ipnode.name); + else + he = NULL; + + /* Merge the results */ + if (he != NULL) { + mergeAddrs = cloneAddrList(he, v6Addrs, &converr); + if (converr) { + if (v6Name != 0) + free(v6Name); + if (v6Addrs != 0) + free(v6Addrs); + if (v6Aliases != 0) + free(v6Aliases); + argp->h_errno = HOST_NOT_FOUND; + argp->erange = 1; + switch_resolver_reset(mt_disabled, oldmask, + old_retry); + return (_herrno2nss(argp->h_errno)); + } + he->h_addr_list = (char **)mergeAddrs; + + mergeAliases = cloneAliasList(he, v6Aliases, &converr); + if (converr) { + if (v6Name != 0) + free(v6Name); + if (v6Addrs != 0) + free(v6Addrs); + if (v6Aliases != 0) + free(v6Aliases); + if (mergeAddrs != 0) + free(mergeAddrs); + argp->h_errno = HOST_NOT_FOUND; + argp->erange = 1; + switch_resolver_reset(mt_disabled, oldmask, + old_retry); + return (_herrno2nss(argp->h_errno)); + } + he->h_aliases = mergeAliases; + + /* reset h_length, h_addrtype */ + he->h_length = sizeof (struct in6_addr); + he->h_addrtype = AF_INET6; + + } else if (gotv6) { + v6he.h_name = v6Name; + v6he.h_length = sizeof (struct in6_addr); + v6he.h_addrtype = AF_INET6; + v6he.h_addr_list = (char **)v6Addrs; + v6he.h_aliases = v6Aliases; + he = &v6he; + argp->h_errno = v6_h_errno; + } + + if (he != 0) { + ret = ent2result(he, a, AF_INET6); + if (ret == NSS_STR_PARSE_SUCCESS) { + argp->returnval = argp->buf.result; + } else { + argp->h_errno = HOST_NOT_FOUND; + if (ret == NSS_STR_PARSE_ERANGE) { + argp->erange = 1; + } + } + } + + if (v6Name != 0) + free(v6Name); + if (v6Addrs != 0) + free(v6Addrs); + if (v6Aliases != 0) + free(v6Aliases); + if (mergeAddrs != 0) + free(mergeAddrs); + if (mergeAliases != 0) + free(mergeAliases); + + switch_resolver_reset(mt_disabled, oldmask, old_retry); + + return (_herrno2nss(argp->h_errno)); +} + + +extern nss_status_t __nss_dns_getbyaddr(dns_backend_ptr_t, void *); + +static nss_status_t +getbyaddr(be, a) + dns_backend_ptr_t be; + void *a; +{ + /* uses the same getbyaddr from IPv4 */ + return (__nss_dns_getbyaddr(be, a)); +} + + +/*ARGSUSED*/ +static nss_status_t +_nss_dns_getent(be, args) + dns_backend_ptr_t be; + void *args; +{ + return (NSS_UNAVAIL); +} + + +/*ARGSUSED*/ +static nss_status_t +_nss_dns_setent(be, dummy) + dns_backend_ptr_t be; + void *dummy; +{ + /* XXXX not implemented at this point */ + return (NSS_UNAVAIL); +} + + +/*ARGSUSED*/ +static nss_status_t +_nss_dns_endent(be, dummy) + dns_backend_ptr_t be; + void *dummy; +{ + /* XXXX not implemented at this point */ + return (NSS_UNAVAIL); +} + + +/*ARGSUSED*/ +static nss_status_t +_nss_dns_destr(be, dummy) + dns_backend_ptr_t be; + void *dummy; +{ + nss_status_t errp; + + if (be != 0) { + /* === Should change to invoke ops[ENDENT] ? */ + sigset_t oldmask, newmask; + int mt_disabled = 1; + + if (enable_mt == 0 || (mt_disabled = (*enable_mt)()) != 0) { + (void) sigfillset(&newmask); + _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); + _mutex_lock(&one_lane); + } + + _endhostent(&errp); + + if (mt_disabled) { + _mutex_unlock(&one_lane); + _thr_sigsetmask(SIG_SETMASK, &oldmask, NULL); + } else { + (void) (*disable_mt)(); + } + + free(be); + } + return (NSS_SUCCESS); /* In case anyone is dumb enough to check */ +} + + + +static dns_backend_op_t ipnodes_ops[] = { + _nss_dns_destr, + _nss_dns_endent, + _nss_dns_setent, + _nss_dns_getent, + getbyname, + getbyaddr, +}; + +/*ARGSUSED*/ +nss_backend_t * +_nss_dns_ipnodes_constr(dummy1, dummy2, dummy3) + const char *dummy1, *dummy2, *dummy3; +{ + return (_nss_dns_constr(ipnodes_ops, + sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0]))); +} diff --git a/usr/src/lib/nsswitch/dns/common/mapfile-vers b/usr/src/lib/nsswitch/dns/common/mapfile-vers new file mode 100644 index 0000000000..6e44ffe568 --- /dev/null +++ b/usr/src/lib/nsswitch/dns/common/mapfile-vers @@ -0,0 +1,46 @@ +# +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Generic interface definition for usr/src/lib/nsswitch/dns. +# +# For information regarding the establishment of versioned definitions see: +# The Linker and Libraries Manual (version 2.5 or greater) +# This is part of the Developers Guide in the Answerbook. Specifically refer +# to Chapter 2 under section "Defining Additional Symbols" through section +# "Reducing Symbol Scope", and Chapter 5 "Versioning". +# +# For specific OSNET rules for the modification (evolution) of these version +# definitions see: +# Policy for Shared Library Version Names and Interface Definitions + + +SUNWprivate_1.1 { + global: + _nss_dns_hosts_constr; + _nss_dns_ipnodes_constr; + local: + *; +}; diff --git a/usr/src/lib/nsswitch/dns/i386/Makefile b/usr/src/lib/nsswitch/dns/i386/Makefile new file mode 100644 index 0000000000..164288fc1d --- /dev/null +++ b/usr/src/lib/nsswitch/dns/i386/Makefile @@ -0,0 +1,36 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 1993,2001-2003 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# lib/nsswitch/dns/i386/Makefile + +include ../Makefile.com + +LIBS = $(DYNLIB1) + +include ../../Makefile.targ + +install: all $(ROOTLIBS) diff --git a/usr/src/lib/nsswitch/dns/sparc/Makefile b/usr/src/lib/nsswitch/dns/sparc/Makefile new file mode 100644 index 0000000000..9ea99483e7 --- /dev/null +++ b/usr/src/lib/nsswitch/dns/sparc/Makefile @@ -0,0 +1,36 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 1993,2001-2003 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# +# lib/nsswitch/dns/sparc/Makefile + +include ../Makefile.com + +LIBS = $(DYNLIB1) + +include ../../Makefile.targ + +install: all $(ROOTLIBS) diff --git a/usr/src/lib/nsswitch/dns/sparcv9/Makefile b/usr/src/lib/nsswitch/dns/sparcv9/Makefile new file mode 100644 index 0000000000..dbcedcf28e --- /dev/null +++ b/usr/src/lib/nsswitch/dns/sparcv9/Makefile @@ -0,0 +1,37 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright (c) 1993,2001 by Sun Microsystems, Inc. +# All rights reserved. +# +# lib/nsswitch/dns/sparcv9/Makefile + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +LIBS = $(DYNLIB1) + +include ../../Makefile.targ + +install: all $(ROOT64DYNLIB) |
