453 lines
15 KiB
Plaintext
453 lines
15 KiB
Plaintext
Index: src/clients/kvno/kvno.M
|
|
===================================================================
|
|
--- src/clients/kvno/kvno.M (.../tags/krb5-1-6-2-final) (Revision 19931)
|
|
+++ src/clients/kvno/kvno.M (.../branches/krb5-1-6) (Revision 19931)
|
|
@@ -55,6 +55,15 @@
|
|
specifies that Kerberos version 4 tickets should be acquired and
|
|
described. This option is only available if Kerberos 4 support was
|
|
enabled at compilation time.
|
|
+.TP
|
|
+.B \-S sname
|
|
+specifies that krb5_sname_to_principal() will be used to build
|
|
+principal names. If this flag is specified, the
|
|
+.B service1 service2 ...
|
|
+arguments are interpreted as hostnames (rather than principal names),
|
|
+and
|
|
+.B sname
|
|
+is interpreted as the service name.
|
|
.SH ENVIRONMENT
|
|
.B Kvno
|
|
uses the following environment variable:
|
|
Index: src/clients/kvno/kvno.c
|
|
===================================================================
|
|
--- src/clients/kvno/kvno.c (.../tags/krb5-1-6-2-final) (Revision 19931)
|
|
+++ src/clients/kvno/kvno.c (.../branches/krb5-1-6) (Revision 19931)
|
|
@@ -41,10 +41,10 @@
|
|
{
|
|
#ifdef KRB5_KRB4_COMPAT
|
|
fprintf(stderr,
|
|
- "usage: %s [-4 | [-c ccache] [-e etype] [-k keytab]] service1 service2 ...\n",
|
|
+ "usage: %s [-4 | [-c ccache] [-e etype] [-k keytab] [-S sname]] service1 service2 ...\n",
|
|
prog);
|
|
#else
|
|
- fprintf(stderr, "usage: %s [-c ccache] [-e etype] [-k keytab] service1 service2 ...\n",
|
|
+ fprintf(stderr, "usage: %s [-c ccache] [-e etype] [-k keytab] [-S sname] service1 service2 ...\n",
|
|
prog);
|
|
#endif
|
|
exit(1);
|
|
@@ -54,7 +54,8 @@
|
|
|
|
static void do_v4_kvno (int argc, char *argv[]);
|
|
static void do_v5_kvno (int argc, char *argv[],
|
|
- char *ccachestr, char *etypestr, char *keytab_name);
|
|
+ char *ccachestr, char *etypestr, char *keytab_name,
|
|
+ char *sname);
|
|
|
|
#include <com_err.h>
|
|
static void extended_com_err_fn (const char *, errcode_t, const char *,
|
|
@@ -64,6 +65,7 @@
|
|
{
|
|
int option;
|
|
char *etypestr = NULL, *ccachestr = NULL, *keytab_name = NULL;
|
|
+ char *sname = NULL;
|
|
int v4 = 0;
|
|
|
|
set_com_err_hook (extended_com_err_fn);
|
|
@@ -71,7 +73,7 @@
|
|
prog = strrchr(argv[0], '/');
|
|
prog = prog ? (prog + 1) : argv[0];
|
|
|
|
- while ((option = getopt(argc, argv, "c:e:hk:q4")) != -1) {
|
|
+ while ((option = getopt(argc, argv, "c:e:hk:q4S:")) != -1) {
|
|
switch (option) {
|
|
case 'c':
|
|
ccachestr = optarg;
|
|
@@ -91,6 +93,9 @@
|
|
case '4':
|
|
v4 = 1;
|
|
break;
|
|
+ case 'S':
|
|
+ sname = optarg;
|
|
+ break;
|
|
default:
|
|
xusage();
|
|
break;
|
|
@@ -103,10 +108,14 @@
|
|
if ((ccachestr != NULL || etypestr != NULL || keytab_name != NULL) && v4)
|
|
xusage();
|
|
|
|
+ if (sname != NULL && v4)
|
|
+ xusage();
|
|
+
|
|
if (v4)
|
|
do_v4_kvno(argc - optind, argv + optind);
|
|
else
|
|
- do_v5_kvno(argc - optind, argv + optind, ccachestr, etypestr, keytab_name);
|
|
+ do_v5_kvno(argc - optind, argv + optind,
|
|
+ ccachestr, etypestr, keytab_name, sname);
|
|
return 0;
|
|
}
|
|
|
|
@@ -172,7 +181,8 @@
|
|
}
|
|
|
|
static void do_v5_kvno (int count, char *names[],
|
|
- char * ccachestr, char *etypestr, char *keytab_name)
|
|
+ char * ccachestr, char *etypestr, char *keytab_name,
|
|
+ char *sname)
|
|
{
|
|
krb5_error_code ret;
|
|
int i, errors;
|
|
@@ -230,7 +240,13 @@
|
|
|
|
in_creds.client = me;
|
|
|
|
- ret = krb5_parse_name(context, names[i], &in_creds.server);
|
|
+ if (sname != NULL) {
|
|
+ ret = krb5_sname_to_principal(context, names[i],
|
|
+ sname, KRB5_NT_SRV_HST,
|
|
+ &in_creds.server);
|
|
+ } else {
|
|
+ ret = krb5_parse_name(context, names[i], &in_creds.server);
|
|
+ }
|
|
if (ret) {
|
|
if (!quiet)
|
|
com_err(prog, ret, "while parsing principal name %s", names[i]);
|
|
Index: src/lib/crypto/prng.c
|
|
===================================================================
|
|
--- src/lib/crypto/prng.c (.../tags/krb5-1-6-2-final) (Revision 19931)
|
|
+++ src/lib/crypto/prng.c (.../branches/krb5-1-6) (Revision 19931)
|
|
@@ -162,7 +162,7 @@
|
|
krb5_data data;
|
|
struct stat sb;
|
|
int fd;
|
|
- unsigned char buf[YARROW_SLOW_THRESH/8];
|
|
+ unsigned char buf[YARROW_SLOW_THRESH/8], *bp;
|
|
int left;
|
|
fd = open (device, O_RDONLY);
|
|
if (fd == -1)
|
|
@@ -173,14 +173,16 @@
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
- for (left = sizeof (buf); left > 0;) {
|
|
+
|
|
+ for (bp = &buf, left = sizeof (buf); left > 0;) {
|
|
ssize_t count;
|
|
- count = read (fd, &buf, (unsigned) left);
|
|
+ count = read (fd, bp, (unsigned) left);
|
|
if (count <= 0) {
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
left -= count;
|
|
+ bp += count;
|
|
}
|
|
close (fd);
|
|
data.length = sizeof (buf);
|
|
@@ -199,7 +201,7 @@
|
|
int unused;
|
|
int *oursuccess = success?success:&unused;
|
|
*oursuccess = 0;
|
|
- /* If we are getting strong data then try that first. We aare
|
|
+ /* If we are getting strong data then try that first. We are
|
|
guaranteed to cause a reseed of some kind if strong is true and
|
|
we have both /dev/random and /dev/urandom. We want the strong
|
|
data included in the reseed so we get it first.*/
|
|
Index: src/lib/gssapi/spnego/spnego_mech.c
|
|
===================================================================
|
|
--- src/lib/gssapi/spnego/spnego_mech.c (.../tags/krb5-1-6-2-final) (Revision 19931)
|
|
+++ src/lib/gssapi/spnego/spnego_mech.c (.../branches/krb5-1-6) (Revision 19931)
|
|
@@ -61,7 +61,7 @@
|
|
/* private routines for spnego_mechanism */
|
|
static spnego_token_t make_spnego_token(char *);
|
|
static gss_buffer_desc make_err_msg(char *);
|
|
-static int g_token_size(gss_OID_const, OM_uint32);
|
|
+static int g_token_size(gss_OID_const, unsigned int);
|
|
static int g_make_token_header(gss_OID_const, unsigned int,
|
|
unsigned char **, unsigned int);
|
|
static int g_verify_token_header(gss_OID_const, unsigned int *,
|
|
@@ -835,6 +835,7 @@
|
|
ret = GSS_S_FAILURE;
|
|
}
|
|
}
|
|
+ gss_release_buffer(&tmpmin, &mechtok_out);
|
|
if (ret == GSS_S_COMPLETE) {
|
|
/*
|
|
* Now, switch the output context to refer to the
|
|
Index: src/lib/krb5/ccache/cc_file.c
|
|
===================================================================
|
|
--- src/lib/krb5/ccache/cc_file.c (.../tags/krb5-1-6-2-final) (Revision 19931)
|
|
+++ src/lib/krb5/ccache/cc_file.c (.../branches/krb5-1-6) (Revision 19931)
|
|
@@ -1954,6 +1954,9 @@
|
|
char scratch[sizeof(TKT_ROOT)+6+1]; /* +6 for the scratch part, +1 for
|
|
NUL */
|
|
krb5_fcc_data *data;
|
|
+ krb5_int16 fcc_fvno = htons(context->fcc_default_format);
|
|
+ krb5_int16 fcc_flen = 0;
|
|
+ int errsave, cnt;
|
|
|
|
/* Allocate memory */
|
|
lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
|
|
@@ -1968,13 +1971,20 @@
|
|
ret = mkstemp(scratch);
|
|
if (ret == -1) {
|
|
return krb5_fcc_interpret(context, errno);
|
|
- } else close(ret);
|
|
+ }
|
|
#else /*HAVE_MKSTEMP*/
|
|
mktemp(scratch);
|
|
+ /* Make sure the file name is reserved */
|
|
+ ret = THREEPARAMOPEN(scratch, O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0);
|
|
+ if (ret == -1) {
|
|
+ return krb5_fcc_interpret(context, errno);
|
|
+ }
|
|
#endif
|
|
|
|
lid->data = (krb5_pointer) malloc(sizeof(krb5_fcc_data));
|
|
if (lid->data == NULL) {
|
|
+ close(ret);
|
|
+ unlink(scratch);
|
|
krb5_xfree(lid);
|
|
return KRB5_CC_NOMEM;
|
|
}
|
|
@@ -1982,6 +1992,8 @@
|
|
((krb5_fcc_data *) lid->data)->filename = (char *)
|
|
malloc(strlen(scratch) + 1);
|
|
if (((krb5_fcc_data *) lid->data)->filename == NULL) {
|
|
+ close(ret);
|
|
+ unlink(scratch);
|
|
krb5_xfree(((krb5_fcc_data *) lid->data));
|
|
krb5_xfree(lid);
|
|
return KRB5_CC_NOMEM;
|
|
@@ -1996,63 +2008,54 @@
|
|
data = (krb5_fcc_data *) lid->data;
|
|
|
|
retcode = k5_mutex_init(&data->lock);
|
|
- if (retcode)
|
|
+ if (retcode) {
|
|
+ close(ret);
|
|
+ unlink(scratch);
|
|
goto err_out;
|
|
+ }
|
|
|
|
/* Set up the filename */
|
|
strcpy(((krb5_fcc_data *) lid->data)->filename, scratch);
|
|
|
|
- /* Make sure the file name is reserved */
|
|
- ret = THREEPARAMOPEN(((krb5_fcc_data *) lid->data)->filename,
|
|
- O_CREAT | O_EXCL | O_WRONLY | O_BINARY, 0);
|
|
- if (ret == -1) {
|
|
- retcode = krb5_fcc_interpret(context, errno);
|
|
- goto err_out;
|
|
- } else {
|
|
- krb5_int16 fcc_fvno = htons(context->fcc_default_format);
|
|
- krb5_int16 fcc_flen = 0;
|
|
- int errsave, cnt;
|
|
-
|
|
- /* Ignore user's umask, set mode = 0600 */
|
|
+ /* Ignore user's umask, set mode = 0600 */
|
|
#ifndef HAVE_FCHMOD
|
|
#ifdef HAVE_CHMOD
|
|
- chmod(((krb5_fcc_data *) lid->data)->filename, S_IRUSR | S_IWUSR);
|
|
+ chmod(((krb5_fcc_data *) lid->data)->filename, S_IRUSR | S_IWUSR);
|
|
#endif
|
|
#else
|
|
- fchmod(ret, S_IRUSR | S_IWUSR);
|
|
+ fchmod(ret, S_IRUSR | S_IWUSR);
|
|
#endif
|
|
- if ((cnt = write(ret, (char *)&fcc_fvno, sizeof(fcc_fvno)))
|
|
- != sizeof(fcc_fvno)) {
|
|
- errsave = errno;
|
|
- (void) close(ret);
|
|
- (void) unlink(((krb5_fcc_data *) lid->data)->filename);
|
|
- retcode = (cnt == -1) ? krb5_fcc_interpret(context, errsave) : KRB5_CC_IO;
|
|
- goto err_out;
|
|
+ if ((cnt = write(ret, (char *)&fcc_fvno, sizeof(fcc_fvno)))
|
|
+ != sizeof(fcc_fvno)) {
|
|
+ errsave = errno;
|
|
+ (void) close(ret);
|
|
+ (void) unlink(((krb5_fcc_data *) lid->data)->filename);
|
|
+ retcode = (cnt == -1) ? krb5_fcc_interpret(context, errsave) : KRB5_CC_IO;
|
|
+ goto err_out;
|
|
+ }
|
|
+ /* For version 4 we save a length for the rest of the header */
|
|
+ if (context->fcc_default_format == KRB5_FCC_FVNO_4) {
|
|
+ if ((cnt = write(ret, (char *)&fcc_flen, sizeof(fcc_flen)))
|
|
+ != sizeof(fcc_flen)) {
|
|
+ errsave = errno;
|
|
+ (void) close(ret);
|
|
+ (void) unlink(((krb5_fcc_data *) lid->data)->filename);
|
|
+ retcode = (cnt == -1) ? krb5_fcc_interpret(context, errsave) : KRB5_CC_IO;
|
|
+ goto err_out;
|
|
}
|
|
- /* For version 4 we save a length for the rest of the header */
|
|
- if (context->fcc_default_format == KRB5_FCC_FVNO_4) {
|
|
- if ((cnt = write(ret, (char *)&fcc_flen, sizeof(fcc_flen)))
|
|
- != sizeof(fcc_flen)) {
|
|
- errsave = errno;
|
|
- (void) close(ret);
|
|
- (void) unlink(((krb5_fcc_data *) lid->data)->filename);
|
|
- retcode = (cnt == -1) ? krb5_fcc_interpret(context, errsave) : KRB5_CC_IO;
|
|
- goto err_out;
|
|
- }
|
|
- }
|
|
- if (close(ret) == -1) {
|
|
- errsave = errno;
|
|
- (void) unlink(((krb5_fcc_data *) lid->data)->filename);
|
|
- retcode = krb5_fcc_interpret(context, errsave);
|
|
- goto err_out;
|
|
- }
|
|
- *id = lid;
|
|
- /* default to open/close on every trn - otherwise destroy
|
|
- will get as to state confused */
|
|
- ((krb5_fcc_data *) lid->data)->flags = KRB5_TC_OPENCLOSE;
|
|
- krb5_change_cache ();
|
|
- return KRB5_OK;
|
|
}
|
|
+ if (close(ret) == -1) {
|
|
+ errsave = errno;
|
|
+ (void) unlink(((krb5_fcc_data *) lid->data)->filename);
|
|
+ retcode = krb5_fcc_interpret(context, errsave);
|
|
+ goto err_out;
|
|
+ }
|
|
+ *id = lid;
|
|
+ /* default to open/close on every trn - otherwise destroy
|
|
+ will get as to state confused */
|
|
+ ((krb5_fcc_data *) lid->data)->flags = KRB5_TC_OPENCLOSE;
|
|
+ krb5_change_cache ();
|
|
+ return KRB5_OK;
|
|
|
|
err_out:
|
|
krb5_xfree(((krb5_fcc_data *) lid->data)->filename);
|
|
Index: src/lib/krb5/ccache/ccfns.c
|
|
===================================================================
|
|
--- src/lib/krb5/ccache/ccfns.c (.../tags/krb5-1-6-2-final) (Revision 19931)
|
|
+++ src/lib/krb5/ccache/ccfns.c (.../branches/krb5-1-6) (Revision 19931)
|
|
@@ -1,7 +1,7 @@
|
|
/*
|
|
* lib/krb5/ccache/ccfns.c
|
|
*
|
|
- * Copyright 2000 by the Massachusetts Institute of Technology.
|
|
+ * Copyright 2000, 2007 by the Massachusetts Institute of Technology.
|
|
* All Rights Reserved.
|
|
*
|
|
* Export of this software from the United States of America may
|
|
@@ -65,7 +65,29 @@
|
|
krb5_cc_store_cred (krb5_context context, krb5_ccache cache,
|
|
krb5_creds *creds)
|
|
{
|
|
- return cache->ops->store(context, cache, creds);
|
|
+ krb5_error_code ret;
|
|
+ krb5_ticket *tkt;
|
|
+ krb5_principal s1, s2;
|
|
+
|
|
+ ret = cache->ops->store(context, cache, creds);
|
|
+ if (ret) return ret;
|
|
+
|
|
+ /*
|
|
+ * If creds->server and the server in the decoded ticket differ,
|
|
+ * store both principals.
|
|
+ */
|
|
+ s1 = creds->server;
|
|
+ ret = decode_krb5_ticket(&creds->ticket, &tkt);
|
|
+ /* Bail out on errors in case someone is storing a non-ticket. */
|
|
+ if (ret) return 0;
|
|
+ s2 = tkt->server;
|
|
+ if (!krb5_principal_compare(context, s1, s2)) {
|
|
+ creds->server = s2;
|
|
+ ret = cache->ops->store(context, cache, creds);
|
|
+ creds->server = s1;
|
|
+ }
|
|
+ krb5_free_ticket(context, tkt);
|
|
+ return ret;
|
|
}
|
|
|
|
krb5_error_code KRB5_CALLCONV
|
|
@@ -73,7 +95,23 @@
|
|
krb5_flags flags, krb5_creds *mcreds,
|
|
krb5_creds *creds)
|
|
{
|
|
- return cache->ops->retrieve(context, cache, flags, mcreds, creds);
|
|
+ krb5_error_code ret;
|
|
+ krb5_data tmprealm;
|
|
+
|
|
+ ret = cache->ops->retrieve(context, cache, flags, mcreds, creds);
|
|
+ if (ret != KRB5_CC_NOTFOUND)
|
|
+ return ret;
|
|
+ if (!krb5_is_referral_realm(&mcreds->server->realm))
|
|
+ return ret;
|
|
+
|
|
+ /*
|
|
+ * Retry using client's realm if service has referral realm.
|
|
+ */
|
|
+ tmprealm = mcreds->server->realm;
|
|
+ mcreds->server->realm = mcreds->client->realm;
|
|
+ ret = cache->ops->retrieve(context, cache, flags, mcreds, creds);
|
|
+ mcreds->server->realm = tmprealm;
|
|
+ return ret;
|
|
}
|
|
|
|
krb5_error_code KRB5_CALLCONV
|
|
Index: src/lib/krb5/krb/gc_frm_kdc.c
|
|
===================================================================
|
|
--- src/lib/krb5/krb/gc_frm_kdc.c (.../tags/krb5-1-6-2-final) (Revision 19931)
|
|
+++ src/lib/krb5/krb/gc_frm_kdc.c (.../branches/krb5-1-6) (Revision 19931)
|
|
@@ -906,7 +906,6 @@
|
|
/* Whether or not that succeeded, we're done. */
|
|
goto cleanup;
|
|
}
|
|
- else {
|
|
/* Referral request succeeded; let's see what it is. */
|
|
if (krb5_principal_compare(context, in_cred->server,
|
|
(*out_cred)->server)) {
|
|
@@ -914,8 +913,40 @@
|
|
"for requested server principal\n"));
|
|
DUMP_PRINC("gc_from_kdc final referred reply",
|
|
in_cred->server);
|
|
+
|
|
+ /*
|
|
+ * Check if the return enctype is one that we requested if
|
|
+ * needed.
|
|
+ */
|
|
+ if (old_use_conf_ktypes || context->tgs_ktype_count == 0)
|
|
goto cleanup;
|
|
+ for (i = 0; i < context->tgs_ktype_count; i++) {
|
|
+ if ((*out_cred)->keyblock.enctype == context->tgs_ktypes[i]) {
|
|
+ /* Found an allowable etype, so we're done */
|
|
+ goto cleanup;
|
|
+ }
|
|
}
|
|
+ /*
|
|
+ * We need to try again, but this time use the
|
|
+ * tgs_ktypes in the context. At this point we should
|
|
+ * have all the tgts to succeed.
|
|
+ */
|
|
+
|
|
+ /* Free "wrong" credential */
|
|
+ krb5_free_creds(context, *out_cred);
|
|
+ *out_cred = NULL;
|
|
+ /* Re-establish tgs etypes */
|
|
+ context->use_conf_ktypes = old_use_conf_ktypes;
|
|
+ retval = krb5_get_cred_via_tkt(context, tgtptr,
|
|
+ KDC_OPT_CANONICALIZE |
|
|
+ FLAGS2OPTS(tgtptr->ticket_flags) |
|
|
+ kdcopt |
|
|
+ (in_cred->second_ticket.length ?
|
|
+ KDC_OPT_ENC_TKT_IN_SKEY : 0),
|
|
+ tgtptr->addresses,
|
|
+ in_cred, out_cred);
|
|
+ goto cleanup;
|
|
+ }
|
|
else if (IS_TGS_PRINC(context, (*out_cred)->server)) {
|
|
krb5_data *r1, *r2;
|
|
|
|
@@ -978,7 +1009,6 @@
|
|
krb5_free_creds(context, *out_cred);
|
|
*out_cred = NULL;
|
|
break;
|
|
- }
|
|
}
|
|
}
|
|
|