diff options
Diffstat (limited to 'src/lib/kdb')
-rw-r--r-- | src/lib/kdb/ChangeLog | 73 | ||||
-rw-r--r-- | src/lib/kdb/Makefile.in | 2 | ||||
-rw-r--r-- | src/lib/kdb/fetch_mkey.c | 2 | ||||
-rw-r--r-- | src/lib/kdb/kdb_db2.c | 38 | ||||
-rw-r--r-- | src/lib/kdb/kdb_db2.h | 6 | ||||
-rw-r--r-- | src/lib/kdb/kdb_xdr.c | 16 | ||||
-rw-r--r-- | src/lib/kdb/keytab.c | 58 | ||||
-rw-r--r-- | src/lib/kdb/setup_mkey.c | 2 | ||||
-rw-r--r-- | src/lib/kdb/store_mkey.c | 2 | ||||
-rw-r--r-- | src/lib/kdb/t_kdb.c | 47 |
10 files changed, 213 insertions, 33 deletions
diff --git a/src/lib/kdb/ChangeLog b/src/lib/kdb/ChangeLog index a710eb7..4aeb862 100644 --- a/src/lib/kdb/ChangeLog +++ b/src/lib/kdb/ChangeLog @@ -1,3 +1,76 @@ +2003-03-16 Sam Hartman <hartmans@mit.edu> + + * keytab.c (krb5_ktkdb_get_entry): Match only against the first + enctype for non-cross-realm tickets so we will only accept + tickets that the current configuration would have issued. For + cross-realm tickets be liberal and match against the specified + enctype. + +2002-08-26 Tom Yu <tlyu@mit.edu> + + * kdb_db2.h: Add prototype and rename for + krb5_db2_db_iterate_ext(). + + * kdb_db2.c (krb5_db2_db_iterate_ext): New function; allow + optional backwards or recursive (if btree) traversal of the + database. + + * Makefile.in (LIBMINOR): Bump due to addition of + krb5_db_iterate_ext(). + + [pullups from trunk] + +2002-08-15 Tom Yu <tlyu@mit.edu> + + * keytab.c (krb5_ktkdb_get_entry): For consistency, check for + DISALLOW_ALL_TIX and DISALLOW_SVR when looking up keys. + [pullup from trunk] + +2002-08-12 Sam Hartman <hartmans@mit.edu> + + * kdb_xdr.c (krb5_dbe_search_enctype): Initialize ret to 0; thanks + to Lubos Kejzlar <kejzlar@civ.zcu.cz> + [pullup from trunk] + +2001-11-05 Tom Yu <tlyu@mit.edu> + + * Makefile.in (LIBMINOR): Bump due to some behavior changes + regarding enctype similarity. + +2001-10-22 Tom Yu <tlyu@mit.edu> + + * kdb_xdr.c (krb5_dbe_search_enctype): Filter out enctypes that + aren't in permitted_enctypes. This prevents the KDC from issuing + a ticket whose enctype that it won't accept. + +2001-10-20 Tom Yu <tlyu@mit.edu> + + * keytab.c (krb5_ktkdb_get_entry): For now, coerce enctype of + output keyblock in case we got a match on a similar enctype. + +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * t_kdb.c (gen_principal): Don't overflow "pnamebuf" if bad data was + passed in. + +2000-05-03 Nalin Dahyabhai <nalin@redhat.com> + + * setup_mkey.c (krb5_db_setup_mkey_name): Use REALM_SEP_STRING + when computing size of buffer that is to include it. + + * fetch_mkey.c (krb5_db_fetch_mkey): Make sure "defkeyfile" is + null terminated after construction. + * store_mkey.c (krb5_db_store_mkey): Likewise. + +2000-04-27 Ken Raeburn <raeburn@mit.edu> + Ezra Peisach <epeisach@mit.edu> + + * t_kdb.c (gen_principal): Force argument to isalnum to be in + range 0..255. + (do_testing): Cast pid_t to long before passing to fprintf, and + use %ld format. Fix argument lists to find_principal and + delete_principal. + 2000-03-16 Ezra Peisach <epeisach@mit.edu> * kdb_xdr.c (krb5_dbe_lookup_mod_princ_data): Get rid of diff --git a/src/lib/kdb/Makefile.in b/src/lib/kdb/Makefile.in index 68c6361..10f7580 100644 --- a/src/lib/kdb/Makefile.in +++ b/src/lib/kdb/Makefile.in @@ -9,7 +9,7 @@ PROG_RPATH=$(KRB5_LIBDIR) LIB=kdb5 LIBMAJOR=3 -LIBMINOR=0 +LIBMINOR=2 RELDIR=kdb # Depends on libk5crypto and libkrb5 SHLIB_EXPDEPS = \ diff --git a/src/lib/kdb/fetch_mkey.c b/src/lib/kdb/fetch_mkey.c index 2ff5c29..7ae26bb 100644 --- a/src/lib/kdb/fetch_mkey.c +++ b/src/lib/kdb/fetch_mkey.c @@ -133,7 +133,7 @@ krb5_db_fetch_mkey(context, mname, etype, fromkeyboard, twice, keyfile, (void) strncat(defkeyfile, realm->data, min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1, realm->length)); - (void) strcat(defkeyfile, ""); + defkeyfile[sizeof(defkeyfile) - 1] = '\0'; #ifdef ANSI_STDIO if (!(kf = fopen((keyfile) ? keyfile : defkeyfile, "rb"))) diff --git a/src/lib/kdb/kdb_db2.c b/src/lib/kdb/kdb_db2.c index 627aa75..6420acc 100644 --- a/src/lib/kdb/kdb_db2.c +++ b/src/lib/kdb/kdb_db2.c @@ -1115,10 +1115,11 @@ cleanup: } krb5_error_code -krb5_db2_db_iterate (context, func, func_arg) +krb5_db2_db_iterate_ext(context, func, func_arg, backwards, recursive) krb5_context context; krb5_error_code (*func) PROTOTYPE((krb5_pointer, krb5_db_entry *)); krb5_pointer func_arg; + int backwards, recursive; { krb5_db2_context *db_ctx; DB *db; @@ -1127,17 +1128,31 @@ krb5_db2_db_iterate (context, func, func_arg) krb5_db_entry entries; krb5_error_code retval; int dbret; - + void *cookie; + + cookie = NULL; if (!k5db2_inited(context)) return KRB5_KDB_DBNOTINITED; db_ctx = (krb5_db2_context *) context->db_context; retval = krb5_db2_db_lock(context, KRB5_LOCKMODE_SHARED); + if (retval) return retval; db = db_ctx->db; - dbret = (*db->seq)(db, &key, &contents, R_FIRST); + if (recursive && db->type != DB_BTREE) { + (void)krb5_db2_db_unlock(context); + return KRB5_KDB_UK_RERROR; /* Not optimal, but close enough. */ + } + + if (!recursive) { + dbret = (*db->seq)(db, &key, &contents, + backwards ? R_LAST : R_FIRST); + } else { + dbret = bt_rseq(db, &key, &contents, &cookie, + backwards ? R_LAST : R_FIRST); + } while (dbret == 0) { contdata.data = contents.data; contdata.length = contents.size; @@ -1148,7 +1163,13 @@ krb5_db2_db_iterate (context, func, func_arg) krb5_dbe_free_contents(context, &entries); if (retval) break; - dbret = (*db->seq)(db, &key, &contents, R_NEXT); + if (!recursive) { + dbret = (*db->seq)(db, &key, &contents, + backwards ? R_PREV : R_NEXT); + } else { + dbret = bt_rseq(db, &key, &contents, &cookie, + backwards ? R_PREV : R_NEXT); + } } switch (dbret) { case 1: @@ -1162,6 +1183,15 @@ krb5_db2_db_iterate (context, func, func_arg) return retval; } +krb5_error_code +krb5_db2_db_iterate(context, func, func_arg) + krb5_context context; + krb5_error_code (*func) (krb5_pointer, krb5_db_entry *); + krb5_pointer func_arg; +{ + return krb5_db2_db_iterate_ext(context, func, func_arg, 0, 0); +} + krb5_boolean krb5_db2_db_set_lockmode(context, mode) krb5_context context; diff --git a/src/lib/kdb/kdb_db2.h b/src/lib/kdb/kdb_db2.h index fd35c81..d8f7ba5 100644 --- a/src/lib/kdb/kdb_db2.h +++ b/src/lib/kdb/kdb_db2.h @@ -41,6 +41,7 @@ #define krb5_db2_db_free_principal krb5_db_free_principal #define krb5_db2_db_put_principal krb5_db_put_principal #define krb5_db2_db_delete_principal krb5_db_delete_principal +#define krb5_db2_db_iterate_ext krb5_db_iterate_ext #define krb5_db2_db_iterate krb5_db_iterate #define krb5_db2_db_lock krb5_db_lock #define krb5_db2_db_unlock krb5_db_unlock @@ -104,6 +105,11 @@ krb5_error_code krb5_db2_db_put_principal KRB5_PROTOTYPE((krb5_context, krb5_db_entry *, int * )); +krb5_error_code krb5_db2_db_iterate_ext + KRB5_PROTOTYPE((krb5_context, + krb5_error_code (*) (krb5_pointer, + krb5_db_entry *), + krb5_pointer, int, int )); krb5_error_code krb5_db2_db_iterate KRB5_PROTOTYPE((krb5_context, krb5_error_code (*) KRB5_PROTOTYPE((krb5_pointer, diff --git a/src/lib/kdb/kdb_xdr.c b/src/lib/kdb/kdb_xdr.c index 5d1911e2..b7b8b4a 100644 --- a/src/lib/kdb/kdb_xdr.c +++ b/src/lib/kdb/kdb_xdr.c @@ -724,7 +724,9 @@ krb5_dbe_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap) int i, index; int maxkvno; krb5_key_data *datap; + krb5_error_code ret; + ret = 0; if (kvno == -1 && stype == -1 && ktype == -1) kvno = 0; @@ -741,15 +743,25 @@ krb5_dbe_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap) datap = (krb5_key_data *) NULL; for (i = *start; i < dbentp->n_key_data; i++) { krb5_boolean similar; - krb5_error_code ret; krb5_int32 db_stype; + ret = 0; if (dbentp->key_data[i].key_data_ver > 1) { db_stype = dbentp->key_data[i].key_data_type[1]; } else { db_stype = KRB5_KDB_SALTTYPE_NORMAL; } + + /* + * Filter out non-permitted enctypes. + */ + if (!krb5_is_permitted_enctype(kcontext, + dbentp->key_data[i].key_data_type[0])) { + ret = KRB5_KDB_NO_PERMITTED_KEY; + continue; + } + if (ktype >= 0) { if ((ret = krb5_c_enctype_compare(kcontext, (krb5_enctype) ktype, dbentp->key_data[i].key_data_type[0], @@ -776,7 +788,7 @@ krb5_dbe_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap) } } if (maxkvno < 0) - return ENOENT; + return ret ? ret : KRB5_KDB_NO_MATCHING_KEY; *kdatap = datap; *start = index+1; return 0; diff --git a/src/lib/kdb/keytab.c b/src/lib/kdb/keytab.c index 1e5025c..5881fa1 100644 --- a/src/lib/kdb/keytab.c +++ b/src/lib/kdb/keytab.c @@ -28,6 +28,8 @@ #include "k5-int.h" #include "kdb_kt.h" +static int +is_xrealm_tgt(krb5_context, krb5_const_principal); krb5_error_code krb5_ktkdb_close KRB5_PROTOTYPE((krb5_context, krb5_keytab)); krb5_error_code krb5_ktkdb_get_entry KRB5_PROTOTYPE((krb5_context, krb5_keytab, krb5_const_principal, @@ -98,6 +100,8 @@ krb5_ktkdb_get_entry(context, id, principal, kvno, enctype, entry) krb5_db_entry db_entry; krb5_boolean more = 0; int n = 0; + int xrealm_tgt = is_xrealm_tgt(context, principal); + int similar; /* Open database */ /* krb5_db_init(context); */ @@ -116,21 +120,49 @@ krb5_ktkdb_get_entry(context, id, principal, kvno, enctype, entry) return KRB5_KT_NOTFOUND; } + if (db_entry.attributes & KRB5_KDB_DISALLOW_SVR + || db_entry.attributes & KRB5_KDB_DISALLOW_ALL_TIX) { + kerror = KRB5_KT_NOTFOUND; + goto error; + } + /* match key */ kerror = krb5_db_get_mkey(context, &master_key); if (kerror) goto error; + /* For cross realm tgts, we match whatever enctype is provided; + * for other principals, we only match the first enctype that is + * found. Since the TGS and AS code do the same thing, then we + * will only successfully decrypt tickets we have issued.*/ kerror = krb5_dbe_find_enctype(context, &db_entry, - enctype, -1, kvno, &key_data); + xrealm_tgt?enctype:-1, + -1, kvno, &key_data); if (kerror) goto error; + kerror = krb5_dbekd_decrypt_key_data(context, master_key, key_data, &entry->key, NULL); if (kerror) goto error; + kerror = krb5_c_enctype_compare(context, enctype, entry->key.enctype, &similar); + if (kerror) + goto error; + + if (!similar) { + kerror = KRB5_KDB_NO_PERMITTED_KEY; + goto error; + } + + /* + * Coerce the enctype of the output keyblock in case we got an + * inexact match on the enctype; this behavior will go away when + * the key storage architecture gets redesigned for 1.3. + */ + entry->key.enctype = enctype; + kerror = krb5_copy_principal(context, principal, &entry->principal); if (kerror) goto error; @@ -141,3 +173,27 @@ krb5_ktkdb_get_entry(context, id, principal, kvno, enctype, entry) krb5_db_close_database(context); return(kerror); } + +/* + * is_xrealm_tgt: Returns true if the principal is a cross-realm TGT + * principal-- a principal with first component krbtgt and second + * component not equal to realm. + */ +static int +is_xrealm_tgt(krb5_context context, krb5_const_principal princ) +{ + krb5_data *dat; + if (krb5_princ_size(context, princ) != 2) + return 0; + dat = krb5_princ_component(context, princ, 0); + if (strncmp("krbtgt", dat->data, dat->length) != 0) + return 0; + dat = krb5_princ_component(context, princ, 1); + if (dat->length != princ->realm.length) + return 1; + if (strcmp(dat->data, princ->realm.data) == 0) + return 0; + return 1; + +} + diff --git a/src/lib/kdb/setup_mkey.c b/src/lib/kdb/setup_mkey.c index 0898a63..1788ecd 100644 --- a/src/lib/kdb/setup_mkey.c +++ b/src/lib/kdb/setup_mkey.c @@ -56,7 +56,7 @@ krb5_db_setup_mkey_name(context, keyname, realm, fullname, principal) keylen = strlen(keyname); - fname = malloc(keylen+rlen+2); + fname = malloc(keylen+rlen+strlen(REALM_SEP_STRING)+1); if (!fname) return ENOMEM; diff --git a/src/lib/kdb/store_mkey.c b/src/lib/kdb/store_mkey.c index d18630a..47e0bc9 100644 --- a/src/lib/kdb/store_mkey.c +++ b/src/lib/kdb/store_mkey.c @@ -68,7 +68,7 @@ krb5_db_store_mkey(context, keyfile, mname, key) (void) strncat(defkeyfile, realm->data, min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1, realm->length)); - (void) strcat(defkeyfile, ""); + defkeyfile[sizeof(defkeyfile) - 1] = '\0'; keyfile = defkeyfile; } diff --git a/src/lib/kdb/t_kdb.c b/src/lib/kdb/t_kdb.c index 8358088..10e6163 100644 --- a/src/lib/kdb/t_kdb.c +++ b/src/lib/kdb/t_kdb.c @@ -363,15 +363,23 @@ gen_principal(kcontext, realm, do_rand, n, princp, namep) complen = RANDOM(1,MAX_COMP_SIZE); for (j=0; j<complen; j++) { *cp = (char) RANDOM(0,256); - while (!isalnum(*cp)) + while (!isalnum(*cp & 0xff)) *cp = (char) RANDOM(0,256); cp++; + if(cp + strlen(realm) >= pnamebuf + sizeof(pnamebuf)) + break; } + if(cp + strlen(realm) >= pnamebuf + sizeof(pnamebuf)) + break; *cp = '/'; cp++; } - cp[-1] = '@'; - strcpy(cp, realm); + if(cp + strlen(realm) < pnamebuf + sizeof(pnamebuf)) { + cp[-1] = '@'; + strcpy(cp, realm); + } else { + strcpy(cp , ""); + } } else { instname = instnames[n % (sizeof(instnames)/sizeof(instnames[0]))]; @@ -894,45 +902,40 @@ do_testing(db, passes, verbose, timing, rcases, check, save_db, dontclean, &stat_kb, rseed))) { fprintf(stderr, - "%d: (%d,%d) Failed add of %s with %s\n", - getpid(), i, j, playback_name(base+j), + "%ld: (%d,%d) Failed add of %s with %s\n", + (long) getpid(), i, j, playback_name(base+j), error_message(kret)); break; } if (verbose > 4) - fprintf(stderr, "*A[%d](%s)\n", getpid(), + fprintf(stderr, "*A[%ld](%s)\n", (long) getpid(), playback_name(base+j)); } for (j=0; (j<nper) && (!kret); j++) { if ((kret = find_principal(ccontext, playback_principal(base+j), - &master_encblock, - &stat_kb, - rseed))) { + check))) { fprintf(stderr, - "%d: (%d,%d) Failed lookup of %s with %s\n", - getpid(), i, j, playback_name(base+j), + "%ld: (%d,%d) Failed lookup of %s with %s\n", + (long) getpid(), i, j, playback_name(base+j), error_message(kret)); break; } if (verbose > 4) - fprintf(stderr, "-S[%d](%s)\n", getpid(), + fprintf(stderr, "-S[%ld](%s)\n", (long) getpid(), playback_name(base+j)); } for (j=0; (j<nper) && (!kret); j++) { if ((kret = delete_principal(ccontext, - playback_principal(base+j), - &master_encblock, - &stat_kb, - rseed))) { + playback_principal(base+j)))) { fprintf(stderr, - "%d: (%d,%d) Failed delete of %s with %s\n", - getpid(), i, j, playback_name(base+j), + "%ld: (%d,%d) Failed delete of %s with %s\n", + (long) getpid(), i, j, playback_name(base+j), error_message(kret)); break; } if (verbose > 4) - fprintf(stderr, "XD[%d](%s)\n", getpid(), + fprintf(stderr, "XD[%ld](%s)\n", (long) getpid(), playback_name(base+j)); } krb5_db_fini(ccontext); @@ -949,13 +952,13 @@ do_testing(db, passes, verbose, timing, rcases, check, save_db, dontclean, for (i=0; i<nprocs; i++) { if (waitpid(children[i], &existat, 0) == children[i]) { if (verbose) - fprintf(stderr, "%d finished with %d\n", children[i], - existat); + fprintf(stderr, "%ld finished with %d\n", + (long) children[i], existat); if (existat) kret = KRB5KRB_ERR_GENERIC; } else - fprintf(stderr, "Wait for %d failed\n", children[i]); + fprintf(stderr, "Wait for %ld failed\n", (long) children[i]); } } |