1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * Copyright 2002-2003 Sun Microsystems, Inc.  All rights reserved.
3*0Sstevel@tonic-gate  * Use is subject to license terms.
4*0Sstevel@tonic-gate  */
5*0Sstevel@tonic-gate 
6*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
7*0Sstevel@tonic-gate 
8*0Sstevel@tonic-gate 
9*0Sstevel@tonic-gate /*
10*0Sstevel@tonic-gate  * The contents of this file are subject to the Netscape Public
11*0Sstevel@tonic-gate  * License Version 1.1 (the "License"); you may not use this file
12*0Sstevel@tonic-gate  * except in compliance with the License. You may obtain a copy of
13*0Sstevel@tonic-gate  * the License at http://www.mozilla.org/NPL/
14*0Sstevel@tonic-gate  *
15*0Sstevel@tonic-gate  * Software distributed under the License is distributed on an "AS
16*0Sstevel@tonic-gate  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
17*0Sstevel@tonic-gate  * implied. See the License for the specific language governing
18*0Sstevel@tonic-gate  * rights and limitations under the License.
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * The Original Code is Mozilla Communicator client code, released
21*0Sstevel@tonic-gate  * March 31, 1998.
22*0Sstevel@tonic-gate  *
23*0Sstevel@tonic-gate  * The Initial Developer of the Original Code is Netscape
24*0Sstevel@tonic-gate  * Communications Corporation. Portions created by Netscape are
25*0Sstevel@tonic-gate  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
26*0Sstevel@tonic-gate  * Rights Reserved.
27*0Sstevel@tonic-gate  *
28*0Sstevel@tonic-gate  * Contributor(s):
29*0Sstevel@tonic-gate  */
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate /*
32*0Sstevel@tonic-gate  * DNS callback functions for libldap that use the NSPR (Netscape
33*0Sstevel@tonic-gate  * Portable Runtime) thread API.
34*0Sstevel@tonic-gate  *
35*0Sstevel@tonic-gate  */
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate #ifdef _SOLARIS_SDK
38*0Sstevel@tonic-gate #include "solaris-int.h"
39*0Sstevel@tonic-gate #include <libintl.h>
40*0Sstevel@tonic-gate #include <syslog.h>
41*0Sstevel@tonic-gate #include <nsswitch.h>
42*0Sstevel@tonic-gate #include <synch.h>
43*0Sstevel@tonic-gate #include <nss_dbdefs.h>
44*0Sstevel@tonic-gate #include <netinet/in.h>
45*0Sstevel@tonic-gate static char *host_service = NULL;
46*0Sstevel@tonic-gate static DEFINE_NSS_DB_ROOT(db_root_hosts);
47*0Sstevel@tonic-gate #endif
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate #include "ldappr-int.h"
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate static LDAPHostEnt *prldap_gethostbyname( const char *name,
52*0Sstevel@tonic-gate 	LDAPHostEnt *result, char *buffer, int buflen, int *statusp,
53*0Sstevel@tonic-gate 	void *extradata );
54*0Sstevel@tonic-gate static LDAPHostEnt *prldap_gethostbyaddr( const char *addr, int length,
55*0Sstevel@tonic-gate 	int type, LDAPHostEnt *result, char *buffer, int buflen,
56*0Sstevel@tonic-gate 	int *statusp, void *extradata );
57*0Sstevel@tonic-gate static int prldap_getpeername( LDAP *ld, struct sockaddr *addr,
58*0Sstevel@tonic-gate 	char *buffer, int buflen );
59*0Sstevel@tonic-gate static LDAPHostEnt *prldap_convert_hostent( LDAPHostEnt *ldhp,
60*0Sstevel@tonic-gate 	PRHostEnt *prhp );
61*0Sstevel@tonic-gate 
62*0Sstevel@tonic-gate #ifdef _SOLARIS_SDK
63*0Sstevel@tonic-gate static LDAPHostEnt *
64*0Sstevel@tonic-gate prldap_gethostbyname1(const char *name, LDAPHostEnt *result,
65*0Sstevel@tonic-gate 	char *buffer, int buflen, int *statusp, void *extradata);
66*0Sstevel@tonic-gate extern int
67*0Sstevel@tonic-gate str2hostent(const char *instr, int lenstr, void *ent, char *buffer,
68*0Sstevel@tonic-gate 	int buflen);
69*0Sstevel@tonic-gate #endif /* _SOLARIS_SDK */
70*0Sstevel@tonic-gate 
71*0Sstevel@tonic-gate 
72*0Sstevel@tonic-gate /*
73*0Sstevel@tonic-gate  * Install NSPR DNS functions into ld (if ld is NULL, they are installed
74*0Sstevel@tonic-gate  * as the default functions for new LDAP * handles).
75*0Sstevel@tonic-gate  *
76*0Sstevel@tonic-gate  * Returns 0 if all goes well and -1 if not.
77*0Sstevel@tonic-gate  */
78*0Sstevel@tonic-gate int
79*0Sstevel@tonic-gate prldap_install_dns_functions( LDAP *ld )
80*0Sstevel@tonic-gate {
81*0Sstevel@tonic-gate     struct ldap_dns_fns			dnsfns;
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate     memset( &dnsfns, '\0', sizeof(struct ldap_dns_fns) );
84*0Sstevel@tonic-gate     dnsfns.lddnsfn_bufsize = PR_NETDB_BUF_SIZE;
85*0Sstevel@tonic-gate     dnsfns.lddnsfn_gethostbyname = prldap_gethostbyname;
86*0Sstevel@tonic-gate     dnsfns.lddnsfn_gethostbyaddr = prldap_gethostbyaddr;
87*0Sstevel@tonic-gate 	    dnsfns.lddnsfn_getpeername = prldap_getpeername;
88*0Sstevel@tonic-gate 	    if ( ldap_set_option( ld, LDAP_OPT_DNS_FN_PTRS, (void *)&dnsfns ) != 0 ) {
89*0Sstevel@tonic-gate 		return( -1 );
90*0Sstevel@tonic-gate 	    }
91*0Sstevel@tonic-gate 
92*0Sstevel@tonic-gate     return( 0 );
93*0Sstevel@tonic-gate }
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate 
96*0Sstevel@tonic-gate static LDAPHostEnt *
97*0Sstevel@tonic-gate prldap_gethostbyname( const char *name, LDAPHostEnt *result,
98*0Sstevel@tonic-gate 	char *buffer, int buflen, int *statusp, void *extradata )
99*0Sstevel@tonic-gate {
100*0Sstevel@tonic-gate 	PRHostEnt	prhent;
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate 	if( !statusp || ( *statusp = (int)PR_GetIPNodeByName( name,
103*0Sstevel@tonic-gate 		PRLDAP_DEFAULT_ADDRESS_FAMILY, PR_AI_DEFAULT,
104*0Sstevel@tonic-gate 		buffer, buflen, &prhent )) == PR_FAILURE ) {
105*0Sstevel@tonic-gate 		return( NULL );
106*0Sstevel@tonic-gate 	}
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate 	return( prldap_convert_hostent( result, &prhent ));
109*0Sstevel@tonic-gate }
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate static LDAPHostEnt *
113*0Sstevel@tonic-gate prldap_gethostbyaddr( const char *addr, int length, int type,
114*0Sstevel@tonic-gate 	LDAPHostEnt *result, char *buffer, int buflen, int *statusp,
115*0Sstevel@tonic-gate 	void *extradata )
116*0Sstevel@tonic-gate {
117*0Sstevel@tonic-gate     PRHostEnt	prhent;
118*0Sstevel@tonic-gate     PRNetAddr	iaddr;
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate 	if ( PR_SetNetAddr(PR_IpAddrNull, PRLDAP_DEFAULT_ADDRESS_FAMILY,
121*0Sstevel@tonic-gate 		0, &iaddr) == PR_FAILURE
122*0Sstevel@tonic-gate  		|| PR_StringToNetAddr( addr, &iaddr ) == PR_FAILURE ) {
123*0Sstevel@tonic-gate 		return( NULL );
124*0Sstevel@tonic-gate 	}
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate     if( !statusp || (*statusp = PR_GetHostByAddr(&iaddr, buffer,
127*0Sstevel@tonic-gate 	     buflen, &prhent )) == PR_FAILURE ) {
128*0Sstevel@tonic-gate 	return( NULL );
129*0Sstevel@tonic-gate     }
130*0Sstevel@tonic-gate     return( prldap_convert_hostent( result, &prhent ));
131*0Sstevel@tonic-gate }
132*0Sstevel@tonic-gate 
133*0Sstevel@tonic-gate static int
134*0Sstevel@tonic-gate prldap_getpeername( LDAP *ld, struct sockaddr *addr, char *buffer, int buflen)
135*0Sstevel@tonic-gate {
136*0Sstevel@tonic-gate     PRLDAPIOSocketArg *sa;
137*0Sstevel@tonic-gate     PRFileDesc	*fd;
138*0Sstevel@tonic-gate     PRNetAddr	iaddr;
139*0Sstevel@tonic-gate     int		ret;
140*0Sstevel@tonic-gate 
141*0Sstevel@tonic-gate     if (NULL != ld) {
142*0Sstevel@tonic-gate 	    ret = prldap_socket_arg_from_ld( ld, &sa );
143*0Sstevel@tonic-gate 	    if (ret != LDAP_SUCCESS) {
144*0Sstevel@tonic-gate 		return (-1);
145*0Sstevel@tonic-gate 	    }
146*0Sstevel@tonic-gate 	    ret = PR_GetPeerName(sa->prsock_prfd, &iaddr);
147*0Sstevel@tonic-gate 	    if( ret == PR_FAILURE ) {
148*0Sstevel@tonic-gate 		return( -1 );
149*0Sstevel@tonic-gate 	    }
150*0Sstevel@tonic-gate 	    *addr = *((struct sockaddr *)&iaddr.raw);
151*0Sstevel@tonic-gate 	    ret = PR_NetAddrToString(&iaddr, buffer, buflen);
152*0Sstevel@tonic-gate 	    if( ret == PR_FAILURE ) {
153*0Sstevel@tonic-gate 		return( -1 );
154*0Sstevel@tonic-gate 	    }
155*0Sstevel@tonic-gate 	    return (0);
156*0Sstevel@tonic-gate     }
157*0Sstevel@tonic-gate     return (-1);
158*0Sstevel@tonic-gate }
159*0Sstevel@tonic-gate 
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate /*
162*0Sstevel@tonic-gate  * Function: prldap_convert_hostent()
163*0Sstevel@tonic-gate  * Description: copy the fields of a PRHostEnt struct to an LDAPHostEnt
164*0Sstevel@tonic-gate  * Returns: the LDAPHostEnt pointer passed in.
165*0Sstevel@tonic-gate  */
166*0Sstevel@tonic-gate static LDAPHostEnt *
167*0Sstevel@tonic-gate prldap_convert_hostent( LDAPHostEnt *ldhp, PRHostEnt *prhp )
168*0Sstevel@tonic-gate {
169*0Sstevel@tonic-gate 	ldhp->ldaphe_name = prhp->h_name;
170*0Sstevel@tonic-gate 	ldhp->ldaphe_aliases = prhp->h_aliases;
171*0Sstevel@tonic-gate 	ldhp->ldaphe_addrtype = prhp->h_addrtype;
172*0Sstevel@tonic-gate 	ldhp->ldaphe_length =  prhp->h_length;
173*0Sstevel@tonic-gate 	ldhp->ldaphe_addr_list =  prhp->h_addr_list;
174*0Sstevel@tonic-gate 	return( ldhp );
175*0Sstevel@tonic-gate }
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate #ifdef _SOLARIS_SDK
178*0Sstevel@tonic-gate /*
179*0Sstevel@tonic-gate  * prldap_x_install_dns_skipdb attempts to prevent recursion in resolving
180*0Sstevel@tonic-gate  * the hostname to an IP address when a host name is given to LDAP user.
181*0Sstevel@tonic-gate  *
182*0Sstevel@tonic-gate  * For example, libsldap cannot use LDAP to resolve the host name to an
183*0Sstevel@tonic-gate  * address because of recursion. The caller is instructing libldap to skip
184*0Sstevel@tonic-gate  * the specified name service when resolving addresses for the specified
185*0Sstevel@tonic-gate  * ldap connection.
186*0Sstevel@tonic-gate  *
187*0Sstevel@tonic-gate  * Note:
188*0Sstevel@tonic-gate  *      This only supports ipv4 addresses currently.
189*0Sstevel@tonic-gate  *
190*0Sstevel@tonic-gate  *      Since host_service applies to all connections, calling
191*0Sstevel@tonic-gate  *      prldap_x_install_dns_skipdb with name services other than
192*0Sstevel@tonic-gate  *      ldap or what uses ldap (for example nis+ might use ldap) to
193*0Sstevel@tonic-gate  *      skip will lead to unpredictable results.
194*0Sstevel@tonic-gate  *
195*0Sstevel@tonic-gate  * Returns:
196*0Sstevel@tonic-gate  *      0       if success and data base found
197*0Sstevel@tonic-gate  *      -1      if failure
198*0Sstevel@tonic-gate  */
199*0Sstevel@tonic-gate 
200*0Sstevel@tonic-gate int
201*0Sstevel@tonic-gate prldap_x_install_dns_skipdb(LDAP *ld, const char *skip)
202*0Sstevel@tonic-gate {
203*0Sstevel@tonic-gate 	enum __nsw_parse_err		pserr;
204*0Sstevel@tonic-gate 	struct __nsw_switchconfig       *conf;
205*0Sstevel@tonic-gate 	struct __nsw_lookup             *lkp;
206*0Sstevel@tonic-gate 	struct ldap_dns_fns             dns_fns;
207*0Sstevel@tonic-gate 	char                            *name_list = NULL;
208*0Sstevel@tonic-gate 	char                            *tmp;
209*0Sstevel@tonic-gate 	const char                      *name;
210*0Sstevel@tonic-gate 	int                             len;
211*0Sstevel@tonic-gate 	boolean_t                       got_skip = B_FALSE;
212*0Sstevel@tonic-gate 
213*0Sstevel@tonic-gate 	/*
214*0Sstevel@tonic-gate 	 * db_root_hosts.lock mutex is used to ensure that the name list
215*0Sstevel@tonic-gate 	 * is not in use by the name service switch while we are updating
216*0Sstevel@tonic-gate 	 * the host_service
217*0Sstevel@tonic-gate 	 */
218*0Sstevel@tonic-gate 
219*0Sstevel@tonic-gate         (void) mutex_lock(&db_root_hosts.lock);
220*0Sstevel@tonic-gate         conf = __nsw_getconfig("hosts", &pserr);
221*0Sstevel@tonic-gate         if (conf == NULL) {
222*0Sstevel@tonic-gate                 (void) mutex_unlock(&db_root_hosts.lock);
223*0Sstevel@tonic-gate                 return (0);
224*0Sstevel@tonic-gate         }
225*0Sstevel@tonic-gate 
226*0Sstevel@tonic-gate         /* check for skip and count other backends */
227*0Sstevel@tonic-gate         for (lkp = conf->lookups; lkp != NULL; lkp = lkp->next) {
228*0Sstevel@tonic-gate                 name = lkp->service_name;
229*0Sstevel@tonic-gate                 if (strcmp(name, skip) == 0) {
230*0Sstevel@tonic-gate                         got_skip = B_TRUE;
231*0Sstevel@tonic-gate                         continue;
232*0Sstevel@tonic-gate                 }
233*0Sstevel@tonic-gate                 if (name_list == NULL)
234*0Sstevel@tonic-gate                         name_list = strdup(name);
235*0Sstevel@tonic-gate                 else {
236*0Sstevel@tonic-gate                         len = strlen(name_list);
237*0Sstevel@tonic-gate                         tmp = realloc(name_list, len + strlen(name) + 2);
238*0Sstevel@tonic-gate                         if (tmp == NULL) {
239*0Sstevel@tonic-gate                                 free(name_list);
240*0Sstevel@tonic-gate                                 name_list = NULL;
241*0Sstevel@tonic-gate                         } else {
242*0Sstevel@tonic-gate                                 name_list = tmp;
243*0Sstevel@tonic-gate                                 name_list[len++] = ' ';
244*0Sstevel@tonic-gate                                 (void) strcpy(name_list+len, name);
245*0Sstevel@tonic-gate                         }
246*0Sstevel@tonic-gate                 }
247*0Sstevel@tonic-gate                 if (name_list == NULL) {        /* alloc error */
248*0Sstevel@tonic-gate                         (void) mutex_unlock(&db_root_hosts.lock);
249*0Sstevel@tonic-gate                         __nsw_freeconfig(conf);
250*0Sstevel@tonic-gate                         return (-1);
251*0Sstevel@tonic-gate                 }
252*0Sstevel@tonic-gate         }
253*0Sstevel@tonic-gate         __nsw_freeconfig(conf);
254*0Sstevel@tonic-gate         if (!got_skip) {
255*0Sstevel@tonic-gate 		/*
256*0Sstevel@tonic-gate 		 * Since skip name service not used for hosts, we do not need
257*0Sstevel@tonic-gate 		 * to install our private address resolution function
258*0Sstevel@tonic-gate 		 */
259*0Sstevel@tonic-gate                 (void) mutex_unlock(&db_root_hosts.lock);
260*0Sstevel@tonic-gate                 if (name_list != NULL)
261*0Sstevel@tonic-gate                         free(name_list);
262*0Sstevel@tonic-gate                 return (0);
263*0Sstevel@tonic-gate         }
264*0Sstevel@tonic-gate         if (host_service != NULL)
265*0Sstevel@tonic-gate                 free(host_service);
266*0Sstevel@tonic-gate         host_service = name_list;
267*0Sstevel@tonic-gate         (void) mutex_unlock(&db_root_hosts.lock);
268*0Sstevel@tonic-gate 
269*0Sstevel@tonic-gate         if (ldap_get_option(ld, LDAP_OPT_DNS_FN_PTRS, &dns_fns) != 0)
270*0Sstevel@tonic-gate                 return (-1);
271*0Sstevel@tonic-gate         dns_fns.lddnsfn_bufsize = PR_NETDB_BUF_SIZE;
272*0Sstevel@tonic-gate         dns_fns.lddnsfn_gethostbyname = prldap_gethostbyname1;
273*0Sstevel@tonic-gate         if (ldap_set_option(ld, LDAP_OPT_DNS_FN_PTRS, &dns_fns) != 0)
274*0Sstevel@tonic-gate                 return (-1);
275*0Sstevel@tonic-gate         return (0);
276*0Sstevel@tonic-gate }
277*0Sstevel@tonic-gate 
278*0Sstevel@tonic-gate /*
279*0Sstevel@tonic-gate  * prldap_initf_hosts is passed to and called by nss_search() as a
280*0Sstevel@tonic-gate  * service routine.
281*0Sstevel@tonic-gate  *
282*0Sstevel@tonic-gate  * Returns:
283*0Sstevel@tonic-gate  *      None
284*0Sstevel@tonic-gate  */
285*0Sstevel@tonic-gate 
286*0Sstevel@tonic-gate static void
287*0Sstevel@tonic-gate prldap_initf_hosts(nss_db_params_t *p)
288*0Sstevel@tonic-gate {
289*0Sstevel@tonic-gate         static char *no_service = "";
290*0Sstevel@tonic-gate 
291*0Sstevel@tonic-gate         p->name = NSS_DBNAM_HOSTS;
292*0Sstevel@tonic-gate         p->flags |= NSS_USE_DEFAULT_CONFIG;
293*0Sstevel@tonic-gate         p->default_config = host_service == NULL ? no_service : host_service;
294*0Sstevel@tonic-gate }
295*0Sstevel@tonic-gate 
296*0Sstevel@tonic-gate /*
297*0Sstevel@tonic-gate  * called by prldap_gethostbyname1()
298*0Sstevel@tonic-gate  */
299*0Sstevel@tonic-gate /*
300*0Sstevel@tonic-gate  * prldap_switch_gethostbyname_r is called by prldap_gethostbyname1 as a
301*0Sstevel@tonic-gate  * substitute for gethostbyname_r(). A method which prevents recursion. see
302*0Sstevel@tonic-gate  * prldap_gethostbyname1() and prldap_x_install_dns_skipdb().
303*0Sstevel@tonic-gate  *
304*0Sstevel@tonic-gate  * Returns:
305*0Sstevel@tonic-gate  *      Valid pointer to hostent      if success
306*0Sstevel@tonic-gate  *      PR_FAILURE                    if failure
307*0Sstevel@tonic-gate  */
308*0Sstevel@tonic-gate 
309*0Sstevel@tonic-gate static struct hostent *
310*0Sstevel@tonic-gate prldap_switch_gethostbyname_r(const char *name,
311*0Sstevel@tonic-gate         struct hostent *result, char *buffer, int buflen,
312*0Sstevel@tonic-gate         int *h_errnop)
313*0Sstevel@tonic-gate {
314*0Sstevel@tonic-gate         nss_XbyY_args_t arg;
315*0Sstevel@tonic-gate         nss_status_t    res;
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate 	/*
318*0Sstevel@tonic-gate 	 * Log the information indicating that we are trying to
319*0Sstevel@tonic-gate 	 * resolve the LDAP server name.
320*0Sstevel@tonic-gate 	 */
321*0Sstevel@tonic-gate 	syslog(LOG_INFO, "libldap: Resolving server name \"%s\"", name);
322*0Sstevel@tonic-gate 
323*0Sstevel@tonic-gate         NSS_XbyY_INIT(&arg, result, buffer, buflen, str2hostent);
324*0Sstevel@tonic-gate 
325*0Sstevel@tonic-gate         arg.key.name = name;
326*0Sstevel@tonic-gate         arg.stayopen = 0;
327*0Sstevel@tonic-gate 
328*0Sstevel@tonic-gate         res = nss_search(&db_root_hosts, prldap_initf_hosts,
329*0Sstevel@tonic-gate             NSS_DBOP_HOSTS_BYNAME, &arg);
330*0Sstevel@tonic-gate         arg.status = res;
331*0Sstevel@tonic-gate         *h_errnop = arg.h_errno;
332*0Sstevel@tonic-gate         return (struct hostent *)NSS_XbyY_FINI(&arg);
333*0Sstevel@tonic-gate }
334*0Sstevel@tonic-gate 
335*0Sstevel@tonic-gate /*
336*0Sstevel@tonic-gate  * prldap_gethostbyname1 is used to be a substitute gethostbyname_r for
337*0Sstevel@tonic-gate  * libldap when it is unsafe to use the normal nameservice functions.
338*0Sstevel@tonic-gate  *
339*0Sstevel@tonic-gate  * Returns:
340*0Sstevel@tonic-gate  *      pointer to LDAPHostEnt:         if success contains the address
341*0Sstevel@tonic-gate  *      NULL pointer:                   if failure
342*0Sstevel@tonic-gate  */
343*0Sstevel@tonic-gate 
344*0Sstevel@tonic-gate static LDAPHostEnt *
345*0Sstevel@tonic-gate prldap_gethostbyname1(const char *name, LDAPHostEnt *result,
346*0Sstevel@tonic-gate 	char *buffer, int buflen, int *statusp, void *extradata)
347*0Sstevel@tonic-gate {
348*0Sstevel@tonic-gate         int         h_errno;
349*0Sstevel@tonic-gate 	LDAPHostEnt prhent;
350*0Sstevel@tonic-gate 
351*0Sstevel@tonic-gate         if (!statusp || ( *statusp = prldap_switch_gethostbyname_r(name,
352*0Sstevel@tonic-gate                         &prhent, buffer, buflen, &h_errno )) == PR_FAILURE) {
353*0Sstevel@tonic-gate 		/*
354*0Sstevel@tonic-gate 		 * If we got here, it means that we are not able to
355*0Sstevel@tonic-gate 		 * resolve the LDAP server name and so warn the system
356*0Sstevel@tonic-gate 		 * adminstrator accordingly.
357*0Sstevel@tonic-gate 		 */
358*0Sstevel@tonic-gate 		syslog(LOG_WARNING, "libldap: server name \"%s\" could not "
359*0Sstevel@tonic-gate 		"be resolved", name);
360*0Sstevel@tonic-gate 		return (NULL);
361*0Sstevel@tonic-gate         }
362*0Sstevel@tonic-gate 
363*0Sstevel@tonic-gate         return (prldap_convert_hostent(result, &prhent));
364*0Sstevel@tonic-gate }
365*0Sstevel@tonic-gate 
366*0Sstevel@tonic-gate #endif  /* _SOLARIS_SDK */
367