such as the local SID and machine trust password */
#include "includes.h"
+#include "lib/tdb/include/tdbutil.h"
+#include "secrets.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_PASSDB
-static TDB_CONTEXT *tdb;
+static struct tdb_wrap *tdb;
+
+/**
+ * Use a TDB to store an incrementing random seed.
+ *
+ * Initialised to the current pid, the very first time Samba starts,
+ * and incremented by one each time it is needed.
+ *
+ * @note Not called by systems with a working /dev/urandom.
+ */
+static void get_rand_seed(int *new_seed)
+{
+ *new_seed = getpid();
+ if (tdb) {
+ tdb_change_int32_atomic(tdb->tdb, "INFO/random_seed", new_seed, 1);
+ }
+}
+
+/* close the secrets database */
+void secrets_shutdown(void)
+{
+ talloc_free(tdb);
+}
/* open up the secrets database */
BOOL secrets_init(void)
{
pstring fname;
+ uint8_t dummy;
if (tdb)
return True;
pstrcpy(fname, lp_private_dir());
pstrcat(fname,"/secrets.tdb");
- tdb = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ tdb = tdb_wrap_open(talloc_autofree_context(), fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb) {
DEBUG(0,("Failed to open %s\n", fname));
return False;
}
+
+ /**
+ * Set a reseed function for the crypto random generator
+ *
+ * This avoids a problem where systems without /dev/urandom
+ * could send the same challenge to multiple clients
+ */
+ set_rand_reseed_callback(get_rand_seed);
+
+ /* Ensure that the reseed is done now, while we are root, etc */
+ generate_random_buffer(&dummy, sizeof(dummy));
+
return True;
}
/* read a entry from the secrets database - the caller must free the result
if size is non-null then the size of the entry is put in there
*/
-static void *secrets_fetch(const char *key, size_t *size)
+void *secrets_fetch(const char *key, size_t *size)
{
TDB_DATA kbuf, dbuf;
secrets_init();
return NULL;
kbuf.dptr = strdup(key);
kbuf.dsize = strlen(key);
- dbuf = tdb_fetch(tdb, kbuf);
+ dbuf = tdb_fetch(tdb->tdb, kbuf);
if (size)
*size = dbuf.dsize;
free(kbuf.dptr);
size_t ref_count = *p_ref_count;
int ret = 0;
- if (!message_init())
+ secrets_init();
+ if (!tdb)
return False;
if (ref_count == 0) {
- ret = tdb_lock_bystring(tdb, name, timeout);
+ ret = tdb_lock_bystring(tdb->tdb, name, timeout);
if (ret == 0)
DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
}
SMB_ASSERT(ref_count != 0);
+ secrets_init();
+ if (!tdb)
+ return;
+
if (ref_count == 1) {
- tdb_unlock_bystring(tdb, name);
+ tdb_unlock_bystring(tdb->tdb, name);
DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
}
DEBUG(10,("secrets_named_mutex_release: ref_count for mutex %s = %u\n", name, (uint_t)ref_count ));
}
+/*
+ connect to the schannel ldb
+*/
+struct ldb_wrap *secrets_db_connect(TALLOC_CTX *mem_ctx)
+{
+ char *path;
+ struct ldb_wrap *ldb;
+
+ path = private_path(mem_ctx, "secrets.ldb");
+ if (!path) {
+ return NULL;
+ }
+
+ ldb = ldb_wrap_connect(mem_ctx, path, 0, NULL);
+ talloc_free(path);
+ if (!ldb) {
+ return NULL;
+ }
+
+ return ldb;
+}
+