r9589: Support reading secrets tdb
authorJelmer Vernooij <jelmer@samba.org>
Wed, 24 Aug 2005 16:39:28 +0000 (16:39 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:34:32 +0000 (13:34 -0500)
(This used to be commit dd15131b5219ecf0d09329c0de37c426b9147f45)

source4/include/structs.h
source4/lib/samba3/config.mk
source4/lib/samba3/samba3.c
source4/lib/samba3/samba3.h
source4/lib/samba3/secrets.c

index 6d060fb22f8a24fd8acb38467c370c7923f82e6a..cac46c030f7d6b4d961702865add7fb0b755039f 100644 (file)
@@ -278,4 +278,5 @@ struct samba3_groupdb;
 struct samba3_winsdb_entry;
 struct samba3_policy;
 struct samba3_regdb;
+struct samba3_secrets;
 struct samba3;
index 23f07106f04dc1f3eea81dcdaeac740da4272bee..75073048d0a08436755c3d603084f4d541e00444 100644 (file)
@@ -9,8 +9,8 @@ ADD_OBJ_FILES = \
                lib/samba3/winsdb.o \
                lib/samba3/samba3.o \
                lib/samba3/group.o \
-               lib/samba3/registry.o
-#              lib/samba3/secrets.o
+               lib/samba3/registry.o \
+               lib/samba3/secrets.o
 # End SUBSYSTEM LIBSAMBA3
 ################################################
 
index c74b1b5279e02f1bc42f5e2d768b8ff62ead3ff2..bfd41d6554827f707a68b660ed489506360b2ef2 100644 (file)
@@ -51,5 +51,9 @@ struct samba3 *samba3_read(const char *libdir, TALLOC_CTX *ctx)
        samba3_read_regdb(dbfile, ctx, &ret->registry);
        SAFE_FREE(dbfile);
 
+       asprintf(&dbfile, "%s/secrets.tdb", libdir);
+       samba3_read_secrets(dbfile, ctx, &ret->secrets);
+       SAFE_FREE(dbfile);
+
        return ret;
 }
index bebd1207048807f643b9f26d3b8157266e6ef396..575ee838256c9485f4e7ed51205f16666655c13b 100644 (file)
@@ -137,6 +137,53 @@ struct samba3_regdb
        struct samba3_regkey *keys;
 };
 
