Exemple #1
0
int ldap_pvt_get_hname(
	const struct sockaddr *sa,
	int len,
	char *name,
	int namelen,
	char **err )
{
	int rc;
#if defined( HAVE_GETNAMEINFO )

#if defined( LDAP_R_COMPILE )
	ldap_pvt_thread_mutex_lock( &ldap_int_resolv_mutex );
#endif
	rc = getnameinfo( sa, len, name, namelen, NULL, 0, 0 );
#if defined( LDAP_R_COMPILE )
	ldap_pvt_thread_mutex_unlock( &ldap_int_resolv_mutex );
#endif
	if ( rc ) *err = (char *)AC_GAI_STRERROR( rc );
	return rc;

#else /* !HAVE_GETNAMEINFO */
	char *addr;
	int alen;
	struct hostent *hp = NULL;
#ifdef HAVE_GETHOSTBYADDR_R
	struct hostent hb;
	int buflen=BUFSTART, h_errno;
	char *buf=NULL;
#endif

#ifdef LDAP_PF_INET6
	if (sa->sa_family == AF_INET6) {
		struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
		addr = (char *)&sin->sin6_addr;
		alen = sizeof(sin->sin6_addr);
	} else
#endif
	if (sa->sa_family == AF_INET) {
		struct sockaddr_in *sin = (struct sockaddr_in *)sa;
		addr = (char *)&sin->sin_addr;
		alen = sizeof(sin->sin_addr);
	} else {
		rc = NO_RECOVERY;
		*err = (char *)HSTRERROR( rc );
		return rc;
	}
#if defined( HAVE_GETHOSTBYADDR_R )
	for(;buflen<BUFMAX;) {
		if (safe_realloc( &buf, buflen )==NULL) {
			*err = (char *)STRERROR( ENOMEM );
			return ENOMEM;
		}
#if (GETHOSTBYADDR_R_NARGS < 8)
		hp=gethostbyaddr_r( addr, alen, sa->sa_family,
			&hb, buf, buflen, &h_errno );
		rc = (hp == NULL) ? -1 : 0;
#else
		rc = gethostbyaddr_r( addr, alen, sa->sa_family,
			&hb, buf, buflen, 
			&hp, &h_errno );
#endif
#ifdef NETDB_INTERNAL
		if ((rc<0) &&
			(h_errno==NETDB_INTERNAL) &&
			(errno==ERANGE))
		{
			buflen*=2;
			continue;
		}
#endif
		break;
	}
	if (hp) {
		strncpy( name, hp->h_name, namelen );
	} else {
		*err = (char *)HSTRERROR( h_errno );
	}
	LDAP_FREE(buf);
#else /* HAVE_GETHOSTBYADDR_R */

#if defined( LDAP_R_COMPILE )
	ldap_pvt_thread_mutex_lock( &ldap_int_resolv_mutex );
#endif
	hp = gethostbyaddr( addr, alen, sa->sa_family );
	if (hp) {
		strncpy( name, hp->h_name, namelen );
		rc = 0;
	} else {
		rc = h_errno;
		*err = (char *)HSTRERROR( h_errno );
	}
#if defined( LDAP_R_COMPILE )
	ldap_pvt_thread_mutex_unlock( &ldap_int_resolv_mutex );
#endif

#endif	/* !HAVE_GETHOSTBYADDR_R */
	return rc;
#endif	/* !HAVE_GETNAMEINFO */
}
Exemple #2
0
/* port = 0 indicates AF_LOCAL */
static int slap_get_listener_addresses(
	const char *host,
	unsigned short port,
	struct sockaddr ***sal)
{
	struct sockaddr **sap;

#ifdef LDAP_PF_LOCAL
	if ( port == 0 ) {
		*sal = ch_malloc(2 * sizeof(void *));
		if (*sal == NULL) {
			return -1;
		}

		sap = *sal;
		*sap = ch_malloc(sizeof(struct sockaddr_un));
		if (*sap == NULL)
			goto errexit;
		sap[1] = NULL;

		if ( strlen(host) >
		     (sizeof(((struct sockaddr_un *)*sap)->sun_path) - 1) ) {
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, INFO, 
				"slap_get_listener_addresses: domain socket path (%s) "
				"too long in URL\n", host, 0, 0 );
#else
			Debug( LDAP_DEBUG_ANY,
			       "daemon: domain socket path (%s) too long in URL",
			       host, 0, 0);
#endif
			goto errexit;
		}

