r16516: Get rid of file_exists() as there already is a file_exist().
[samba.git] / source / passdb / secrets.c
index 60b197de933bac8dcfbbd7fed9f85aecf165fac2..8f4b5f4f5eeb71e1a004b427abc1f365d7ec25bb 100644 (file)
    such as the local SID and machine trust password */
 
 #include "includes.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_PASSDB
+#include "lib/tdb/include/tdbutil.h"
+#include "secrets.h"
+#include "param/param.h"
+#include "system/filesys.h"
+#include "db_wrap.h"
+#include "lib/ldb/include/ldb.h"
+#include "dsdb/samdb/samdb.h"
 
 static struct tdb_wrap *tdb;
 
@@ -45,24 +49,31 @@ static void get_rand_seed(int *new_seed)
        }
 }
 
+/* close the secrets database */
+void secrets_shutdown(void)
+{
+       talloc_free(tdb);
+}
+
 /* open up the secrets database */
 BOOL secrets_init(void)
 {
-       pstring fname;
-       char dummy;
+       char *fname;
+       uint8_t dummy;
 
        if (tdb)
                return True;
 
-       pstrcpy(fname, lp_private_dir());
-       pstrcat(fname,"/secrets.tdb");
+       asprintf(&fname, "%s/secrets.tdb", lp_private_dir());
 
-       tdb = tdb_wrap_open(NULL, 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));
+               SAFE_FREE(fname);
                return False;
        }
+       SAFE_FREE(fname);
 
        /**
         * Set a reseed function for the crypto random generator 
@@ -78,83 +89,80 @@ BOOL secrets_init(void)
        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)
+/*
+  connect to the schannel ldb
+*/
+struct ldb_context *secrets_db_connect(TALLOC_CTX *mem_ctx)
 {
-       TDB_DATA kbuf, dbuf;
-       secrets_init();
-       if (!tdb)
+       char *path;
+       struct ldb_context *ldb;
+       BOOL existed;
+       const char *init_ldif = 
+               "dn: @ATTRIBUTES\n" \
+               "computerName: CASE_INSENSITIVE\n" \
+               "flatname: CASE_INSENSITIVE\n";
+
+       path = private_path(mem_ctx, "secrets.ldb");
+       if (!path) {
                return NULL;
-       kbuf.dptr = strdup(key);
-       kbuf.dsize = strlen(key);
-       dbuf = tdb_fetch(tdb->tdb, kbuf);
-       if (size)
-               *size = dbuf.dsize;
-       free(kbuf.dptr);
-       return dbuf.dptr;
-}
+       }
+       
+       existed = file_exist(path);
+
+       /* Secrets.ldb *must* always be local.  If we call for a
+        * system_session() we will recurse */
+       ldb = ldb_wrap_connect(mem_ctx, path, NULL, NULL, 0, NULL);
+       talloc_free(path);
+       if (!ldb) {
+               return NULL;
+       }
+       
+       if (!existed) {
+               gendb_add_ldif(ldb, init_ldif);
+       }
 
-/************************************************************************
- Routine to fetch the plaintext machine account password for a realm
-the password is assumed to be a null terminated ascii string
-************************************************************************/
-char *secrets_fetch_machine_password(const char *domain)
-{
-       char *key;
-       char *ret;
-       asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
-       strupper(key);
-       ret = (char *)secrets_fetch(key, NULL);
-       free(key);
-       return ret;
+       return ldb;
 }
 
-
-
-/*******************************************************************************
- Lock the secrets tdb based on a string - this is used as a primitive form of mutex
- between smbd instances.
-*******************************************************************************/
-
-BOOL secrets_named_mutex(const char *name, uint_t timeout, size_t *p_ref_count)
+struct dom_sid *secrets_get_domain_sid(TALLOC_CTX *mem_ctx,
+                                      const char *domain)
 {
-       size_t ref_count = *p_ref_count;
-       int ret = 0;
+       struct ldb_context *ldb;
+       struct ldb_message **msgs;
+       int ldb_ret;
+       const char *attrs[] = { "objectSid", NULL };
+       struct dom_sid *result = NULL;
+
+       ldb = secrets_db_connect(mem_ctx);
+       if (ldb == NULL) {
+               DEBUG(5, ("secrets_db_connect failed\n"));
+               goto done;
+       }
 
-       if (!message_init())
-               return False;
+       ldb_ret = gendb_search(ldb, ldb,
+                              ldb_dn_explode(mem_ctx, SECRETS_PRIMARY_DOMAIN_DN), 
+                              &msgs, attrs,
+                              SECRETS_PRIMARY_DOMAIN_FILTER, domain);
 
-       if (ref_count == 0) {
-               ret = tdb_lock_bystring(tdb->tdb, name, timeout);
-               if (ret == 0)
-                       DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
+       if (ldb_ret == 0) {
+               DEBUG(5, ("Did not find domain record for %s\n", domain));
+               goto done;
        }
 
-       if (ret == 0) {
-               *p_ref_count = ++ref_count;
-               DEBUG(10,("secrets_named_mutex: ref_count for mutex %s = %u\n", name, (uint_t)ref_count ));
+       if (ldb_ret > 1) {
+               DEBUG(5, ("Found more than one (%d) domain records for %s\n",
+                         ldb_ret, domain));
+               goto done;
        }
-       return (ret == 0);
-}
 
-/*******************************************************************************
- Unlock a named mutex.
-*******************************************************************************/
-
-void secrets_named_mutex_release(const char *name, size_t *p_ref_count)
-{
-       size_t ref_count = *p_ref_count;
-
-       SMB_ASSERT(ref_count != 0);
-
-       if (ref_count == 1) {
-               tdb_unlock_bystring(tdb->tdb, name);
-               DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
+       result = samdb_result_dom_sid(mem_ctx, msgs[0], "objectSid");
+       if (result == NULL) {
+               DEBUG(0, ("Domain object for %s does not contain a SID!\n",
+                         domain));
+               goto done;
        }
 
-       *p_ref_count = --ref_count;
-       DEBUG(10,("secrets_named_mutex_release: ref_count for mutex %s = %u\n", name, (uint_t)ref_count ));
+ done:
+       talloc_free(ldb);
+       return result;
 }
-