示例#1
0
/* Heimdal */
 krb5_error_code smb_krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters)
{
	krb5_krbhst_handle hnd;
	krb5_krbhst_info *hinfo;
	krb5_error_code rc;
	int num_kdcs, i;
	struct sockaddr *sa;
	struct addrinfo *ai;

	*addr_pp = NULL;
	*naddrs = 0;

	rc = krb5_krbhst_init(ctx, realm->data, KRB5_KRBHST_KDC, &hnd);
	if (rc) {
		DEBUG(0, ("smb_krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc)));
		return rc;
	}

	for ( num_kdcs = 0; (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); num_kdcs++)
		;

	krb5_krbhst_reset(ctx, hnd);

	if (!num_kdcs) {
		DEBUG(0, ("smb_krb5_locate_kdc: zero kdcs found !\n"));
		krb5_krbhst_free(ctx, hnd);
		return -1;
	}

	sa = SMB_MALLOC_ARRAY( struct sockaddr, num_kdcs );
	if (!sa) {
		DEBUG(0, ("smb_krb5_locate_kdc: malloc failed\n"));
		krb5_krbhst_free(ctx, hnd);
		naddrs = 0;
		return -1;
	}

	memset(sa, '\0', sizeof(struct sockaddr) * num_kdcs );

	for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) {

#if defined(HAVE_KRB5_KRBHST_GET_ADDRINFO)
		rc = krb5_krbhst_get_addrinfo(ctx, hinfo, &ai);
		if (rc) {
			DEBUG(0,("krb5_krbhst_get_addrinfo failed: %s\n", error_message(rc)));
			continue;
		}
#endif
		if (hinfo->ai && hinfo->ai->ai_family == AF_INET) 
			memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr));
	}

	krb5_krbhst_free(ctx, hnd);

	*naddrs = num_kdcs;
	*addr_pp = sa;
	return 0;
}
示例#2
0
文件: krbhst.c 项目: 2asoft/freebsd
static krb5_error_code
gethostlist(krb5_context context, const char *realm,
	    unsigned int type, char ***hostlist)
{
    krb5_error_code ret;
    int nhost = 0;
    krb5_krbhst_handle handle;
    char host[MAXHOSTNAMELEN];
    krb5_krbhst_info *hostinfo;

    ret = krb5_krbhst_init(context, realm, type, &handle);
    if (ret)
	return ret;

    while(krb5_krbhst_next(context, handle, &hostinfo) == 0)
	nhost++;
    if(nhost == 0) {
	krb5_set_error_message(context, KRB5_KDC_UNREACH,
			       N_("No KDC found for realm %s", ""), realm);
	return KRB5_KDC_UNREACH;
    }
    *hostlist = calloc(nhost + 1, sizeof(**hostlist));
    if(*hostlist == NULL) {
	krb5_krbhst_free(context, handle);
	return ENOMEM;
    }

    krb5_krbhst_reset(context, handle);
    nhost = 0;
    while(krb5_krbhst_next_as_string(context, handle,
				     host, sizeof(host)) == 0) {
	if(((*hostlist)[nhost++] = strdup(host)) == NULL) {
	    krb5_free_krbhst(context, *hostlist);
	    krb5_krbhst_free(context, handle);
	    return ENOMEM;
	}
    }
    (*hostlist)[nhost] = NULL;
    krb5_krbhst_free(context, handle);
    return 0;
}
示例#3
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_krbhst_handle handle;
    char host[MAXHOSTNAMELEN];
    int found = 0;

    setprogname(argv[0]);

    ret = krb5_init_context(&context);
    if (ret)
	errx(1, "krb5_init_contex");

    ret = krb5_plugin_register(context, PLUGIN_TYPE_DATA,
			       KRB5_PLUGIN_LOCATE, &resolve);
    if (ret)
	krb5_err(context, 1, ret, "krb5_plugin_register");


    ret = krb5_krbhst_init_flags(context,
				 "NOTHERE.H5L.SE",
				 KRB5_KRBHST_KDC,
				 0,
				 &handle);
    if (ret)
	krb5_err(context, 1, ret, "krb5_krbhst_init_flags");


    while(krb5_krbhst_next_as_string(context, handle, host, sizeof(host)) == 0){
	found++;
 	if (strcmp(host, "127.0.0.2") != 0 && strcmp(host, "tcp/127.0.0.2") != 0)
	    krb5_errx(context, 1, "wrong address: %s", host);
    }
    if (!found)
	krb5_errx(context, 1, "failed to find host");

    krb5_krbhst_free(context, handle);

    krb5_free_context(context);
    return 0;
}
示例#4
0
static krb5_error_code
change_password_loop (krb5_context	context,
		      krb5_creds	*creds,
		      krb5_principal	targprinc,
		      char		*newpw,
		      int		*result_code,
		      krb5_data		*result_code_string,
		      krb5_data		*result_string,
		      struct kpwd_proc	*proc)
{
    krb5_error_code ret;
    krb5_auth_context auth_context = NULL;
    krb5_krbhst_handle handle = NULL;
    krb5_krbhst_info *hi;
    int sock;
    int i;
    int done = 0;
    krb5_realm realm = creds->client->realm;

