Esempio n. 1
0
static krb5_error_code
add_plugin_host(struct krb5_krbhst_data *kd,
		const char *host,
		const char *port,
		int portnum,
		int proto)
{
    struct krb5_krbhst_info *hi;
    struct addrinfo hints, *ai;
    size_t hostlen;
    int ret;

    make_hints(&hints, proto);
    ret = getaddrinfo(host, port, &hints, &ai);
    if (ret)
	return 0;

    hostlen = strlen(host);

    hi = calloc(1, sizeof(*hi) + hostlen);
    if(hi == NULL)
	return ENOMEM;

    hi->proto = proto;
    hi->port  = hi->def_port = portnum;
    hi->ai    = ai;
    memmove(hi->hostname, host, hostlen);
    hi->hostname[hostlen] = '\0';
    append_host_hostinfo(kd, hi);

    return 0;
}
Esempio n. 2
0
static krb5_error_code
fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
		   const char *serv_string, int port, int proto)
{
    char *host = NULL;
    int ret;
    struct addrinfo *ai;
    struct addrinfo hints;
    char portstr[NI_MAXSERV];

    _krb5_debug(context, 2, "fallback lookup %d for realm %s (service %s)",
		kd->fallback_count, kd->realm, serv_string);

    /*
     * Don't try forever in case the DNS server keep returning us
     * entries (like wildcard entries or the .nu TLD)
     */
    if(kd->fallback_count >= 5) {
	kd->flags |= KD_FALLBACK;
	return 0;
    }

    if(kd->fallback_count == 0)
	ret = asprintf(&host, "%s.%s.", serv_string, kd->realm);
    else
	ret = asprintf(&host, "%s-%d.%s.",
		       serv_string, kd->fallback_count, kd->realm);

    if (ret < 0 || host == NULL)
	return ENOMEM;

    make_hints(&hints, proto);
    snprintf(portstr, sizeof(portstr), "%d", port);
    ret = getaddrinfo(host, portstr, &hints, &ai);
    if (ret) {
	/* no more hosts, so we're done here */
	free(host);
	kd->flags |= KD_FALLBACK;
    } else {
	struct krb5_krbhst_info *hi;
	size_t hostlen = strlen(host);

	hi = calloc(1, sizeof(*hi) + hostlen);
	if(hi == NULL) {
	    free(host);
	    return ENOMEM;
	}

	hi->proto = proto;
	hi->port  = hi->def_port = port;
	hi->ai    = ai;
	memmove(hi->hostname, host, hostlen);
	hi->hostname[hostlen] = '\0';
	free(host);
	append_host_hostinfo(kd, hi);
	kd->fallback_count++;
    }
    return 0;
}
Esempio n. 3
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_krbhst_get_addrinfo(krb5_context context, krb5_krbhst_info *host,
			 struct addrinfo **ai)
{
    int ret = 0;

    if (host->ai == NULL) {
	struct addrinfo hints;
	char portstr[NI_MAXSERV];
	char *hostname = host->hostname;

	snprintf (portstr, sizeof(portstr), "%d", host->port);
	make_hints(&hints, host->proto);

	/**
	 * First try this as an IP address, this allows us to add a
	 * dot at the end to stop using the search domains.
	 */

	hints.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV;

	ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
	if (ret == 0)
	    goto out;

	/**
	 * If the hostname contains a dot, assumes it's a FQDN and
	 * don't use search domains since that might be painfully slow
	 * when machine is disconnected from that network.
	 */

	hints.ai_flags &= ~(AI_NUMERICHOST);

	if (strchr(hostname, '.') && hostname[strlen(hostname) - 1] != '.') {
	    ret = asprintf(&hostname, "%s.", host->hostname);
	    if (ret < 0 || hostname == NULL)
		return ENOMEM;
	}

	ret = getaddrinfo(hostname, portstr, &hints, &host->ai);
	if (hostname != host->hostname)
	    free(hostname);
	if (ret) {
	    ret = krb5_eai_to_heim_errno(ret, errno);
	    goto out;
	}
    }
 out:
    *ai = host->ai;
    return ret;
}
Esempio n. 4
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_krbhst_get_addrinfo(krb5_context context, krb5_krbhst_info *host,
			 struct addrinfo **ai)
{
    struct addrinfo hints;
    char portstr[NI_MAXSERV];
    int ret;

    if (host->ai == NULL) {
	make_hints(&hints, host->proto);
	snprintf (portstr, sizeof(portstr), "%d", host->port);
	ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
	if (ret)
	    return krb5_eai_to_heim_errno(ret, errno);
    }
    *ai = host->ai;
    return 0;
}
Esempio n. 5
0
static krb5_error_code 
add_locate(void *ctx, int type, struct sockaddr *addr)
{
    struct krb5_krbhst_info *hi;
    struct krb5_krbhst_data *kd = ctx;
    char host[NI_MAXHOST], port[NI_MAXSERV];
    struct addrinfo hints, *ai;
    socklen_t socklen;
    size_t hostlen;
    int ret;

    socklen = socket_sockaddr_size(addr);

    ret = getnameinfo(addr, socklen, host, sizeof(host), port, sizeof(port),
		      NI_NUMERICHOST|NI_NUMERICSERV);
    if (ret != 0)
	return 0;

    make_hints(&hints, krbhst_get_default_proto(kd));
    ret = getaddrinfo(host, port, &hints, &ai);
    if (ret)
	return 0;

    hostlen = strlen(host);

    hi = calloc(1, sizeof(*hi) + hostlen);
    if(hi == NULL)
	return ENOMEM;
    
    hi->proto = krbhst_get_default_proto(kd);
    hi->port  = hi->def_port = socket_get_port(addr);
    hi->ai    = ai;
    memmove(hi->hostname, host, hostlen);
    hi->hostname[hostlen] = '\0';
    append_host_hostinfo(kd, hi);

    return 0;
}