summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Provenzano <proven@mit.edu>1995-07-27 08:44:02 +0000
committerChris Provenzano <proven@mit.edu>1995-07-27 08:44:02 +0000
commit4f0debdb553c49e68b36ee4e0ece3d2f32e4ae03 (patch)
tree30f4ad36ba60acb37c882e626cf3316fb817691b
parent9492970827609efce31ce4ce5bd4f0535ff97e53 (diff)
downloadkrb5-4f0debdb553c49e68b36ee4e0ece3d2f32e4ae03.tar.gz
krb5-4f0debdb553c49e68b36ee4e0ece3d2f32e4ae03.tar.xz
krb5-4f0debdb553c49e68b36ee4e0ece3d2f32e4ae03.zip
* decrypt_key.c, encrypt_key.c, kdb_dbm.c, kdb_xdr.c:
Rewritten for new kdb format. * kdb_cpw.c : New password changing routines for new kdb format. * verify_mky.c, t_kdb.c : Use new kdb format. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@6328 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/kdb/ChangeLog8
-rw-r--r--src/lib/kdb/Makefile.in2
-rw-r--r--src/lib/kdb/decrypt_key.c77
-rw-r--r--src/lib/kdb/encrypt_key.c99
-rw-r--r--src/lib/kdb/kdb_cpw.c68
-rw-r--r--src/lib/kdb/kdb_dbm.c498
-rw-r--r--src/lib/kdb/kdb_xdr.c652
-rw-r--r--src/lib/kdb/t_kdb.c116
-rw-r--r--src/lib/kdb/verify_mky.c4
9 files changed, 936 insertions, 588 deletions
diff --git a/src/lib/kdb/ChangeLog b/src/lib/kdb/ChangeLog
index fcebad85d7..5cb3bf9144 100644
--- a/src/lib/kdb/ChangeLog
+++ b/src/lib/kdb/ChangeLog
@@ -1,3 +1,11 @@
+
+Thu Jul 27 02:59:05 1995 Chris Provenzano (proven@mit.edu)
+ * decrypt_key.c, encrypt_key.c, kdb_dbm.c, kdb_xdr.c:
+ Rewritten for new kdb format.
+ * kdb_cpw.c : New password changing routines for new kdb format.
+ * verify_mky.c, t_kdb.c : Use new kdb format.
+
+
Tue Jul 25 14:06:50 1995 Tom Yu <tlyu@lothlorien.MIT.EDU>
* kdb_dbm.c, t_kdb.c: Add prototype for dbm_error and dbm_clearerr
diff --git a/src/lib/kdb/Makefile.in b/src/lib/kdb/Makefile.in
index afb8fe31e7..fad482eecb 100644
--- a/src/lib/kdb/Makefile.in
+++ b/src/lib/kdb/Makefile.in
@@ -8,6 +8,7 @@ SRCS= \
$(srcdir)/encrypt_key.c \
$(srcdir)/decrypt_key.c \
$(srcdir)/kdb_dbm.c \
+ $(srcdir)/kdb_xdr.c \
$(srcdir)/verify_mky.c \
$(srcdir)/fetch_mkey.c \
$(srcdir)/setup_mkey.c \
@@ -17,6 +18,7 @@ OBJS= \
encrypt_key.o \
decrypt_key.o \
kdb_dbm.o \
+ kdb_xdr.o \
verify_mky.o \
fetch_mkey.o \
setup_mkey.o \
diff --git a/src/lib/kdb/decrypt_key.c b/src/lib/kdb/decrypt_key.c
index cb901b677c..cc0503f8f8 100644
--- a/src/lib/kdb/decrypt_key.c
+++ b/src/lib/kdb/decrypt_key.c
@@ -33,51 +33,50 @@
*/
krb5_error_code
-krb5_kdb_decrypt_key(context, eblock, in, out)
- krb5_context context;
- krb5_encrypt_block *eblock;
- const krb5_encrypted_keyblock *in;
- krb5_keyblock *out;
+krb5_dbekd_decrypt_key_data(context, eblock, key_data, keyblock, keysalt)
+ krb5_context context;
+ krb5_encrypt_block * eblock;
+ const krb5_key_data * key_data;
+ krb5_keyblock * keyblock;
+ krb5_keysalt * keysalt;
{
- krb5_error_code retval;
+ krb5_error_code retval;
+ krb5_octet * ptr;
- /* the encrypted version is stored as the unencrypted key length
- (4 bytes, MSB first) followed by the encrypted key. */
- out->magic = KV5M_KEYBLOCK;
- out->etype = ETYPE_UNKNOWN;
- out->keytype = in->keytype;
- out->length = krb5_encrypt_size(in->length-sizeof(in->length),
- eblock->crypto_entry);
- out->contents = (krb5_octet *)malloc(out->length);
- if (!out->contents) {
- out->contents = 0;
- out->length = 0;
- return ENOMEM;
- }
+ keyblock->magic = KV5M_KEYBLOCK;
+ keyblock->etype = ETYPE_UNKNOWN;
+ keyblock->keytype = key_data->key_data_type[0];
- /* copy out the real length count */
- out->length = (((unsigned char *)in->contents)[0] << 24)
- + (((unsigned char *)in->contents)[1] << 16)
- + (((unsigned char *)in->contents)[2] << 8)
- + ((unsigned char *)in->contents)[3];
+ /* Decrypt key_data_contents */
+ if ((keyblock->contents = (krb5_octet *)malloc(krb5_encrypt_size(
+ key_data->key_data_length[0] - 2, eblock->crypto_entry))) == NULL)
+ return ENOMEM;
- /* remember the contents of the encrypted version has a 4 byte
- integer length of the real embedded key, followed by the
- encrypted key, so the offset here is needed */
- if (retval = krb5_decrypt(context, (krb5_pointer) (
- (char *) in->contents + 4),
- (krb5_pointer) out->contents,
- in->length-sizeof(in->length), eblock, 0)) {
- krb5_xfree(out->contents);
- out->contents = 0;
- out->length = 0;
+ keyblock->length = 0;
+ ptr = key_data->key_data_contents[0];
+ *(((krb5_octet *)(&keyblock->length))) = *ptr++;
+ *(((krb5_octet *)(&keyblock->length)) + 1) = *ptr++;
+ if (retval = krb5_decrypt(context, (krb5_pointer) ptr,
+ (krb5_pointer)keyblock->contents,
+ key_data->key_data_length[0] - 2,
+ eblock, 0)) {
+ krb5_xfree(keyblock->contents);
return retval;
}
- if (out->length < 0) {
- krb5_xfree(out->contents);
- out->contents = 0;
- out->length = 0;
- return KRB5_KDB_INVALIDKEYSIZE;
+
+ /* Decode salt data */
+ if (keysalt) {
+ if (key_data->key_data_ver == 2) {
+ keysalt->type = key_data->key_data_type[1];
+ keysalt->data.length = key_data->key_data_length[1];
+ if (!(keysalt->data.data = (krb5_octet *)malloc(keysalt->data.length))){
+ krb5_xfree(keyblock->contents);
+ return ENOMEM;
+ }
+ } else {
+ keysalt->type = KRB5_KDB_SALTTYPE_NORMAL;
+ keysalt->data.length = 0;
+ }
}
return retval;
}
diff --git a/src/lib/kdb/encrypt_key.c b/src/lib/kdb/encrypt_key.c
index 277983e345..272280a009 100644
--- a/src/lib/kdb/encrypt_key.c
+++ b/src/lib/kdb/encrypt_key.c
@@ -33,57 +33,74 @@
*/
krb5_error_code
-krb5_kdb_encrypt_key(context, eblock, in, out)
- krb5_context context;
- krb5_encrypt_block *eblock;
- const krb5_keyblock *in;
- register krb5_encrypted_keyblock *out;
+krb5_dbekd_encrypt_key_data(context, eblock, keyblock, keysalt, keyver,key_data)
+ krb5_context context;
+ krb5_encrypt_block * eblock;
+ const krb5_keyblock * keyblock;
+ const krb5_keysalt * keysalt;
+ int keyver;
+ krb5_key_data * key_data;
{
- /* Encrypted rep has the real (unencrypted) key length stored
- along with the encrypted key. The length is stored as a 4
- byte integer, MSB first. */
+ krb5_error_code retval;
+ krb5_keyblock tmp;
+ krb5_octet * ptr;
+ krb5_int16 len;
+ int i;
- krb5_error_code retval;
- krb5_keyblock tmpin;
- unsigned int length;
+ for (i = 0; i < key_data->key_data_ver; i++)
+ if (key_data->key_data_contents[i])
+ krb5_xfree(key_data->key_data_contents[i]);
- out->keytype = in->keytype;
- out->length = krb5_encrypt_size(in->length, eblock->crypto_entry);
+ key_data->key_data_ver = 1;
+ key_data->key_data_kvno = keyver;
- /* because of checksum space requirements imposed by the encryption
- interface, we need to copy the input key into a larger area. */
- tmpin.length = in->length;
- tmpin.contents = (krb5_octet *)malloc(out->length);
- if (!tmpin.contents) {
- out->length = 0;
+ /*
+ * The First element of the type/length/contents
+ * fields is the key type/length/contents
+ */
+ key_data->key_data_type[0] = keyblock->keytype;
+ key_data->key_data_length[0] = krb5_encrypt_size(keyblock->length,
+ eblock->crypto_entry) + 2;
+
+ /*
+ * because of checksum space requirements imposed by the encryption
+ * interface, we need to copy the input key into a larger area.
+ */
+ tmp.contents = (krb5_octet *)malloc(key_data->key_data_length[0] - 2);
+ len = tmp.length = keyblock->length;
+ if (tmp.contents == NULL)
return ENOMEM;
- }
- memcpy((char *)tmpin.contents, (const char *)in->contents, tmpin.length);
- out->length += sizeof(out->length);
- out->contents = (krb5_octet *)malloc(out->length);
- if (!out->contents) {
- krb5_xfree(tmpin.contents);
- out->contents = 0;
- out->length = 0;
+ memcpy((char *)tmp.contents, (const char *)keyblock->contents, tmp.length);
+ key_data->key_data_contents[0] = ptr = (krb5_octet *)malloc(
+ key_data->key_data_length[0] - 2);
+ if (key_data->key_data_contents[0] == NULL) {
+ krb5_xfree(tmp.contents);
return ENOMEM;
}
- length = tmpin.length;
- ((char *)out->contents)[0] = length >> 24;
- ((char *)out->contents)[1] = length >> 16;
- ((char *)out->contents)[2] = length >> 8;
- ((char *)out->contents)[3] = length;
-
- retval = krb5_encrypt(context, (krb5_pointer) tmpin.contents,
- (krb5_pointer) ((char *) out->contents + 4),
- tmpin.length, eblock, 0);
- krb5_xfree(tmpin.contents);
- if (retval) {
- krb5_xfree(out->contents);
- out->contents = 0;
- out->length = 0;
+ *ptr++ = len & 0xff;
+ *ptr++ = (len >> 8) & 0xff;
+ if (retval = krb5_encrypt(context, (krb5_pointer) tmp.contents,
+ (krb5_pointer)(ptr), tmp.length, eblock, 0)) {
+ krb5_xfree(key_data->key_data_contents[0]);
+ krb5_xfree(tmp.contents);
+ return retval;
}
+ krb5_xfree(tmp.contents);
+
+ /* After key comes the salt in necessary */
+ if (keysalt) {
+ key_data->key_data_contents[1] =
+ (krb5_octet *)malloc(keysalt->data.length);
+ if (key_data->key_data_contents[1] == NULL) {
+ krb5_xfree(key_data->key_data_contents[0]);
+ return ENOMEM;
+ }
+ key_data->key_data_length[1] = keysalt->data.length;
+ key_data->key_data_type[1] = keysalt->type;
+ key_data->key_data_ver++;
+ }
return retval;
}
diff --git a/src/lib/kdb/kdb_cpw.c b/src/lib/kdb/kdb_cpw.c
new file mode 100644
index 0000000000..7376c22c4d
--- /dev/null
+++ b/src/lib/kdb/kdb_cpw.c
@@ -0,0 +1,68 @@
+/*
+ * lib/kdb/kdb_cpw.c
+ *
+ * Copyright 1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+#include "k5-int.h"
+#include <stdio.h>
+#include <errno.h>
+
+/*
+ * Change password for a krb5_db_entry for a specific key version number
+ */
+krb5_error_code
+krb5_kdb_cpw_dbe_for_kvno(context, db_entry, password, kvno)
+ krb5_context context;
+ krb5_db_entry * db_entry;
+ char * password;
+ int kvno;
+{
+ krb5_error_code retval;
+ int key;
+
+ for (key = 0; key < db_entry.n_key_data; key++) {
+ if (db_entry.key_data[key] == kvno) {
+ }
+ }
+ return retval;
+}
+
+/*
+ * Change password for a krb5_db_entry
+ * Assumes the max kvno
+ */
+krb5_error_code
+krb5_kdb_cpw_dbe_for_kvno(context, db_entry, password)
+ krb5_context context;
+ krb5_db_entry * db_entry;
+ char * password;
+ int kvno;
+{
+ int key, kvno;
+
+ for (kvno = key = 0; key < db_entry.n_key_data; key++) {
+ if (kvno < db_entry.key_data[key].key_data_kvno) {
+ kvno = db_entry.key_data[key].key_data_kvno;
+ }
+ }
+ return(krb5_kdb_cpw_dbe_for_kvno(context, db_entry, password, kvno));
+}
diff --git a/src/lib/kdb/kdb_dbm.c b/src/lib/kdb/kdb_dbm.c
index 88ebb55b0e..9cb02a36e0 100644
--- a/src/lib/kdb/kdb_dbm.c
+++ b/src/lib/kdb/kdb_dbm.c
@@ -87,35 +87,6 @@ static krb5_error_code krb5_dbm_db_start_read
static krb5_error_code krb5_dbm_db_end_read
PROTOTYPE((krb5_context,
time_t ));
-static krb5_error_code encode_princ_dbmkey
- PROTOTYPE((krb5_context,
- datum *,
- krb5_principal ));
-static void free_encode_princ_dbmkey
- PROTOTYPE((krb5_context,
- datum * ));
-static krb5_error_code encode_princ_contents
- PROTOTYPE((krb5_context,
- datum *,
- krb5_db_entry * ));
-static void free_encode_princ_contents
- PROTOTYPE((datum * ));
-static krb5_error_code decode_princ_contents
- PROTOTYPE((krb5_context,
- datum *,
- krb5_db_entry * ));
-static void free_decode_princ_contents
- PROTOTYPE((krb5_context,
- krb5_db_entry * ));
-
-#if 0
-/* not used */
-static krb5_error_code decode_princ_dbmkey
- PROTOTYPE((datum *,
- krb5_principal * ));
-static void free_decode_princ_dbmkey
- PROTOTYPE((krb5_principal ));
-#endif
#ifdef BERK_DB_DBM
@@ -170,9 +141,8 @@ int dbm_clearerr PROTOTYPE((DBM *));
/*
* This module contains all of the code which directly interfaces to
* the underlying representation of the Kerberos database; this
- * implementation uses a DBM or NDBM indexed "file" (actually
- * implemented as two separate files) to store the relations, plus a
- * third file as a semaphore to allow the database to be replaced out
+ * implementation uses the Berkeley hash db to store the relations, plus a
+ * second file as a semaphore to allow the database to be replaced out
* from underneath the KDC server.
*/
static kdb5_dispatch_table kdb5_default_dispatch = {
@@ -693,402 +663,6 @@ krb5_dbm_db_end_read(context, age)
return 0;
}
-
-static krb5_error_code
-encode_princ_dbmkey(context, key, principal)
- krb5_context context;
- datum *key;
- krb5_principal principal;
-{
- char *princ_name;
- krb5_error_code retval;
-
- if (retval = krb5_unparse_name(context, principal, &princ_name))
- return(retval);
- key->dptr = princ_name;
- key->dsize = strlen(princ_name)+1; /* need to store the NULL for
- decoding */
- return 0;
-}
-
-static void
-free_encode_princ_dbmkey(context, key)
- krb5_context context;
- datum *key;
-{
- (void) free(key->dptr);
- key->dptr = 0;
- key->dsize = 0;
- return;
-}
-
-#if 0
-/* these aren't used, but if they ever should be... */
-static krb5_error_code
-decode_princ_dbmkey(context, key, principal)
- datum *key;
- krb5_principal *principal;
-{
- return(krb5_parse_name(context, key->dptr, principal));
-}
-
-static void
-free_decode_princ_dbmkey(context, principal)
- krb5_context context;
- krb5_principal principal;
-{
- krb5_free_principal(context, principal);
- return;
-}
-#endif
-
-static krb5_error_code
-encode_princ_contents(context, contents, entry)
- krb5_context context;
- register datum *contents;
- krb5_db_entry *entry;
-{
- krb5_db_entry copy_princ;
- char *unparse_princ, *unparse_mod_princ;
- register char *nextloc;
- int princ_size, mod_size;
-
- krb5_error_code retval;
-
- /* since there is some baggage pointing off of the entry
- structure, we'll encode it by writing the structure, with nulled
- pointers, followed by the unparsed principal name, then the key, and
- then the unparsed mod_princ name, and then the salt (if any).
- */
- copy_princ = *entry;
- copy_princ.principal = 0;
- copy_princ.mod_name = 0;
- copy_princ.salt = 0;
- copy_princ.alt_salt = 0;
- if (!entry->salt)
- copy_princ.salt_length = 0; /* Safety measures.... */
- if (!entry->alt_salt)
- copy_princ.alt_salt_length = 0;
-
- if (retval = krb5_unparse_name(context, entry->principal, &unparse_princ))
- return(retval);
- if (retval = krb5_unparse_name(context, entry->mod_name, &unparse_mod_princ)) {
- free(unparse_princ);
- return(retval);
- }
- princ_size = strlen(unparse_princ)+1;
- mod_size = strlen(unparse_mod_princ)+1;
- contents->dsize = (2 + sizeof(copy_princ) + princ_size
- + sizeof(entry->principal->type) + mod_size
- + sizeof(copy_princ.key.length)
- + copy_princ.key.length + copy_princ.salt_length
- + sizeof(copy_princ.alt_key.length)
- + copy_princ.alt_key.length
- + copy_princ.alt_salt_length);
- contents->dptr = malloc(contents->dsize);
- if (!contents->dptr) {
- free(unparse_princ);
- free(unparse_mod_princ);
- contents->dsize = 0;
- contents->dptr = 0;
- return(ENOMEM);
- }
- nextloc = contents->dptr;
- *nextloc++ = 2; /* Version number 2.0 */
- *nextloc++ = 0;
- (void) memcpy(nextloc, (char *)&copy_princ, sizeof(copy_princ));
- nextloc += sizeof(copy_princ);
-
- (void) memcpy(nextloc, unparse_princ, princ_size);
- nextloc += princ_size;
- (void) memcpy(nextloc, (char *)&entry->principal->type,
- sizeof(entry->principal->type));
- nextloc += sizeof(entry->principal->type);
- (void) memcpy(nextloc, unparse_mod_princ, mod_size);
- nextloc += mod_size;
- if (copy_princ.key.length) {
- (void) memcpy(nextloc, (char *)entry->key.contents, entry->key.length);
- nextloc += entry->key.length;
- }
- if (copy_princ.salt_length) {
- (void) memcpy(nextloc, (char *)entry->salt, entry->salt_length);
- nextloc += entry->salt_length;
- }
- if (copy_princ.alt_key.length) {
- (void) memcpy(nextloc, (char *)entry->alt_key.contents,
- entry->alt_key.length);
- nextloc += entry->alt_key.length;
- }
- if (copy_princ.alt_salt_length) {
- (void) memcpy(nextloc, (char *)entry->alt_salt,
- entry->alt_salt_length);
- nextloc += entry->alt_salt_length;
- }
- free(unparse_princ);
- free(unparse_mod_princ);
- return 0;
-}
-
-static void
-free_encode_princ_contents(contents)
- datum *contents;
-{
- free(contents->dptr);
- contents->dsize = 0;
- contents->dptr = 0;
- return;
-}
-
-static krb5_error_code
-decode_princ_contents(context, contents, entry)
- krb5_context context;
- datum *contents;
- krb5_db_entry *entry;
-{
- register char *nextloc;
- krb5_principal princ, mod_princ;
- krb5_error_code retval;
- int sizeleft;
- int major_version = 0, minor_version = 0;
-
- /*
- * undo the effects of encode_princ_contents.
- */
- sizeleft = contents->dsize;
- nextloc = contents->dptr;
- if (sizeleft <= 0)
- return KRB5_KDB_TRUNCATED_RECORD;
-
- /*
- * First, check the version number. If the major version number is
- * greater than zero, then the version number is explicitly
- * allocated; otherwise, it is part of the zeroed principal pointer.
- */
- major_version = *nextloc;
- if (major_version) {
- nextloc++; sizeleft--;
- minor_version = *nextloc;
- nextloc++; sizeleft--;
- }
-#ifdef OLD_COMPAT_VERSION_1
- if (major_version == 0 || major_version == 1) {
- old_krb5_db_entry old_entry;
-
- /*
- * Copy in structure to old-style structure, and then copy it
- * to the new structure.
- */
- sizeleft -= sizeof(old_entry);
- if (sizeleft < 0)
- return KRB5_KDB_TRUNCATED_RECORD;
-
- memcpy((char *) &old_entry, nextloc, sizeof(old_entry));
- nextloc += sizeof(old_entry); /* Skip past structure */
-
- entry->key.keytype = old_entry.key.keytype;
- entry->key.length = old_entry.key.length;
-
- entry->kvno = old_entry.kvno;
- entry->max_life = old_entry.max_life;
- entry->max_renewable_life = old_entry.max_renewable_life;
- entry->mkvno = old_entry.mkvno;
-
- entry->expiration = old_entry.expiration;
- entry->pw_expiration = old_entry.pw_expiration;
- entry->last_pwd_change = old_entry.last_pwd_change;
- entry->last_success = old_entry.last_success;
-
- entry->last_failed = old_entry.last_failed;
- entry->fail_auth_count = old_entry.fail_auth_count;
-
- entry->mod_date = old_entry.mod_date;
- entry->attributes = old_entry.attributes;
- entry->salt_type = old_entry.salt_type;
- entry->salt_length = old_entry.salt_length;
-
- entry->alt_key.keytype = old_entry.alt_key.keytype;
- entry->alt_key.length = old_entry.alt_key.length;
- entry->alt_salt_type = old_entry.alt_salt_type;
- entry->alt_salt_length = old_entry.alt_salt_length;
-
- goto resume_processing;
- }
-#endif
- if (major_version != 2)
- return KRB5_KDB_BAD_VERSION;
-
- sizeleft -= sizeof(*entry);
- if (sizeleft < 0)
- return KRB5_KDB_TRUNCATED_RECORD;
-
- memcpy((char *) entry, nextloc, sizeof(*entry));
- nextloc += sizeof(*entry); /* Skip past structure */
-
-#ifdef OLD_COMPAT_VERSION_1
-resume_processing:
-#endif
-
- /*
- * These values should be zero if they are not in use, but just in
- * case, we clear them to make sure nothing bad happens if we need
- * to call free_decode_princ_contents(). (What me, paranoid?)
- */
- entry->principal = 0;
- entry->mod_name = 0;
- entry->salt = 0;
- entry->alt_salt = 0;
- entry->key.contents = 0;
- entry->alt_key.contents = 0;
-
- /*
- * Get the principal name for the entry (stored as a string which
- * gets unparsed.)
- */
- sizeleft -= strlen(nextloc)+1;
- if (sizeleft < 0) {
- retval = KRB5_KDB_TRUNCATED_RECORD;
- goto error_out;
- }
- retval = krb5_parse_name(context, nextloc, &princ);
- if (retval)
- goto error_out;
- entry->principal = princ;
- nextloc += strlen(nextloc)+1; /* advance past 1st string */
-
- if (major_version >= 1) { /* Get principal type */
- sizeleft -= sizeof(entry->principal->type);
- if (sizeleft < 0) {
- retval = KRB5_KDB_TRUNCATED_RECORD;
- goto error_out;
- }
- memcpy((char *)&entry->principal->type,nextloc,
- sizeof(entry->principal->type));
- nextloc += sizeof(princ->type);
- }
-
- /*
- * Get the last modified principal for the entry (again stored as
- * string which gets unparased.)
- */
- sizeleft -= strlen(nextloc)+1; /* check size for 2nd string */
- if (sizeleft < 0) {
- retval = KRB5_KDB_TRUNCATED_RECORD;
- goto error_out;
- }
- retval = krb5_parse_name(context, nextloc, &mod_princ);
- if (retval)
- goto error_out;
- entry->mod_name = mod_princ;
- nextloc += strlen(nextloc)+1; /* advance past 2nd string */
-
- /*
- * Get the primary key...
- */
- if (entry->key.length) {
- sizeleft -= entry->key.length; /* check size for key */
- if (sizeleft < 0) {
- retval = KRB5_KDB_TRUNCATED_RECORD;
- goto error_out;
- }
- entry->key.contents = (unsigned char *)malloc(entry->key.length);
- if (!entry->key.contents) {
- retval = ENOMEM;
- goto error_out;
- }
- (void) memcpy((char *)entry->key.contents, nextloc, entry->key.length);
- nextloc += entry->key.length; /* advance past key */
- }
-
- /*
- * ...and the salt, if present...
- */
- if (entry->salt_length) {
- sizeleft -= entry->salt_length;
- if (sizeleft < 0) {
- retval = KRB5_KDB_TRUNCATED_RECORD;
- goto error_out;
- }
- entry->salt = (krb5_octet *)malloc(entry->salt_length);
- if (!entry->salt) {
- retval = KRB5_KDB_TRUNCATED_RECORD;
- goto error_out;
- }
- (void) memcpy((char *)entry->salt, nextloc, entry->salt_length);
- nextloc += entry->salt_length; /* advance past salt */
- }
-
- /*
- * ... and the alternate key, if present...
- */
- if (entry->alt_key.length) {
- sizeleft -= entry->alt_key.length; /* check size for alt_key */
- if (sizeleft < 0) {
- retval = KRB5_KDB_TRUNCATED_RECORD;
- goto error_out;
- }
- entry->alt_key.contents = (unsigned char *) malloc(entry->alt_key.length);
- if (!entry->alt_key.contents) {
- retval = ENOMEM;
- goto error_out;
- }
- (void) memcpy((char *)entry->alt_key.contents, nextloc,
- entry->alt_key.length);
- nextloc += entry->alt_key.length; /* advance past alt_key */
- }
-
- /*
- * ...and the alternate key's salt, if present.
- */
- if (entry->alt_salt_length) {
- sizeleft -= entry->alt_salt_length;
- if (sizeleft < 0) {
- retval = KRB5_KDB_TRUNCATED_RECORD;
- goto error_out;
- }
- entry->alt_salt = (krb5_octet *)malloc(entry->alt_salt_length);
- if (!entry->alt_salt) {
- retval = KRB5_KDB_TRUNCATED_RECORD;
- goto error_out;
- }
- (void) memcpy((char *)entry->alt_salt, nextloc,
- entry->alt_salt_length);
- nextloc += entry->alt_salt_length; /* advance past salt */
- }
-
- return 0;
-error_out:
- free_decode_princ_contents(context, entry);
- return retval;
-}
-
-static void
-free_decode_princ_contents(context, entry)
- krb5_context context;
- krb5_db_entry *entry;
-{
- /* erase the key */
- if (entry->key.contents) {
- memset((char *)entry->key.contents, 0, entry->key.length);
- krb5_xfree(entry->key.contents);
- }
- if (entry->salt)
- krb5_xfree(entry->salt);
-
- if (entry->alt_key.contents) {
- memset((char *)entry->alt_key.contents, 0, entry->alt_key.length);
- krb5_xfree(entry->alt_key.contents);
- }
- if (entry->alt_salt)
- krb5_xfree(entry->alt_salt);
-
- if (entry->principal)
- krb5_free_principal(context, entry->principal);
- if (entry->mod_name)
- krb5_free_principal(context, entry->mod_name);
- (void) memset((char *)entry, 0, sizeof(*entry));
- return;
-}
-
krb5_error_code
krb5_dbm_db_lock(context, mode)
krb5_context context;
@@ -1431,7 +1005,7 @@ errout:
free_dbsuffix (fromdir);
if (retval == 0)
- retval = krb5_dbm_db_end_update(context, to, trans);
+ return krb5_dbm_db_end_update(context, to, trans);
if (tmpcontext) {
k5dbm_clear_context((db_context_t *) context->db_context);
@@ -1488,15 +1062,15 @@ krb5_boolean *more; /* are there more? */
*more = FALSE;
/* XXX deal with wildcard lookups */
- if (retval = encode_princ_dbmkey(context, &key, searchfor))
+ if (retval = krb5_encode_princ_dbmkey(context, &key, searchfor))
goto cleanup;
contents = KDBM_FETCH(db_ctx, db, key);
- free_encode_princ_dbmkey(context, &key);
+ krb5_free_princ_dbmkey(context, &key);
if (contents.dptr == NULL)
found = 0;
- else if (retval = decode_princ_contents(context, &contents, entries))
+ else if (retval = krb5_decode_princ_contents(context,&contents,entries))
goto cleanup;
else found = 1;
@@ -1534,7 +1108,7 @@ krb5_dbm_db_free_principal(context, entries, nentries)
{
register int i;
for (i = 0; i < nentries; i++)
- free_decode_princ_contents(context, &entries[i]);
+ krb5_dbe_free_contents(context, &entries[i]);
return;
}
@@ -1587,19 +1161,19 @@ krb5_dbm_db_put_principal(context, entries, nentries)
/* for each one, stuff temps, and do replace/append */
for (i = 0; i < *nentries; i++) {
- if (retval = encode_princ_contents(context, &contents, entries))
+ if (retval = krb5_encode_princ_contents(context, &contents, entries))
break;
- if (retval = encode_princ_dbmkey(context, &key, entries->principal)) {
- free_encode_princ_contents(&contents);
+ if (retval = krb5_encode_princ_dbmkey(context, &key, entries->princ)) {
+ krb5_free_princ_contents(context, &contents);
break;
}
if (KDBM_STORE(db_ctx, db, key, contents, DBM_REPLACE))
retval = errno;
else
retval = 0;
- free_encode_princ_contents(&contents);
- free_encode_princ_dbmkey(context, &key);
+ krb5_free_princ_contents(context, &contents);
+ krb5_free_princ_dbmkey(context, &key);
if (retval)
break;
entries++; /* bump to next struct */
@@ -1619,16 +1193,16 @@ krb5_dbm_db_put_principal(context, entries, nentries)
krb5_error_code
krb5_dbm_db_delete_principal(context, searchfor, nentries)
- krb5_context context;
-krb5_principal searchfor;
-int *nentries; /* how many found & deleted */
+ krb5_context context;
+ krb5_principal searchfor;
+ int * nentries; /* how many found & deleted */
{
- int found = 0;
- datum key, contents, contents2;
- krb5_db_entry entry;
- DBM *db;
- krb5_error_code retval;
- db_context_t *db_ctx;
+ krb5_error_code retval;
+ krb5_db_entry entry;
+ db_context_t * db_ctx;
+ datum key, contents, contents2;
+ DBM * db;
+ int i;
if (!k5dbm_inited(context))
return KRB5_KDB_DBNOTINITED;
@@ -1648,19 +1222,26 @@ int *nentries; /* how many found & deleted */
}
}
- if (retval = encode_princ_dbmkey(context, &key, searchfor))
+ if (retval = krb5_encode_princ_dbmkey(context, &key, searchfor))
goto cleanup;
contents = KDBM_FETCH(db_ctx, db, key);
if (contents.dptr == NULL) {
- found = 0;
retval = KRB5_KDB_NOENTRY;
+ *nentries = 0;
} else {
- if (retval = decode_princ_contents(context, &contents, &entry))
+ memset((char *)&entry, 0, sizeof(entry));
+ if (retval = krb5_decode_princ_contents(context, &contents, &entry))
goto cleankey;
- found = 1;
- memset((char *)entry.key.contents, 0, entry.key.length);
- if (retval = encode_princ_contents(context, &contents2, &entry))
+ *nentries = 1;
+ /* Clear encrypted key contents */
+ for (i = 0; i < entry.n_key_data; i++) {
+ if (entry.key_data[i].key_data_length[0]) {
+ memset((char *)entry.key_data[i].key_data_contents[0], 0,
+ entry.key_data[i].key_data_length[0]);
+ }
+ }
+ if (retval = krb5_encode_princ_contents(context, &contents2, &entry))
goto cleancontents;
if (KDBM_STORE(db_ctx, db, key, contents2, DBM_REPLACE))
@@ -1671,18 +1252,17 @@ int *nentries; /* how many found & deleted */
else
retval = 0;
}
- free_encode_princ_contents(&contents2);
+ krb5_free_princ_contents(context, &contents2);
cleancontents:
- free_decode_princ_contents(context, &entry);
+ krb5_dbe_free_contents(context, &entry);
cleankey:
- free_encode_princ_dbmkey(context, &key);
+ krb5_free_princ_dbmkey(context, &key);
}
cleanup:
if (db_ctx->db_dbm_ctx == 0)
KDBM_CLOSE(db_ctx, db);
(void) krb5_dbm_db_unlock(context); /* unlock write lock */
- *nentries = found;
return retval;
}
@@ -1719,10 +1299,10 @@ krb5_dbm_db_iterate (context, func, func_arg)
for (key = KDBM_FIRSTKEY (db_ctx, db);
key.dptr != NULL; key = KDBM_NEXTKEY(db_ctx, db)) {
contents = KDBM_FETCH (db_ctx, db, key);
- if (retval = decode_princ_contents(context, &contents, &entries))
+ if (retval = krb5_decode_princ_contents(context, &contents, &entries))
break;
retval = (*func)(func_arg, &entries);
- free_decode_princ_contents(context, &entries);
+ krb5_dbe_free_contents(context, &entries);
if (retval)
break;
}
diff --git a/src/lib/kdb/kdb_xdr.c b/src/lib/kdb/kdb_xdr.c
new file mode 100644
index 0000000000..84ad28d48d
--- /dev/null
+++ b/src/lib/kdb/kdb_xdr.c
@@ -0,0 +1,652 @@
+/*
+ * lib/kdb/kdb_xdr.c
+ *
+ * Copyright 1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+#include "k5-int.h"
+#include <stdio.h>
+#include <errno.h>
+
+krb5_error_code
+krb5_dbe_create_key_data(context, entry)
+ krb5_context context;
+ krb5_db_entry * entry;
+{
+ if (entry->n_key_data) {
+ if (entry->key_data = (krb5_key_data *)realloc(entry->key_data,
+ sizeof(krb5_key_data) * entry->n_key_data + 1))
+ memset(entry->key_data + entry->n_key_data,0,sizeof(krb5_key_data));
+ else
+ return ENOMEM;
+ } else {
+ if (entry->key_data = (krb5_key_data *)malloc(sizeof(krb5_key_data)))
+ memset(entry->key_data, 0, sizeof(krb5_key_data));
+ else
+ return ENOMEM;
+ }
+ entry->n_key_data++;
+ return 0;
+}
+
+krb5_dbe_encode_mod_princ_data(context, mod_princ, entry)
+ krb5_context context;
+ krb5_tl_mod_princ * mod_princ;
+ krb5_db_entry * entry;
+{
+ krb5_error_code retval;
+ krb5_tl_data ** tl_data;
+ krb5_octet * nextloc;
+ char * unparse_mod_princ;
+ int unparse_mod_princ_size;
+
+ /*
+ * Allocate *tl_data if necessary otherwise reuse it
+ * Need 04 bytes for date
+ * Need XX bytes for string
+ */
+ if (retval = krb5_unparse_name(context, mod_princ->mod_princ,
+ &unparse_mod_princ))
+ return(retval);
+
+ if ((nextloc = malloc(unparse_mod_princ_size + 4)) == NULL)
+ return ENOMEM;
+
+ /* Find any old versions and delete them. */
+ for (tl_data = &(entry->tl_data); *tl_data;
+ tl_data = &((*tl_data)->tl_data_next)) {
+ if ((*tl_data)->tl_data_type == KRB5_TL_MOD_PRINC) {
+ free((*tl_data)->tl_data_contents);
+ entry->n_tl_data--;
+ break;
+ }
+ }
+
+ unparse_mod_princ_size = strlen(unparse_mod_princ) + 1;
+
+ if ((*tl_data) ||
+ /* Only zero data if it is freshly allocated */
+ ((*tl_data) = (krb5_tl_data *)calloc(1, sizeof(krb5_tl_data)))) {
+ entry->n_tl_data++;
+ (*tl_data)->tl_data_type = KRB5_TL_MOD_PRINC;
+ (*tl_data)->tl_data_length = unparse_mod_princ_size + 4;
+ (*tl_data)->tl_data_contents = nextloc;
+
+ /* Mod Date */
+ *nextloc++ = (krb5_octet)(mod_princ->mod_date & 0xff);
+ *nextloc++ = (krb5_octet)((mod_princ->mod_date >> 8) & 0xff);
+ *nextloc++ = (krb5_octet)((mod_princ->mod_date >> 16) & 0xff);
+ *nextloc++ = (krb5_octet)((mod_princ->mod_date >> 24) & 0xff);
+
+ /* Mod Princ */
+ memcpy(nextloc, unparse_mod_princ, unparse_mod_princ_size);
+ return 0;
+ }
+
+ free(nextloc);
+ return ENOMEM;
+}
+
+krb5_dbe_decode_mod_princ_data(context, entry, mod_princ)
+ krb5_context context;
+ krb5_db_entry * entry;
+ krb5_tl_mod_princ ** mod_princ;
+{
+ krb5_error_code retval;
+ krb5_tl_data * tl_data;
+ krb5_octet * nextloc;
+
+ for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
+ if (tl_data->tl_data_type == KRB5_TL_MOD_PRINC) {
+ if ((*mod_princ = malloc(sizeof(krb5_tl_mod_princ))) == NULL)
+ return ENOMEM;
+
+ nextloc = tl_data->tl_data_contents;
+
+ /* Mod Date */
+ *(((krb5_octet *)(&(*mod_princ)->mod_date))) = *nextloc++;
+ *(((krb5_octet *)(&(*mod_princ)->mod_date)) + 1) = *nextloc++;
+ *(((krb5_octet *)(&(*mod_princ)->mod_date)) + 2) = *nextloc++;
+ *(((krb5_octet *)(&(*mod_princ)->mod_date)) + 3) = *nextloc++;
+
+ /* Mod Princ */
+ if (retval = krb5_parse_name(context, nextloc,
+ &((*mod_princ)->mod_princ)))
+ break;
+ if ((strlen(nextloc) + 1 + 4) != tl_data->tl_data_length) {
+ retval = KRB5_KDB_TRUNCATED_RECORD;
+ break;
+ }
+ }
+ }
+
+ if (retval)
+ free(*mod_princ);
+ return retval;
+}
+
+krb5_encode_princ_dbmkey(context, key, principal)
+ krb5_context context;
+ datum *key;
+ krb5_principal principal;
+{
+ char *princ_name;
+ krb5_error_code retval;
+
+ if (!(retval = krb5_unparse_name(context, principal, &princ_name))) {
+ /* need to store the NULL for decoding */
+ key->dsize = strlen(princ_name)+1;
+ key->dptr = princ_name;
+ }
+ return(retval);
+}
+
+void
+krb5_free_princ_dbmkey(context, key)
+ krb5_context context;
+ datum *key;
+{
+ (void) free(key->dptr);
+ key->dsize = 0;
+ key->dptr = 0;
+ return;
+}
+
+krb5_error_code
+krb5_encode_princ_contents(context, content, entry)
+ krb5_context context;
+ datum * content;
+ krb5_db_entry * entry;
+{
+ int unparse_princ_size, i, j;
+ char * unparse_princ;
+ char * nextloc;
+ krb5_tl_data * tl_data;
+ krb5_error_code retval;
+
+ krb5_db_entry copy_princ;
+
+ /*
+ * Generate one lump of data from the krb5_db_entry.
+ * This data must be independent of byte order of the machine,
+ * compact and extensible.
+ */
+
+ /*
+ * First allocate enough space for all the data.
+ * Need 2 bytes for the length of the base structure
+ * then 40 [9 * 4 + 2 * 2] bytes for the base information
+ * [ mkvno, attributes, max_life, max_renewable_life, expiration,
+ * pw_expiration, last_success, last_failed, fail_auth_count ]
+ * [ n_key_data, n_tl_data ]
+ * then XX bytes [ e_length ] for the extra data [ e_data ]
+ * then XX bytes [ 2 for length + length for string ] for the principal,
+ * then (4 [type + length] + tl_data_length) bytes per tl_data
+ * then (4 + (4 + key_data_length) per key_data_contents) bytes per key_data
+ */
+ content->dsize = entry->len + entry->e_length;
+
+ if (retval = krb5_unparse_name(context, entry->princ, &unparse_princ))
+ return(retval);
+
+ unparse_princ_size = strlen(unparse_princ) + 1;
+ content->dsize += unparse_princ_size;
+ content->dsize += 2;
+
+ i = 0;
+ /* tl_data is a linked list */
+ for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
+ content->dsize += tl_data->tl_data_length;
+ content->dsize += 4; /* type, length */
+ i++;
+ }
+
+ if (i != entry->n_tl_data) {
+ retval = KRB5_KDB_TRUNCATED_RECORD;
+ goto epc_error;
+ }
+
+ /* key_data is an array */
+ for (i = 0; i < entry->n_key_data; i++) {
+ content->dsize += 4; /* Version, KVNO */
+ for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
+ content->dsize += entry->key_data[i].key_data_length[j];
+ content->dsize += 4; /* type + length */
+ }
+ }
+
+ if ((content->dptr = malloc(content->dsize)) == NULL) {
+ retval = ENOMEM;
+ goto epc_error;
+ }
+
+ /*
+ * Now we go through entry again, this time copying data
+ * These first entries are always saved regaurdless of version
+ */
+ nextloc = content->dptr;
+
+ /* Base Length */
+ *nextloc++ = (krb5_octet)(entry->len & 0xff);
+ *nextloc++ = (krb5_octet)((entry->len >> 8) & 0xff);
+
+ /* Master Key Version */
+ *nextloc++ = (krb5_octet)(entry->mkvno & 0xff);
+ *nextloc++ = (krb5_octet)((entry->mkvno >> 8) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->mkvno >> 16) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->mkvno >> 24) & 0xff);
+
+ /* Attributes */
+ *nextloc++ = (krb5_octet)(entry->attributes & 0xff);
+ *nextloc++ = (krb5_octet)((entry->attributes >> 8) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->attributes >> 16) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->attributes >> 24) & 0xff);
+
+ /* Max Life */
+ *nextloc++ = (krb5_octet)(entry->max_life & 0xff);
+ *nextloc++ = (krb5_octet)((entry->max_life >> 8) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->max_life >> 16) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->max_life >> 24) & 0xff);
+
+ /* Max Renewable Life */
+ *nextloc++ = (krb5_octet)(entry->max_renewable_life & 0xff);
+ *nextloc++ = (krb5_octet)((entry->max_renewable_life >> 8) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->max_renewable_life >> 16) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->max_renewable_life >> 24) & 0xff);
+
+ /* When the client expires */
+ *nextloc++ = (krb5_octet)(entry->expiration & 0xff);
+ *nextloc++ = (krb5_octet)((entry->expiration >> 8) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->expiration >> 16) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->expiration >> 24) & 0xff);
+
+ /* When its passwd expires */
+ *nextloc++ = (krb5_octet)(entry->pw_expiration & 0xff);
+ *nextloc++ = (krb5_octet)((entry->pw_expiration >> 8) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->pw_expiration >> 16) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->pw_expiration >> 24) & 0xff);
+
+ /* Last successful passwd */
+ *nextloc++ = (krb5_octet)(entry->last_success & 0xff);
+ *nextloc++ = (krb5_octet)((entry->last_success >> 8) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->last_success >> 16) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->last_success >> 24) & 0xff);
+
+ /* Last failed passwd attempt */
+ *nextloc++ = (krb5_octet)(entry->last_failed & 0xff);
+ *nextloc++ = (krb5_octet)((entry->last_failed >> 8) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->last_failed >> 16) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->last_failed >> 24) & 0xff);
+
+ /* # of failed passwd attempt */
+ *nextloc++ = (krb5_octet)(entry->fail_auth_count & 0xff);
+ *nextloc++ = (krb5_octet)((entry->fail_auth_count >> 8) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->fail_auth_count >> 16) & 0xff);
+ *nextloc++ = (krb5_octet)((entry->fail_auth_count >> 24) & 0xff);
+
+ /* # tl_data strutures */
+ *nextloc++ = (krb5_octet)(entry->n_tl_data & 0xff);
+ *nextloc++ = (krb5_octet)((entry->n_tl_data >> 8) & 0xff);
+
+ /* # key_data strutures */
+ *nextloc++ = (krb5_octet)(entry->n_key_data & 0xff);
+ *nextloc++ = (krb5_octet)((entry->n_key_data >> 8) & 0xff);
+
+ /* Put extended fields here */
+ if (entry->len != KRB5_KDB_V1_BASE_LENGTH)
+ abort();
+
+ /* Any extra data that this version doesn't understand. */
+ if (entry->e_length) {
+ memcpy(nextloc, entry->e_data, entry->e_length);
+ nextloc += entry->e_length;
+ }
+
+ /*
+ * Now we get to the principal.
+ * To squeze a few extra bytes out it is always assumed to come
+ * after the base type.
+ */
+ *nextloc++ = (krb5_octet)(unparse_princ_size & 0xff);
+ *nextloc++ = (krb5_octet)((unparse_princ_size >> 8) & 0xff);
+ (void) memcpy(nextloc, unparse_princ, unparse_princ_size);
+ nextloc += unparse_princ_size;
+
+ /* tl_data is a linked list, of type, legth, contents */
+ for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
+ *nextloc++ = (krb5_octet)(tl_data->tl_data_type & 0xff);
+ *nextloc++ = (krb5_octet)((tl_data->tl_data_type >> 8) & 0xff);
+
+ *nextloc++ = (krb5_octet)(tl_data->tl_data_length & 0xff);
+ *nextloc++ = (krb5_octet)((tl_data->tl_data_length >> 8) & 0xff);
+
+ memcpy(nextloc, tl_data->tl_data_contents, tl_data->tl_data_length);
+ nextloc += tl_data->tl_data_length;
+ }
+
+ /* key_data is an array */
+ for (i = 0; i < entry->n_key_data; i++) {
+ *nextloc++ = (krb5_octet)(entry->key_data[i].key_data_ver & 0xff);
+ *nextloc++ = (krb5_octet)((entry->key_data[i].key_data_ver >> 8)&0xff);
+ *nextloc++ = (krb5_octet)(entry->key_data[i].key_data_kvno & 0xff);
+ *nextloc++ = (krb5_octet)((entry->key_data[i].key_data_kvno >> 8)&0xff);
+
+ for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
+ krb5_int16 type = entry->key_data[i].key_data_type[j];
+ krb5_int16 length = entry->key_data[i].key_data_length[j];
+
+ *nextloc++ = (krb5_octet)(type & 0xff);
+ *nextloc++ = (krb5_octet)((type >> 8) & 0xff);
+
+ *nextloc++ = (krb5_octet)(length & 0xff);
+ *nextloc++ = (krb5_octet)((length >> 8) & 0xff);
+
+ if (length) {
+ memcpy(nextloc, entry->key_data[i].key_data_contents[j],length);
+ nextloc += length;
+ }
+ }
+ }
+
+epc_error:;
+ free(unparse_princ);
+ return retval;
+}
+
+void
+krb5_free_princ_contents(context, contents)
+ krb5_context context;
+ datum *contents;
+{
+ free(contents->dptr);
+ contents->dsize = 0;
+ contents->dptr = 0;
+ return;
+}
+
+krb5_error_code
+krb5_decode_princ_contents(context, content, entry)
+ krb5_context context;
+ datum * content;
+ krb5_db_entry * entry;
+{
+ int sizeleft, i;
+ char * nextloc;
+ krb5_tl_data ** tl_data;
+
+ krb5_principal princ;
+ krb5_error_code retval;
+ int major_version = 0, minor_version = 0;
+
+ /* Zero out entry and NULL pointers */
+ memset(entry, 0, sizeof(krb5_db_entry));
+
+ /*
+ * undo the effects of encode_princ_contents.
+ *
+ * The first part is decoding the base type. If the base type is
+ * bigger than the original base type then the additional fields
+ * need to be filled in. If the base type is larger than any
+ * known base type the additional data goes in e_data.
+ */
+
+ /* First do the easy stuff */
+ nextloc = content->dptr;
+ sizeleft = content->dsize;
+ if ((sizeleft -= KRB5_KDB_V1_BASE_LENGTH) < 0)
+ return KRB5_KDB_TRUNCATED_RECORD;
+
+ /* Base Length */
+ *(((krb5_octet *)(&entry->len))) = *nextloc++;
+ *(((krb5_octet *)(&entry->len)) + 1) = *nextloc++;
+
+ /* Master Key Version */
+ *(((krb5_octet *)(&entry->mkvno))) = *nextloc++;
+ *(((krb5_octet *)(&entry->mkvno)) + 1) = *nextloc++;
+ *(((krb5_octet *)(&entry->mkvno)) + 2) = *nextloc++;
+ *(((krb5_octet *)(&entry->mkvno)) + 3) = *nextloc++;
+
+ /* Attributes */
+ *(((krb5_octet *)(&entry->attributes))) = *nextloc++;
+ *(((krb5_octet *)(&entry->attributes)) + 1) = *nextloc++;
+ *(((krb5_octet *)(&entry->attributes)) + 2) = *nextloc++;
+ *(((krb5_octet *)(&entry->attributes)) + 3) = *nextloc++;
+
+ /* Max Life */
+ *(((krb5_octet *)(&entry->max_life))) = *nextloc++;
+ *(((krb5_octet *)(&entry->max_life)) + 1) = *nextloc++;
+ *(((krb5_octet *)(&entry->max_life)) + 2) = *nextloc++;
+ *(((krb5_octet *)(&entry->max_life)) + 3) = *nextloc++;
+
+ /* Max Renewable Life */
+ *(((krb5_octet *)(&entry->max_renewable_life))) = *nextloc++;
+ *(((krb5_octet *)(&entry->max_renewable_life)) + 1) = *nextloc++;
+ *(((krb5_octet *)(&entry->max_renewable_life)) + 2) = *nextloc++;
+ *(((krb5_octet *)(&entry->max_renewable_life)) + 3) = *nextloc++;
+
+ /* When the client expires */
+ *(((krb5_octet *)(&entry->expiration))) = *nextloc++;
+ *(((krb5_octet *)(&entry->expiration)) + 1) = *nextloc++;
+ *(((krb5_octet *)(&entry->expiration)) + 2) = *nextloc++;
+ *(((krb5_octet *)(&entry->expiration)) + 3) = *nextloc++;
+
+ /* When its passwd expires */
+ *(((krb5_octet *)(&entry->pw_expiration))) = *nextloc++;
+ *(((krb5_octet *)(&entry->pw_expiration)) + 1) = *nextloc++;
+ *(((krb5_octet *)(&entry->pw_expiration)) + 2) = *nextloc++;
+ *(((krb5_octet *)(&entry->pw_expiration)) + 3) = *nextloc++;
+
+ /* Last successful passwd */
+ *(((krb5_octet *)(&entry->last_success))) = *nextloc++;
+ *(((krb5_octet *)(&entry->last_success)) + 1) = *nextloc++;
+ *(((krb5_octet *)(&entry->last_success)) + 2) = *nextloc++;
+ *(((krb5_octet *)(&entry->last_success)) + 3) = *nextloc++;
+
+ /* Last failed passwd attempt */
+ *(((krb5_octet *)(&entry->last_failed))) = *nextloc++;
+ *(((krb5_octet *)(&entry->last_failed)) + 1) = *nextloc++;
+ *(((krb5_octet *)(&entry->last_failed)) + 2) = *nextloc++;
+ *(((krb5_octet *)(&entry->last_failed)) + 3) = *nextloc++;
+
+ /* # of failed passwd attempt */
+ *(((krb5_octet *)(&entry->fail_auth_count))) = *nextloc++;
+ *(((krb5_octet *)(&entry->fail_auth_count)) + 1) = *nextloc++;
+ *(((krb5_octet *)(&entry->fail_auth_count)) + 2) = *nextloc++;
+ *(((krb5_octet *)(&entry->fail_auth_count)) + 3) = *nextloc++;
+
+ /* # tl_data strutures */
+ *(((krb5_octet *)(&entry->n_tl_data))) = *nextloc++;
+ *(((krb5_octet *)(&entry->n_tl_data)) + 1) = *nextloc++;
+
+ if (entry->n_tl_data < 0)
+ return KRB5_KDB_TRUNCATED_RECORD;
+
+ /* # key_data strutures */
+ *(((krb5_octet *)(&entry->n_key_data))) = *nextloc++;
+ *(((krb5_octet *)(&entry->n_key_data)) + 1) = *nextloc++;
+
+ if (entry->n_key_data < 0)
+ return KRB5_KDB_TRUNCATED_RECORD;
+
+ /* Check for extra data */
+ if (entry->len > KRB5_KDB_V1_BASE_LENGTH) {
+ entry->e_length = entry->len - KRB5_KDB_V1_BASE_LENGTH;
+ if (entry->e_data = (krb5_octet *)malloc(entry->e_length)) {
+ memcpy(entry->e_data, nextloc, entry->e_length);
+ nextloc += entry->e_length;
+ } else {
+ return ENOMEM;
+ }
+ }
+
+ /*
+ * Get the principal name for the entry
+ * (stored as a string which gets unparsed.)
+ */
+ if ((sizeleft -= 2) < 0) {
+ retval = KRB5_KDB_TRUNCATED_RECORD;
+ goto error_out;
+ }
+
+ i = 0;
+ *(((krb5_octet *)(&i))) = *nextloc++;
+ *(((krb5_octet *)(&i)) + 1) = *nextloc++;
+
+ if (retval = krb5_parse_name(context, nextloc, &(entry->princ)))
+ goto error_out;
+ if ((i != (strlen(nextloc) + 1)) || (sizeleft < i)) {
+ retval = KRB5_KDB_TRUNCATED_RECORD;
+ goto error_out;
+ }
+ sizeleft -= i;
+ nextloc += i;
+
+ /* tl_data is a linked list */
+ tl_data = &entry->tl_data;
+ for (i = 0; i < entry->n_tl_data; i++) {
+ if ((sizeleft -= 4) < 0) {
+ retval = KRB5_KDB_TRUNCATED_RECORD;
+ goto error_out;
+ }
+ if ((*tl_data = (krb5_tl_data *)
+ malloc(sizeof(krb5_tl_data))) == NULL) {
+ retval = ENOMEM;
+ goto error_out;
+ }
+ (*tl_data)->tl_data_next = NULL;
+ (*tl_data)->tl_data_contents = NULL;
+ *(((krb5_octet *)(&(*tl_data)->tl_data_type))) = *nextloc++;
+ *(((krb5_octet *)(&(*tl_data)->tl_data_type)) + 1) = *nextloc++;
+ *(((krb5_octet *)(&(*tl_data)->tl_data_length))) = *nextloc++;
+ *(((krb5_octet *)(&(*tl_data)->tl_data_length)) + 1) = *nextloc++;
+
+ if ((sizeleft -= (*tl_data)->tl_data_length) < 0) {
+ retval = KRB5_KDB_TRUNCATED_RECORD;
+ goto error_out;
+ }
+ if (((*tl_data)->tl_data_contents = (krb5_octet *)
+ malloc((*tl_data)->tl_data_length)) == NULL) {
+ retval = ENOMEM;
+ goto error_out;
+ }
+ memcpy((*tl_data)->tl_data_contents,nextloc,(*tl_data)->tl_data_length);
+ nextloc += (*tl_data)->tl_data_length;
+ }
+
+ /* key_data is an array */
+ if ((entry->key_data = (krb5_key_data *)
+ malloc(sizeof(krb5_key_data) * entry->n_key_data)) == NULL) {
+ retval = ENOMEM;
+ goto error_out;
+ }
+ for (i = 0; i < entry->n_key_data; i++) {
+ krb5_key_data * key_data;
+ int j;
+
+ if ((sizeleft -= 4) < 0) {
+ retval = KRB5_KDB_TRUNCATED_RECORD;
+ goto error_out;
+ }
+ key_data = entry->key_data + i;
+ *(((krb5_octet *)(&key_data->key_data_ver))) = *nextloc++;
+ *(((krb5_octet *)(&key_data->key_data_ver)) + 1) = *nextloc++;
+ *(((krb5_octet *)(&key_data->key_data_kvno))) = *nextloc++;
+ *(((krb5_octet *)(&key_data->key_data_kvno)) + 1) = *nextloc++;
+
+ /* key_data_ver determins number of elements and how to unparse them. */
+ if (key_data->key_data_ver < KRB5_KDB_V1_KEY_DATA_ARRAY) {
+ for (j = 0; j < key_data->key_data_ver; j++) {
+ if ((sizeleft -= 4) < 0) {
+ retval = KRB5_KDB_TRUNCATED_RECORD;
+ goto error_out;
+ }
+ *(((krb5_octet *)(&key_data->key_data_type[j]))) = *nextloc++;
+ *(((krb5_octet *)(&key_data->key_data_type[j]))+1) = *nextloc++;
+ *(((krb5_octet *)(&key_data->key_data_length[j]))) = *nextloc++;
+ *(((krb5_octet *)(&key_data->key_data_length[j]))+1)=*nextloc++;
+
+ if ((sizeleft -= key_data->key_data_length[j]) < 0) {
+ retval = KRB5_KDB_TRUNCATED_RECORD;
+ goto error_out;
+ }
+ if (key_data->key_data_length[j]) {
+ if ((key_data->key_data_contents[j] = (krb5_octet *)
+ malloc(key_data->key_data_length[j])) == NULL) {
+ retval = ENOMEM;
+ goto error_out;
+ }
+ memcpy(key_data->key_data_contents[j], nextloc,
+ key_data->key_data_length[j]);
+ nextloc += key_data->key_data_length[j];
+ }
+ }
+ } else {
+ /* This isn't right. I'll fix it later */
+ abort();
+ }
+ }
+ return 0;
+
+error_out:;
+ krb5_dbe_free_contents(context, entry);
+ return retval;
+}
+
+void
+krb5_dbe_free_contents(context, entry)
+ krb5_context context;
+ krb5_db_entry * entry;
+{
+ krb5_tl_data * tl_data_next;
+ krb5_tl_data * tl_data;
+ int i, j;
+
+ if (entry->e_data)
+ free(entry->e_data);
+ if (entry->princ)
+ krb5_free_principal(context, entry->princ);
+ for (tl_data = entry->tl_data; tl_data; tl_data = tl_data_next) {
+ tl_data_next = tl_data->tl_data_next;
+ if (tl_data->tl_data_contents)
+ free(tl_data->tl_data_contents);
+ free(tl_data);
+ }
+ if (entry->key_data) {
+ for (i = 0; i < entry->n_key_data; i++) {
+ for (j = 0; j < entry->key_data[i].key_data_ver; j++) {
+ if (entry->key_data[i].key_data_length[j]) {
+ if (entry->key_data[i].key_data_contents[j]) {
+ memset(entry->key_data[i].key_data_contents[j],
+ 0, entry->key_data[i].key_data_length[j]);
+ free (entry->key_data[i].key_data_contents[j]);
+ }
+ }
+ entry->key_data[i].key_data_contents[j] = NULL;
+ entry->key_data[i].key_data_length[j] = 0;
+ entry->key_data[i].key_data_type[j] = 0;
+ }
+ }
+ free(entry->key_data);
+ }
+ memset(entry, 0, sizeof(*entry));
+ return;
+}
+
diff --git a/src/lib/kdb/t_kdb.c b/src/lib/kdb/t_kdb.c
index 1010b65dd3..f067f58dc9 100644
--- a/src/lib/kdb/t_kdb.c
+++ b/src/lib/kdb/t_kdb.c
@@ -137,12 +137,20 @@ static kdb5_dispatch_table dbm_dispatch = {
#ifdef dbm_error
(int (*)()) NULL, /* Get Database Error */
#else /* dbm_error */
+#ifdef HAVE_DBM_ERROR
dbm_error, /* Get Database Error */
+#else
+ (int (*)()) NULL, /* Get Database Error */
+#endif
#endif /* dbm_error */
#ifdef dbm_clearerr
(int (*)()) NULL, /* Clear Database Error */
#else /* dbm_clearerr */
+#ifdef HAVE_DBM_CLEARERR
dbm_clearerr, /* Clear Database Error */
+#else
+ (int (*)()) NULL, /* Clear Database Error */
+#endif
#endif /* dbm_clearerr */
#ifdef dbm_dirfno
(int (*)()) NULL, /* Get Database FD num */
@@ -255,54 +263,56 @@ principal_found(nvalid, pname)
*/
krb5_error_code
add_principal(kcontext, principal, eblock, key, rseed)
- krb5_context kcontext;
- krb5_principal principal;
- krb5_encrypt_block *eblock;
- krb5_keyblock *key;
- krb5_pointer rseed;
+ krb5_context kcontext;
+ krb5_principal principal;
+ krb5_encrypt_block * eblock;
+ krb5_keyblock * key;
+ krb5_pointer rseed;
{
- krb5_error_code kret;
- krb5_db_entry dbent;
- krb5_keyblock *rkey;
- krb5_keyblock *kp;
- int nentries = 1;
+ krb5_error_code kret;
+ krb5_db_entry dbent;
+ krb5_tl_mod_princ mod_princ;
+ krb5_keyblock * rkey = NULL;
+ int nentries = 1;
memset((char *) &dbent, 0, sizeof(dbent));
- rkey = (krb5_keyblock *) NULL;
- dbent.principal = principal;
- dbent.kvno = 1;
- dbent.max_life = KRB5_KDB_MAX_LIFE;
- dbent.max_renewable_life = KRB5_KDB_MAX_RLIFE;
- dbent.mkvno = 1;
- dbent.expiration = KRB5_KDB_EXPIRATION;
- dbent.mod_name = principal;
- dbent.attributes = KRB5_KDB_DEF_FLAGS;
- if (kret = krb5_timeofday(kcontext, &dbent.mod_date))
- return(kret);
+ dbent.len = KRB5_KDB_V1_BASE_LENGTH;
+
+ dbent.mkvno = 1;
+ dbent.attributes = KRB5_KDB_DEF_FLAGS;
+ dbent.max_life = KRB5_KDB_MAX_LIFE;
+ dbent.expiration = KRB5_KDB_EXPIRATION;
+ dbent.max_renewable_life = KRB5_KDB_MAX_RLIFE;
+
+ if (kret = krb5_copy_principal(kcontext, principal, &dbent.princ))
+ goto out;
+
+ mod_princ.mod_princ = principal;
+ if (kret = krb5_timeofday(kcontext, &mod_princ.mod_date))
+ goto out;
+ if (kret = krb5_dbe_encode_mod_princ_data(kcontext, &mod_princ, &dbent))
+ goto out;
if (!key) {
if (kret = krb5_random_key(kcontext, eblock, rseed, &rkey))
- return(kret);
- kp = rkey;
- }
- else
- kp = key;
+ goto out;
+ } else
+ rkey = key;
- if (kret = krb5_kdb_encrypt_key(kcontext, eblock, kp, &dbent.key))
+ if (kret = krb5_dbe_create_key_data(kcontext, &dbent))
+ goto out;
+ if (kret = krb5_dbekd_encrypt_key_data(kcontext, eblock, rkey, NULL, 1,
+ &dbent.key_data[0]))
goto out;
- if (rkey)
+ if (!key)
krb5_free_keyblock(kcontext, rkey);
- dbent.salt_type = KRB5_KDB_SALTTYPE_NORMAL;
- dbent.salt_length = 0;
- dbent.salt = (krb5_octet *) NULL;
kret = krb5_db_put_principal(kcontext, &dbent, &nentries);
- if (!kret && (nentries != 1))
+ if ((!kret) && (nentries != 1))
kret = KRB5KRB_ERR_GENERIC;
out:
- if (dbent.key.contents)
- free(dbent.key.contents);
+ krb5_dbe_free_contents(kcontext, &dbent);
return(kret);
}
@@ -369,32 +379,42 @@ find_principal(kcontext, principal, docompare)
{
krb5_error_code kret;
krb5_db_entry dbent;
+ krb5_tl_mod_princ * mod_princ;
int how_many;
krb5_boolean more;
- how_many = 1;
more = 0;
- if (kret = krb5_db_get_principal(kcontext,
- principal,
- &dbent,
- &how_many,
- &more))
+ how_many = 1;
+ if (kret = krb5_db_get_principal(kcontext, principal, &dbent,
+ &how_many, &more))
+ return(kret);
+ if (how_many == 0)
+ return(KRB5KRB_ERR_GENERIC);
+
+ if (kret = krb5_dbe_decode_mod_princ_data(kcontext, &dbent, &mod_princ)) {
+ krb5_db_free_principal(kcontext, &dbent, how_many);
return(kret);
+ }
+
if (docompare) {
- if ((dbent.kvno != 1) ||
+ if ((dbent.mkvno != 1) ||
(dbent.max_life != KRB5_KDB_MAX_LIFE) ||
(dbent.max_renewable_life != KRB5_KDB_MAX_RLIFE) ||
- (dbent.mkvno != 1) ||
(dbent.expiration != KRB5_KDB_EXPIRATION) ||
(dbent.attributes != KRB5_KDB_DEF_FLAGS) ||
- !krb5_principal_compare(kcontext, principal, dbent.principal) ||
- !krb5_principal_compare(kcontext, principal, dbent.mod_name))
+ !krb5_principal_compare(kcontext, principal, dbent.princ) ||
+ !krb5_principal_compare(kcontext, principal, mod_princ->mod_princ))
kret = KRB5_PRINC_NOMATCH;
- krb5_db_free_principal(kcontext, &dbent, how_many);
}
- if (!kret && how_many)
- krb5_db_free_principal(kcontext, &dbent, how_many);
- return(((how_many == 1) && (more == 0)) ? 0 : KRB5KRB_ERR_GENERIC);
+
+ krb5_db_free_principal(kcontext, &dbent, how_many);
+ krb5_free_principal(kcontext, mod_princ->mod_princ);
+ krb5_xfree(mod_princ);
+ if (!kret)
+ return(((how_many == 1) && (more == 0)) ? 0 : KRB5KRB_ERR_GENERIC);
+ else
+ return(kret);
+
}
/*
diff --git a/src/lib/kdb/verify_mky.c b/src/lib/kdb/verify_mky.c
index 4ef8304e3c..dbac6ff353 100644
--- a/src/lib/kdb/verify_mky.c
+++ b/src/lib/kdb/verify_mky.c
@@ -64,7 +64,9 @@ krb5_db_verify_master_key(context, mprinc, mkey, eblock)
krb5_db_free_principal(context, &master_entry, nprinc);
return(retval);
}
- if (retval = krb5_kdb_decrypt_key(context, eblock, &master_entry.key, &tempkey)) {
+ if (retval = krb5_dbekd_decrypt_key_data(context, eblock,
+ &master_entry.key_data[0],
+ &tempkey, NULL)) {
(void) krb5_finish_key(context, eblock);
krb5_db_free_principal(context, &master_entry, nprinc);
return retval;