    ret = krb5_auth_con_init (context, &auth_context);
    if (ret)
	return ret;

    krb5_auth_con_setflags (context, auth_context,
			    KRB5_AUTH_CONTEXT_DO_SEQUENCE);

    ret = krb5_krbhst_init (context, realm, KRB5_KRBHST_CHANGEPW, &handle);
    if (ret)
	goto out;

    while (!done && (ret = krb5_krbhst_next(context, handle, &hi)) == 0) {
	struct addrinfo *ai, *a;
	int is_stream;

	switch (hi->proto) {
	case KRB5_KRBHST_UDP:
	    if ((proc->flags & SUPPORT_UDP) == 0)
		continue;
	    is_stream = 0;
	    break;
	case KRB5_KRBHST_TCP:
	    if ((proc->flags & SUPPORT_TCP) == 0)
		continue;
	    is_stream = 1;
	    break;
	default:
	    continue;
	}

	ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
	if (ret)
	    continue;

	for (a = ai; !done && a != NULL; a = a->ai_next) {
	    int replied = 0;

	    sock = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
	    if (sock < 0)
		continue;

	    ret = connect(sock, a->ai_addr, a->ai_addrlen);
	    if (ret < 0) {
		close (sock);
		goto out;
	    }

	    ret = krb5_auth_con_genaddrs (context, auth_context, sock,
					  KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR);
	    if (ret) {
		close (sock);
		goto out;
	    }

	    for (i = 0; !done && i < 5; ++i) {
		fd_set fdset;
		struct timeval tv;

		if (!replied) {
		    replied = 0;
		    
		    ret = (*proc->send_req) (context,
					     &auth_context,
					     creds,
					     targprinc,
					     is_stream,
					     sock,
					     newpw,
					     hi->hostname);
		    if (ret) {
			close(sock);
			goto out;
		    }
		}
	    
		if (sock >= FD_SETSIZE) {
		    krb5_set_error_string(context, "fd %d too large", sock);
		    ret = ERANGE;
		    close (sock);
		    goto out;
		}

		FD_ZERO(&fdset);
		FD_SET(sock, &fdset);
		tv.tv_usec = 0;
		tv.tv_sec  = 1 + (1 << i);

		ret = select (sock + 1, &fdset, NULL, NULL, &tv);
		if (ret < 0 && errno != EINTR) {
		    close(sock);
		    goto out;
		}
		if (ret == 1) {
		    ret = (*proc->process_rep) (context,
						auth_context,
						is_stream,
						sock,
						result_code,
						result_code_string,
						result_string,
						hi->hostname);
		    if (ret == 0)
			done = 1;
		    else if (i > 0 && ret == KRB5KRB_AP_ERR_MUT_FAIL)
			replied = 1;
		} else {
		    ret = KRB5_KDC_UNREACH;
		}
	    }
	    close (sock);
	}
    }

