summaryrefslogtreecommitdiff
path: root/usr/src/lib/nsswitch/dns/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/nsswitch/dns/common')
-rw-r--r--usr/src/lib/nsswitch/dns/common/dns_common.c389
-rw-r--r--usr/src/lib/nsswitch/dns/common/dns_common.h20
-rw-r--r--usr/src/lib/nsswitch/dns/common/dns_mt.c12
-rw-r--r--usr/src/lib/nsswitch/dns/common/gethostent.c76
-rw-r--r--usr/src/lib/nsswitch/dns/common/gethostent6.c63
-rw-r--r--usr/src/lib/nsswitch/dns/common/mapfile-vers9
6 files changed, 511 insertions, 58 deletions
diff --git a/usr/src/lib/nsswitch/dns/common/dns_common.c b/usr/src/lib/nsswitch/dns/common/dns_common.c
index da766c4d12..0ed02f1d23 100644
--- a/usr/src/lib/nsswitch/dns/common/dns_common.c
+++ b/usr/src/lib/nsswitch/dns/common/dns_common.c
@@ -2,9 +2,8 @@
* 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.
+ * Common Development and Distribution License (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.
@@ -20,16 +19,27 @@
* CDDL HEADER END
*/
/*
- * dns_common.c
- *
- * Copyright (c) 1993,1998 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * dns_common.c
+ */
#include "dns_common.h"
+#pragma weak dn_expand
+#pragma weak res_ninit
+#pragma weak res_nsearch
+#pragma weak res_nclose
+#pragma weak ns_get16
+#pragma weak ns_get32
+#pragma weak __ns_get16
+#pragma weak __ns_get32
+
#define DNS_ALIASES 0
#define DNS_ADDRLIST 1
#define DNS_MAPDLIST 2
@@ -58,7 +68,8 @@ dns_netdb_aliases(from_list, to_list, aliaspp, type, count, af_type)
if (*aliaspp <= (char *)&to_list[cnt+1])
return (NSS_STR_PARSE_ERANGE);
if (type == DNS_MAPDLIST) {
- struct in6_addr *addr6p = (struct in6_addr *) *aliaspp;
+ /* LINTED: E_BAD_PTR_CAST_ALIGN */
+ struct in6_addr *addr6p = (struct in6_addr *)*aliaspp;
(void) memset(addr6p, '\0', sizeof (struct in6_addr));
(void) memcpy(&addr6p->s6_addr[12], fstr,
@@ -96,7 +107,7 @@ ent2result(he, argp, af_type)
struct in6_addr *addrp6;
limit = argp->buf.buffer + buflen;
- host = (struct hostent *) argp->buf.result;
+ host = (struct hostent *)argp->buf.result;
buffer = argp->buf.buffer;
/* h_addrtype and h_length */
@@ -114,7 +125,7 @@ ent2result(he, argp, af_type)
/* h_addr_list */
if (af_type == AF_INET) {
- addrp = (struct in_addr *) ROUND_DOWN(limit, sizeof (*addrp));
+ 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,
@@ -152,16 +163,368 @@ ent2result(he, argp, af_type)
return (ret);
}
+/*
+ * Convert the hostent structure into string in the following
+ * format:
+ *
+ * IP-address official-host-name nicknames ...
+ *
+ * If more than one IP-addresses matches the official-host-name,
+ * the above line will be followed by:
+ * IP-address-1 official-host-name
+ * IP-address-2 official-host-name
+ * ...
+ *
+ * This is so that the str2hostent function in libnsl
+ * can convert the string back to the original hostent
+ * data.
+ */
+int
+ent2str(
+ struct hostent *hp,
+ nss_XbyY_args_t *ap,
+ int af_type)
+{
+ char **p;
+ char obuf[INET6_ADDRSTRLEN];
+ void *addr;
+ struct in_addr in4;
+ int af;
+ int n;
+ const char *res;
+ char **q;
+ int l = ap->buf.buflen;
+ char *s = ap->buf.buffer;
+
+ /*
+ * for "hosts" lookup, we only want address type of
+ * AF_INET. For "ipnodes", we can have both AF_INET
+ * and AF_INET6.
+ */
+ if (af_type == AF_INET && hp->h_addrtype != AF_INET)
+ return (NSS_STR_PARSE_PARSE);
+
+ for (p = hp->h_addr_list; *p != 0; p++) {
+
+ if (p != hp->h_addr_list) {
+ *s = '\n';
+ s++;
+ l--;
+ }
+
+ if (hp->h_addrtype == AF_INET6) {
+ /* LINTED: E_BAD_PTR_CAST_ALIGN */
+ if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)*p)) {
+ /* LINTED: E_BAD_PTR_CAST_ALIGN */
+ IN6_V4MAPPED_TO_INADDR((struct in6_addr *)*p,
+ &in4);
+ af = AF_INET;
+ addr = &in4;
+ } else {
+ af = AF_INET6;
+ addr = *p;
+ }
+ } else {
+ af = AF_INET;
+ addr = *p;
+ }
+ res = inet_ntop(af, addr, obuf, sizeof (obuf));
+ if (res == NULL)
+ return (NSS_STR_PARSE_PARSE);
+
+ if ((n = snprintf(s, l, "%s %s", res, hp->h_name)) >= l)
+ return (NSS_STR_PARSE_ERANGE);
+ l -= n;
+ s += n;
+ if (p == hp->h_addr_list) {
+ for (q = hp->h_aliases; q && *q; q++) {
+ if ((n = snprintf(s, l, " %s", *q)) >= l)
+ return (NSS_STR_PARSE_ERANGE);
+ l -= n;
+ s += n;
+ }
+ }
+ }
+
+ ap->returnlen = s - ap->buf.buffer;
+ return (NSS_STR_PARSE_SUCCESS);
+}
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)
+ 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);
+ return ((nss_backend_t *)be);
+}
+
+
+/*
+ * nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode)
+ * nss2 get hosts/ipnodes with ttl backend DNS search engine.
+ *
+ * This API is given a pointer to a packed buffer, and the buffer size
+ * It's job is to perform the appropriate res_nsearch, extract the
+ * results and build a unmarshalled hosts/ipnodes result buffer.
+ * Additionally in the extended results a nssuint_t ttl is placed.
+ * This ttl is the lessor of the ttl's extracted from the result.
+ *
+ * ***Currently the first version of this API only performs simple
+ * single res_nsearch lookups for with T_A or T_AAAA results.
+ * Other searches are deferred to the generic API w/t ttls.
+ *
+ * This function is not a generic res_* operation. It only performs
+ * a single T_A or T_AAAA lookups***
+ *
+ * RETURNS: NSS_SUCCESS or NSS_ERROR
+ * If an NSS_ERROR result is returned, nscd is expected
+ * to resubmit the gethosts request using the old style
+ * nsswitch lookup format.
+ */
+
+struct tsd_priv {
+ struct __res_state *statp; /* dns state block */
+ union msg {
+ uchar_t buf[NS_MAXMSG]; /* max legal DNS answer size */
+ HEADER h;
+ } resbuf;
+ char aliases[NS_MAXMSG]; /* set of aliases */
+};
+
+static void ghttlcleanup(void *ptr)
+{
+ struct tsd_priv *priv = (struct tsd_priv *)ptr;
+
+ if (priv) {
+ if (priv->statp != NULL) {
+ res_nclose(priv->statp);
+ free((void *)priv->statp);
+ }
+ free(ptr);
+ }
+}
+
+nss_status_t
+_nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode)
+{
+ /* nss buffer variables */
+ nss_pheader_t *pbuf = (nss_pheader_t *)buffer;
+ nss_XbyY_args_t arg;
+ char *dbname;
+ int dbop;
+ nss_status_t sret;
+ size_t bsize, blen;
+ char *bptr;
+ /* resolver query variables */
+ static mutex_t keylock;
+ static thread_key_t key;
+ static int once_per_keyname = 0;
+ struct tsd_priv *tsd = NULL;
+ const char *name;
+ int qtype;
+ /* answer parsing variables */
+ HEADER *hp;
+ uchar_t *cp; /* current location in message */
+ uchar_t *bom; /* start of message */
+ uchar_t *eom; /* end of message */
+ uchar_t *eor; /* end of record */
+ int ancount, qdcount;
+ int type, class;
+ nssuint_t nttl, ttl, *pttl; /* The purpose of this API */
+ int n, ret;
+ const char *np;
+ /* temporary buffers */
+ char nbuf[INET6_ADDRSTRLEN]; /* address parser */
+ char host[MAXHOSTNAMELEN]; /* result host name */
+ char ans[MAXHOSTNAMELEN]; /* record name */
+ char aname[MAXHOSTNAMELEN]; /* alias result (C_NAME) */
+ /* misc variables */
+ int af;
+ char *ap, *apc;
+ int hlen, alen, iplen, len;
+
+ if (!once_per_keyname) {
+ (void) mutex_lock(&keylock);
+ if (!once_per_keyname) {
+ (void) thr_keycreate(&key, ghttlcleanup);
+ once_per_keyname++;
+ }
+ (void) mutex_unlock(&keylock);
+ }
+ (void) thr_getspecific(key, (void **)&tsd);
+ if (tsd == NULL) {
+ tsd = (struct tsd_priv *)calloc(1, sizeof (struct tsd_priv));
+ (void) thr_setspecific(key, (void *)tsd);
+ (void) thr_getspecific(key, (void **)&tsd);
+ tsd->statp = (struct __res_state *)
+ calloc(1, sizeof (struct __res_state));
+ if (tsd->statp == NULL)
+ return (NSS_ERROR);
+ if (res_ninit(tsd->statp) == -1) {
+ free(tsd->statp);
+ return (NSS_ERROR);
+ }
+ }
+ ap = apc = (char *)tsd->aliases;
+ alen = 0;
+ ttl = (nssuint_t)0xFFFFFFF; /* start w/max, find smaller */
+
+ /* save space for ttl otherwise, why bother... */
+ bsize = pbuf->data_len - sizeof (nssuint_t);
+ bptr = (char *)buffer + pbuf->data_off;
+ blen = 0;
+ sret = nss_packed_getkey(buffer, bufsize, &dbname, &dbop, &arg);
+ if (sret != NSS_SUCCESS) {
+ return (NSS_ERROR);
+ }
+
+ if (ipnode) {
+ /* initially only handle the simple cases */
+ if (arg.key.ipnode.flags != 0)
+ return (NSS_ERROR);
+ name = arg.key.ipnode.name;
+ if (arg.key.ipnode.af_family == AF_INET6)
+ qtype = T_AAAA;
+ else
+ qtype = T_A;
+ } else {
+ name = arg.key.name;
+ qtype = T_A;
+ }
+ ret = res_nsearch(tsd->statp, name, C_IN, qtype,
+ tsd->resbuf.buf, NS_MAXMSG);
+ if (ret == -1) {
+ if (tsd->statp->res_h_errno == HOST_NOT_FOUND) {
+ pbuf->p_herrno = HOST_NOT_FOUND;
+ pbuf->p_status = NSS_NOTFOUND;
+ pbuf->data_len = 0;
+ return (NSS_NOTFOUND);
+ }
+ /* else lookup error - handle in general code */
+ return (NSS_ERROR);
+ }
+
+ cp = tsd->resbuf.buf;
+ hp = (HEADER *)&tsd->resbuf.h;
+ bom = cp;
+ eom = cp + ret;
+
+ ancount = ntohs(hp->ancount);
+ qdcount = ntohs(hp->qdcount);
+ cp += HFIXEDSZ;
+ if (qdcount != 1)
+ return (NSS_ERROR);
+ n = dn_expand(bom, eom, cp, host, MAXHOSTNAMELEN);
+ if (n < 0) {
+ return (NSS_ERROR);
+ } else
+ hlen = strlen(host);
+ cp += n + QFIXEDSZ;
+ if (cp > eom)
+ return (NSS_ERROR);
+ while (ancount-- > 0 && cp < eom && blen < bsize) {
+ n = dn_expand(bom, eom, cp, ans, MAXHOSTNAMELEN);
+ if (n > 0) {
+ if (strncasecmp(host, ans, hlen) != 0)
+ return (NSS_ERROR); /* spoof? */
+ }
+ cp += n;
+ /* bounds check */
+ type = ns_get16(cp); /* type */
+ cp += INT16SZ;
+ class = ns_get16(cp); /* class */
+ cp += INT16SZ;
+ nttl = (nssuint_t)ns_get32(cp); /* ttl in sec */
+ if (nttl < ttl)
+ ttl = nttl;
+ cp += INT32SZ;
+ n = ns_get16(cp); /* len */
+ cp += INT16SZ;
+ if (class != C_IN) {
+ cp += n;
+ continue;
+ }
+ eor = cp + n;
+ if (type == T_CNAME) {
+ /* add an alias to the alias list */
+ n = dn_expand(bom, eor, cp, aname, MAXHOSTNAMELEN);
+ if (n > 0) {
+ len = strlen(aname);
+ if (len > 0) {
+ /*
+ * Just error out if there is an
+ * attempted buffer overflow exploit
+ * generic code will do a syslog
+ */
+ if (alen + len + 2 > NS_MAXMSG)
+ return (NSS_ERROR);
+ *apc++ = ' ';
+ alen++;
+ (void) strlcpy(apc, aname, len + 1);
+ alen += len;
+ apc += len;
+ }
+ }
+ cp += n;
+ continue;
+ }
+ if (type != qtype) {
+ cp += n;
+ continue;
+ }
+ /* check data size */
+ if ((type == T_A && n != INADDRSZ) ||
+ (type == T_AAAA && n != IN6ADDRSZ)) {
+ cp += n;
+ continue;
+ }
+ af = (type == T_A ? AF_INET : AF_INET6);
+ np = inet_ntop(af, (void *)cp, nbuf, INET6_ADDRSTRLEN);
+ if (np == NULL)
+ return (NSS_ERROR);
+ cp += n;
+ /* append IP host aliases to results */
+ iplen = strlen(np);
+ /* ip <SP> hostname [<SP>][aliases] */
+ len = iplen + 2 + hlen + alen;
+ if (alen > 0)
+ len++;
+ if (blen + len > bsize)
+ return (NSS_ERROR);
+ (void) strlcpy(bptr, np, bsize - blen);
+ blen += iplen;
+ bptr += iplen;
+ *bptr++ = ' ';
+ blen++;
+ (void) strlcpy(bptr, host, bsize - blen);
+ blen += hlen;
+ bptr += hlen;
+ if (alen > 0) {
+ *bptr++ = ' ';
+ blen++;
+ (void) strlcpy(bptr, ap, bsize - blen);
+ blen += alen;
+ bptr += alen;
+ }
+ *bptr++ = '\n';
+ blen++;
+ }
+ /* Presumably the buffer is now filled. */
+ len = ROUND_UP(blen, sizeof (nssuint_t));
+ /* still room? */
+ if (len + sizeof (nssuint_t) > pbuf->data_len) {
+ /* sigh, no, what happened? */
+ return (NSS_ERROR);
+ }
+ pbuf->ext_off = pbuf->data_off + len;
+ pbuf->ext_len = sizeof (nssuint_t);
+ pbuf->data_len = blen;
+ pttl = (nssuint_t *)((void *)((char *)pbuf + pbuf->ext_off));
+ *pttl = ttl;
+ return (NSS_SUCCESS);
}
diff --git a/usr/src/lib/nsswitch/dns/common/dns_common.h b/usr/src/lib/nsswitch/dns/common/dns_common.h
index 7861cbb683..f60a37e436 100644
--- a/usr/src/lib/nsswitch/dns/common/dns_common.h
+++ b/usr/src/lib/nsswitch/dns/common/dns_common.h
@@ -2,9 +2,8 @@
* 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.
+ * Common Development and Distribution License (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.
@@ -20,9 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1993, 1998-1999 by Sun Microsystems, Inc.
- * All rights reserved.
- *
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/*
* Common code and structures used by name-service-switch "dns" backends.
*/
@@ -39,10 +39,12 @@
#include <netdb.h>
#include <strings.h>
#include <thread.h>
+#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <syslog.h>
#include <nsswitch.h>
+#include <nss_common.h>
#include <nss_dbdefs.h>
#include <stdlib.h>
#include <signal.h>
@@ -74,13 +76,17 @@ 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);
+extern int ent2str(struct hostent *, nss_XbyY_args_t *, int);
nss_backend_t *_nss_dns_constr(dns_backend_op_t *, int);
extern nss_status_t _herrno2nss(int);
+nss_status_t _nss_dns_gethost_withttl(void *buf, size_t bufsize, int ipnode);
+nss_status_t _nss_get_dns_hosts_name(dns_backend_ptr_t *, void **, size_t *);
+nss_status_t _nss_get_dns_ipnodes_name(dns_backend_ptr_t *, void **, size_t *);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/nsswitch/dns/common/dns_mt.c b/usr/src/lib/nsswitch/dns/common/dns_mt.c
index 7e236c40eb..bf6ac565c4 100644
--- a/usr/src/lib/nsswitch/dns/common/dns_mt.c
+++ b/usr/src/lib/nsswitch/dns/common/dns_mt.c
@@ -2,9 +2,8 @@
* 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.
+ * Common Development and Distribution License (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.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1993, 1998-2001 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -109,11 +108,10 @@ 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 (res_gethostbyname == 0) {
if ((reslib =
dlopen(NSS_DNS_LIBRESOLV, RTLD_LAZY|RTLD_GLOBAL)) != 0) {
/* Turn off /etc/hosts fall back in libresolv */
diff --git a/usr/src/lib/nsswitch/dns/common/gethostent.c b/usr/src/lib/nsswitch/dns/common/gethostent.c
index 38c8a44a3a..af365f4f2a 100644
--- a/usr/src/lib/nsswitch/dns/common/gethostent.c
+++ b/usr/src/lib/nsswitch/dns/common/gethostent.c
@@ -2,9 +2,8 @@
* 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.
+ * Common Development and Distribution License (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.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1993, 1998-2000 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -144,10 +143,22 @@ getbyname(be, a)
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;
+ if (argp->buf.result == NULL) {
+ /*
+ * if asked to return data in string,
+ * convert the hostent structure into
+ * string data
+ */
+ ret = ent2str(he, a, AF_INET);
+ if (ret == NSS_STR_PARSE_SUCCESS)
+ argp->returnval = argp->buf.buffer;
} else {
+ ret = ent2result(he, a, AF_INET);
+ if (ret == NSS_STR_PARSE_SUCCESS)
+ argp->returnval = argp->buf.result;
+ }
+
+ if (ret != NSS_STR_PARSE_SUCCESS) {
argp->h_errno = HOST_NOT_FOUND;
if (ret == NSS_STR_PARSE_ERANGE) {
argp->erange = 1;
@@ -176,6 +187,7 @@ getbyaddr(be, a)
* Exposing a DNS backend specific interface so that it doesn't conflict
* with other getbyaddr() routines from other switch backends.
*/
+/*ARGSUSED*/
nss_status_t
__nss_dns_getbyaddr(be, a)
dns_backend_ptr_t be;
@@ -195,11 +207,12 @@ __nss_dns_getbyaddr(be, a)
switch_resolver_setup(&mt_disabled, &oldmask, &old_retry);
+ /* LINTED: E_BAD_PTR_CAST_ALIGN */
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);
+ (void) memcpy(addrp, &argp->key.hostaddr.addr[12], addrlen);
} else {
addrp = (void *)argp->key.hostaddr.addr;
addrlen = argp->key.hostaddr.len;
@@ -217,7 +230,18 @@ __nss_dns_getbyaddr(be, a)
if (n < MAXHOSTNAMELEN-1 && hbuf[n-1] != '.') {
(void) strcat(hbuf, ".");
}
- ret = ent2result(he, a, argp->key.hostaddr.type);
+
+ /*
+ * if asked to return data in string,
+ * convert the hostent structure into
+ * string data
+ */
+ if (argp->buf.result == NULL)
+ ret = ent2str(he, a, argp->key.hostaddr.type);
+ else
+ ret = ent2result(he, a,
+ argp->key.hostaddr.type);
+
save_h_errno = argp->h_errno;
}
if (ret == NSS_STR_PARSE_SUCCESS) {
@@ -242,7 +266,12 @@ __nss_dns_getbyaddr(be, a)
if (memcmp(*ans, addrp, addrlen) ==
0) {
argp->h_errno = save_h_errno;
- argp->returnval = argp->buf.result;
+ if (argp->buf.result == NULL)
+ argp->returnval =
+ argp->buf.buffer;
+ else
+ argp->returnval =
+ argp->buf.result;
break;
}
} else {
@@ -259,12 +288,16 @@ __nss_dns_getbyaddr(be, a)
* this go. And return the name from byaddr.
*/
argp->h_errno = save_h_errno;
- argp->returnval = argp->buf.result;
+ if (argp->buf.result == NULL)
+ argp->returnval = argp->buf.buffer;
+ else
+ 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",
+ /* LINTED: E_BAD_PTR_CAST_ALIGN */
hbuf, inet_ntoa(*(struct in_addr *)argp->key.hostaddr.addr));
else
syslog(LOG_NOTICE, "gethostbyaddr: %s != %s",
@@ -414,3 +447,22 @@ _nss_dns_hosts_constr(dummy1, dummy2, dummy3)
return (_nss_dns_constr(host_ops,
sizeof (host_ops) / sizeof (host_ops[0])));
}
+
+/*
+ * optional NSS2 packed backend gethostsbyname with ttl
+ * entry point.
+ *
+ * Returns:
+ * NSS_SUCCESS - successful
+ * NSS_NOTFOUND - successful but nothing found
+ * NSS_ERROR - fallback to NSS backend lookup mode
+ * If successful, buffer will be filled with valid data
+ *
+ */
+
+/*ARGSUSED*/
+nss_status_t
+_nss_get_dns_hosts_name(dns_backend_ptr_t *be, void **bufp, size_t *sizep)
+{
+ return (_nss_dns_gethost_withttl(*bufp, *sizep, 0));
+}
diff --git a/usr/src/lib/nsswitch/dns/common/gethostent6.c b/usr/src/lib/nsswitch/dns/common/gethostent6.c
index e92ce6a356..b2d71d6b24 100644
--- a/usr/src/lib/nsswitch/dns/common/gethostent6.c
+++ b/usr/src/lib/nsswitch/dns/common/gethostent6.c
@@ -2,9 +2,8 @@
* 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.
+ * Common Development and Distribution License (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.
@@ -20,9 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 1993-2000, 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- *
+ */
+/*
* gethostent6.c
*/
@@ -115,7 +115,7 @@ cloneName(struct hostent *h, int *outerr) {
return (0);
}
- memcpy(name, h->h_name, len+1);
+ (void) memcpy(name, h->h_name, len+1);
*errp = 0;
return (name);
@@ -130,7 +130,7 @@ cloneName(struct hostent *h, int *outerr) {
* Note: The pointers to the addresses in the moreAddrs[] array are copied,
* but not the IP addresses themselves.
*/
-struct in6_addr **
+static struct in6_addr **
cloneAddrList(struct hostent *h, struct in6_addr **moreAddrs, int *outerr) {
struct in6_addr **addrArray, *addrList;
@@ -176,10 +176,12 @@ cloneAddrList(struct hostent *h, struct in6_addr **moreAddrs, int *outerr) {
for (i = 0; i < addrCount; i++) {
addrArray[i] = addrList;
if (domap) {
+ /* LINTED: E_BAD_PTR_CAST_ALIGN */
IN6_INADDR_TO_V4MAPPED(
(struct in_addr *)h->h_addr_list[i], addrArray[i]);
} else {
- memcpy(addrArray[i], h->h_addr_list[i], addrlen);
+ (void) memcpy(addrArray[i], h->h_addr_list[i],
+ addrlen);
}
addrList = PTROFF(addrList, addrlen);
}
@@ -211,7 +213,7 @@ static char **
cloneAliasList(struct hostent *h, char **mergeAliases, int *outerr) {
char **aliasArray, *aliasList;
- int i, j, k, aliasCount, mergeAliasCount = 0, realMac = 0;
+ int i, j, aliasCount, mergeAliasCount = 0, realMac = 0;
int stringSize = 0;
int error, *errp;
@@ -259,7 +261,7 @@ cloneAliasList(struct hostent *h, char **mergeAliases, int *outerr) {
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);
+ (void) memcpy(aliasArray[i], h->h_aliases[i], len+1);
aliasList = PTROFF(aliasList, RNDUP(len+1));
}
@@ -275,7 +277,7 @@ cloneAliasList(struct hostent *h, char **mergeAliases, int *outerr) {
return (aliasArray);
}
-
+/*ARGSUSED*/
static nss_status_t
getbyname(be, a)
dns_backend_ptr_t be;
@@ -407,11 +409,23 @@ getbyname(be, a)
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;
+ if (he != NULL) {
+ /*
+ * if asked to return data in string,
+ * convert the hostent structure into
+ * string data
+ */
+ if (argp->buf.result == NULL) {
+ ret = ent2str(he, a, AF_INET6);
+ if (ret == NSS_STR_PARSE_SUCCESS)
+ argp->returnval = argp->buf.buffer;
} else {
+ ret = ent2result(he, a, AF_INET6);
+ if (ret == NSS_STR_PARSE_SUCCESS)
+ argp->returnval = argp->buf.result;
+ }
+
+ if (ret != NSS_STR_PARSE_SUCCESS) {
argp->h_errno = HOST_NOT_FOUND;
if (ret == NSS_STR_PARSE_ERANGE) {
argp->erange = 1;
@@ -532,3 +546,22 @@ _nss_dns_ipnodes_constr(dummy1, dummy2, dummy3)
return (_nss_dns_constr(ipnodes_ops,
sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0])));
}
+
+/*
+ * optional NSS2 packed backend gethostsbyipnode with ttl
+ * entry point.
+ *
+ * Returns:
+ * NSS_SUCCESS - successful
+ * NSS_NOTFOUND - successful but nothing found
+ * NSS_ERROR - fallback to NSS backend lookup mode
+ * If successful, buffer will be filled with valid data
+ *
+ */
+
+/*ARGSUSED*/
+nss_status_t
+_nss_get_dns_ipnodes_name(dns_backend_ptr_t *be, void **bufp, size_t *sizep)
+{
+ return (_nss_dns_gethost_withttl(*bufp, *sizep, 1));
+}
diff --git a/usr/src/lib/nsswitch/dns/common/mapfile-vers b/usr/src/lib/nsswitch/dns/common/mapfile-vers
index 6e44ffe568..9aa3d5ff1a 100644
--- a/usr/src/lib/nsswitch/dns/common/mapfile-vers
+++ b/usr/src/lib/nsswitch/dns/common/mapfile-vers
@@ -1,15 +1,14 @@
#
#ident "%Z%%M% %I% %E% SMI"
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2006 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.
+# Common Development and Distribution License (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.
@@ -41,6 +40,8 @@ SUNWprivate_1.1 {
global:
_nss_dns_hosts_constr;
_nss_dns_ipnodes_constr;
+ _nss_get_dns_hosts_name;
+ _nss_get_dns_ipnodes_name;
local:
*;
};