summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/lib/krb5/changepw.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/lib/krb5/changepw.c')
-rw-r--r--crypto/heimdal/lib/krb5/changepw.c205
1 files changed, 101 insertions, 104 deletions
diff --git a/crypto/heimdal/lib/krb5/changepw.c b/crypto/heimdal/lib/krb5/changepw.c
index 309e972..35534f4 100644
--- a/crypto/heimdal/lib/krb5/changepw.c
+++ b/crypto/heimdal/lib/krb5/changepw.c
@@ -33,54 +33,13 @@
#include <krb5_locl.h>
-RCSID("$Id: changepw.c,v 1.32 2001/05/14 22:49:55 assar Exp $");
-
-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;
-}
+RCSID("$Id: changepw.c,v 1.34 2001/09/27 01:29:12 assar Exp $");
static krb5_error_code
send_request (krb5_context context,
krb5_auth_context *auth_context,
krb5_creds *creds,
int sock,
- struct sockaddr *sa,
- int sa_size,
char *passwd,
const char *host)
{
@@ -128,8 +87,8 @@ send_request (krb5_context context,
*p++ = (ap_req_data.length >> 0) & 0xFF;
memset(&msghdr, 0, sizeof(msghdr));
- msghdr.msg_name = (void *)sa;
- msghdr.msg_namelen = sa_size;
+ msghdr.msg_name = NULL;
+ msghdr.msg_namelen = 0;
msghdr.msg_iov = iov;
msghdr.msg_iovlen = sizeof(iov)/sizeof(*iov);
#if 0
@@ -294,96 +253,134 @@ 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);
+ 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;
- 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;
-
- if (!replied) {
- replied = 0;
- ret = send_request (context,
- &auth_context,
- creds,
- sock,
- a->ai_addr,
- a->ai_addrlen,
- newpw,
- host);
- if (ret) {
- close(sock);
- goto out;
- }
- }
-
- if (sock >= FD_SETSIZE) {
- krb5_set_error_string(context, "fd %d too large", sock);
- ret = ERANGE;
+ 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;
}
- 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);
+ ret = krb5_auth_con_genaddrs (context, auth_context, sock,
+ KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR);
+ if (ret) {
+ 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;
+
+ 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,
+ 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;
+ }
}
+ 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;
}
}
+
+const char *
+krb5_passwd_result_to_string (krb5_context context,
+ int result)
+{
+ static const char *strings[] = {
+ "Success",
+ "Malformed",
+ "Hard error",
+ "Auth error",
+ "Soft error"
+ };
+
+ if (result < 0 || result > KRB5_KPASSWD_SOFTERROR)
+ return "unknown result code";
+ else
+ return strings[result];
+}
OpenPOWER on IntegriCloud