]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Reload rxkad.keytab on CellServDB modification
authorAndrew Deason <adeason@sinenomine.net>
Wed, 10 Jul 2013 17:52:28 +0000 (12:52 -0500)
committerSimon Wilkinson <sxw@your-file-system.com>
Wed, 17 Jul 2013 12:14:16 +0000 (13:14 +0100)
Make the reloading of rxkad.keytab keys occur in the same way that
KeyFile keys are reloaded. That is, we only try to reload them if the
CellServDB mtime has changed. This is intended to have exactly the
same reloading behavior as KeyFile reloads.

I would have triggered this from afsconf_Check, but that approach
has annoyances. (Calling ticket5_keytab functions directly from
cellconfig pulls in libkrb5 dependencies for everything that uses
cellconfig, and we'd have to trigger an afsconf_Check call by calling
some other cellconfig function.)

9102f49a3bdc67ed74e254349eb55b529472f45c

src/auth/authcon.c
src/rxkad/rxkad_prototypes.h
src/rxkad/ticket5_keytab.c

index 748c3febcdd2db3fe3d747c311d1ff2b34436bd5..1a9c26807c58a72c0ef4a2b59427a9c7e2017f66 100644 (file)
@@ -62,17 +62,24 @@ afsconf_ServerAuth(void *arock,
     struct rx_securityClass *tclass;
 #ifdef USE_RXKAD_KEYTAB
     int keytab_enable = 0;
+    char *csdb_name;
+    size_t csdblen;
     char *keytab_name;
     size_t ktlen;
+    csdblen = strlen(adir->name) + 1 + strlen(AFSDIR_CELLSERVDB_FILE) + 1;
+    csdb_name = malloc(csdblen);
     ktlen = 5 + strlen(adir->name) + 1 + strlen(AFSDIR_RXKAD_KEYTAB_FILE) + 1;
     keytab_name = malloc(ktlen);
-    if (keytab_name != NULL) {
+    if (csdb_name != NULL && keytab_name != NULL) {
+       strcompose(csdb_name, csdblen, adir->name, "/",
+                  AFSDIR_CELLSERVDB_FILE, (char *)NULL);
        strcompose(keytab_name, ktlen, "FILE:", adir->name, "/",
                   AFSDIR_RXKAD_KEYTAB_FILE, (char *)NULL);
-       if (rxkad_InitKeytabDecrypt(keytab_name) == 0)
+       if (rxkad_InitKeytabDecrypt(csdb_name, keytab_name) == 0)
            keytab_enable = 1;
-       free(keytab_name);
     }
+    free(csdb_name);
+    free(keytab_name);
 #endif
     LOCK_GLOBAL_MUTEX;
     tclass = (struct rx_securityClass *)
@@ -343,17 +350,24 @@ afsconf_BuildServerSecurityObjects(struct afsconf_dir *dir,
 {
 #ifdef USE_RXKAD_KEYTAB
     int keytab_enable = 0;
+    char *csdb_name;
+    size_t csdblen;
     char *keytab_name;
     size_t ktlen;
+    csdblen = strlen(dir->name) + 1 + strlen(AFSDIR_CELLSERVDB_FILE) + 1;
+    csdb_name = malloc(csdblen);
     ktlen = 5 + strlen(dir->name) + 1 + strlen(AFSDIR_RXKAD_KEYTAB_FILE) + 1;
     keytab_name = malloc(ktlen);
-    if (keytab_name != NULL) {
+    if (csdb_name != NULL && keytab_name != NULL) {
+       strcompose(csdb_name, csdblen, dir->name, "/",
+                  AFSDIR_CELLSERVDB_FILE, (char *)NULL);
        strcompose(keytab_name, ktlen, "FILE:", dir->name, "/",
                   AFSDIR_RXKAD_KEYTAB_FILE, (char *)NULL);
-       if (rxkad_InitKeytabDecrypt(keytab_name) == 0)
+       if (rxkad_InitKeytabDecrypt(csdb_name, keytab_name) == 0)
            keytab_enable = 1;
-       free(keytab_name);
     }
+    free(csdb_name);
+    free(keytab_name);
 #endif
     if (flags & AFSCONF_SEC_OBJS_RXKAD_CRYPT)
        *numClasses = 4;
index dad8b6c2ae144cc8a781fe2f3c2bc99da93f675b..1db16a191c95233ab188075574cb5d36dbdad18b 100644 (file)
@@ -170,7 +170,7 @@ extern int tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
 extern int tkt_DeriveDesKey(int enctype, void *keydata, size_t keylen, struct ktc_encryptionKey
                            *output);
 /* ticket5_keytab.c */
-extern int rxkad_InitKeytabDecrypt(const char *);
+extern int rxkad_InitKeytabDecrypt(const char *, const char *);
 extern int rxkad_BindKeytabDecrypt(struct rx_securityClass *);
 
 #if !defined(NO_DES_H_INCLUDE)
index a969e023a632fafe544633bb7d4aad9bdfb5b8fd..329140c09b5d353fb80cc78ecdadebba57ae8b72 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <string.h>
 #include <errno.h>
+#include <sys/stat.h>
 
 #include <krb5.h>
 
@@ -39,6 +40,7 @@ static afs_kmutex_t krb5_lock;
 #endif
 
 /* these globals are expected to be set only once, so locking is not needed */
+static char *checkfile_path;
 static char *keytab_name;
 static int have_keytab_keys;
 
@@ -95,8 +97,22 @@ reload_keys(void)
     krb5_keytab_entry kte;
     int i, n_nkeys, o_nkeys;
     krb5_keytab_entry *n_ktent = NULL, *o_ktent;
+    struct stat tstat;
+
+    if (stat(checkfile_path, &tstat) == 0) {
+       if (have_keytab_keys && tstat.st_mtime == last_reload) {
+           /* We haven't changed since the last time we loaded our keys, so
+            * there's nothing to do. */
+           ret = 0;
+           goto cleanup;
+       }
+       last_reload = tstat.st_mtime;
+    } else if (have_keytab_keys) {
+       /* stat() failed, but we already have keys, so don't do anything. */
+       ret = 0;
+       goto cleanup;
+    }
 
-    time(&last_reload);
     if (keytab_name != NULL)
        ret = krb5_kt_resolve(k5ctx, keytab_name, &fkeytab);
     else
@@ -219,21 +235,15 @@ rxkad_keytab_decrypt(int kvno, int et, void *in, size_t inlen,
     krb5_enc_data ind;
 #endif
     krb5_data outd;
-    int retried, i, foundkey;
+    int i, foundkey;
     MUTEX_ENTER(&krb5_lock);
+    reload_keys();
     if (have_keytab_keys == 0) {
-       if (time(NULL) - last_reload > 600) {
-           reload_keys();
-       }
-       if (have_keytab_keys == 0) {
-           MUTEX_EXIT(&krb5_lock);
-           return RXKADUNKNOWNKEY;
-       }
+       MUTEX_EXIT(&krb5_lock);
+       return RXKADUNKNOWNKEY;
     }
     foundkey = 0;
     code = -1;
-    retried = 0;
-retry:
     for (i = 0; i < nkeys; i++) {
        /* foundkey determines what error code we return for failure */
        if (ktent[i].vno == kvno)
@@ -283,11 +293,6 @@ retry:
 #endif
        }
     }
-    if (code != 0 && time(NULL) - last_reload > 600 && !retried) {
-       reload_keys();
-       retried = 1;
-       goto retry;
-    }
     MUTEX_EXIT(&krb5_lock);
     if (code == 0)
        return 0;
@@ -309,7 +314,7 @@ static pthread_once_t rxkad_keytab_once_init = PTHREAD_ONCE_INIT;
 #define INIT_PTHREAD_LOCKS
 #endif
 int
-rxkad_InitKeytabDecrypt(const char *ktname)
+rxkad_InitKeytabDecrypt(const char *csdb, const char *ktname)
 {
     int code;
     static int keytab_init;
@@ -319,6 +324,11 @@ rxkad_InitKeytabDecrypt(const char *ktname)
        MUTEX_EXIT(&krb5_lock);
        return 0;
     }
+    checkfile_path = strdup(csdb);
+    if (checkfile_path == NULL) {
+       code = ENOMEM;
+       goto cleanup;
+    }
     k5ctx = NULL;
     keytab_name = NULL;
     code = krb5_init_context(&k5ctx);
@@ -336,6 +346,9 @@ rxkad_InitKeytabDecrypt(const char *ktname)
     MUTEX_EXIT(&krb5_lock);
     return 0;
 cleanup:
+    if (checkfile_path != NULL) {
+       free(checkfile_path);
+    }
     if (keytab_name != NULL) {
        free(keytab_name);
     }