summaryrefslogtreecommitdiffstats
path: root/src/lib/kdb
diff options
context:
space:
mode:
authorMarc Horowitz <marc@mit.edu>1996-07-22 20:49:46 +0000
committerMarc Horowitz <marc@mit.edu>1996-07-22 20:49:46 +0000
commitedf8b4d8a6a665c2aa150993cd813ea6c5cf12e1 (patch)
tree6c2974a97b448c040fa4a31708ec5e02f187526c /src/lib/kdb
parent013bb1391582ed9e653ae706e398ddb8d08cfcc9 (diff)
downloadkrb5-edf8b4d8a6a665c2aa150993cd813ea6c5cf12e1.tar.gz
krb5-edf8b4d8a6a665c2aa150993cd813ea6c5cf12e1.tar.xz
krb5-edf8b4d8a6a665c2aa150993cd813ea6c5cf12e1.zip
this commit includes all the changes on the OV_9510_INTEGRATION and
OV_MERGE branches. This includes, but is not limited to, the new openvision admin system, and major changes to gssapi to add functionality, and bring the implementation in line with rfc1964. before committing, the code was built and tested for netbsd and solaris. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@8774 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/kdb')
-rw-r--r--src/lib/kdb/ChangeLog40
-rw-r--r--src/lib/kdb/Makefile.in21
-rw-r--r--src/lib/kdb/configure.in3
-rw-r--r--src/lib/kdb/kdb_cpw.c46
-rw-r--r--src/lib/kdb/kdb_dbm.c138
-rw-r--r--src/lib/kdb/kdb_xdr.c297
6 files changed, 368 insertions, 177 deletions
diff --git a/src/lib/kdb/ChangeLog b/src/lib/kdb/ChangeLog
index fa274c12ae..4e5440cc91 100644
--- a/src/lib/kdb/ChangeLog
+++ b/src/lib/kdb/ChangeLog
@@ -1,3 +1,25 @@
+Fri Jul 12 15:32:26 1996 Marc Horowitz <marc@mit.edu>
+
+ * kdb_cpw.c (add_key_pwd): initialize retval = 0, in case the
+ function is called with ks_tuple_count == 0.
+
+Wed Jul 10 16:22:14 1996 Marc Horowitz <marc@mit.edu>
+
+ * configure.in (USE_KDB5_LIBRARY): removed. the library does not
+ need itself to build, and in fact fails to do so if I try.
+ * Makefile.in (clean-unix): remove the shared/ subdir
+
+Tue Jul 9 17:55:30 1996 Marc Horowitz <marc@mit.edu>
+
+ * configure.in, Makefile.in: added rules and macros to do shared
+ library creation
+
+Mon Jul 8 17:06:00 1996 Barry Jaspan <bjaspan@mit.edu>
+
+ * kdb_dbm.c: Create DB_OPENCLOSE, which opens and closes the
+ databases for each lock. This is slower than the previous method,
+ but unlike the previous method it works.
+
Tue Jun 11 19:27:22 1996 Ezra Peisach <epeisach@kangaroo.mit.edu>
* keytab.c (krb5_ktkdb_close): Free memory allocated by
@@ -12,6 +34,24 @@ Sat May 18 15:07:09 1996 Ezra Peisach (epeisach@paris)
* kdb_dbm.c: Do not provide prototypes for dbm_error or
dbm_clearerr if they are really macros.
+Sun May 12 01:03:07 1996 Marc Horowitz <marc@mit.edu>
+
+ * kdb_xdr.c: reworked all of the krb5_dbe_* tl_data functions.
+ This was necessary so that the admin system could store it's own
+ tl_data, without needing code here. This has the side-effect of
+ eliminating some structures which added no value, therefore
+ changing about a half-dozen files elsewhere in the tree.
+
+ * kdb_cpw.c (add_key_rnd): handle kvno incrementing in the caller,
+ not here.
+ (krb5_dbe_crk): increment the kvno here, not in add_key_rnd
+ (krb5_dbe_ark): increment the kvno here, not in add_key_rnd
+ (add_key_pwd): handle kvno incrementing in the caller, not here.
+ (krb5_dbe_cpw): take an arg to specify the new kvno. if it's
+ <= the old kvno, just increment. Otherwise, pass it to add_key_pwd.
+ This is why all the code in this revision was changed.
+ (krb5_dbe_apw): increment the kvno here, not in add_key_pwd
+
Tue May 7 19:48:57 1996 Ezra Peisach <epeisach@dumpster.rose.brandeis.edu>
* t_kdb.c (do_testing): Compile if using BERK_DB and dbm is not
diff --git a/src/lib/kdb/Makefile.in b/src/lib/kdb/Makefile.in
index 7b1176d890..ba683222a4 100644
--- a/src/lib/kdb/Makefile.in
+++ b/src/lib/kdb/Makefile.in
@@ -3,6 +3,10 @@ KRB5_RUN_ENV = @KRB5_RUN_ENV@
all:: $(OBJS)
+.c.o:
+ $(CC) $(CFLAGS) -c $(srcdir)/$*.c
+@SHARED_RULE@
+
SRCS= \
$(srcdir)/keytab.c \
$(srcdir)/encrypt_key.c \
@@ -27,6 +31,21 @@ OBJS= \
setup_mkey.o \
store_mkey.o
+LIB_SUBDIRS= .
+LIBDONE = DONE
+
+all-unix:: shared
+shared::
+ test -d shared || mkdir shared
+
+clean-unix::
+ $(RM) shared/*
+ -rmdir shared
+
+DONE: $(OBJS)
+ $(RM) DONE
+ echo $(OBJS) > DONE
+
libkdb5.a: $(OBJS)
$(RM) $@
$(ARADD) $@ $(OBJS)
@@ -37,7 +56,7 @@ install:: libkdb5.a
$(RANLIB) $(DESTDIR)$(KRB5_LIBDIR)/libkdb5.a
clean::
- $(RM) libkdb5.a
+ $(RM) libkdb5.a DONE
t_kdb: t_kdb.o $(DEPLIBS)
$(LD) $(LDFLAGS) $(LDARGS) -o t_kdb t_kdb.o $(LIBS)
diff --git a/src/lib/kdb/configure.in b/src/lib/kdb/configure.in
index ec7f93ec1a..e480603e4c 100644
--- a/src/lib/kdb/configure.in
+++ b/src/lib/kdb/configure.in
@@ -8,8 +8,9 @@ AC_HAVE_HEADERS(unistd.h)
AC_CHECK_FUNCS(srand48 srand srandom umask)
KRB5_RUN_FLAGS
V5_USE_SHARED_LIB
-USE_KDB5_LIBRARY
KRB5_LIBRARIES
+V5_SHARED_LIB_OBJS
+V5_MAKE_SHARED_LIB(libkdb5,0.1,.., ./kdb)
LinkFileDir(../libkdb5.a, libkdb5.a, ./kdb)
AppendRule([all:: libkdb5.a])
AppendRule([all-unix:: ../libkdb5.a])
diff --git a/src/lib/kdb/kdb_cpw.c b/src/lib/kdb/kdb_cpw.c
index 0928eba2a1..54316dde09 100644
--- a/src/lib/kdb/kdb_cpw.c
+++ b/src/lib/kdb/kdb_cpw.c
@@ -188,7 +188,7 @@ add_key_rnd(context, master_eblock, ks_tuple, ks_tuple_count, db_entry, kvno)
krb5_finish_key(context, &krbtgt_eblock);
if (retval = krb5_dbekd_encrypt_key_data(context, master_eblock,
- key, NULL, kvno + 1,
+ key, NULL, kvno,
&db_entry->key_data[db_entry->n_key_data-1])) {
krb5_free_keyblock(context, key);
goto add_key_rnd_err;
@@ -233,6 +233,9 @@ krb5_dbe_crk(context, master_eblock, ks_tuple, ks_tuple_count, db_entry)
db_entry->key_data = NULL;
db_entry->n_key_data = 0;
+ /* increment the kvno */
+ kvno++;
+
if (retval = add_key_rnd(context, master_eblock, ks_tuple,
ks_tuple_count, db_entry, kvno)) {
cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data);
@@ -271,15 +274,18 @@ krb5_dbe_ark(context, master_eblock, ks_tuple, ks_tuple_count, db_entry)
db_entry->key_data = NULL;
db_entry->n_key_data = 0;
+ /* increment the kvno */
+ kvno++;
+
if (retval = add_key_rnd(context, master_eblock, ks_tuple,
ks_tuple_count, db_entry, kvno)) {
cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data);
db_entry->n_key_data = key_data_count;
db_entry->key_data = key_data;
} else {
- /* Copy keys with key_data_kvno = kvno */
+ /* Copy keys with key_data_kvno == kvno - 1 ( = old kvno ) */
for (i = 0; i < key_data_count; i++) {
- if (key_data[i].key_data_kvno = kvno) {
+ if (key_data[i].key_data_kvno == (kvno - 1)) {
if (retval = krb5_dbe_create_key_data(context, db_entry)) {
cleanup_key_data(context, db_entry->n_key_data,
db_entry->key_data);
@@ -318,6 +324,8 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd,
krb5_boolean found;
int i, j;
+ retval = 0;
+
for (i = 0; i < ks_tuple_count; i++) {
krb5_enctype new_enctype, old_enctype;
@@ -405,7 +413,7 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd,
if (retval = krb5_dbekd_encrypt_key_data(context, master_eblock, &key,
(const krb5_keysalt *)&key_salt,
- kvno + 1, &db_entry->key_data[db_entry->n_key_data-1])) {
+ kvno, &db_entry->key_data[db_entry->n_key_data-1])) {
krb5_xfree(key.contents);
return(retval);
}
@@ -421,28 +429,36 @@ add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count, passwd,
* As a side effect all old keys are nuked.
*/
krb5_error_code
-krb5_dbe_cpw(context, master_eblock, ks_tuple, ks_tuple_count, passwd, db_entry)
+krb5_dbe_cpw(context, master_eblock, ks_tuple, ks_tuple_count, passwd,
+ new_kvno, db_entry)
krb5_context context;
krb5_encrypt_block * master_eblock;
krb5_key_salt_tuple * ks_tuple;
int ks_tuple_count;
char * passwd;
+ int new_kvno;
krb5_db_entry * db_entry;
{
int key_data_count;
krb5_key_data * key_data;
krb5_error_code retval;
- int kvno;
+ int old_kvno;
/* First save the old keydata */
- kvno = get_key_data_kvno(context, db_entry->n_key_data, db_entry->key_data);
+ old_kvno = get_key_data_kvno(context, db_entry->n_key_data,
+ db_entry->key_data);
key_data_count = db_entry->n_key_data;
key_data = db_entry->key_data;
db_entry->key_data = NULL;
db_entry->n_key_data = 0;
+ /* increment the kvno. if the requested kvno is too small,
+ increment the old kvno */
+ if (new_kvno < old_kvno+1)
+ new_kvno = old_kvno+1;
+
if (retval = add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count,
- passwd, db_entry, kvno)) {
+ passwd, db_entry, new_kvno)) {
cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data);
db_entry->n_key_data = key_data_count;
db_entry->key_data = key_data;
@@ -470,25 +486,29 @@ krb5_dbe_apw(context, master_eblock, ks_tuple, ks_tuple_count, passwd, db_entry)
int key_data_count;
krb5_key_data * key_data;
krb5_error_code retval;
- int kvno;
+ int old_kvno, new_kvno;
int i;
/* First save the old keydata */
- kvno = get_key_data_kvno(context, db_entry->n_key_data, db_entry->key_data);
+ old_kvno = get_key_data_kvno(context, db_entry->n_key_data,
+ db_entry->key_data);
key_data_count = db_entry->n_key_data;
key_data = db_entry->key_data;
db_entry->key_data = NULL;
db_entry->n_key_data = 0;
+ /* increment the kvno */
+ new_kvno = old_kvno+1;
+
if (retval = add_key_pwd(context, master_eblock, ks_tuple, ks_tuple_count,
- passwd, db_entry, kvno)) {
+ passwd, db_entry, new_kvno)) {
cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data);
db_entry->n_key_data = key_data_count;
db_entry->key_data = key_data;
} else {
- /* Copy keys with key_data_kvno = kvno */
+ /* Copy keys with key_data_kvno == old_kvno */
for (i = 0; i < key_data_count; i++) {
- if (key_data[i].key_data_kvno = kvno) {
+ if (key_data[i].key_data_kvno == old_kvno) {
if (retval = krb5_dbe_create_key_data(context, db_entry)) {
cleanup_key_data(context, db_entry->n_key_data,
db_entry->key_data);
diff --git a/src/lib/kdb/kdb_dbm.c b/src/lib/kdb/kdb_dbm.c
index e42e31f9d3..3931389f47 100644
--- a/src/lib/kdb/kdb_dbm.c
+++ b/src/lib/kdb/kdb_dbm.c
@@ -22,6 +22,8 @@
*
*/
+#define DB_OPENCLOSE
+
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -341,9 +343,13 @@ krb5_dbm_db_init(context)
return(retval);
db_ctx = context->db_context;
+#ifdef DB_OPENCLOSE
+ db_ctx->db_dbm_ctx = NULL;
+#else
if (!(db_ctx->db_dbm_ctx = (DBM *)KDBM_OPEN(db_ctx, db_ctx->db_name,
O_RDWR, 0600)))
return errno;
+#endif
if (!(filename = gen_dbsuffix (db_ctx->db_name, KDBM_LOCK_EXT(db_ctx))))
return ENOMEM;
@@ -367,7 +373,9 @@ krb5_dbm_db_init(context)
return 0;
err_out:
+#ifndef DB_OPENCLOSE
KDBM_CLOSE(db_ctx, db_ctx->db_dbm_ctx);
+#endif
db_ctx->db_dbm_ctx = (DBM *) NULL;
k5dbm_clear_context(db_ctx);
return (retval);
@@ -387,6 +395,7 @@ krb5_dbm_db_fini(context)
db_ctx = (krb5_db_context *) context->db_context;
if (k5dbm_inited(context)) {
+#ifndef DB_OPENCLOSE
if (db_ctx->db_dbm_ctx) {
/* dbm_close returns void, but it is possible for there to be an
error in close(). Possible changes to this routine: check errno
@@ -395,6 +404,7 @@ krb5_dbm_db_fini(context)
KDBM_CLOSE(db_ctx, db_ctx->db_dbm_ctx);
db_ctx->db_dbm_ctx = NULL;
}
+#endif
if (close(db_ctx->db_lf_file))
retval = errno;
@@ -471,6 +481,8 @@ krb5_dbm_db_get_mkey(context, db_context, eblock)
*
* Passing a null pointer as "name" will set back to the default.
* If the alternate database doesn't exist, nothing is changed.
+ *
+ * XXX rethink this
*/
krb5_error_code
@@ -621,6 +633,17 @@ krb5_dbm_db_lock(context, mode)
if ((retval = krb5_dbm_db_get_age(context, NULL, &mod_time)))
goto lock_error;
+#ifdef DB_OPENCLOSE
+ if ((db = KDBM_OPEN(db_ctx, db_ctx->db_name,
+ mode == KRB5_LOCKMODE_SHARED ? O_RDONLY : O_RDWR,
+ 0600))) {
+ db_ctx->db_lf_time = mod_time;
+ db_ctx->db_dbm_ctx = db;
+ } else {
+ retval = errno;
+ goto lock_error;
+ }
+#else
if (mod_time != db_ctx->db_lf_time) {
KDBM_CLOSE(db_ctx, db_ctx->db_dbm_ctx);
if ((db = KDBM_OPEN(db_ctx, db_ctx->db_name, O_RDWR, 0600))) {
@@ -631,12 +654,15 @@ krb5_dbm_db_lock(context, mode)
goto lock_error;
}
}
+#endif
db_ctx->db_lock_mode = mode;
db_ctx->db_locks_held++;
return 0;
lock_error:;
+ db_ctx->db_lock_mode = 0;
+ db_ctx->db_locks_held = 0;
(void) krb5_dbm_db_unlock(context);
return retval;
}
@@ -655,6 +681,10 @@ krb5_dbm_db_unlock(context)
if (!db_ctx->db_locks_held) /* lock already unlocked */
return KRB5_KDB_NOTLOCKED;
+#ifdef DB_OPENCLOSE
+ KDBM_CLOSE(db_ctx, db_ctx->db_dbm_ctx);
+#endif
+
if (--(db_ctx->db_locks_held) == 0) {
retval = krb5_lock_file(context, db_ctx->db_lf_file,
KRB5_LOCKMODE_UNLOCK);
@@ -720,9 +750,8 @@ destroy_file_suffix(dbname, suffix)
if (filename == 0)
return ENOMEM;
if ((fd = open(filename, O_RDWR, 0)) < 0) {
- int retval = errno == ENOENT ? 0 : errno;
free(filename);
- return retval;
+ return errno;
}
/* fstat() will probably not fail unless using a remote filesystem
(which is inappropriate for the kerberos database) so this check
@@ -796,26 +825,40 @@ krb5_dbm_db_destroy(context, dbname)
krb5_context context;
char *dbname;
{
- krb5_error_code retval;
+ krb5_error_code retval1, retval2, retval3;
krb5_boolean tmpcontext;
tmpcontext = 0;
if (!context->db_context) {
tmpcontext = 1;
- if ((retval = k5dbm_init_context(context)))
- return(retval);
+ if ((retval1 = k5dbm_init_context(context)))
+ return(retval1);
}
- if (KDBM_DATA_EXT(context->db_context) &&
- (retval = destroy_file_suffix(dbname,
- KDBM_DATA_EXT(context->db_context))))
- return(retval);
- if (KDBM_INDEX_EXT(context->db_context) &&
- (retval = destroy_file_suffix(dbname,
- KDBM_INDEX_EXT(context->db_context))))
- return(retval);
- if ((retval = destroy_file_suffix(dbname,
- KDBM_LOCK_EXT(context->db_context))))
- return(retval);
+ retval1 = retval2 = retval3 = 0;
+ if (KDBM_DATA_EXT(context->db_context))
+ retval1 = destroy_file_suffix(dbname,
+ KDBM_DATA_EXT(context->db_context));
+ if (KDBM_INDEX_EXT(context->db_context))
+ retval2 = destroy_file_suffix(dbname,
+ KDBM_INDEX_EXT(context->db_context));
+ retval3 = destroy_file_suffix(dbname,
+ KDBM_LOCK_EXT(context->db_context));
+ /*
+ * This kludgery is needed because it is possible to link
+ * against BSD DB but use the ndbm interface. The result is
+ * that the dispatch table thinks the file extensions are
+ * .dir and .pag, but the database layer uses .db.
+ */
+ if (retval1 == ENOENT && retval2 == ENOENT &&
+ KDBM_INDEX_EXT(context->db_context) &&
+ strcmp(KDBM_INDEX_EXT(context->db_context), ".dir") == 0 &&
+ KDBM_DATA_EXT(context->db_context) &&
+ strcmp(KDBM_DATA_EXT(context->db_context), ".pag") == 0) {
+ retval1 = retval2 = destroy_file_suffix(dbname, ".db");
+ }
+ if (retval1 || retval2 || retval3)
+ return (retval1 ? retval1 : (retval2 ? retval2 : retval3));
+
if (tmpcontext) {
k5dbm_clear_context((krb5_db_context *) context->db_context);
free(context->db_context);
@@ -841,6 +884,7 @@ krb5_dbm_db_rename(context, from, to)
char *from;
char *to;
{
+ DBM *db;
char *fromdir = 0;
char *todir = 0;
char *frompag = 0;
@@ -853,19 +897,28 @@ krb5_dbm_db_rename(context, from, to)
s_context = context->db_context;
context->db_context = (void *) NULL;
if (!(retval = k5dbm_init_context(context))) {
+ db_ctx = (krb5_db_context *) context->db_context;
+
+ /*
+ * Create the database, failing if it already exists; the
+ * files must exist because krb5_dbm_db_lock, called below,
+ * will fail otherwise.
+ */
+ db = KDBM_OPEN(db_ctx, to, O_RDWR|O_CREAT|O_EXCL, 0600);
+ if (db == NULL) {
+ retval = errno;
+ goto errout;
+ }
+ else
+ KDBM_CLOSE(db_ctx, db);
+
/*
* Set the database to the target, so that other processes sharing
* the target will stop their activity, and notice the new database.
*/
- db_ctx = (krb5_db_context *) context->db_context;
-
retval = krb5_dbm_db_set_name(context, to);
- if (retval) {
- if (retval == ENOENT)
- db_ctx->db_name = strdup(to);
- else
+ if (retval)
goto errout;
- }
db_ctx->db_lf_name = gen_dbsuffix(db_ctx->db_name,
KDBM_LOCK_EXT(db_ctx));
@@ -931,8 +984,39 @@ krb5_dbm_db_rename(context, from, to)
(void) unlink(fromok);
retval = krb5_dbm_db_end_update(context);
} else {
- (void) krb5_dbm_db_end_update(context);
- retval = errno;
+ /*
+ * This kludgery is needed because it is possible to link
+ * against BSD DB but use the ndbm interface. The result is
+ * that the dispatch table thinks the file extensions are
+ * .dir and .pag, but the database layer uses .db.
+ */
+ if (errno == ENOENT &&
+ KDBM_INDEX_EXT(context->db_context) &&
+ strcmp(KDBM_INDEX_EXT(context->db_context), ".dir") == 0 &&
+ KDBM_DATA_EXT(context->db_context) &&
+ strcmp(KDBM_DATA_EXT(context->db_context), ".pag") == 0) {
+ free(fromdir); free(todir); free(frompag); free(topag);
+
+ fromdir = todir = NULL;
+ frompag = gen_dbsuffix (from, ".db");
+ topag = gen_dbsuffix (to, ".db");
+ if (!frompag || !topag) {
+ retval = ENOMEM;
+ goto errout;
+ }
+ if (rename(frompag, topag) == 0) {
+ /* We only need to unlink the source lock file */
+ if (fromok)
+ (void) unlink(fromok);
+ retval = krb5_dbm_db_end_update(context);
+ } else {
+ (void) krb5_dbm_db_end_update(context);
+ retval = errno;
+ }
+ } else {
+ (void) krb5_dbm_db_end_update(context);
+ retval = errno;
+ }
}
@@ -1082,6 +1166,7 @@ krb5_dbm_db_put_principal(context, entries, nentries)
}
if (KDBM_STORE(db_ctx, db_ctx->db_dbm_ctx, key, contents, DBM_REPLACE))
retval = errno;
+#ifndef DB_OPENCLOSE
else {
DBM *db;
@@ -1093,6 +1178,7 @@ krb5_dbm_db_put_principal(context, entries, nentries)
else
retval = errno;
}
+#endif
krb5_free_princ_contents(context, &contents);
krb5_free_princ_dbmkey(context, &key);
if (retval)
@@ -1166,6 +1252,7 @@ krb5_dbm_db_delete_principal(context, searchfor, nentries)
else {
if (KDBM_DELETE(db_ctx, db, key))
retval = errno;
+#ifndef DB_OPENCLOSE
else {
DBM *db;
@@ -1177,6 +1264,7 @@ krb5_dbm_db_delete_principal(context, searchfor, nentries)
else
retval = errno;
}
+#endif
}
krb5_free_princ_contents(context, &contents2);
cleancontents:
diff --git a/src/lib/kdb/kdb_xdr.c b/src/lib/kdb/kdb_xdr.c
index 5953d6dd25..044ce4c7fe 100644
--- a/src/lib/kdb/kdb_xdr.c
+++ b/src/lib/kdb/kdb_xdr.c
@@ -23,200 +23,223 @@
*/
#include "k5-int.h"
+#include <string.h>
#include <stdio.h>
#include <errno.h>
+#define safe_realloc(p,n) ((p)?(realloc(p,n)):(malloc(n)))
+
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;
- }
+ if ((entry->key_data =
+ (krb5_key_data *) safe_realloc(entry->key_data,
+ (sizeof(krb5_key_data)*
+ (entry->n_key_data + 1)))) == NULL)
+ return(ENOMEM);
+
+
+ memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data));
entry->n_key_data++;
+
return 0;
}
krb5_error_code
-krb5_dbe_encode_last_pwd_change(context, stamp, entry)
+krb5_dbe_update_tl_data(context, entry, new_tl_data)
krb5_context context;
- krb5_tl_last_change * stamp;
krb5_db_entry * entry;
+ krb5_tl_data * new_tl_data;
{
- krb5_tl_data ** tl_data;
- krb5_octet * nextloc;
-
- /* 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_LAST_PWD_CHANGE) {
- break;
- }
- }
+ krb5_tl_data * tl_data;
+ krb5_octet * tmp;
+
+ /* copy the new data first, so we can fail cleanly if malloc()
+ fails */
- if ((*tl_data) ||
- /* Only zero data if it is freshly allocated */
- ((*tl_data) = (krb5_tl_data *)calloc(1, sizeof(krb5_tl_data)))) {
- if (!(*tl_data)->tl_data_type) {
- if ((nextloc = (*tl_data)->tl_data_contents =
- (krb5_octet *)malloc(sizeof(krb5_timestamp))) == NULL) {
- krb5_xfree(*tl_data);
- (*tl_data) = NULL;
- return ENOMEM;
- }
- (*tl_data)->tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
- (*tl_data)->tl_data_length = sizeof(krb5_timestamp);
- entry->n_tl_data++;
- }
-
- *nextloc++ = (krb5_octet)(stamp->last_pwd_change & 0xff);
- *nextloc++ = (krb5_octet)((stamp->last_pwd_change >> 8) & 0xff);
- *nextloc++ = (krb5_octet)((stamp->last_pwd_change >> 16) & 0xff);
- *nextloc++ = (krb5_octet)((stamp->last_pwd_change >> 24) & 0xff);
-
- return 0;
+ if ((tmp = (krb5_octet *) malloc(new_tl_data->tl_data_length)) == NULL)
+ return(ENOMEM);
+
+ /* Find an existing entry of the specified type and point at
+ it, or NULL if not found */
+
+ for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next)
+ if (tl_data->tl_data_type == new_tl_data->tl_data_type)
+ break;
+
+ /* if necessary, chain a new record in the beginning and point at it */
+
+ if (!tl_data) {
+ if ((tl_data = (krb5_tl_data *) calloc(1, sizeof(krb5_tl_data)))
+ == NULL) {
+ free(tmp);
+ return(ENOMEM);
+ }
+ tl_data->tl_data_next = entry->tl_data;
+ entry->tl_data = tl_data;
+ entry->n_tl_data++;
}
- return ENOMEM;
+
+ /* fill in the record */
+
+ if (tl_data->tl_data_contents)
+ free(tl_data->tl_data_contents);
+
+ tl_data->tl_data_type = new_tl_data->tl_data_type;
+ tl_data->tl_data_length = new_tl_data->tl_data_length;
+ tl_data->tl_data_contents = tmp;
+ memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length);
+
+ return(0);
}
krb5_error_code
-krb5_dbe_decode_last_pwd_change(context, entry, stamp)
+krb5_dbe_lookup_tl_data(context, entry, ret_tl_data)
krb5_context context;
krb5_db_entry * entry;
- krb5_tl_last_change * stamp;
+ krb5_tl_data * ret_tl_data;
{
- krb5_tl_data * tl_data;
+ krb5_tl_data *tl_data;
for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
- if (tl_data->tl_data_type == KRB5_TL_LAST_PWD_CHANGE) {
- krb5_octet * nextloc = tl_data->tl_data_contents;
-
- stamp->last_pwd_change = *nextloc++;
- stamp->last_pwd_change += (*nextloc++ << 8);
- stamp->last_pwd_change += (*nextloc++ << 16);
- stamp->last_pwd_change += (*nextloc++ << 24);
- return 0;
- }
+ if (tl_data->tl_data_type == ret_tl_data->tl_data_type) {
+ *ret_tl_data = *tl_data;
+ return(0);
+ }
}
- stamp->last_pwd_change = 0;
- return 0;
+
+ /* if the requested record isn't found, return zero bytes.
+ if it ever means something to have a zero-length tl_data,
+ this code and its callers will have to be changed */
+
+ ret_tl_data->tl_data_length = 0;
+ ret_tl_data->tl_data_contents = NULL;
+ return(0);
+}
+
+krb5_error_code
+krb5_dbe_update_last_pwd_change(context, entry, stamp)
+ krb5_context context;
+ krb5_db_entry * entry;
+ krb5_timestamp stamp;
+{
+ krb5_tl_data tl_data;
+ krb5_octet buf[4]; /* this is the encoded size of an int32 */
+
+ tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
+ tl_data.tl_data_length = sizeof(buf);
+ krb5_kdb_encode_int32((krb5_int32) stamp, buf);
+ tl_data.tl_data_contents = buf;
+
+ return(krb5_dbe_update_tl_data(context, entry, &tl_data));
}
krb5_error_code
-krb5_dbe_encode_mod_princ_data(context, mod_princ, entry)
+krb5_dbe_lookup_last_pwd_change(context, entry, stamp)
+ krb5_context context;
+ krb5_db_entry * entry;
+ krb5_timestamp * stamp;
+{
+ krb5_tl_data tl_data;
+ krb5_error_code code;
+ krb5_int32 tmp;
+
+ tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
+
+ if (code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))
+ return(code);
+
+ if (tl_data.tl_data_length != 4) {
+ *stamp = 0;
+ return(0);
+ }
+
+ krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp);
+
+ *stamp = (krb5_timestamp) tmp;
+
+ return(0);
+}
+
+/* it seems odd that there's no function to remove a tl_data, but if
+ I need one, I'll add one */
+
+krb5_error_code
+krb5_dbe_update_mod_princ_data(context, entry, mod_date, mod_princ)
krb5_context context;
- krb5_tl_mod_princ * mod_princ;
krb5_db_entry * entry;
+ krb5_timestamp mod_date;
+ krb5_principal mod_princ;
{
+ krb5_tl_data tl_data;
+
krb5_error_code retval = 0;
- krb5_tl_data ** tl_data;
krb5_octet * nextloc = 0;
char * unparse_mod_princ = 0;
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)))
+ if ((retval = krb5_unparse_name(context, mod_princ,
+ &unparse_mod_princ)))
return(retval);
unparse_mod_princ_size = (int) strlen(unparse_mod_princ) + 1;
- if ((nextloc = malloc(unparse_mod_princ_size + 4)) == NULL) {
- retval = ENOMEM;
- goto cleanup;
- }
-
- /* 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;
- }
+ if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4))
+ == NULL) {
+ free(unparse_mod_princ);
+ return(ENOMEM);
}
- /* Allocate a new TL_MOD_PRINC structure if necessary */
- if (*tl_data == 0) {
- (*tl_data) = (krb5_tl_data *)calloc(1, sizeof(krb5_tl_data));
- if (*tl_data == 0) {
- retval = ENOMEM;
- goto cleanup;
- }
- }
-
- 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;
+ 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 */
- krb5_kdb_encode_int32(mod_princ->mod_date, nextloc);
- nextloc += 4;
+ krb5_kdb_encode_int32(mod_date, nextloc);
/* Mod Princ */
- memcpy(nextloc, unparse_mod_princ, unparse_mod_princ_size);
- nextloc = 0;
+ memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size);
-cleanup:
- if (nextloc)
- free(nextloc);
- if (unparse_mod_princ)
- free(unparse_mod_princ);
- return retval;
+ retval = krb5_dbe_update_tl_data(context, entry, &tl_data);
+
+ free(unparse_mod_princ);
+ free(nextloc);
+
+ return(retval);
}
krb5_error_code
-krb5_dbe_decode_mod_princ_data(context, entry, mod_princ)
+krb5_dbe_lookup_mod_princ_data(context, entry, mod_time, mod_princ)
krb5_context context;
krb5_db_entry * entry;
- krb5_tl_mod_princ ** mod_princ;
+ krb5_timestamp * mod_time;
+ krb5_principal * mod_princ;
{
- krb5_error_code retval;
- krb5_tl_data * tl_data;
- krb5_octet * nextloc;
+ krb5_tl_data tl_data;
+ krb5_error_code code;
+ krb5_int32 tmp;
- retval = 0;
- 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_kdb_decode_int32(nextloc, (*mod_princ)->mod_date);
- nextloc += 4;
-
- /* Mod Princ */
- if ((retval = krb5_parse_name(context, (const char *) nextloc,
- &((*mod_princ)->mod_princ))))
- break;
- if ((strlen((char *) nextloc) + 1 + 4) !=
- (size_t) tl_data->tl_data_length) {
- retval = KRB5_KDB_TRUNCATED_RECORD;
- break;
- }
- }
- }
+ tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
- if (retval && (*mod_princ))
- free(*mod_princ);
- return retval;
+ if (code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))
+ return(code);
+
+ if ((tl_data.tl_data_length < 5) ||
+ (tl_data.tl_data_contents[tl_data.tl_data_length-1] != '\0'))
+ return(KRB5_KDB_TRUNCATED_RECORD);
+
+ /* Mod Date */
+ krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time);
+
+ /* Mod Princ */
+ if ((code = krb5_parse_name(context,
+ (const char *) (tl_data.tl_data_contents+4),
+ mod_princ)))
+ return(code);
+
+ return(0);
}
krb5_error_code