+struct samba3_secrets
+{
+       struct cli_credentials *ipc_cred;
+       
+       uint32_t ldappw_count;
+       struct samba3_ldappw 
+       {
+               char *dn;
+               char *password;
+       } *ldappws;
+
+       uint32_t domain_count;
+       struct samba3_domainsecrets 
+       {
+               char *name;
+               struct dom_sid sid;
+               struct GUID guid;
+               char *plaintext_pw;
+               time_t last_change_time;
+               struct {
+                       uint8_t hash[16];
+                       time_t mod_time;
+               } hash_pw;;
+               int sec_channel_type;
+       } *domains;
+
+       uint32_t trusted_domain_count;
+       struct samba3_trusted_dom_pass {
+               uint32_t uni_name_len;
+               const char *uni_name[32]; /* unicode domain name */
+               const char *pass;               /* trust relationship's password */
+               time_t mod_time;
+               struct dom_sid domain_sid;      /* remote domain's sid */
+       } *trusted_domains;
+
+       uint32_t afs_keyfile_count;
+
+       struct samba3_afs_keyfile {
+               uint32_t nkeys;
+               struct {
+                       uint32_t kvno;
+                       char key[8];
+               } entry[8];
+               char *cell;
+       } *afs_keyfiles;
+};
+
 struct samba3 
 {
        uint32_t winsdb_count;
@@ -145,6 +192,7 @@ struct samba3
        uint32_t samaccount_count;
        struct samba3_samaccount *samaccounts;
 
+       struct samba3_secrets secrets;
        struct samba3_groupdb group;
        struct samba3_idmapdb idmap;
        struct samba3_policy policy;
index ab19f166eefd3d542d202fb79297cb543e73fe62..4aacffda34f42f9b97ddca5a328e3fc8a053e8ba 100644 (file)
 /* the Samba secrets database stores any generated, private information
    such as the local SID and machine trust password */
 
-#define SECRETS_DOMAIN_SID "SECRETS/SID"
-#define SECRETS_DOMAIN_GUID "SECRETS/DOMGUID"
-#define SECRETS_LDAP_BIND_PW "SECRETS/LDAP_BIND_PW"
-#define SECRETS_MACHINE_ACCT_PASS "SECRETS/$MACHINE.ACC"
-#define SECRETS_DOMTRUST_ACCT_PASS "SECRETS/$DOMTRUST.ACC"
-#define SECRETS_MACHINE_PASSWORD "SECRETS/MACHINE_PASSWORD"
-#define SECRETS_MACHINE_LAST_CHANGE_TIME "SECRETS/MACHINE_LAST_CHANGE_TIME"
-#define SECRETS_MACHINE_SEC_CHANNEL_TYPE "SECRETS/MACHINE_SEC_CHANNEL_TYPE"
-#define SECRETS_AFS_KEYFILE "SECRETS/AFS_KEYFILE"
-#define SECRETS_AUTH_USER      "SECRETS/AUTH_USER"
-#define SECRETS_AUTH_DOMAIN      "SECRETS/AUTH_DOMAIN"
-#define SECRETS_AUTH_PASSWORD  "SECRETS/AUTH_PASSWORD"
-
-
 #include "includes.h"
 #include "tdb.h"
+#include "lib/samba3/samba3.h"
 #include "system/filesys.h"
 #include "librpc/gen_ndr/ndr_security.h"
 #include "lib/tdb/include/tdbutil.h"
 
-/* structure for storing machine account password
-   (ie. when samba server is member of a domain */
-struct machine_acct_pass {
-       uint8_t hash[16];
-       time_t mod_time;
-};
-
-#define SECRETS_AFS_MAXKEYS 8
-
-struct afs_key {
-       uint32_t kvno;
-       char key[8];
-};
-
-/*
- * storage structure for trusted domain
- */
-typedef struct trusted_dom_pass {
-       size_t uni_name_len;
-       const char *uni_name[32]; /* unicode domain name */
-       size_t pass_len;
-       const char *pass;               /* trust relationship's password */
-       time_t mod_time;
-       struct dom_sid domain_sid;      /* remote domain's sid */
-} TRUSTED_DOM_PASS;
-
 /**
  * Unpack SID into a pointer
  *
@@ -99,492 +60,197 @@ static size_t tdb_sid_unpack(TDB_CONTEXT *tdb, char* pack_buf, int bufsize, stru
        return len;
 }
 
-/**
- * Unpack TRUSTED_DOM_PASS passed by pointer
- *
- * @param pack_buf pointer to buffer with packed representation
- * @param bufsize size of the buffer
- * @param pass pointer to trusted domain password to be filled with unpacked data
- *
- * @return size of structure unpacked from buffer
- **/
-static size_t tdb_trusted_dom_pass_unpack(TDB_CONTEXT *tdb, char* pack_buf, int bufsize, TRUSTED_DOM_PASS* pass)
+static struct samba3_domainsecrets *secrets_find_domain(TALLOC_CTX *ctx, struct samba3_secrets *db, const char *key)
 {
-       int idx, len = 0;
-       
-       if (!pack_buf || !pass) return -1;
+       int i;
 
-       /* unpack unicode domain name and plaintext password */
-       len += tdb_unpack(tdb, pack_buf, bufsize - len, "d", &pass->uni_name_len);
-       
-       for (idx = 0; idx < 32; idx++)
-               len +=  tdb_unpack(tdb, pack_buf + len, bufsize - len, "w", &pass->uni_name[idx]);
+       for (i = 0; i < db->domain_count; i++) 
+       {
+               if (!StrCaseCmp(db->domains[i].name, key)) 
+                       return &db->domains[i];
+       }
 
-       len += tdb_unpack(tdb, pack_buf + len, bufsize - len, "dPd", &pass->pass_len, &pass->pass,
-                         &pass->mod_time);
-       
-       /* unpack domain sid */
-       len += tdb_sid_unpack(tdb, pack_buf + len, bufsize - len, &pass->domain_sid);
+       db->domains = talloc_realloc(ctx, db->domains, struct samba3_domainsecrets, db->domain_count+1);
+       ZERO_STRUCT(db->domains[db->domain_count]);
+       db->domains[db->domain_count].name = talloc_strdup(ctx, key); 
+
+       db->domain_count++;
        
-       return len;     
+       return &db->domains[db->domain_count-1];
 }
 
-
-static TDB_CONTEXT *secrets_open(const char *fname)
+static NTSTATUS ipc_password (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db) 
 {
-       TDB_CONTEXT *tdb = tdb_open(fname, 0, TDB_DEFAULT, O_RDONLY, 0600);
-
-       if (!tdb) {
-               DEBUG(0,("Failed to open %s\n", fname));
-               return NULL;
-       }
-
-       return tdb;
+       cli_credentials_set_password(db->ipc_cred, vbuf.dptr, CRED_SPECIFIED);
+       return NT_STATUS_OK;
 }
 
-static BOOL secrets_fetch_domain_sid(TDB_CONTEXT *tdb, const char *domain, struct dom_sid *sid)
+static NTSTATUS ipc_username (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db) 
 {
-       struct dom_sid *dyn_sid;
-       TDB_DATA val;
-       char *key;
-       size_t size;
-
-       asprintf(&key, "%s/%s", SECRETS_DOMAIN_SID, domain);
-       strupper_m(key);
+       cli_credentials_set_username(db->ipc_cred, vbuf.dptr, CRED_SPECIFIED);
+       return NT_STATUS_OK;
+}
        
-       val = tdb_fetch_bystring(tdb, key);
-       /* FIXME: Convert val to dyn_sid */
-       SAFE_FREE(key);
-
-       if (dyn_sid == NULL)
-               return False;
-
-       if (size != sizeof(struct dom_sid))
-       { 
-               SAFE_FREE(dyn_sid);
-               return False;
-       }
-
-       *sid = *dyn_sid;
-       SAFE_FREE(dyn_sid);
-       return True;
+static NTSTATUS ipc_domain (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db) 
+{
+       cli_credentials_set_domain(db->ipc_cred, vbuf.dptr, CRED_SPECIFIED);
+       return NT_STATUS_OK;
 }
 
-static BOOL secrets_fetch_domain_guid(TDB_CONTEXT *tdb, const char *domain, struct GUID *guid)
+static NTSTATUS domain_sid (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db) 
 {
-       struct GUID *dyn_guid;
-       char *key;
-       TDB_DATA val;
-       size_t size;
-
-       asprintf(&key, "%s/%s", SECRETS_DOMAIN_GUID, domain);
-       strupper_m(key);
-       val = tdb_fetch_bystring(tdb, key);
-
-       dyn_guid = (struct GUID *)val.dptr;
-
-       if (!dyn_guid) {
-               return False;
-       }
-
-       if (val.dsize != sizeof(struct GUID))
-       { 
-               DEBUG(1,("GUID size %d is wrong!\n", (int)size));
-               SAFE_FREE(dyn_guid);
-               return False;
-       }
-
-       *guid = *dyn_guid;
-       SAFE_FREE(dyn_guid);
-       return True;
+       struct samba3_domainsecrets *domainsec = secrets_find_domain(ctx, db, key);
+       domainsec->sid.sub_auths = talloc_array(ctx, uint32_t, 15);
+       tdb_sid_unpack(tdb, vbuf.dptr, vbuf.dsize, &domainsec->sid);
+       return NT_STATUS_OK;
 }
 
-/**
- * Form a key for fetching the machine trust account password
- *
- * @param domain domain name
- *
- * @return stored password's key
- **/
-static char *trust_keystr(const char *domain)
+static NTSTATUS domain_guid (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db) 
 {
-       char *keystr;
-
-       asprintf(&keystr, "%s/%s", SECRETS_MACHINE_ACCT_PASS, domain);
-       strupper_m(keystr);
-
-       return keystr;
+       struct samba3_domainsecrets *domainsec = secrets_find_domain(ctx, db, key);
+       memcpy(&domainsec->guid, vbuf.dptr, vbuf.dsize);
+       return NT_STATUS_OK;
 }
 
-/**
- * Form a key for fetching a trusted domain password
- *
- * @param domain trusted domain name
- *
- * @return stored password's key
- **/
-static char *trustdom_keystr(const char *domain)
+static NTSTATUS ldap_bind_pw (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db) 
 {
-       char *keystr;
-
-       asprintf(&keystr, "%s/%s", SECRETS_DOMTRUST_ACCT_PASS, domain);
-       strupper_m(keystr);
-               
-       return keystr;
+       struct samba3_ldappw pw;
+       pw.dn = talloc_strdup(ctx, key);
+       pw.password = talloc_strdup(ctx, vbuf.dptr);
+
+       db->ldappws = talloc_realloc(ctx, db->ldappws, struct samba3_ldappw, db->ldappw_count+1);
+       db->ldappws[db->ldappw_count] = pw;
+       db->ldappw_count++;
+       return NT_STATUS_OK;
 }
 
-/************************************************************************
- Routine to get the trust account password for a domain.
- The user of this function must have locked the trust password file using
- the above secrets_lock_trust_account_password().
-************************************************************************/
-
-static BOOL secrets_fetch_trust_account_password(TDB_CONTEXT *tdb, 
-                                         const char *domain, uint8_t ret_pwd[16],
-                                         time_t *pass_last_set_time,
-                                         uint32_t *channel)
+static NTSTATUS afs_keyfile (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db) 
 {
-       struct machine_acct_pass *pass;
-       char *plaintext;
-       TDB_DATA val;
-
-       plaintext = secrets_fetch_machine_password(tdb, domain, pass_last_set_time, 
-                                                  channel);
-       if (plaintext) {
-               DEBUG(4,("Using cleartext machine password\n"));
-               E_md4hash(plaintext, ret_pwd);
-               SAFE_FREE(plaintext);
-               return True;
-       }
-       
-       val = tdb_fetch_bystring(tdb, trust_keystr(domain));
-       if (!val.dptr) {
-               DEBUG(5, ("tdb_fetch_bystring failed!\n"));
-               return False;
-       }
-       
-       if (val.dsize != sizeof(*pass)) {
-               DEBUG(0, ("secrets were of incorrect size!\n"));
-               return False;
-       }
-
-       pass = (struct machine_acct_pass *)val.dptr;
+       struct samba3_afs_keyfile keyfile;
+       memcpy(&keyfile, vbuf.dptr, vbuf.dsize);
+       keyfile.cell = talloc_strdup(ctx, key);
 
-       if (pass_last_set_time) *pass_last_set_time = pass->mod_time;
-       memcpy(ret_pwd, pass->hash, 16);
-
-       return True;
+       db->afs_keyfiles = talloc_realloc(ctx, db->afs_keyfiles, struct samba3_afs_keyfile, db->afs_keyfile_count+1);
+       db->afs_keyfiles[db->afs_keyfile_count] = keyfile;
+       db->afs_keyfile_count++;
+       
+       return NT_STATUS_OK;
 }
 
-/************************************************************************
- Routine to get account password to trusted domain
-************************************************************************/
-
-static BOOL secrets_fetch_trusted_domain_password(TDB_CONTEXT *tdb, const char *domain, char** pwd, struct dom_sid **sid, time_t *pass_last_set_time)
+static NTSTATUS machine_sec_channel_type (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db) 
 {
-       struct trusted_dom_pass pass;
-       
-       /* unpacking structures */
-       int pass_len = 0;
-       TDB_DATA val;
+       struct samba3_domainsecrets *domainsec = secrets_find_domain(ctx, db, key);
 
-       ZERO_STRUCT(pass);
-
-       /* fetching trusted domain password structure */
-       val = tdb_fetch_bystring(tdb, trustdom_keystr(domain));
-       if (!val.dptr) {
-               DEBUG(5, ("secrets_fetch failed!\n"));
-               return False;
-       }
-
-       /* unpack trusted domain password */
-       pass_len = tdb_trusted_dom_pass_unpack(val.dptr, val.dsize, &pass);
-
-       if (pass_len != val.dsize) {
-               DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
-               return False;
-       }
-                       
-       /* the trust's password */      
-       if (pwd) {
-               *pwd = strdup(pass.pass);
-               if (!*pwd) {
-                       return False;
-               }
-       }
-
-       /* last change time */
-       if (pass_last_set_time) *pass_last_set_time = pass.mod_time;
-
-       /* domain sid */
-       
-       *sid = dom_sid_dup(tdb, &pass.domain_sid);
-               
-       return True;
+       domainsec->sec_channel_type = IVAL(vbuf.dptr, 0);
+       return NT_STATUS_OK;
 }
 
-/************************************************************************
- Routine to fetch the plaintext machine account password for a realm
-the password is assumed to be a null terminated ascii string
-************************************************************************/
-static char *secrets_fetch_machine_password(TDB_CONTEXT *tdb, const char *domain, 
-                                    time_t *pass_last_set_time,
-                                    uint32_t *channel)
+static NTSTATUS machine_last_change_time (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db) 
 {
-       char *key = NULL;
-       char *ret;
-       TDB_DATA val;
-       asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
-       strupper_m(key);
-       val = tdb_fetch_bystring(tdb, key);
-       SAFE_FREE(key);
-       
-       if (pass_last_set_time) {
-               asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
-               strupper_m(key);
-               tdb_fetch_uint32(tdb, key, (uint32_t *)pass_last_set_time);
-               SAFE_FREE(key);
-       }
-       
-       if (channel) {
-               asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
-               strupper_m(key);
-               tdb_fetch_uint32(tdb, key, channel);
-               SAFE_FREE(key);
-       }
-       
-       return ret;
+       struct samba3_domainsecrets *domainsec = secrets_find_domain(ctx, db, key);
+       domainsec->last_change_time = IVAL(vbuf.dptr, 0);
+       return NT_STATUS_OK;
 }
 
-/*******************************************************************
- find the ldap password
-******************************************************************/
-static BOOL fetch_ldap_pw(TDB_CONTEXT *tdb, const char *dn, char** pw)
+static NTSTATUS machine_password (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db) 
 {
-       char *key = NULL;
-       size_t size;
-       TDB_DATA val;
-       
-       if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
-               DEBUG(0, ("fetch_ldap_pw: asprintf failed!\n"));
-       }
-       
-       val = tdb_fetch_bystring(tdb, key);
-       *pw = val.dptr;
-       SAFE_FREE(key);
-
-       if (!size) {
-               return False;
-       }
-       
-       return True;
+       struct samba3_domainsecrets *domainsec = secrets_find_domain(ctx, db, key);
+       domainsec->plaintext_pw = talloc_strdup(ctx, vbuf.dptr);
+       return NT_STATUS_OK;
 }
 
