r5296: - only include the tdb headers where they are needed
[kai/samba.git] / source / passdb / secrets.c
index b5bae614b631e08606e5b4d3caf1ee7d7e8c6016..89041fa4ebd752a10ed6aa4ab463c62d3dfbd2e2 100644 (file)
    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;
@@ -40,19 +65,31 @@ BOOL secrets_init(void)
        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();
@@ -60,7 +97,7 @@ static void *secrets_fetch(const char *key, size_t *size)
                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);
@@ -94,11 +131,12 @@ BOOL secrets_named_mutex(const char *name, uint_t timeout, size_t *p_ref_count)
        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 ));
        }
@@ -120,8 +158,12 @@ void secrets_named_mutex_release(const char *name, size_t *p_ref_count)
 
        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 ));
        }
 
@@ -129,3 +171,25 @@ void secrets_named_mutex_release(const char *name, size_t *p_ref_count)
        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;
+}
+