(krb5_change_password): update to use krb5_krbhst API

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@10077 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Assar Westerlund
2001-06-17 23:11:06 +00:00
parent 016dcaae5f
commit 4c5fb0d0c5

View File

@@ -35,45 +35,6 @@
RCSID("$Id$");
static krb5_error_code
get_kdc_address (krb5_context context,
krb5_realm realm,
struct addrinfo **ai,
char **ret_host)
{
krb5_error_code ret;
char **hostlist;
int port = 0;
int error;
char *host;
int save_errno;
ret = krb5_get_krb_changepw_hst (context,
&realm,
&hostlist);
if (ret)
return ret;
host = strdup(*hostlist);
krb5_free_krbhst(context, hostlist);
if (host == NULL) {
krb5_set_error_string (context, "malloc: out of memory");
return ENOMEM;
}
port = ntohs(krb5_getportbyname (context, "kpasswd", "udp", KPASSWD_PORT));
error = roken_getaddrinfo_hostspec2(host, SOCK_DGRAM, port, ai);
if(error) {
save_errno = errno;
krb5_set_error_string(context, "resolving %s: %s",
host, gai_strerror(error));
return krb5_eai_to_heim_errno(error, save_errno);
}
*ret_host = host;
return 0;
}
static krb5_error_code
send_request (krb5_context context,
krb5_auth_context *auth_context,
@@ -294,96 +255,102 @@ krb5_change_password (krb5_context context,
{
krb5_error_code ret;
krb5_auth_context auth_context = NULL;
krb5_krbhst_handle handle = NULL;
krb5_krbhst_info *hi;
int sock;
int i;
struct addrinfo *ai, *a;
int done = 0;
char *host = NULL;
krb5_realm realm = creds->client->realm;
ret = krb5_auth_con_init (context, &auth_context);
if (ret)
return ret;
ret = get_kdc_address (context, creds->client->realm, &ai, &host);
ret = krb5_krbhst_init (context, realm, KRB5_KRBHST_CHANGEPW, &handle);
if (ret)
goto out;
for (a = ai; !done && a != NULL; a = a->ai_next) {
int replied = 0;
while (krb5_krbhst_next(context, handle, &hi) == 0) {
struct addrinfo *ai, *a;
sock = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
if (sock < 0)
ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
if (ret)
continue;
for (i = 0; !done && i < 5; ++i) {
fd_set fdset;
struct timeval tv;
for (a = ai; !done && a != NULL; a = a->ai_next) {
int replied = 0;
if (!replied) {
replied = 0;
ret = send_request (context,
&auth_context,
creds,
sock,
a->ai_addr,
a->ai_addrlen,
newpw,
host);
if (ret) {
sock = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
if (sock < 0)
continue;
for (i = 0; !done && i < 5; ++i) {
fd_set fdset;
struct timeval tv;
if (!replied) {
replied = 0;
ret = send_request (context,
&auth_context,
creds,
sock,
a->ai_addr,
a->ai_addrlen,
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 = process_reply (context,
auth_context,
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;
}
}
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 = process_reply (context,
auth_context,
sock,
result_code,
result_code_string,
result_string,
host);
if (ret == 0)
done = 1;
else if (i > 0 && ret == KRB5KRB_AP_ERR_MUT_FAIL)
replied = 1;
} else {
ret = KRB5_KDC_UNREACH;
}
close (sock);
}
close (sock);
}
freeaddrinfo (ai);
out:
out:
krb5_krbhst_free (context, handle);
krb5_auth_con_free (context, auth_context);
free (host);
if (done)
return 0;
else {
if (ret == KRB5_KDC_UNREACH)
krb5_set_error_string(context,
"failed to reach kpasswd server %s "
"in realm %s",
host, creds->client->realm);
"unable to reach any changepw server "
" in realm %s", realm);
return ret;
}
}