17c478bd9Sstevel@tonic-gate /*
2*7d575517Ssdussud  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
77c478bd9Sstevel@tonic-gate 
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the Netscape Public
117c478bd9Sstevel@tonic-gate  * License Version 1.1 (the "License"); you may not use this file
127c478bd9Sstevel@tonic-gate  * except in compliance with the License. You may obtain a copy of
137c478bd9Sstevel@tonic-gate  * the License at http://www.mozilla.org/NPL/
147c478bd9Sstevel@tonic-gate  *
157c478bd9Sstevel@tonic-gate  * Software distributed under the License is distributed on an "AS
167c478bd9Sstevel@tonic-gate  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
177c478bd9Sstevel@tonic-gate  * implied. See the License for the specific language governing
187c478bd9Sstevel@tonic-gate  * rights and limitations under the License.
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * The Original Code is Mozilla Communicator client code, released
217c478bd9Sstevel@tonic-gate  * March 31, 1998.
227c478bd9Sstevel@tonic-gate  *
237c478bd9Sstevel@tonic-gate  * The Initial Developer of the Original Code is Netscape
247c478bd9Sstevel@tonic-gate  * Communications Corporation. Portions created by Netscape are
257c478bd9Sstevel@tonic-gate  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
267c478bd9Sstevel@tonic-gate  * Rights Reserved.
277c478bd9Sstevel@tonic-gate  *
287c478bd9Sstevel@tonic-gate  * Contributor(s):
297c478bd9Sstevel@tonic-gate  */
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate /*
327c478bd9Sstevel@tonic-gate  * DNS callback functions for libldap that use the NSPR (Netscape
337c478bd9Sstevel@tonic-gate  * Portable Runtime) thread API.
347c478bd9Sstevel@tonic-gate  *
357c478bd9Sstevel@tonic-gate  */
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK
387c478bd9Sstevel@tonic-gate #include "solaris-int.h"
397c478bd9Sstevel@tonic-gate #include <libintl.h>
407c478bd9Sstevel@tonic-gate #include <syslog.h>
417c478bd9Sstevel@tonic-gate #include <nsswitch.h>
427c478bd9Sstevel@tonic-gate #include <synch.h>
437c478bd9Sstevel@tonic-gate #include <nss_dbdefs.h>
447c478bd9Sstevel@tonic-gate #include <netinet/in.h>
457c478bd9Sstevel@tonic-gate static char *host_service = NULL;
467c478bd9Sstevel@tonic-gate static DEFINE_NSS_DB_ROOT(db_root_hosts);
477c478bd9Sstevel@tonic-gate #endif
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate #include "ldappr-int.h"
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate static LDAPHostEnt *prldap_gethostbyname( const char *name,
527c478bd9Sstevel@tonic-gate 	LDAPHostEnt *result, char *buffer, int buflen, int *statusp,
537c478bd9Sstevel@tonic-gate 	void *extradata );
547c478bd9Sstevel@tonic-gate static LDAPHostEnt *prldap_gethostbyaddr( const char *addr, int length,
557c478bd9Sstevel@tonic-gate 	int type, LDAPHostEnt *result, char *buffer, int buflen,
567c478bd9Sstevel@tonic-gate 	int *statusp, void *extradata );
577c478bd9Sstevel@tonic-gate static int prldap_getpeername( LDAP *ld, struct sockaddr *addr,
587c478bd9Sstevel@tonic-gate 	char *buffer, int buflen );
597c478bd9Sstevel@tonic-gate static LDAPHostEnt *prldap_convert_hostent( LDAPHostEnt *ldhp,
607c478bd9Sstevel@tonic-gate 	PRHostEnt *prhp );
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK
637c478bd9Sstevel@tonic-gate static LDAPHostEnt *
647c478bd9Sstevel@tonic-gate prldap_gethostbyname1(const char *name, LDAPHostEnt *result,
657c478bd9Sstevel@tonic-gate 	char *buffer, int buflen, int *statusp, void *extradata);
667c478bd9Sstevel@tonic-gate extern int
677c478bd9Sstevel@tonic-gate str2hostent(const char *instr, int lenstr, void *ent, char *buffer,
687c478bd9Sstevel@tonic-gate 	int buflen);
697c478bd9Sstevel@tonic-gate #endif /* _SOLARIS_SDK */
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate /*
737c478bd9Sstevel@tonic-gate  * Install NSPR DNS functions into ld (if ld is NULL, they are installed
747c478bd9Sstevel@tonic-gate  * as the default functions for new LDAP * handles).
757c478bd9Sstevel@tonic-gate  *
767c478bd9Sstevel@tonic-gate  * Returns 0 if all goes well and -1 if not.
777c478bd9Sstevel@tonic-gate  */
787c478bd9Sstevel@tonic-gate int
797c478bd9Sstevel@tonic-gate prldap_install_dns_functions( LDAP *ld )
807c478bd9Sstevel@tonic-gate {
817c478bd9Sstevel@tonic-gate     struct ldap_dns_fns			dnsfns;
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate     memset( &dnsfns, '\0', sizeof(struct ldap_dns_fns) );
847c478bd9Sstevel@tonic-gate     dnsfns.lddnsfn_bufsize = PR_NETDB_BUF_SIZE;
857c478bd9Sstevel@tonic-gate     dnsfns.lddnsfn_gethostbyname = prldap_gethostbyname;
867c478bd9Sstevel@tonic-gate     dnsfns.lddnsfn_gethostbyaddr = prldap_gethostbyaddr;
877c478bd9Sstevel@tonic-gate 	    dnsfns.lddnsfn_getpeername = prldap_getpeername;
887c478bd9Sstevel@tonic-gate 	    if ( ldap_set_option( ld, LDAP_OPT_DNS_FN_PTRS, (void *)&dnsfns ) != 0 ) {
897c478bd9Sstevel@tonic-gate 		return( -1 );
907c478bd9Sstevel@tonic-gate 	    }
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate     return( 0 );
937c478bd9Sstevel@tonic-gate }
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate static LDAPHostEnt *
977c478bd9Sstevel@tonic-gate prldap_gethostbyname( const char *name, LDAPHostEnt *result,
987c478bd9Sstevel@tonic-gate 	char *buffer, int buflen, int *statusp, void *extradata )
997c478bd9Sstevel@tonic-gate {
1007c478bd9Sstevel@tonic-gate 	PRHostEnt	prhent;
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate 	if( !statusp || ( *statusp = (int)PR_GetIPNodeByName( name,
1037c478bd9Sstevel@tonic-gate 		PRLDAP_DEFAULT_ADDRESS_FAMILY, PR_AI_DEFAULT,
1047c478bd9Sstevel@tonic-gate 		buffer, buflen, &prhent )) == PR_FAILURE ) {
1057c478bd9Sstevel@tonic-gate 		return( NULL );
1067c478bd9Sstevel@tonic-gate 	}
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate 	return( prldap_convert_hostent( result, &prhent ));
1097c478bd9Sstevel@tonic-gate }
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate static LDAPHostEnt *
1137c478bd9Sstevel@tonic-gate prldap_gethostbyaddr( const char *addr, int length, int type,
1147c478bd9Sstevel@tonic-gate 	LDAPHostEnt *result, char *buffer, int buflen, int *statusp,
1157c478bd9Sstevel@tonic-gate 	void *extradata )
1167c478bd9Sstevel@tonic-gate {
1177c478bd9Sstevel@tonic-gate     PRHostEnt	prhent;
1187c478bd9Sstevel@tonic-gate     PRNetAddr	iaddr;
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	if ( PR_SetNetAddr(PR_IpAddrNull, PRLDAP_DEFAULT_ADDRESS_FAMILY,
1217c478bd9Sstevel@tonic-gate 		0, &iaddr) == PR_FAILURE
1227c478bd9Sstevel@tonic-gate  		|| PR_StringToNetAddr( addr, &iaddr ) == PR_FAILURE ) {
1237c478bd9Sstevel@tonic-gate 		return( NULL );
1247c478bd9Sstevel@tonic-gate 	}
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate     if( !statusp || (*statusp = PR_GetHostByAddr(&iaddr, buffer,
1277c478bd9Sstevel@tonic-gate 	     buflen, &prhent )) == PR_FAILURE ) {
1287c478bd9Sstevel@tonic-gate 	return( NULL );
1297c478bd9Sstevel@tonic-gate     }
1307c478bd9Sstevel@tonic-gate     return( prldap_convert_hostent( result, &prhent ));
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate static int
1347c478bd9Sstevel@tonic-gate prldap_getpeername( LDAP *ld, struct sockaddr *addr, char *buffer, int buflen)
1357c478bd9Sstevel@tonic-gate {
1367c478bd9Sstevel@tonic-gate     PRLDAPIOSocketArg *sa;
1377c478bd9Sstevel@tonic-gate     PRFileDesc	*fd;
1387c478bd9Sstevel@tonic-gate     PRNetAddr	iaddr;
1397c478bd9Sstevel@tonic-gate     int		ret;
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate     if (NULL != ld) {
1427c478bd9Sstevel@tonic-gate 	    ret = prldap_socket_arg_from_ld( ld, &sa );
1437c478bd9Sstevel@tonic-gate 	    if (ret != LDAP_SUCCESS) {
1447c478bd9Sstevel@tonic-gate 		return (-1);
1457c478bd9Sstevel@tonic-gate 	    }
1467c478bd9Sstevel@tonic-gate 	    ret = PR_GetPeerName(sa->prsock_prfd, &iaddr);
1477c478bd9Sstevel@tonic-gate 	    if( ret == PR_FAILURE ) {
1487c478bd9Sstevel@tonic-gate 		return( -1 );
1497c478bd9Sstevel@tonic-gate 	    }
1507c478bd9Sstevel@tonic-gate 	    *addr = *((struct sockaddr *)&iaddr.raw);
1517c478bd9Sstevel@tonic-gate 	    ret = PR_NetAddrToString(&iaddr, buffer, buflen);
1527c478bd9Sstevel@tonic-gate 	    if( ret == PR_FAILURE ) {
1537c478bd9Sstevel@tonic-gate 		return( -1 );
1547c478bd9Sstevel@tonic-gate 	    }
1557c478bd9Sstevel@tonic-gate 	    return (0);
1567c478bd9Sstevel@tonic-gate     }
1577c478bd9Sstevel@tonic-gate     return (-1);
1587c478bd9Sstevel@tonic-gate }
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate /*
1627c478bd9Sstevel@tonic-gate  * Function: prldap_convert_hostent()
1637c478bd9Sstevel@tonic-gate  * Description: copy the fields of a PRHostEnt struct to an LDAPHostEnt
1647c478bd9Sstevel@tonic-gate  * Returns: the LDAPHostEnt pointer passed in.
1657c478bd9Sstevel@tonic-gate  */
1667c478bd9Sstevel@tonic-gate static LDAPHostEnt *
1677c478bd9Sstevel@tonic-gate prldap_convert_hostent( LDAPHostEnt *ldhp, PRHostEnt *prhp )
1687c478bd9Sstevel@tonic-gate {
1697c478bd9Sstevel@tonic-gate 	ldhp->ldaphe_name = prhp->h_name;
1707c478bd9Sstevel@tonic-gate 	ldhp->ldaphe_aliases = prhp->h_aliases;
1717c478bd9Sstevel@tonic-gate 	ldhp->ldaphe_addrtype = prhp->h_addrtype;
1727c478bd9Sstevel@tonic-gate 	ldhp->ldaphe_length =  prhp->h_length;
1737c478bd9Sstevel@tonic-gate 	ldhp->ldaphe_addr_list =  prhp->h_addr_list;
1747c478bd9Sstevel@tonic-gate 	return( ldhp );
1757c478bd9Sstevel@tonic-gate }
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK
1787c478bd9Sstevel@tonic-gate /*
1797c478bd9Sstevel@tonic-gate  * prldap_x_install_dns_skipdb attempts to prevent recursion in resolving
1807c478bd9Sstevel@tonic-gate  * the hostname to an IP address when a host name is given to LDAP user.
1817c478bd9Sstevel@tonic-gate  *
1827c478bd9Sstevel@tonic-gate  * For example, libsldap cannot use LDAP to resolve the host name to an
1837c478bd9Sstevel@tonic-gate  * address because of recursion. The caller is instructing libldap to skip
1847c478bd9Sstevel@tonic-gate  * the specified name service when resolving addresses for the specified
1857c478bd9Sstevel@tonic-gate  * ldap connection.
1867c478bd9Sstevel@tonic-gate  *
1877c478bd9Sstevel@tonic-gate  * Note:
1887c478bd9Sstevel@tonic-gate  *      This only supports ipv4 addresses currently.
1897c478bd9Sstevel@tonic-gate  *
1907c478bd9Sstevel@tonic-gate  *      Since host_service applies to all connections, calling
1917c478bd9Sstevel@tonic-gate  *      prldap_x_install_dns_skipdb with name services other than
1927c478bd9Sstevel@tonic-gate  *      ldap or what uses ldap (for example nis+ might use ldap) to
1937c478bd9Sstevel@tonic-gate  *      skip will lead to unpredictable results.
1947c478bd9Sstevel@tonic-gate  *
1957c478bd9Sstevel@tonic-gate  * Returns:
1967c478bd9Sstevel@tonic-gate  *      0       if success and data base found
1977c478bd9Sstevel@tonic-gate  *      -1      if failure
1987c478bd9Sstevel@tonic-gate  */
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate int
2017c478bd9Sstevel@tonic-gate prldap_x_install_dns_skipdb(LDAP *ld, const char *skip)
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate 	enum __nsw_parse_err		pserr;
2047c478bd9Sstevel@tonic-gate 	struct __nsw_switchconfig       *conf;
2057c478bd9Sstevel@tonic-gate 	struct __nsw_lookup             *lkp;
2067c478bd9Sstevel@tonic-gate 	struct ldap_dns_fns             dns_fns;
2077c478bd9Sstevel@tonic-gate 	char                            *name_list = NULL;
2087c478bd9Sstevel@tonic-gate 	char                            *tmp;
2097c478bd9Sstevel@tonic-gate 	const char                      *name;
2107c478bd9Sstevel@tonic-gate 	int                             len;
2117c478bd9Sstevel@tonic-gate 	boolean_t                       got_skip = B_FALSE;
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate 	/*
2147c478bd9Sstevel@tonic-gate 	 * db_root_hosts.lock mutex is used to ensure that the name list
2157c478bd9Sstevel@tonic-gate 	 * is not in use by the name service switch while we are updating
2167c478bd9Sstevel@tonic-gate 	 * the host_service
2177c478bd9Sstevel@tonic-gate 	 */
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate         (void) mutex_lock(&db_root_hosts.lock);
2207c478bd9Sstevel@tonic-gate         conf = __nsw_getconfig("hosts", &pserr);
2217c478bd9Sstevel@tonic-gate         if (conf == NULL) {
2227c478bd9Sstevel@tonic-gate                 (void) mutex_unlock(&db_root_hosts.lock);
2237c478bd9Sstevel@tonic-gate                 return (0);
2247c478bd9Sstevel@tonic-gate         }
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate         /* check for skip and count other backends */
2277c478bd9Sstevel@tonic-gate         for (lkp = conf->lookups; lkp != NULL; lkp = lkp->next) {
2287c478bd9Sstevel@tonic-gate                 name = lkp->service_name;
2297c478bd9Sstevel@tonic-gate                 if (strcmp(name, skip) == 0) {
2307c478bd9Sstevel@tonic-gate                         got_skip = B_TRUE;
2317c478bd9Sstevel@tonic-gate                         continue;
2327c478bd9Sstevel@tonic-gate                 }
2337c478bd9Sstevel@tonic-gate                 if (name_list == NULL)
2347c478bd9Sstevel@tonic-gate                         name_list = strdup(name);
2357c478bd9Sstevel@tonic-gate                 else {
2367c478bd9Sstevel@tonic-gate                         len = strlen(name_list);
2377c478bd9Sstevel@tonic-gate                         tmp = realloc(name_list, len + strlen(name) + 2);
2387c478bd9Sstevel@tonic-gate                         if (tmp == NULL) {
2397c478bd9Sstevel@tonic-gate                                 free(name_list);
2407c478bd9Sstevel@tonic-gate                                 name_list = NULL;
2417c478bd9Sstevel@tonic-gate                         } else {
2427c478bd9Sstevel@tonic-gate                                 name_list = tmp;
2437c478bd9Sstevel@tonic-gate                                 name_list[len++] = ' ';
2447c478bd9Sstevel@tonic-gate                                 (void) strcpy(name_list+len, name);
2457c478bd9Sstevel@tonic-gate                         }
2467c478bd9Sstevel@tonic-gate                 }
2477c478bd9Sstevel@tonic-gate                 if (name_list == NULL) {        /* alloc error */
2487c478bd9Sstevel@tonic-gate                         (void) mutex_unlock(&db_root_hosts.lock);
2497c478bd9Sstevel@tonic-gate                         __nsw_freeconfig(conf);
2507c478bd9Sstevel@tonic-gate                         return (-1);
2517c478bd9Sstevel@tonic-gate                 }
2527c478bd9Sstevel@tonic-gate         }
2537c478bd9Sstevel@tonic-gate         __nsw_freeconfig(conf);
2547c478bd9Sstevel@tonic-gate         if (!got_skip) {
2557c478bd9Sstevel@tonic-gate 		/*
2567c478bd9Sstevel@tonic-gate 		 * Since skip name service not used for hosts, we do not need
2577c478bd9Sstevel@tonic-gate 		 * to install our private address resolution function
2587c478bd9Sstevel@tonic-gate 		 */
2597c478bd9Sstevel@tonic-gate                 (void) mutex_unlock(&db_root_hosts.lock);
2607c478bd9Sstevel@tonic-gate                 if (name_list != NULL)
2617c478bd9Sstevel@tonic-gate                         free(name_list);
2627c478bd9Sstevel@tonic-gate                 return (0);
2637c478bd9Sstevel@tonic-gate         }
2647c478bd9Sstevel@tonic-gate         if (host_service != NULL)
2657c478bd9Sstevel@tonic-gate                 free(host_service);
2667c478bd9Sstevel@tonic-gate         host_service = name_list;
2677c478bd9Sstevel@tonic-gate         (void) mutex_unlock(&db_root_hosts.lock);
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate         if (ldap_get_option(ld, LDAP_OPT_DNS_FN_PTRS, &dns_fns) != 0)
2707c478bd9Sstevel@tonic-gate                 return (-1);
2717c478bd9Sstevel@tonic-gate         dns_fns.lddnsfn_bufsize = PR_NETDB_BUF_SIZE;
2727c478bd9Sstevel@tonic-gate         dns_fns.lddnsfn_gethostbyname = prldap_gethostbyname1;
2737c478bd9Sstevel@tonic-gate         if (ldap_set_option(ld, LDAP_OPT_DNS_FN_PTRS, &dns_fns) != 0)
2747c478bd9Sstevel@tonic-gate                 return (-1);
2757c478bd9Sstevel@tonic-gate         return (0);
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate /*
2797c478bd9Sstevel@tonic-gate  * prldap_initf_hosts is passed to and called by nss_search() as a
2807c478bd9Sstevel@tonic-gate  * service routine.
2817c478bd9Sstevel@tonic-gate  *
2827c478bd9Sstevel@tonic-gate  * Returns:
2837c478bd9Sstevel@tonic-gate  *      None
2847c478bd9Sstevel@tonic-gate  */
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate static void
2877c478bd9Sstevel@tonic-gate prldap_initf_hosts(nss_db_params_t *p)
2887c478bd9Sstevel@tonic-gate {
2897c478bd9Sstevel@tonic-gate         static char *no_service = "";
2907c478bd9Sstevel@tonic-gate 
2917c478bd9Sstevel@tonic-gate         p->name = NSS_DBNAM_HOSTS;
2927c478bd9Sstevel@tonic-gate         p->flags |= NSS_USE_DEFAULT_CONFIG;
2937c478bd9Sstevel@tonic-gate         p->default_config = host_service == NULL ? no_service : host_service;
2947c478bd9Sstevel@tonic-gate }
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate /*
2977c478bd9Sstevel@tonic-gate  * called by prldap_gethostbyname1()
2987c478bd9Sstevel@tonic-gate  */
2997c478bd9Sstevel@tonic-gate /*
3007c478bd9Sstevel@tonic-gate  * prldap_switch_gethostbyname_r is called by prldap_gethostbyname1 as a
3017c478bd9Sstevel@tonic-gate  * substitute for gethostbyname_r(). A method which prevents recursion. see
3027c478bd9Sstevel@tonic-gate  * prldap_gethostbyname1() and prldap_x_install_dns_skipdb().
3037c478bd9Sstevel@tonic-gate  *
3047c478bd9Sstevel@tonic-gate  * Returns:
305*7d575517Ssdussud  *      PR_SUCCESS                    if success
3067c478bd9Sstevel@tonic-gate  *      PR_FAILURE                    if failure
3077c478bd9Sstevel@tonic-gate  */
3087c478bd9Sstevel@tonic-gate 
309*7d575517Ssdussud static int
3107c478bd9Sstevel@tonic-gate prldap_switch_gethostbyname_r(const char *name,
3117c478bd9Sstevel@tonic-gate         struct hostent *result, char *buffer, int buflen,
3127c478bd9Sstevel@tonic-gate         int *h_errnop)
3137c478bd9Sstevel@tonic-gate {
3147c478bd9Sstevel@tonic-gate         nss_XbyY_args_t arg;
3157c478bd9Sstevel@tonic-gate         nss_status_t    res;
316*7d575517Ssdussud 	struct hostent	*resp;
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 	/*
3197c478bd9Sstevel@tonic-gate 	 * Log the information indicating that we are trying to
3207c478bd9Sstevel@tonic-gate 	 * resolve the LDAP server name.
3217c478bd9Sstevel@tonic-gate 	 */
3227c478bd9Sstevel@tonic-gate 	syslog(LOG_INFO, "libldap: Resolving server name \"%s\"", name);
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate         NSS_XbyY_INIT(&arg, result, buffer, buflen, str2hostent);
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate         arg.key.name = name;
3277c478bd9Sstevel@tonic-gate         arg.stayopen = 0;
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate         res = nss_search(&db_root_hosts, prldap_initf_hosts,
3307c478bd9Sstevel@tonic-gate             NSS_DBOP_HOSTS_BYNAME, &arg);
3317c478bd9Sstevel@tonic-gate         arg.status = res;
3327c478bd9Sstevel@tonic-gate         *h_errnop = arg.h_errno;
333*7d575517Ssdussud 	resp = (struct hostent *)NSS_XbyY_FINI(&arg);
334*7d575517Ssdussud 
335*7d575517Ssdussud 	return (resp != NULL ? PR_SUCCESS : PR_FAILURE);
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate /*
3397c478bd9Sstevel@tonic-gate  * prldap_gethostbyname1 is used to be a substitute gethostbyname_r for
3407c478bd9Sstevel@tonic-gate  * libldap when it is unsafe to use the normal nameservice functions.
3417c478bd9Sstevel@tonic-gate  *
3427c478bd9Sstevel@tonic-gate  * Returns:
3437c478bd9Sstevel@tonic-gate  *      pointer to LDAPHostEnt:         if success contains the address
3447c478bd9Sstevel@tonic-gate  *      NULL pointer:                   if failure
3457c478bd9Sstevel@tonic-gate  */
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate static LDAPHostEnt *
3487c478bd9Sstevel@tonic-gate prldap_gethostbyname1(const char *name, LDAPHostEnt *result,
3497c478bd9Sstevel@tonic-gate 	char *buffer, int buflen, int *statusp, void *extradata)
3507c478bd9Sstevel@tonic-gate {
3517c478bd9Sstevel@tonic-gate         int         h_errno;
3527c478bd9Sstevel@tonic-gate 	LDAPHostEnt prhent;
3537c478bd9Sstevel@tonic-gate 
354*7d575517Ssdussud 	memset(&prhent, '\0', sizeof (prhent));
3557c478bd9Sstevel@tonic-gate         if (!statusp || ( *statusp = prldap_switch_gethostbyname_r(name,
3567c478bd9Sstevel@tonic-gate                         &prhent, buffer, buflen, &h_errno )) == PR_FAILURE) {
3577c478bd9Sstevel@tonic-gate 		/*
3587c478bd9Sstevel@tonic-gate 		 * If we got here, it means that we are not able to
3597c478bd9Sstevel@tonic-gate 		 * resolve the LDAP server name and so warn the system
3607c478bd9Sstevel@tonic-gate 		 * adminstrator accordingly.
3617c478bd9Sstevel@tonic-gate 		 */
3627c478bd9Sstevel@tonic-gate 		syslog(LOG_WARNING, "libldap: server name \"%s\" could not "
3637c478bd9Sstevel@tonic-gate 		"be resolved", name);
3647c478bd9Sstevel@tonic-gate 		return (NULL);
3657c478bd9Sstevel@tonic-gate         }
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate         return (prldap_convert_hostent(result, &prhent));
3687c478bd9Sstevel@tonic-gate }
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate #endif  /* _SOLARIS_SDK */
371