示例#1
0
static int
dns_find_realm(krb5_context context,
	       const char *domain,
	       krb5_realm **realms)
{
    static char *default_labels[] = { "_kerberos", NULL };
    char dom[MAXHOSTNAMELEN];
    struct dns_reply *r;
    char **labels;
    int i, ret;
    
    labels = krb5_config_get_strings(context, NULL, "libdefaults",
	"dns_lookup_realm_labels", NULL);
    if(labels == NULL)
	labels = default_labels;
    if(*domain == '.')
	domain++;
    for (i = 0; labels[i] != NULL; i++) {
	ret = snprintf(dom, sizeof(dom), "%s.%s.", labels[i], domain);
	if(ret < 0 || ret >= sizeof(dom))
	    return -1;
    	r = dns_lookup(dom, "TXT");
    	if(r != NULL) {
	    ret = copy_txt_to_realms (r->head, realms);
	    dns_free_data(r);
	    if(ret == 0)
		return 0;
	}
    }
    return -1;
}
示例#2
0
static krb5_error_code
srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count, 
	       const char *realm, const char *dns_type,
	       const char *proto, const char *service, int port)
{
    char domain[1024];
    struct dns_reply *r;
    struct resource_record *rr;
    int num_srv;
    int proto_num;
    int def_port;

    *res = NULL;
    *count = 0;

    proto_num = string_to_proto(proto);
    if(proto_num < 0) {
	krb5_set_error_string(context, "unknown protocol `%s'", proto);
	return EINVAL;
    }

    if(proto_num == KRB5_KRBHST_HTTP)
	def_port = ntohs(krb5_getportbyname (context, "http", "tcp", 80));
    else if(port == 0)
	def_port = ntohs(krb5_getportbyname (context, service, proto, 88));
    else
	def_port = port;

    snprintf(domain, sizeof(domain), "_%s._%s.%s.", service, proto, realm);

    r = dns_lookup(domain, dns_type);
    if(r == NULL)
	return KRB5_KDC_UNREACH;

    for(num_srv = 0, rr = r->head; rr; rr = rr->next) 
	if(rr->type == T_SRV)
	    num_srv++;

    *res = malloc(num_srv * sizeof(**res));
    if(*res == NULL) {
	dns_free_data(r);
	krb5_set_error_string(context, "malloc: out of memory");
	return ENOMEM;
    }

    dns_srv_order(r);

    for(num_srv = 0, rr = r->head; rr; rr = rr->next) 
	if(rr->type == T_SRV) {
	    krb5_krbhst_info *hi;
	    size_t len = strlen(rr->u.srv->target);

	    hi = calloc(1, sizeof(*hi) + len);
	    if(hi == NULL) {
		dns_free_data(r);
		while(--num_srv >= 0)
		    free((*res)[num_srv]);
		free(*res);
		*res = NULL;
		return ENOMEM;
	    }
	    (*res)[num_srv++] = hi;

	    hi->proto = proto_num;
	    
	    hi->def_port = def_port;
	    if (port != 0)
		hi->port = port;
	    else
		hi->port = rr->u.srv->port;

	    strlcpy(hi->hostname, rr->u.srv->target, len + 1);
	}

    *count = num_srv;
	    
    dns_free_data(r);
    return 0;
}
示例#3
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_425_conv_principal_ext2(krb5_context context,
			     const char *name,
			     const char *instance,
			     const char *realm,
			     krb5_boolean (*func)(krb5_context, 
						  void *, krb5_principal),
			     void *funcctx,
			     krb5_boolean resolve,
			     krb5_principal *princ)
{
    const char *p;
    krb5_error_code ret;
    krb5_principal pr;
    char host[MAXHOSTNAMELEN];
    char local_hostname[MAXHOSTNAMELEN];

    /* do the following: if the name is found in the
       `v4_name_convert:host' part, is is assumed to be a `host' type
       principal, and the instance is looked up in the
       `v4_instance_convert' part. if not found there the name is
       (optionally) looked up as a hostname, and if that doesn't yield
       anything, the `default_domain' is appended to the instance
       */

    if(instance == NULL)
	goto no_host;
    if(instance[0] == 0){
	instance = NULL;
	goto no_host;
    }
    p = get_name_conversion(context, realm, name);
    if(p == NULL)
	goto no_host;
    name = p;
    p = krb5_config_get_string(context, NULL, "realms", realm, 
			       "v4_instance_convert", instance, NULL);
    if(p){
	instance = p;
	ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
	if(func == NULL || (*func)(context, funcctx, pr)){
	    *princ = pr;
	    return 0;
	}
	krb5_free_principal(context, pr);
	*princ = NULL;
	krb5_clear_error_string (context);
	return HEIM_ERR_V4_PRINC_NO_CONV;
    }
    if(resolve){
	krb5_boolean passed = FALSE;
	char *inst = NULL;
#ifdef USE_RESOLVER
	struct dns_reply *r;

	r = dns_lookup(instance, "aaaa");
	if (r) {
	    if (r->head && r->head->type == T_AAAA) {
		inst = strdup(r->head->domain);
		passed = TRUE;
	    }
	    dns_free_data(r);
	} else {
	    r = dns_lookup(instance, "a");
	    if (r) {
		if(r->head && r->head->type == T_A) {
		    inst = strdup(r->head->domain);
		    passed = TRUE;
		}
		dns_free_data(r);
	    }
	}
#else
	struct addrinfo hints, *ai;
	
	memset (&hints, 0, sizeof(hints));
	hints.ai_flags = AI_CANONNAME;
	ret = getaddrinfo(instance, NULL, &hints, &ai);
	if (ret == 0) {
	    const struct addrinfo *a;
	    for (a = ai; a != NULL; a = a->ai_next) {
		if (a->ai_canonname != NULL) {
		    inst = strdup (a->ai_canonname);
		    passed = TRUE;
		    break;
		}
	    }
	    freeaddrinfo (ai);
	}
#endif
	if (passed) {
	    if (inst == NULL) {
		krb5_set_error_string (context, "malloc: out of memory");
		return ENOMEM;
	    }
	    strlwr(inst);
	    ret = krb5_make_principal(context, &pr, realm, name, inst,
				      NULL);
	    free (inst);
	    if(ret == 0) {
		if(func == NULL || (*func)(context, funcctx, pr)){
		    *princ = pr;
		    return 0;
		}
		krb5_free_principal(context, pr);
	    }
	}
    }
    if(func != NULL) {
	snprintf(host, sizeof(host), "%s.%s", instance, realm);
	strlwr(host);
	ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
	if((*func)(context, funcctx, pr)){
	    *princ = pr;
	    return 0;
	}
	krb5_free_principal(context, pr);
    }

    /*
     * if the instance is the first component of the local hostname,
     * the converted host should be the long hostname.
     */

    if (func == NULL && 
        gethostname (local_hostname, sizeof(local_hostname)) == 0 &&
        strncmp(instance, local_hostname, strlen(instance)) == 0 && 
	local_hostname[strlen(instance)] == '.') {
	strlcpy(host, local_hostname, sizeof(host));
	goto local_host;
    }

    {
	char **domains, **d;
	domains = krb5_config_get_strings(context, NULL, "realms", realm,
					  "v4_domains", NULL);
	for(d = domains; d && *d; d++){
	    snprintf(host, sizeof(host), "%s.%s", instance, *d);
	    ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
	    if(func == NULL || (*func)(context, funcctx, pr)){
		*princ = pr;
		krb5_config_free_strings(domains);
		return 0;
	    }
	    krb5_free_principal(context, pr);
	}
	krb5_config_free_strings(domains);
    }

    
    p = krb5_config_get_string(context, NULL, "realms", realm, 
			       "default_domain", NULL);
    if(p == NULL){
	/* this should be an error, just faking a name is not good */
	krb5_clear_error_string (context);
	return HEIM_ERR_V4_PRINC_NO_CONV;
    }
	
    if (*p == '.')
	++p;
    snprintf(host, sizeof(host), "%s.%s", instance, p);
local_host:
    ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
    if(func == NULL || (*func)(context, funcctx, pr)){
	*princ = pr;
	return 0;
    }
    krb5_free_principal(context, pr);
    krb5_clear_error_string (context);
    return HEIM_ERR_V4_PRINC_NO_CONV;
no_host:
    p = krb5_config_get_string(context, NULL,
			       "realms",
			       realm,
			       "v4_name_convert",
			       "plain",
			       name,
			       NULL);
    if(p == NULL)
	p = krb5_config_get_string(context, NULL,
				   "libdefaults",
				   "v4_name_convert",
				   "plain",
				   name,
				   NULL);
    if(p)
	name = p;
    
    ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
    if(func == NULL || (*func)(context, funcctx, pr)){
	*princ = pr;
	return 0;
    }
    krb5_free_principal(context, pr);
    krb5_clear_error_string (context);
    return HEIM_ERR_V4_PRINC_NO_CONV;
}