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
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 *)
{
#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;
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)
#include <string.h>
#include <errno.h>
+#include <sys/stat.h>
#include <krb5.h>
#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;
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
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)
#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;
#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;
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);
MUTEX_EXIT(&krb5_lock);
return 0;
cleanup:
+ if (checkfile_path != NULL) {
+ free(checkfile_path);
+ }
if (keytab_name != NULL) {
free(keytab_name);
}