+2004-02-26 Jeffrey Altman <jaltman@mit.edu>
+
+ * k5-int.h: change prototype declarations necessary to support
+ the use of krb5_get_init_creds_password's use_master as an
+ in/out parameter
+
2004-02-26 Ken Raeburn <raeburn@mit.edu>
* win-mac.h (GETSOCKNAME_ARG2_TYPE, GETSOCKNAME_ARG3_TYPE): Set
krb5_error_code krb5_lock_file (krb5_context, int, int);
krb5_error_code krb5_unlock_file (krb5_context, int);
krb5_error_code krb5_sendto_kdc (krb5_context, const krb5_data *,
- const krb5_data *, krb5_data *, int, int);
+ const krb5_data *, krb5_data *, int *, int);
krb5_error_code krb5int_sendto (krb5_context, const krb5_data *,
const struct addrlist *, krb5_data *,
- struct sockaddr *, socklen_t *);
+ struct sockaddr *, socklen_t *, int *);
krb5_error_code krb5_get_krbhst (krb5_context, const krb5_data *, char *** );
krb5_error_code krb5_free_krbhst (krb5_context, char * const * );
krb5_error_code krb5_create_secure_file (krb5_context, const char * pathname);
krb5_get_init_creds_opt *gic_options,
krb5_gic_get_as_key_fct gak,
void *gak_data,
- int master,
+ int *master,
krb5_kdc_rep **as_reply);
void krb5int_populate_gic_opt (
int, int, int, int);
krb5_error_code (*sendto_udp) (krb5_context, const krb5_data *msg,
const struct addrlist *, krb5_data *reply,
- struct sockaddr *, socklen_t *);
+ struct sockaddr *, socklen_t *, int *);
krb5_error_code (*add_host_to_list)(struct addrlist *lp,
const char *hostname,
int port, int secport,
+2004-02-26 Jeffrey Altman <jaltman@mit.edu>
+
+ * send_to_kdc.c: modify call to internals.sendto_udp to support
+ the new declaration which contains an additional output parameter
+ which will not be used.
+
2004-02-24 Sam Hartman <hartmans@avalanche-breakdown.mit.edu>
* rd_svc_key.c (krb54_get_service_keyblock): Remove ENCTYPE_LOCAL_DES3_HMAC_SHA1
message.length = pkt->length;
message.data = (char *)pkt->dat; /* XXX yuck */
retval = internals.sendto_udp(NULL, &message, &al, &reply, addr,
- addrlen);
+ addrlen, NULL);
DEB(("sendto_udp returns %d\n", retval));
free_al:
internals.free_addrlist(&al);
+2004-02-26 Jeffrey Altman <jaltman@mit.edu>
+
+ * get_in_tkt.c, gic_keytab.c, gic_pwd.c, send_tgs.c:
+ Implement changes to support the use of
+ krb5_get_init_creds_password's use_master as an in/out
+ parameter. This allows us to prevent a duplicate request
+ being sent to the KDC in the situation that the password
+ used is incorrect. This behavior results a negative user
+ experience and had to be corrected.
+
2004-02-13 Ken Raeburn <raeburn@mit.edu>
* sendauth.c: Don't specify defaults for
krb5_timestamp *time_now,
krb5_error ** ret_err_reply,
krb5_kdc_rep ** ret_as_reply,
- int use_master)
+ int *use_master)
{
krb5_kdc_rep *as_reply = 0;
krb5_error_code retval;
krb5_pa_data ** preauth_to_use = 0;
int loopcount = 0;
krb5_int32 do_more = 0;
+ int use_master = 0;
if (! krb5_realm_compare(context, creds->client, creds->server))
return KRB5_IN_TKT_REALM_MISMATCH;
err_reply = 0;
as_reply = 0;
if ((retval = send_as_request(context, &request, &time_now, &err_reply,
- &as_reply, 0)))
+ &as_reply, &use_master)))
goto cleanup;
if (err_reply) {
krb5_get_init_creds_opt *options,
krb5_gic_get_as_key_fct gak_fct,
void *gak_data,
- int use_master,
+ int *use_master,
krb5_kdc_rep **as_reply)
{
krb5_error_code ret;
ret = krb5_get_init_creds(context, creds, client, NULL, NULL,
start_time, in_tkt_service, options,
krb5_get_as_key_keytab, (void *) keytab,
- use_master,NULL);
+ &use_master,NULL);
/* check for success */
ret2 = krb5_get_init_creds(context, creds, client, NULL, NULL,
start_time, in_tkt_service, options,
krb5_get_as_key_keytab, (void *) keytab,
- use_master, NULL);
+ &use_master, NULL);
if (ret2 == 0) {
ret = 0;
ret = krb5_get_init_creds(context, creds, client, prompter, data,
start_time, in_tkt_service, options,
krb5_get_as_key_password, (void *) &pw0,
- use_master, &as_reply);
+ &use_master, &as_reply);
/* check for success */
ret2 = krb5_get_init_creds(context, creds, client, prompter, data,
start_time, in_tkt_service, options,
krb5_get_as_key_password, (void *) &pw0,
- use_master, &as_reply);
+ &use_master, &as_reply);
if (ret2 == 0) {
ret = 0;
prompter, data,
start_time, "kadmin/changepw", &chpw_opts,
krb5_get_as_key_password, (void *) &pw0,
- use_master, NULL)))
+ &use_master, NULL)))
goto cleanup;
prompt[0].prompt = "Enter new password";
ret = krb5_get_init_creds(context, creds, client, prompter, data,
start_time, in_tkt_service, options,
krb5_get_as_key_password, (void *) &pw0,
- use_master, &as_reply);
+ &use_master, &as_reply);
cleanup:
krb5int_set_prompt_types(context, 0);
krb5_timestamp time_now;
krb5_pa_data **combined_padata;
krb5_pa_data ap_req_padata;
- int tcp_only = 0;
+ int tcp_only = 0, use_master;
/*
* in_creds MUST be a valid credential NOT just a partially filled in
/* now send request & get response from KDC */
send_again:
+ use_master = 0;
retval = krb5_sendto_kdc(context, scratch,
krb5_princ_realm(context, sname),
- &rep->response, 0, tcp_only);
+ &rep->response, &use_master, tcp_only);
if (retval == 0) {
if (krb5_is_krb_error(&rep->response)) {
if (!tcp_only) {
+2004-02-26 Jeffrey Altman <jaltman@mit.edu>
+
+ * sendto_kdc.c, send524.c:
+ The use_master parameter of sendto_kdc is now an in/out
+ parameter used to report to the caller whether or not
+ the responding KDC was in fact the master. This is
+ necessary to allow callers to prevent making an unnecessary
+ additional call to query the master if the original
+ query did not explicitly state that the master should be
+ queried.
+
2004-02-25 Ken Raeburn <raeburn@mit.edu>
* sendto_kdc.c (start_connection): Close socket if connect() call
if (al.naddrs == 0)
return KRB5_REALM_UNKNOWN;
- retval = krb5int_sendto (context, message, &al, reply, addr, addrlen);
+ retval = krb5int_sendto (context, message, &al, reply, addr, addrlen, NULL);
krb5int_free_addrlist (&al);
return retval;
#else
krb5_error_code
krb5_sendto_kdc (krb5_context context, const krb5_data *message,
const krb5_data *realm, krb5_data *reply,
- int use_master, int tcp_only)
+ int *use_master, int tcp_only)
{
krb5_error_code retval;
struct addrlist addrs;
- int socktype1 = 0, socktype2 = 0;
+ int socktype1 = 0, socktype2 = 0, addr_used;
/*
* find KDC location(s) for realm
*/
dprint("krb5_sendto_kdc(%d@%p, \"%D\", use_master=%d, tcp_only=%d)\n",
- message->length, message->data, realm, use_master, tcp_only);
+ message->length, message->data, realm, *use_master, tcp_only);
if (!tcp_only && context->udp_pref_limit < 0) {
int tmp;
context->udp_pref_limit = tmp;
}
- retval = (use_master ? KRB5_KDC_UNREACH : KRB5_REALM_UNKNOWN);
+ retval = (*use_master ? KRB5_KDC_UNREACH : KRB5_REALM_UNKNOWN);
if (tcp_only)
socktype1 = SOCK_STREAM, socktype2 = 0;
else
socktype1 = SOCK_STREAM, socktype2 = SOCK_DGRAM;
- retval = krb5_locate_kdc(context, realm, &addrs, use_master, socktype1, 0);
+ retval = krb5_locate_kdc(context, realm, &addrs, *use_master, socktype1, 0);
if (socktype2) {
struct addrlist addrs2;
}
if (addrs.naddrs > 0) {
- retval = krb5int_sendto (context, message, &addrs, reply, 0, 0);
- krb5int_free_addrlist (&addrs);
- if (retval == 0)
- return 0;
+ retval = krb5int_sendto (context, message, &addrs, reply, 0, 0,
+ &addr_used);
+ if (retval == 0) {
+ /*
+ * Set use_master to 1 if we ended up talking to a master when
+ * we didn't explicitly request to
+ */
+ if (*use_master == 0) {
+ struct addrlist addrs3;
+ retval = krb5_locate_kdc(context, realm, &addrs3, 1,
+ addrs.addrs[addr_used]->ai_socktype,
+ addrs.addrs[addr_used]->ai_family);
+ if (retval == 0) {
+ int i;
+ for (i = 0; i < addrs3.naddrs; i++) {
+ if (addrs.addrs[addr_used]->ai_addrlen ==
+ addrs3.addrs[i]->ai_addrlen &&
+ memcmp(addrs.addrs[addr_used]->ai_addr,
+ addrs3.addrs[i]->ai_addr,
+ addrs.addrs[addr_used]->ai_addrlen) == 0) {
+ *use_master = 1;
+ break;
+ }
+ }
+ krb5int_free_addrlist (&addrs3);
+ }
+ }
+ krb5int_free_addrlist (&addrs);
+ return 0;
+ }
+ krb5int_free_addrlist (&addrs);
}
return retval;
}
krb5_error_code
krb5int_sendto (krb5_context context, const krb5_data *message,
- const struct addrlist *addrs, krb5_data *reply,
- struct sockaddr *localaddr, socklen_t *localaddrlen)
+ const struct addrlist *addrs, krb5_data *reply,
+ struct sockaddr *localaddr, socklen_t *localaddrlen,
+ int *addr_used)
{
int i, pass;
int delay_this_pass = 2;
(int) reply->length, reply->data);
retval = 0;
conns[winning_conn].x.in.buf = 0;
+ if (addr_used)
+ *addr_used = winning_conn;
if (localaddr != 0 && localaddrlen != 0 && *localaddrlen > 0)
(void) getsockname(conns[winning_conn].fd, localaddr, localaddrlen);
egress: