From 794f0d854711dbee20ca8cfb3ec2ae729c41910c Mon Sep 17 00:00:00 2001 From: Tom Yu Date: Tue, 8 Oct 2002 20:20:29 +0000 Subject: [PATCH] libkadm5 should allow persistent locks libkadm5 should have a way to persistently lock the databases to avoid wasting time on closing and reopening. These patches implement persistent exclusive locks for local access only. ticket: new target_version: 1.3 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14914 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kadmin/cli/ChangeLog | 10 +++++++ src/kadmin/cli/kadmin.c | 45 +++++++++++++++++++++++++++++++ src/kadmin/cli/kadmin.h | 2 ++ src/kadmin/cli/kadmin_ct.ct | 6 +++++ src/lib/kadm5/ChangeLog | 7 +++++ src/lib/kadm5/adb.h | 1 + src/lib/kadm5/admin.h | 2 ++ src/lib/kadm5/clnt/ChangeLog | 7 +++++ src/lib/kadm5/clnt/Makefile.in | 2 +- src/lib/kadm5/clnt/client_init.c | 11 ++++++++ src/lib/kadm5/srv/ChangeLog | 11 ++++++++ src/lib/kadm5/srv/Makefile.in | 2 +- src/lib/kadm5/srv/adb_openclose.c | 17 ++++++++---- src/lib/kadm5/srv/server_init.c | 28 +++++++++++++++++++ 14 files changed, 144 insertions(+), 7 deletions(-) diff --git a/src/kadmin/cli/ChangeLog b/src/kadmin/cli/ChangeLog index 322b5159a..3b468f163 100644 --- a/src/kadmin/cli/ChangeLog +++ b/src/kadmin/cli/ChangeLog @@ -1,3 +1,13 @@ +2002-10-08 Tom Yu + + * kadmin.c (quit): Release exclusive lock, if acquired. + (kadmin_lock, kadmin_unlock): New functions to call kadm5_lock and + kadm5_unlock. + + * kadmin.h: Add kadmin_lock and kadmin_unlock. + + * kadmin_ct.ct: Add lock and unlock commands. + 2002-08-29 Ken Raeburn * Makefile.in: Revert $(S)=>/ change, for Windows support. diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c index b3308797a..72dc594b8 100644 --- a/src/kadmin/cli/kadmin.c +++ b/src/kadmin/cli/kadmin.c @@ -93,6 +93,8 @@ void *handle = NULL; krb5_context context; char *ccache_name = NULL; +int locked = 0; + static void usage() { fprintf(stderr, @@ -465,6 +467,17 @@ char *kadmin_startup(argc, argv) int quit() { + kadm5_ret_t retval; + + if (locked) { + retval = kadm5_unlock(handle); + if (retval) { + com_err("quit", retval, "while unlocking locked database"); + return 1; + } + locked = 0; + } + kadm5_destroy(handle); if (ccache_name != NULL) { fprintf(stderr, @@ -477,6 +490,38 @@ int quit() return 0; } +void kadmin_lock(argc, argv) + int argc; + char *argv[]; +{ + kadm5_ret_t retval; + + if (locked) + return; + retval = kadm5_lock(handle); + if (retval) { + com_err("lock", retval, ""); + return; + } + locked = 1; +} + +void kadmin_unlock(argc, argv) + int argc; + char *argv[]; +{ + kadm5_ret_t retval; + + if (!locked) + return; + retval = kadm5_lock(handle); + if (retval) { + com_err("unlock", retval, ""); + return; + } + locked = 0; +} + void kadmin_delprinc(argc, argv) int argc; char *argv[]; diff --git a/src/kadmin/cli/kadmin.h b/src/kadmin/cli/kadmin.h index 4255e0c7e..4e6e8185f 100644 --- a/src/kadmin/cli/kadmin.h +++ b/src/kadmin/cli/kadmin.h @@ -33,6 +33,8 @@ /* It would be nice if ss produced a header file we could reference */ extern char *kadmin_startup(int argc, char *argv[]); extern int quit (void); +extern void kadmin_lock(int argc, char *argv[]); +extern void kadmin_unlock(int argc, char *argv[]); extern void kadmin_delprinc(int argc, char *argv[]); extern void kadmin_cpw(int argc, char *argv[]); extern void kadmin_addprinc(int argc, char *argv[]); diff --git a/src/kadmin/cli/kadmin_ct.ct b/src/kadmin/cli/kadmin_ct.ct index 9ecef0da7..05a4efb84 100644 --- a/src/kadmin/cli/kadmin_ct.ct +++ b/src/kadmin/cli/kadmin_ct.ct @@ -68,6 +68,12 @@ request kadmin_keytab_add, "Add entry(s) to a keytab", request kadmin_keytab_remove, "Remove entry(s) from a keytab", ktremove, ktrem; +request kadmin_lock, "Lock database exclusively (use with extreme caution!)", + lock; + +request kadmin_unlock, "Release exclusive database lock", + unlock; + # list_requests is generic -- unrelated to Kerberos request ss_list_requests, "List available requests.", list_requests, lr, "?"; diff --git a/src/lib/kadm5/ChangeLog b/src/lib/kadm5/ChangeLog index bed518889..6a91bf428 100644 --- a/src/lib/kadm5/ChangeLog +++ b/src/lib/kadm5/ChangeLog @@ -1,3 +1,10 @@ +2002-10-08 Tom Yu + + * adb.h (struct _osa_adb_db_ent_t): Add opencnt, which keeps track + of how many times an open was attempted on the adb. + + * admin.h: Add kadm5_lock and kadm5_unlock. + 2002-09-18 Ken Raeburn * admin.h (struct __krb5_realm_params): New field diff --git a/src/lib/kadm5/adb.h b/src/lib/kadm5/adb.h index 0277aba07..7b49adc50 100644 --- a/src/lib/kadm5/adb.h +++ b/src/lib/kadm5/adb.h @@ -47,6 +47,7 @@ typedef struct _osa_adb_db_ent_t { BTREEINFO btinfo; char *filename; osa_adb_lock_t lock; + int opencnt; } osa_adb_db_ent, *osa_adb_db_t, *osa_adb_princ_t, *osa_adb_policy_t; /* an osa_pw_hist_ent stores all the key_datas for a single password */ diff --git a/src/lib/kadm5/admin.h b/src/lib/kadm5/admin.h index 9c366ff72..c2236ae51 100644 --- a/src/lib/kadm5/admin.h +++ b/src/lib/kadm5/admin.h @@ -330,6 +330,8 @@ kadm5_ret_t kadm5_init_with_creds(char *client_name, krb5_ui_4 api_version, void **server_handle); #endif +kadm5_ret_t kadm5_lock(void *server_handle); +kadm5_ret_t kadm5_unlock(void *server_handle); kadm5_ret_t kadm5_flush(void *server_handle); kadm5_ret_t kadm5_destroy(void *server_handle); kadm5_ret_t kadm5_create_principal(void *server_handle, diff --git a/src/lib/kadm5/clnt/ChangeLog b/src/lib/kadm5/clnt/ChangeLog index ebee3a1b4..7d393c0b3 100644 --- a/src/lib/kadm5/clnt/ChangeLog +++ b/src/lib/kadm5/clnt/ChangeLog @@ -1,3 +1,10 @@ +2002-10-08 Tom Yu + + * Makefile.in (LIBMINOR): Bump. + + * client_init.c (kadm5_lock, kadm5_unlock): Add stubs that error + out, since these are not supported on the client side. + 2002-09-18 Ken Raeburn * client_init.c (_kadm5_init_any): If creating a new ccache, put diff --git a/src/lib/kadm5/clnt/Makefile.in b/src/lib/kadm5/clnt/Makefile.in index 2908f5cd9..3e4fb8cf2 100644 --- a/src/lib/kadm5/clnt/Makefile.in +++ b/src/lib/kadm5/clnt/Makefile.in @@ -6,7 +6,7 @@ LOCALINCLUDES = -I$(BUILDTOP)/include/kadm5 LIB=kadm5clnt LIBMAJOR=5 -LIBMINOR=0 +LIBMINOR=1 STOBJLISTS=../OBJS.ST OBJS.ST SHLIB_EXPDEPS=\ $(TOPLIBD)/libgssrpc$(SHLIBEXT) \ diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c index 4e0b53fd9..247af875c 100644 --- a/src/lib/kadm5/clnt/client_init.c +++ b/src/lib/kadm5/clnt/client_init.c @@ -605,6 +605,17 @@ kadm5_destroy(void *server_handle) return code; } +/* not supported on client */ +kadm5_ret_t kadm5_lock(void *server_handle) +{ + return EINVAL; +} + +/* not supported on client */ +kadm5_ret_t kadm5_unlock(void *server_handle) +{ + return EINVAL; +} kadm5_ret_t kadm5_flush(void *server_handle) { diff --git a/src/lib/kadm5/srv/ChangeLog b/src/lib/kadm5/srv/ChangeLog index f575d9005..e7e569e82 100644 --- a/src/lib/kadm5/srv/ChangeLog +++ b/src/lib/kadm5/srv/ChangeLog @@ -1,3 +1,14 @@ +2002-10-08 Tom Yu + + * adb_openclose.c (osa_adb_init_db): Reset opencnt. + (osa_adb_open_and_lock): Don't open multiple times; merely + increment opencnt if already open. + (osa_adb_close_and_unlock): Decrement opencnt instead of + unconditionaly closing. + + * server_init.c (kadm5_lock, kadm5_unlock): New functions to + support persistent exclusive locks across multiple API calls. + 2002-08-29 Ken Raeburn * Makefile.in: Revert $(S)=>/ change, for Windows support. diff --git a/src/lib/kadm5/srv/Makefile.in b/src/lib/kadm5/srv/Makefile.in index 5dc71e469..11fc1b631 100644 --- a/src/lib/kadm5/srv/Makefile.in +++ b/src/lib/kadm5/srv/Makefile.in @@ -10,7 +10,7 @@ DEFINES = @HESIOD_DEFS@ LIB=kadm5srv LIBMAJOR=5 -LIBMINOR=0 +LIBMINOR=1 STOBJLISTS=../OBJS.ST OBJS.ST SHLIB_EXPDEPS=\ $(TOPLIBD)/libgssrpc$(SHLIBEXT) \ diff --git a/src/lib/kadm5/srv/adb_openclose.c b/src/lib/kadm5/srv/adb_openclose.c index 12219cdab..7bb671e9c 100644 --- a/src/lib/kadm5/srv/adb_openclose.c +++ b/src/lib/kadm5/srv/adb_openclose.c @@ -214,6 +214,7 @@ osa_adb_ret_t osa_adb_init_db(osa_adb_db_t *dbp, char *filename, db->lock = &lockp->lockinfo; db->lock->refcnt++; + db->opencnt = 0; db->filename = strdup(filename); db->magic = magic; @@ -369,10 +370,12 @@ osa_adb_ret_t osa_adb_open_and_lock(osa_adb_princ_t db, int locktype) ret = osa_adb_get_lock(db, locktype); if (ret != OSA_ADB_OK) return ret; - + if (db->opencnt) + goto open_ok; + db->db = dbopen(db->filename, O_RDWR, 0600, DB_BTREE, &db->btinfo); if (db->db != NULL) - return OSA_ADB_OK; + goto open_ok; switch (errno) { #ifdef EFTYPE case EFTYPE: @@ -380,18 +383,23 @@ osa_adb_ret_t osa_adb_open_and_lock(osa_adb_princ_t db, int locktype) case EINVAL: db->db = dbopen(db->filename, O_RDWR, 0600, DB_HASH, &db->info); if (db->db != NULL) - return OSA_ADB_OK; + goto open_ok; default: (void) osa_adb_release_lock(db); if (errno == EINVAL) return OSA_ADB_BAD_DB; return errno; } +open_ok: + db->opencnt++; + return OSA_ADB_OK; } osa_adb_ret_t osa_adb_close_and_unlock(osa_adb_princ_t db) { - if(db->db->close(db->db) == -1) { + if (--db->opencnt) + return osa_adb_release_lock(db); + if(db->db != NULL && db->db->close(db->db) == -1) { (void) osa_adb_release_lock(db); return OSA_ADB_FAILURE; } @@ -400,4 +408,3 @@ osa_adb_ret_t osa_adb_close_and_unlock(osa_adb_princ_t db) return(osa_adb_release_lock(db)); } - diff --git a/src/lib/kadm5/srv/server_init.c b/src/lib/kadm5/srv/server_init.c index 31dd71ad8..f2cbc991f 100644 --- a/src/lib/kadm5/srv/server_init.c +++ b/src/lib/kadm5/srv/server_init.c @@ -306,6 +306,34 @@ kadm5_ret_t kadm5_destroy(void *server_handle) return KADM5_OK; } +kadm5_ret_t kadm5_lock(void *server_handle) +{ + kadm5_server_handle_t handle = server_handle; + kadm5_ret_t ret; + + CHECK_HANDLE(server_handle); + ret = osa_adb_open_and_lock(handle->policy_db, OSA_ADB_EXCLUSIVE); + if (ret) + return ret; + ret = krb5_db_lock(handle->context, KRB5_LOCKMODE_EXCLUSIVE); + if (ret) + return ret; +} + +kadm5_ret_t kadm5_unlock(void *server_handle) +{ + kadm5_server_handle_t handle = server_handle; + kadm5_ret_t ret; + + CHECK_HANDLE(server_handle); + ret = osa_adb_close_and_unlock(handle->policy_db); + if (ret) + return ret; + ret = krb5_db_unlock(handle->context); + if (ret) + return ret; +} + kadm5_ret_t kadm5_flush(void *server_handle) { kadm5_server_handle_t handle = server_handle; -- 2.26.2