diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/include/structs.h | 1 | ||||
-rw-r--r-- | source4/lib/samba3/config.mk | 4 | ||||
-rw-r--r-- | source4/lib/samba3/samba3.c | 4 | ||||
-rw-r--r-- | source4/lib/samba3/samba3.h | 48 | ||||
-rw-r--r-- | source4/lib/samba3/secrets.c | 614 |
5 files changed, 195 insertions, 476 deletions
diff --git a/source4/include/structs.h b/source4/include/structs.h index 6d060fb22f..cac46c030f 100644 --- a/source4/include/structs.h +++ b/source4/include/structs.h @@ -278,4 +278,5 @@ struct samba3_groupdb; struct samba3_winsdb_entry; struct samba3_policy; struct samba3_regdb; +struct samba3_secrets; struct samba3; diff --git a/source4/lib/samba3/config.mk b/source4/lib/samba3/config.mk index 23f07106f0..75073048d0 100644 --- a/source4/lib/samba3/config.mk +++ b/source4/lib/samba3/config.mk @@ -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 ################################################ diff --git a/source4/lib/samba3/samba3.c b/source4/lib/samba3/samba3.c index c74b1b5279..bfd41d6554 100644 --- a/source4/lib/samba3/samba3.c +++ b/source4/lib/samba3/samba3.c @@ -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; } diff --git a/source4/lib/samba3/samba3.h b/source4/lib/samba3/samba3.h index bebd120704..575ee83825 100644 --- a/source4/lib/samba3/samba3.h +++ b/source4/lib/samba3/samba3.h @@ -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; diff --git a/source4/lib/samba3/secrets.c b/source4/lib/samba3/secrets.c index ab19f166ee..4aacffda34 100644 --- a/source4/lib/samba3/secrets.c +++ b/source4/lib/samba3/secrets.c @@ -24,52 +24,13 @@ /* 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; +} |