use new addr_families functions. Now works over IPv6
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@3516 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -63,7 +63,8 @@ static char *database = HDB_DEFAULT_DB;
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
send_reply (int s,
|
send_reply (int s,
|
||||||
struct sockaddr_in *addr,
|
struct sockaddr *sa,
|
||||||
|
int sa_size,
|
||||||
krb5_data *ap_rep,
|
krb5_data *ap_rep,
|
||||||
krb5_data *rest)
|
krb5_data *rest)
|
||||||
{
|
{
|
||||||
@@ -88,8 +89,8 @@ send_reply (int s,
|
|||||||
*p++ = (ap_rep_len >> 0) & 0xFF;
|
*p++ = (ap_rep_len >> 0) & 0xFF;
|
||||||
|
|
||||||
memset (&msghdr, 0, sizeof(msghdr));
|
memset (&msghdr, 0, sizeof(msghdr));
|
||||||
msghdr.msg_name = (void *)addr;
|
msghdr.msg_name = (void *)sa;
|
||||||
msghdr.msg_namelen = sizeof(*addr);
|
msghdr.msg_namelen = sa_size;
|
||||||
msghdr.msg_iov = iov;
|
msghdr.msg_iov = iov;
|
||||||
msghdr.msg_iovlen = sizeof(iov)/sizeof(*iov);
|
msghdr.msg_iovlen = sizeof(iov)/sizeof(*iov);
|
||||||
#if 0
|
#if 0
|
||||||
@@ -139,7 +140,8 @@ make_result (krb5_data *data,
|
|||||||
static void
|
static void
|
||||||
reply_error (krb5_principal server,
|
reply_error (krb5_principal server,
|
||||||
int s,
|
int s,
|
||||||
struct sockaddr_in *addr,
|
struct sockaddr *sa,
|
||||||
|
int sa_size,
|
||||||
krb5_error_code error_code,
|
krb5_error_code error_code,
|
||||||
u_int16_t result_code,
|
u_int16_t result_code,
|
||||||
const char *expl)
|
const char *expl)
|
||||||
@@ -166,14 +168,15 @@ reply_error (krb5_principal server,
|
|||||||
krb5_get_err_text (context, ret));
|
krb5_get_err_text (context, ret));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
send_reply (s, addr, NULL, &error_data);
|
send_reply (s, sa, sa_size, NULL, &error_data);
|
||||||
krb5_data_free (&error_data);
|
krb5_data_free (&error_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reply_priv (krb5_auth_context auth_context,
|
reply_priv (krb5_auth_context auth_context,
|
||||||
int s,
|
int s,
|
||||||
struct sockaddr_in *addr,
|
struct sockaddr *sa,
|
||||||
|
int sa_size,
|
||||||
u_int16_t result_code,
|
u_int16_t result_code,
|
||||||
const char *expl)
|
const char *expl)
|
||||||
{
|
{
|
||||||
@@ -207,7 +210,7 @@ reply_priv (krb5_auth_context auth_context,
|
|||||||
krb5_get_err_text (context, ret));
|
krb5_get_err_text (context, ret));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
send_reply (s, addr, &ap_rep_data, &krb_priv_data);
|
send_reply (s, sa, sa_size, &ap_rep_data, &krb_priv_data);
|
||||||
krb5_data_free (&ap_rep_data);
|
krb5_data_free (&ap_rep_data);
|
||||||
krb5_data_free (&krb_priv_data);
|
krb5_data_free (&krb_priv_data);
|
||||||
}
|
}
|
||||||
@@ -216,7 +219,8 @@ static void
|
|||||||
change (krb5_auth_context auth_context,
|
change (krb5_auth_context auth_context,
|
||||||
krb5_principal principal,
|
krb5_principal principal,
|
||||||
int s,
|
int s,
|
||||||
struct sockaddr_in *addr,
|
struct sockaddr *sa,
|
||||||
|
int sa_size,
|
||||||
krb5_data *pwd_data)
|
krb5_data *pwd_data)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
@@ -235,7 +239,7 @@ change (krb5_auth_context auth_context,
|
|||||||
if (pwd_data->length < 6) { /* XXX */
|
if (pwd_data->length < 6) { /* XXX */
|
||||||
krb5_log (context, log_facility,
|
krb5_log (context, log_facility,
|
||||||
KPASSWDD_LOG_ERR, "Password too short");
|
KPASSWDD_LOG_ERR, "Password too short");
|
||||||
reply_priv (auth_context, s, addr, 4, "password too short");
|
reply_priv (auth_context, s, sa, sa_size, 4, "password too short");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +247,7 @@ change (krb5_auth_context auth_context,
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
||||||
"hdb_open: %s", krb5_get_err_text(context, ret));
|
"hdb_open: %s", krb5_get_err_text(context, ret));
|
||||||
reply_priv (auth_context, s, addr, 2, "hdb_open failed");
|
reply_priv (auth_context, s, sa, sa_size, 2, "hdb_open failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +259,7 @@ change (krb5_auth_context auth_context,
|
|||||||
case HDB_ERR_NOENTRY:
|
case HDB_ERR_NOENTRY:
|
||||||
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
||||||
"not found in database");
|
"not found in database");
|
||||||
reply_priv (auth_context, s, addr, 2,
|
reply_priv (auth_context, s, sa, sa_size, 2,
|
||||||
"entry not found in database");
|
"entry not found in database");
|
||||||
goto out;
|
goto out;
|
||||||
case 0:
|
case 0:
|
||||||
@@ -263,7 +267,7 @@ change (krb5_auth_context auth_context,
|
|||||||
default :
|
default :
|
||||||
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
||||||
"dbfetch: %s", krb5_get_err_text(context, ret));
|
"dbfetch: %s", krb5_get_err_text(context, ret));
|
||||||
reply_priv (auth_context, s, addr, 2,
|
reply_priv (auth_context, s, sa, sa_size, 2,
|
||||||
"db_fetch failed");
|
"db_fetch failed");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -308,10 +312,10 @@ change (krb5_auth_context auth_context,
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
||||||
"dbstore: %s", krb5_get_err_text (context, ret));
|
"dbstore: %s", krb5_get_err_text (context, ret));
|
||||||
reply_priv (auth_context, s, addr, 2,
|
reply_priv (auth_context, s, sa, sa_size, 2,
|
||||||
"db_store failed");
|
"db_store failed");
|
||||||
} else {
|
} else {
|
||||||
reply_priv (auth_context, s, addr, 0, "password changed");
|
reply_priv (auth_context, s, sa, sa_size, 0, "password changed");
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
hdb_free_entry (context, &ent);
|
hdb_free_entry (context, &ent);
|
||||||
@@ -324,7 +328,8 @@ verify (krb5_auth_context *auth_context,
|
|||||||
krb5_ticket **ticket,
|
krb5_ticket **ticket,
|
||||||
krb5_data *out_data,
|
krb5_data *out_data,
|
||||||
int s,
|
int s,
|
||||||
struct sockaddr_in *addr,
|
struct sockaddr *sa,
|
||||||
|
int sa_size,
|
||||||
u_char *msg,
|
u_char *msg,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
@@ -339,13 +344,13 @@ verify (krb5_auth_context *auth_context,
|
|||||||
if (pkt_len != len) {
|
if (pkt_len != len) {
|
||||||
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
||||||
"Strange len: %d != %d", pkt_len, len);
|
"Strange len: %d != %d", pkt_len, len);
|
||||||
reply_error (server, s, addr, 0, 1, "bad length");
|
reply_error (server, s, sa, sa_size, 0, 1, "bad length");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (pkt_ver != 0x0001) {
|
if (pkt_ver != 0x0001) {
|
||||||
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
||||||
"Bad version (%d)", pkt_ver);
|
"Bad version (%d)", pkt_ver);
|
||||||
reply_error (server, s, addr, 0, 1, "bad version");
|
reply_error (server, s, sa, sa_size, 0, 1, "bad version");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,14 +367,14 @@ verify (krb5_auth_context *auth_context,
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
krb5_log (context, log_facility, KPASSWDD_LOG_ERR, "krb5_rd_req: %s",
|
krb5_log (context, log_facility, KPASSWDD_LOG_ERR, "krb5_rd_req: %s",
|
||||||
krb5_get_err_text(context, ret));
|
krb5_get_err_text(context, ret));
|
||||||
reply_error (server, s, addr, ret, 3, "rd_req failed");
|
reply_error (server, s, sa, sa_size, ret, 3, "rd_req failed");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*ticket)->ticket.flags.initial) {
|
if (!(*ticket)->ticket.flags.initial) {
|
||||||
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
||||||
"initial flag not set");
|
"initial flag not set");
|
||||||
reply_error (server, s, addr, ret, 1,
|
reply_error (server, s, sa, sa_size, ret, 1,
|
||||||
"initial flag not set");
|
"initial flag not set");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -385,7 +390,7 @@ verify (krb5_auth_context *auth_context,
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
krb5_log (context, log_facility, KPASSWDD_LOG_ERR, "krb5_rd_priv: %s",
|
krb5_log (context, log_facility, KPASSWDD_LOG_ERR, "krb5_rd_priv: %s",
|
||||||
krb5_get_err_text(context, ret));
|
krb5_get_err_text(context, ret));
|
||||||
reply_error (server, s, addr, ret, 3, "rd_priv failed");
|
reply_error (server, s, sa, sa_size, ret, 3, "rd_priv failed");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -397,8 +402,9 @@ out:
|
|||||||
static void
|
static void
|
||||||
process (krb5_principal server,
|
process (krb5_principal server,
|
||||||
int s,
|
int s,
|
||||||
void *this_addr,
|
krb5_address *this_addr,
|
||||||
struct sockaddr_in *other_addr,
|
struct sockaddr *sa,
|
||||||
|
int sa_size,
|
||||||
u_char *msg,
|
u_char *msg,
|
||||||
int len)
|
int len)
|
||||||
{
|
{
|
||||||
@@ -406,7 +412,7 @@ process (krb5_principal server,
|
|||||||
krb5_auth_context auth_context = NULL;
|
krb5_auth_context auth_context = NULL;
|
||||||
krb5_data out_data;
|
krb5_data out_data;
|
||||||
krb5_ticket *ticket;
|
krb5_ticket *ticket;
|
||||||
krb5_address remote_addr, local_addr;
|
krb5_address other_addr;
|
||||||
|
|
||||||
krb5_data_zero (&out_data);
|
krb5_data_zero (&out_data);
|
||||||
|
|
||||||
@@ -421,18 +427,19 @@ process (krb5_principal server,
|
|||||||
krb5_auth_con_setflags (context, auth_context,
|
krb5_auth_con_setflags (context, auth_context,
|
||||||
KRB5_AUTH_CONTEXT_DO_SEQUENCE);
|
KRB5_AUTH_CONTEXT_DO_SEQUENCE);
|
||||||
|
|
||||||
local_addr.addr_type = AF_INET;
|
ret = krb5_sockaddr2address (sa, &other_addr);
|
||||||
local_addr.address.length = sizeof(other_addr->sin_addr);
|
if (ret) {
|
||||||
local_addr.address.data = this_addr;
|
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
||||||
|
"krb5_sockaddr2address: %s",
|
||||||
remote_addr.addr_type = AF_INET;
|
krb5_get_err_text(context, ret));
|
||||||
remote_addr.address.length = sizeof(other_addr->sin_addr);
|
goto out;
|
||||||
remote_addr.address.data = &other_addr->sin_addr;
|
}
|
||||||
|
|
||||||
ret = krb5_auth_con_setaddrs (context,
|
ret = krb5_auth_con_setaddrs (context,
|
||||||
auth_context,
|
auth_context,
|
||||||
&local_addr,
|
this_addr,
|
||||||
&remote_addr);
|
&other_addr);
|
||||||
|
krb5_free_address (context, &other_addr);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
krb5_log (context, log_facility, KPASSWDD_LOG_ERR,
|
||||||
"krb5_auth_con_setaddr: %s",
|
"krb5_auth_con_setaddr: %s",
|
||||||
@@ -441,11 +448,11 @@ process (krb5_principal server,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (verify (&auth_context, server, &ticket, &out_data,
|
if (verify (&auth_context, server, &ticket, &out_data,
|
||||||
s, other_addr, msg, len) == 0) {
|
s, sa, sa_size, msg, len) == 0) {
|
||||||
change (auth_context,
|
change (auth_context,
|
||||||
ticket->client,
|
ticket->client,
|
||||||
s,
|
s,
|
||||||
other_addr,
|
sa, sa_size,
|
||||||
&out_data);
|
&out_data);
|
||||||
krb5_free_ticket (context, ticket);
|
krb5_free_ticket (context, ticket);
|
||||||
free (ticket);
|
free (ticket);
|
||||||
@@ -467,6 +474,15 @@ doit (int port)
|
|||||||
krb5_addresses addrs;
|
krb5_addresses addrs;
|
||||||
unsigned n, i;
|
unsigned n, i;
|
||||||
fd_set real_fdset;
|
fd_set real_fdset;
|
||||||
|
char *sa_buf;
|
||||||
|
int sa_max_size;
|
||||||
|
struct sockaddr *sa;
|
||||||
|
|
||||||
|
sa_max_size = krb5_max_sockaddr_size ();
|
||||||
|
sa_buf = malloc (sa_max_size);
|
||||||
|
if (sa_buf == NULL)
|
||||||
|
syslog_and_die ("out of memory");
|
||||||
|
sa = (struct sockaddr *)sa_buf;
|
||||||
|
|
||||||
ret = krb5_get_default_realm (context, &realm);
|
ret = krb5_get_default_realm (context, &realm);
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -497,18 +513,15 @@ doit (int port)
|
|||||||
maxfd = 0;
|
maxfd = 0;
|
||||||
FD_ZERO(&real_fdset);
|
FD_ZERO(&real_fdset);
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
struct sockaddr_in addr;
|
int sa_size;
|
||||||
|
|
||||||
sockets[i] = socket (AF_INET, SOCK_DGRAM, 0);
|
krb5_addr2sockaddr (&addrs.val[i], sa, &sa_size, port);
|
||||||
|
|
||||||
|
sockets[i] = socket (sa->sa_family, SOCK_DGRAM, 0);
|
||||||
if (sockets[i] < 0)
|
if (sockets[i] < 0)
|
||||||
syslog_and_die ("socket: %m");
|
syslog_and_die ("socket: %m");
|
||||||
memset (&addr, 0, sizeof(addr));
|
|
||||||
addr.sin_family = AF_INET;
|
|
||||||
memcpy (&addr.sin_addr, addrs.val[i].address.data,
|
|
||||||
sizeof(addr.sin_addr));
|
|
||||||
addr.sin_port = port;
|
|
||||||
|
|
||||||
if (bind (sockets[i], (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
if (bind (sockets[i], sa, sa_size) < 0)
|
||||||
syslog_and_die ("bind: %m");
|
syslog_and_die ("bind: %m");
|
||||||
maxfd = max (maxfd, sockets[i]);
|
maxfd = max (maxfd, sockets[i]);
|
||||||
FD_SET(sockets[i], &real_fdset);
|
FD_SET(sockets[i], &real_fdset);
|
||||||
@@ -526,25 +539,27 @@ doit (int port)
|
|||||||
syslog_and_die ("select: %m");
|
syslog_and_die ("select: %m");
|
||||||
for (i = 0; i < n; ++i)
|
for (i = 0; i < n; ++i)
|
||||||
if (FD_ISSET(sockets[i], &fdset)) {
|
if (FD_ISSET(sockets[i], &fdset)) {
|
||||||
struct sockaddr_in other_addr;
|
|
||||||
u_char buf[BUFSIZ];
|
u_char buf[BUFSIZ];
|
||||||
int addrlen = sizeof(other_addr);
|
int addrlen = sa_max_size;
|
||||||
|
|
||||||
ret = recvfrom (sockets[i], buf, sizeof(buf), 0,
|
ret = recvfrom (sockets[i], buf, sizeof(buf), 0,
|
||||||
(struct sockaddr *)&other_addr,
|
sa, &addrlen);
|
||||||
&addrlen);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
if(errno == EINTR)
|
if(errno == EINTR)
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
syslog_and_die ("recvfrom: %m");
|
syslog_and_die ("recvfrom: %m");
|
||||||
|
|
||||||
process (server, sockets[i],
|
process (server, sockets[i],
|
||||||
addrs.val[i].address.data, &other_addr, buf, ret);
|
&addrs.val[i],
|
||||||
|
sa, addrlen,
|
||||||
|
buf, ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
krb5_free_addresses (context, &addrs);
|
krb5_free_addresses (context, &addrs);
|
||||||
krb5_free_principal (context, server);
|
krb5_free_principal (context, server);
|
||||||
krb5_free_context (context);
|
krb5_free_context (context);
|
||||||
|
free (sa_buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -43,12 +43,14 @@ RCSID("$Id$");
|
|||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
get_kdc_address (krb5_context context,
|
get_kdc_address (krb5_context context,
|
||||||
krb5_realm realm,
|
krb5_realm realm,
|
||||||
struct sockaddr_in *addr)
|
struct sockaddr *sa,
|
||||||
|
int *sa_size)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
struct hostent *hostent;
|
struct hostent *hostent;
|
||||||
char **hostlist;
|
char **hostlist;
|
||||||
char *dot;
|
char *dot;
|
||||||
|
char *p;
|
||||||
|
|
||||||
ret = krb5_get_krbhst (context,
|
ret = krb5_get_krbhst (context,
|
||||||
&realm,
|
&realm,
|
||||||
@@ -56,22 +58,31 @@ get_kdc_address (krb5_context context,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
dot = strchr (*hostlist, ':');
|
p = *hostlist;
|
||||||
|
|
||||||
|
dot = strchr (p, ':');
|
||||||
if (dot)
|
if (dot)
|
||||||
*dot = '\0';
|
*dot = '\0';
|
||||||
|
|
||||||
hostent = gethostbyname (*hostlist);
|
#ifdef HAVE_GETHOSTBYNAME2
|
||||||
|
hostent = gethostbyname2 (p, AF_INET6);
|
||||||
|
if (hostent == NULL)
|
||||||
|
hostent = gethostbyname2 (p, AF_INET);
|
||||||
|
#else
|
||||||
|
hostent = gethostbyname (p);
|
||||||
|
#endif
|
||||||
krb5_free_krbhst (context, hostlist);
|
krb5_free_krbhst (context, hostlist);
|
||||||
if (hostent == 0)
|
if (hostent == NULL)
|
||||||
return h_errno; /* XXX */
|
return h_errno; /* XXX */
|
||||||
|
|
||||||
memset (addr, 0, sizeof(*addr));
|
return krb5_h_addr2sockaddr (hostent->h_addrtype,
|
||||||
addr->sin_family = AF_INET;
|
hostent->h_addr_list[0],
|
||||||
memcpy (&addr->sin_addr, hostent->h_addr_list[0], sizeof(addr->sin_addr));
|
sa,
|
||||||
addr->sin_port = krb5_getportbyname (context, "kpasswd", "udp",
|
sa_size,
|
||||||
KPASSWD_PORT);
|
krb5_getportbyname (context,
|
||||||
|
"kpasswd",
|
||||||
return 0;
|
"udp",
|
||||||
|
KPASSWD_PORT));
|
||||||
}
|
}
|
||||||
|
|
||||||
static krb5_error_code
|
static krb5_error_code
|
||||||
@@ -79,7 +90,8 @@ send_request (krb5_context context,
|
|||||||
krb5_auth_context *auth_context,
|
krb5_auth_context *auth_context,
|
||||||
krb5_creds *creds,
|
krb5_creds *creds,
|
||||||
int sock,
|
int sock,
|
||||||
struct sockaddr_in addr,
|
struct sockaddr *sa,
|
||||||
|
int sa_size,
|
||||||
char *passwd)
|
char *passwd)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
@@ -126,8 +138,8 @@ send_request (krb5_context context,
|
|||||||
*p++ = (ap_req_data.length >> 0) & 0xFF;
|
*p++ = (ap_req_data.length >> 0) & 0xFF;
|
||||||
|
|
||||||
memset(&msghdr, 0, sizeof(msghdr));
|
memset(&msghdr, 0, sizeof(msghdr));
|
||||||
msghdr.msg_name = (void *)&addr;
|
msghdr.msg_name = (void *)sa;
|
||||||
msghdr.msg_namelen = sizeof(addr);
|
msghdr.msg_namelen = sa_size;
|
||||||
msghdr.msg_iov = iov;
|
msghdr.msg_iov = iov;
|
||||||
msghdr.msg_iovlen = sizeof(iov)/sizeof(*iov);
|
msghdr.msg_iovlen = sizeof(iov)/sizeof(*iov);
|
||||||
#if 0
|
#if 0
|
||||||
@@ -276,21 +288,32 @@ krb5_change_password (krb5_context context,
|
|||||||
krb5_auth_context auth_context = NULL;
|
krb5_auth_context auth_context = NULL;
|
||||||
krb5_creds cred;
|
krb5_creds cred;
|
||||||
int sock;
|
int sock;
|
||||||
struct sockaddr_in addr;
|
|
||||||
int i;
|
int i;
|
||||||
|
char *buf;
|
||||||
sock = socket (AF_INET, SOCK_DGRAM, 0);
|
struct sockaddr *sa;
|
||||||
if (sock < 0)
|
int sa_size;
|
||||||
return errno;
|
|
||||||
|
|
||||||
ret = get_kdc_address (context, creds->client->realm, &addr);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = krb5_auth_con_init (context, &auth_context);
|
ret = krb5_auth_con_init (context, &auth_context);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
buf = malloc (krb5_max_sockaddr_size ());
|
||||||
|
if (buf == NULL) {
|
||||||
|
ret = ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
sa = (struct sockaddr *)buf;
|
||||||
|
|
||||||
|
ret = get_kdc_address (context, creds->client->realm, sa, &sa_size);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
sock = socket (sa->sa_family, SOCK_DGRAM, 0);
|
||||||
|
if (sock < 0) {
|
||||||
|
ret = errno;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
krb5_auth_con_setflags (context, auth_context,
|
krb5_auth_con_setflags (context, auth_context,
|
||||||
KRB5_AUTH_CONTEXT_DO_SEQUENCE);
|
KRB5_AUTH_CONTEXT_DO_SEQUENCE);
|
||||||
|
|
||||||
@@ -302,7 +325,8 @@ krb5_change_password (krb5_context context,
|
|||||||
&auth_context,
|
&auth_context,
|
||||||
creds,
|
creds,
|
||||||
sock,
|
sock,
|
||||||
addr,
|
sa,
|
||||||
|
sa_size,
|
||||||
newpw);
|
newpw);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -332,5 +356,6 @@ krb5_change_password (krb5_context context,
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
krb5_auth_con_free (context, auth_context);
|
krb5_auth_con_free (context, auth_context);
|
||||||
|
free (buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user