libkadm5 should allow persistent locks
authorTom Yu <tlyu@mit.edu>
Tue, 8 Oct 2002 20:20:29 +0000 (20:20 +0000)
committerTom Yu <tlyu@mit.edu>
Tue, 8 Oct 2002 20:20:29 +0000 (20:20 +0000)
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

14 files changed:
src/kadmin/cli/ChangeLog
src/kadmin/cli/kadmin.c
src/kadmin/cli/kadmin.h
src/kadmin/cli/kadmin_ct.ct
src/lib/kadm5/ChangeLog
src/lib/kadm5/adb.h
src/lib/kadm5/admin.h
src/lib/kadm5/clnt/ChangeLog
src/lib/kadm5/clnt/Makefile.in
src/lib/kadm5/clnt/client_init.c
src/lib/kadm5/srv/ChangeLog
src/lib/kadm5/srv/Makefile.in
src/lib/kadm5/srv/adb_openclose.c
src/lib/kadm5/srv/server_init.c

index 322b5159a1c71cae1acb60d32fa5a10522769329..3b468f1631f0250591b80b95a61dc6fb93c02a24 100644 (file)
@@ -1,3 +1,13 @@
+2002-10-08  Tom Yu  <tlyu@mit.edu>
+
+       * 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  <raeburn@mit.edu>
 
        * Makefile.in: Revert $(S)=>/ change, for Windows support.
index b3308797a7edbb476b84708c0625b65247183f01..72dc594b86a27c285c8b056a604b19cde5e944fc 100644 (file)
@@ -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[];
index 4255e0c7ec479fce8f0b522a61d395894ee602ea..4e6e8185f240dc36c28899be9d720fe0c0e63bf3 100644 (file)
@@ -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[]);
index 9ecef0da701bd203c9841f50627296d8e27c93d1..05a4efb840c7fb6a772b4e7868d79b9f62f1c01b 100644 (file)
@@ -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, "?";
index bed518889c6dd9fcbc5e7ab144aaba6b7ed2067a..6a91bf428c845acfd90f3589db38604d6540136f 100644 (file)
@@ -1,3 +1,10 @@
+2002-10-08  Tom Yu  <tlyu@mit.edu>
+
+       * 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  <raeburn@mit.edu>
 
        * admin.h (struct __krb5_realm_params): New field
index 0277aba0751ffc00e9e92e0239da166e27b12f92..7b49adc509cab018293dd075e992902f53fc8ff9 100644 (file)
@@ -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 */
index 9c366ff72ef990a5638768a5ef46b660ccf0e59a..c2236ae51e9e2551e38de313d7a62a3fcb3a1120 100644 (file)
@@ -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,
index ebee3a1b411ce65bc710574de564d75c0a07332d..7d393c0b365046abc4b5f8e2a9136a399012b3df 100644 (file)
@@ -1,3 +1,10 @@
+2002-10-08  Tom Yu  <tlyu@mit.edu>
+
+       * 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  <raeburn@mit.edu>
 
        * client_init.c (_kadm5_init_any): If creating a new ccache, put
index 2908f5cd9bd37ff303352b19f69dbdc397914abd..3e4fb8cf2f1675b117eb10a0123fdcb15eaeaffd 100644 (file)
@@ -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) \
index 4e0b53fd9828b9853c0bcbb813310feabb722618..247af875c0ce04fbc3b2866f2eb600e5f880d8e7 100644 (file)
@@ -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)
 {
index f575d90058342aea957d632b75d2477b6d85ac24..e7e569e8207c10c83856f9558978f0ae3d886aad 100644 (file)
@@ -1,3 +1,14 @@
+2002-10-08  Tom Yu  <tlyu@mit.edu>
+
+       * 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  <raeburn@mit.edu>
 
        * Makefile.in: Revert $(S)=>/ change, for Windows support.
index 5dc71e469c1f2b24f152c4efbd8e46033c54810b..11fc1b631a929d006cb4ca9f8566c13b2ecf4497 100644 (file)
@@ -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) \
index 12219cdabe08a728e5bbf278e2280a4dd323d995..7bb671e9c057a71fc62c85662b1ce7814075f1f1 100644 (file)
@@ -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));
 }
-
index 31dd71ad827fb7f5acfdd1c69198aef91df21080..f2cbc991fb3153eaaf334cecda8a07f99603ed7e 100644 (file)
@@ -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;