+static NTSTATUS machine_acc (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db) 
+{
+       struct samba3_domainsecrets *domainsec = secrets_find_domain(ctx, db, key);
 
-/**
- * Get trusted domains info from secrets.tdb.
- *
- * The linked list is allocated on the supplied talloc context, caller gets to destroy
- * when done.
- *
- * @param ctx Allocation context
- * @param enum_ctx Starting index, eg. we can start fetching at third
- *        or sixth trusted domain entry. Zero is the first index.
- *        Value it is set to is the enum context for the next enumeration.
- * @param num_domains Number of domain entries to fetch at one call
- * @param domains Pointer to array of trusted domain structs to be filled up
- *
- * @return nt status code of rpc response
- **/ 
+       memcpy(&domainsec->hash_pw, vbuf.dptr, vbuf.dsize);
+
+       return NT_STATUS_OK;
+}
 
-static NTSTATUS secrets_get_trusted_domains(TDB_CONTEXT *tdb, TALLOC_CTX* ctx, int* enum_ctx, unsigned int max_num_domains,
-                                     int *num_domains, struct samba3_trustdom ***domains)
+static NTSTATUS domtrust_acc (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db) 
 {
-       TDB_LIST_NODE *keys, *k;
-       struct samba3_trustdom *dom = NULL;
-       char *pattern;
-       unsigned int start_idx;
-       uint32_t idx = 0;
-       size_t size, packed_size = 0;
-       fstring dom_name;
-       char *packed_pass;
-       struct trusted_dom_pass *pass = talloc(ctx, struct trusted_dom_pass);
-       NTSTATUS status;
-
-       if (!pass) {
-               DEBUG(0, ("talloc_zero failed!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
-                               
-       *num_domains = 0;
-       start_idx = *enum_ctx;
-
-       /* generate searching pattern */
-       if (!(pattern = talloc_asprintf(ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS))) {
-               DEBUG(0, ("secrets_get_trusted_domains: talloc_asprintf() failed!\n"));
-               return NT_STATUS_NO_MEMORY;
-       }
+       int idx, len = 0;
+       struct samba3_trusted_dom_pass pass;
+       int pass_len;
+       
+       if (!vbuf.dptr) 
+               return NT_STATUS_UNSUCCESSFUL;
 
-       DEBUG(5, ("secrets_get_trusted_domains: looking for %d domains, starting at index %d\n", 
-                 max_num_domains, *enum_ctx));
-
-       *domains = talloc_zero_array(ctx, struct samba3_trustdom *, max_num_domains);
-
-       /* fetching trusted domains' data and collecting them in a list */
-       keys = tdb_search_keys(tdb, pattern);
-
-       /* 
-        * if there's no keys returned ie. no trusted domain,
-        * return "no more entries" code
-        */
-       status = NT_STATUS_NO_MORE_ENTRIES;
-
-       /* searching for keys in secrets db -- way to go ... */
-       for (k = keys; k; k = k->next) {
-               char *secrets_key;
-               
-               /* important: ensure null-termination of the key string */
-               secrets_key = strndup(k->node_key.dptr, k->node_key.dsize);
-               if (!secrets_key) {
-                       DEBUG(0, ("strndup failed!\n"));
-                       return NT_STATUS_NO_MEMORY;
-               }
+       /* unpack unicode domain name and plaintext password */
+       len += tdb_unpack(tdb, vbuf.dptr, vbuf.dsize - len, "d", &pass.uni_name_len);
+       
+       for (idx = 0; idx < 32; idx++)
+               len +=  tdb_unpack(tdb, vbuf.dptr + len, vbuf.dsize - len, "w", &pass.uni_name[idx]);
 
-               packed_pass = secrets_fetch(tdb, secrets_key, &size);
-               packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size, pass);
-               /* packed representation isn't needed anymore */
-               SAFE_FREE(packed_pass);
-               
-               if (size != packed_size) {
-                       DEBUG(2, ("Secrets record %s is invalid!\n", secrets_key));
-                       continue;
-               }
-               
-               pull_ucs2_fstring(dom_name, pass->uni_name);
-               DEBUG(18, ("Fetched secret record num %d.\nDomain name: %s, SID: %s\n",
-                          idx, dom_name, sid_string_static(&pass->domain_sid)));
-
-               SAFE_FREE(secrets_key);
-
-               if (idx >= start_idx && idx < start_idx + max_num_domains) {
-                       dom = talloc(ctx, struct samba3_trustdom);
-                       if (!dom) {
-                               /* free returned tdb record */
-                               return NT_STATUS_NO_MEMORY;
-                       }
-                       
-                       /* copy domain sid */
-                       SMB_ASSERT(sizeof(dom->sid) == sizeof(pass->domain_sid));
-                       memcpy(&(dom->sid), &(pass->domain_sid), sizeof(dom->sid));
-                       
-                       /* copy unicode domain name */
-                       dom->name = talloc_memdup(ctx, pass->uni_name,
-                                                 (strlen_w(pass->uni_name) + 1) * sizeof(smb_ucs2_t));
-                       
-                       (*domains)[idx - start_idx] = dom;
-                       
-                       DEBUG(18, ("Secret record is in required range.\n \
-                                  start_idx = %d, max_num_domains = %d. Added to returned array.\n",
-                                  start_idx, max_num_domains));
-
-                       *enum_ctx = idx + 1;
-                       (*num_domains)++;
-               
-                       /* set proper status code to return */
-                       if (k->next) {
-                               /* there are yet some entries to enumerate */
-                               status = STATUS_MORE_ENTRIES;
-                       } else {
-                               /* this is the last entry in the whole enumeration */
-                               status = NT_STATUS_OK;
-                       }
-               } else {
-                       DEBUG(18, ("Secret is outside the required range.\n \
-                                  start_idx = %d, max_num_domains = %d. Not added to returned array\n",
-                                  start_idx, max_num_domains));
-               }
-               
-               idx++;          
-       }
+       len += tdb_unpack(tdb, vbuf.dptr + len, vbuf.dsize - len, "d", &pass_len);
+       pass.pass = talloc_strdup(ctx, vbuf.dptr+len);
+       len += strlen(vbuf.dptr)+1;
+       len += tdb_unpack(tdb, vbuf.dptr + len, vbuf.dsize - len, "d", &pass.mod_time);
        
-       DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n", *num_domains));
+       pass.domain_sid.sub_auths = talloc_array(ctx, uint32_t, 15);
+       /* unpack domain sid */
+       len += tdb_sid_unpack(tdb, vbuf.dptr + len, vbuf.dsize - len, &pass.domain_sid);
 
-       /* free the results of searching the keys */
-       tdb_search_list_free(keys);
+       /* FIXME: Add to list */
 
-       return status;
+       return NT_STATUS_OK;
 }
 
-/*******************************************************************************
- Fetch the current (highest) AFS key from secrets.tdb
-*******************************************************************************/
-static BOOL secrets_fetch_afs_key(TDB_CONTEXT *tdb, const char *cell, struct afs_key *result)
-{
-       fstring key;
-       struct afs_keyfile *keyfile;
-       size_t size;
-       uint32_t i;
-
-       slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_AFS_KEYFILE, cell);
+static const struct {
+       const char *prefix;
+       NTSTATUS (*handler) (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db);
+} secrets_handlers[] = {
+       { "SECRETS/AUTH_PASSWORD", ipc_password },
+       { "SECRETS/AUTH_DOMAIN", ipc_domain },
+       { "SECRETS/AUTH_USER", ipc_username },
+       { "SECRETS/SID/", domain_sid },
+       { "SECRETS/DOMGUID/", domain_guid },
+       { "SECRETS/LDAP_BIND_PW/", ldap_bind_pw },
+       { "SECRETS/AFS_KEYFILE/", afs_keyfile },
+       { "SECRETS/MACHINE_SEC_CHANNEL_TYPE/", machine_sec_channel_type },
+       { "SECRETS/MACHINE_LAST_CHANGE_TIME/", machine_last_change_time },
+       { "SECRETS/MACHINE_PASSWORD/", machine_password },
+       { "SECRETS/$MACHINE.ACC/", machine_acc },
+       { "SECRETS/$DOMTRUST.ACC/", domtrust_acc },
+};
 
-       keyfile = (struct afs_keyfile *)secrets_fetch(tdb, key, &size);
 
-       if (keyfile == NULL)
-               return False;
+NTSTATUS samba3_read_secrets(const char *fname, TALLOC_CTX *ctx, struct samba3_secrets *db)
+{
+       TDB_CONTEXT *tdb = tdb_open(fname, 0, TDB_DEFAULT, O_RDONLY, 0600);
+       TDB_DATA kbuf, vbuf;
 
-       if (size != sizeof(struct afs_keyfile)) {
-               SAFE_FREE(keyfile);
-               return False;
+       if (!tdb) {
+               DEBUG(0,("Failed to open %s\n", fname));
+               return NT_STATUS_UNSUCCESSFUL;
        }
 
-       i = ntohl(keyfile->nkeys);
+       ZERO_STRUCTP(db);
+       
+       db->ipc_cred = cli_credentials_init(ctx);
+       
+       for (kbuf = tdb_firstkey(tdb); kbuf.dptr; kbuf = tdb_nextkey(tdb, kbuf))
+       {
+               int i;
+               char *key;
+               vbuf = tdb_fetch(tdb, kbuf);
+
+               for (i = 0; secrets_handlers[i].prefix; i++) {
+                       if (!strncmp(kbuf.dptr, secrets_handlers[i].prefix, strlen(secrets_handlers[i].prefix))) {
+                               key = talloc_strndup(ctx, kbuf.dptr+strlen(secrets_handlers[i].prefix), kbuf.dsize-strlen(secrets_handlers[i].prefix));
+                               secrets_handlers[i].handler(tdb, key, vbuf, ctx, db);
+                               talloc_free(key);
+                               break;
+                       }
+               }
 
-       if (i > SECRETS_AFS_MAXKEYS) {
-               SAFE_FREE(keyfile);
-               return False;
+               if (!secrets_handlers[i].prefix) {
+                       DEBUG(0, ("Unable to find handler for string %s", kbuf.dptr));
+               }
        }
-
-       *result = keyfile->entry[i-1];
-
-       result->kvno = ntohl(result->kvno);
-
-       return True;
-}
-
-/******************************************************************************
-  When kerberos is not available, choose between anonymous or
-  authenticated connections.  
-
-  We need to use an authenticated connection if DCs have the
-  RestrictAnonymous registry entry set > 0, or the "Additional
-  restrictions for anonymous connections" set in the win2k Local
-  Security Policy.
-
-  Caller to free() result in domain, username, password
-*******************************************************************************/
-static void secrets_fetch_ipc_userpass(TDB_CONTEXT *tdb, char **username, char **domain, char **password)
-{
-       *username = secrets_fetch(tdb, SECRETS_AUTH_USER, NULL);
-       *domain = secrets_fetch(tdb, SECRETS_AUTH_DOMAIN, NULL);
-       *password = secrets_fetch(tdb, SECRETS_AUTH_PASSWORD, NULL);
        
-       if (*username && **username) {
-
-               if (!*domain || !**domain)
-                       *domain = smb_xstrdup(lp_workgroup());
-               
-               if (!*password || !**password)
-                       *password = smb_xstrdup("");
-
-               DEBUG(3, ("IPC$ connections done by user %s\\%s\n", 
-                         *domain, *username));
-
-       } else {
-               DEBUG(3, ("IPC$ connections done anonymously\n"));
-               *username = smb_xstrdup("");
-               *domain = smb_xstrdup("");
-               *password = smb_xstrdup("");
-       }
-}
-
+       tdb_close(tdb);
 
+       return NT_STATUS_OK;
+}