(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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user