		(void)memset( (void *)*sap, '\0', sizeof(struct sockaddr_un) );
		(*sap)->sa_family = AF_LOCAL;
		strcpy( ((struct sockaddr_un *)*sap)->sun_path, host );
	} else
#endif
	{
#ifdef HAVE_GETADDRINFO
		struct addrinfo hints, *res, *sai;
		int n, err;
		char serv[7];

		memset( &hints, '\0', sizeof(hints) );
		hints.ai_flags = AI_PASSIVE;
		hints.ai_socktype = SOCK_STREAM;
		hints.ai_family = slap_inet4or6;
		snprintf(serv, sizeof serv, "%d", port);

		if ( (err = getaddrinfo(host, serv, &hints, &res)) ) {
#ifdef NEW_LOGGING
			LDAP_LOG( CONNECTION, INFO, 
				   "slap_get_listener_addresses: getaddrinfo failed: %s\n",
				   AC_GAI_STRERROR(err), 0, 0 );
#else
			Debug( LDAP_DEBUG_ANY, "daemon: getaddrinfo failed: %s\n",
				AC_GAI_STRERROR(err), 0, 0);
#endif
			return -1;
		}

		sai = res;
		for (n=2; (sai = sai->ai_next) != NULL; n++) {
			/* EMPTY */ ;
		}
		*sal = ch_calloc(n, sizeof(void *));
		if (*sal == NULL) {
			return -1;
		}

		sap = *sal;
		*sap = NULL;

		for ( sai=res; sai; sai=sai->ai_next ) {
			if( sai->ai_addr == NULL ) {
#ifdef NEW_LOGGING
				LDAP_LOG( CONNECTION, INFO,
					"slap_get_listener_addresses: "
					"getaddrinfo ai_addr is NULL?\n", 0, 0, 0 );
#else
				Debug( LDAP_DEBUG_ANY, "slap_get_listener_addresses: "
					"getaddrinfo ai_addr is NULL?\n", 0, 0, 0 );
#endif
				freeaddrinfo(res);
				goto errexit;
			}

			switch (sai->ai_family) {
#  ifdef LDAP_PF_INET6
			case AF_INET6:
				*sap = ch_malloc(sizeof(struct sockaddr_in6));
				if (*sap == NULL) {
					freeaddrinfo(res);
					goto errexit;
				}
				*(struct sockaddr_in6 *)*sap =
					*((struct sockaddr_in6 *)sai->ai_addr);
				break;
#  endif
			case AF_INET:
				*sap = ch_malloc(sizeof(struct sockaddr_in));
				if (*sap == NULL) {
					freeaddrinfo(res);
					goto errexit;
				}
				*(struct sockaddr_in *)*sap =
					*((struct sockaddr_in *)sai->ai_addr);
				break;
			default:
				*sap = NULL;
				break;
			}

			if (*sap != NULL) {
				(*sap)->sa_family = sai->ai_family;
				sap++;
				*sap = NULL;
			}
		}

		freeaddrinfo(res);
#else
		int i, n = 1;
		struct in_addr in;
		struct hostent *he = NULL;

		if ( host == NULL ) {
			in.s_addr = htonl(INADDR_ANY);

		} else if ( !inet_aton( host, &in ) ) {
			he = gethostbyname( host );
			if( he == NULL ) {
#ifdef NEW_LOGGING
				LDAP_LOG( CONNECTION, INFO, 
					"slap_get_listener_addresses: invalid host %s\n", host, 0, 0 );
#else
				Debug( LDAP_DEBUG_ANY,
				       "daemon: invalid host %s", host, 0, 0);
#endif
				return -1;
			}
			for (n = 0; he->h_addr_list[n]; n++) ;
		}

		*sal = ch_malloc((n+1) * sizeof(void *));
		if (*sal == NULL) {
			return -1;
		}

		sap = *sal;
		for ( i = 0; i<n; i++ ) {
			sap[i] = ch_malloc(sizeof(struct sockaddr_in));
			if (*sap == NULL) {
				goto errexit;
			}
			(void)memset( (void *)sap[i], '\0', sizeof(struct sockaddr_in) );
			sap[i]->sa_family = AF_INET;
			((struct sockaddr_in *)sap[i])->sin_port = htons(port);
			if (he) {
				AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr, he->h_addr_list[i], sizeof(struct in_addr) );
			} else {
				AC_MEMCPY( &((struct sockaddr_in *)sap[i])->sin_addr, &in, sizeof(struct in_addr) );
			}
		}
		sap[i] = NULL;
#endif
	}

	return 0;

errexit:
	slap_free_listener_addresses(*sal);
	return -1;
}