 out:
    krb5_krbhst_free (context, handle);
    krb5_auth_con_free (context, auth_context);
    if (done)
	return 0;
    else {
	if (ret == KRB5_KDC_UNREACH) {
	    krb5_set_error_string(context,
				  "unable to reach any changepw server "
				  " in realm %s", realm);
	    *result_code = KRB5_KPASSWD_HARDERROR;
	}
	return ret;
    }
}
示例#5
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_sendto_context(krb5_context context,
		    krb5_sendto_ctx ctx,
		    const krb5_data *send_data,
		    const krb5_realm realm,
		    krb5_data *receive)
{
    krb5_error_code ret;
    krb5_krbhst_handle handle = NULL;
    int type, freectx = 0;
    int action;

    krb5_data_zero(receive);

    if (ctx == NULL) {
	freectx = 1;
	ret = krb5_sendto_ctx_alloc(context, &ctx);
	if (ret)
	    return ret;
    }

    type = ctx->type;
    if (type == 0) {
	if ((ctx->flags & KRB5_KRBHST_FLAGS_MASTER) || context->use_admin_kdc)
	    type = KRB5_KRBHST_ADMIN;
	else
	    type = KRB5_KRBHST_KDC;
    }

    if ((int)send_data->length > context->large_msg_size)
	ctx->flags |= KRB5_KRBHST_FLAGS_LARGE_MSG;

    /* loop until we get back a appropriate response */

    do {
	action = KRB5_SENDTO_DONE;

	krb5_data_free(receive);

	if (handle == NULL) {
	    ret = krb5_krbhst_init_flags(context, realm, type,
					 ctx->flags, &handle);
	    if (ret) {
		if (freectx)
		    krb5_sendto_ctx_free(context, ctx);
		return ret;
	    }
	}

	ret = krb5_sendto(context, send_data, handle, receive);
	if (ret)
	    break;
	if (ctx->func) {
	    ret = (*ctx->func)(context, ctx, ctx->data, receive, &action);
	    if (ret)
		break;
	}
	if (action != KRB5_SENDTO_CONTINUE) {
	    krb5_krbhst_free(context, handle);
	    handle = NULL;
	}
    } while (action != KRB5_SENDTO_DONE);
    if (handle)
	krb5_krbhst_free(context, handle);
    if (ret == KRB5_KDC_UNREACH)
	krb5_set_error_message(context, ret,
			       N_("unable to reach any KDC in realm %s", ""),
			       realm);
    if (ret)
	krb5_data_free(receive);
    if (freectx)
	krb5_sendto_ctx_free(context, ctx);
    return ret;
}
kadm5_ret_t
_kadm5_c_init_context(kadm5_client_context **ctx,
		      kadm5_config_params *params,
		      krb5_context context)
{
    krb5_error_code ret;
    char *colon;

    *ctx = malloc(sizeof(**ctx));
    if(*ctx == NULL)
	return ENOMEM;
    memset(*ctx, 0, sizeof(**ctx));
    krb5_add_et_list (context, initialize_kadm5_error_table_r);
    set_funcs(*ctx);
    (*ctx)->context = context;
    if(params->mask & KADM5_CONFIG_REALM) {
	ret = 0;
	(*ctx)->realm = strdup(params->realm);
	if ((*ctx)->realm == NULL)
	    ret = ENOMEM;
    } else
	ret = krb5_get_default_realm((*ctx)->context, &(*ctx)->realm);
    if (ret) {
	free(*ctx);
	return ret;
    }
    if(params->mask & KADM5_CONFIG_ADMIN_SERVER)
	(*ctx)->admin_server = strdup(params->admin_server);
    else {
	krb5_krbhst_handle handle = NULL;
	char host[MAXHOSTNAMELEN];

	ret = krb5_krbhst_init(context, (*ctx)->realm, KRB5_KRBHST_ADMIN, &handle);
	if (ret == 0)
	    ret = krb5_krbhst_next_as_string(context, handle, host, sizeof(host));
	krb5_krbhst_free(context, handle);
	if (ret) {
	    free((*ctx)->realm);
	    free(*ctx);
	    return ret;
	}

	(*ctx)->admin_server = strdup(host);
    }

    if ((*ctx)->admin_server == NULL) {
	free((*ctx)->realm);
	free(*ctx);
	return ENOMEM;
    }
    colon = strchr ((*ctx)->admin_server, ':');
    if (colon != NULL)
	*colon++ = '\0';

    (*ctx)->kadmind_port = 0;

    if(params->mask & KADM5_CONFIG_KADMIND_PORT)
	(*ctx)->kadmind_port = params->kadmind_port;
    else if (colon != NULL) {
	char *end;

	(*ctx)->kadmind_port = htons(strtol (colon, &end, 0));
    }
    if ((*ctx)->kadmind_port == 0)
	(*ctx)->kadmind_port = krb5_getportbyname (context, "kerberos-adm",
						   "tcp", 749);
    return 0;
}