1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-28 01:58:17 +03:00

r9589: Support reading secrets tdb

(This used to be commit dd15131b5219ecf0d09329c0de37c426b9147f45)
This commit is contained in:
Jelmer Vernooij 2005-08-24 16:39:28 +00:00 committed by Gerald (Jerry) Carter
parent b873c1789f
commit cdf218e270
5 changed files with 227 additions and 508 deletions

View File

@ -278,4 +278,5 @@ struct samba3_groupdb;
struct samba3_winsdb_entry;
struct samba3_policy;
struct samba3_regdb;
struct samba3_secrets;
struct samba3;

View 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
################################################

View 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;
}

View 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;

View File

@ -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);
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++;
/* unpack domain sid */
len += tdb_sid_unpack(tdb, pack_buf + len, bufsize - len, &pass->domain_sid);
return len;
return &db->domains[db->domain_count-1];
}
static NTSTATUS ipc_password (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
{
cli_credentials_set_password(db->ipc_cred, vbuf.dptr, CRED_SPECIFIED);
return NT_STATUS_OK;
}
static TDB_CONTEXT *secrets_open(const char *fname)
static NTSTATUS ipc_username (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
{
cli_credentials_set_username(db->ipc_cred, vbuf.dptr, CRED_SPECIFIED);
return NT_STATUS_OK;
}
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 NTSTATUS domain_sid (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);
domainsec->sid.sub_auths = talloc_array(ctx, uint32_t, 15);
tdb_sid_unpack(tdb, vbuf.dptr, vbuf.dsize, &domainsec->sid);
return NT_STATUS_OK;
}
static NTSTATUS domain_guid (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);
memcpy(&domainsec->guid, vbuf.dptr, vbuf.dsize);
return NT_STATUS_OK;
}
static NTSTATUS ldap_bind_pw (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
{
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;
}
static NTSTATUS afs_keyfile (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
{
struct samba3_afs_keyfile keyfile;
memcpy(&keyfile, vbuf.dptr, vbuf.dsize);
keyfile.cell = talloc_strdup(ctx, key);
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;
}
static NTSTATUS machine_sec_channel_type (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);
domainsec->sec_channel_type = IVAL(vbuf.dptr, 0);
return NT_STATUS_OK;
}
static NTSTATUS machine_last_change_time (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);
domainsec->last_change_time = IVAL(vbuf.dptr, 0);
return NT_STATUS_OK;
}
static NTSTATUS machine_password (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);
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);
memcpy(&domainsec->hash_pw, vbuf.dptr, vbuf.dsize);
return NT_STATUS_OK;
}
static NTSTATUS domtrust_acc (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
{
int idx, len = 0;
struct samba3_trusted_dom_pass pass;
int pass_len;
if (!vbuf.dptr)
return NT_STATUS_UNSUCCESSFUL;
/* 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]);
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);
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);
/* FIXME: Add to list */
return NT_STATUS_OK;
}
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 },
};
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 (!tdb) {
DEBUG(0,("Failed to open %s\n", fname));
return NULL;
return NT_STATUS_UNSUCCESSFUL;
}
return tdb;
}
static BOOL secrets_fetch_domain_sid(TDB_CONTEXT *tdb, const char *domain, struct dom_sid *sid)
{
struct dom_sid *dyn_sid;
TDB_DATA val;
char *key;
size_t size;
asprintf(&key, "%s/%s", SECRETS_DOMAIN_SID, domain);
strupper_m(key);
ZERO_STRUCTP(db);
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 BOOL secrets_fetch_domain_guid(TDB_CONTEXT *tdb, const char *domain, struct GUID *guid)
{
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;
}
/**
* 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)
{
char *keystr;
asprintf(&keystr, "%s/%s", SECRETS_MACHINE_ACCT_PASS, domain);
strupper_m(keystr);
return keystr;
}
/**
* 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)
{
char *keystr;
asprintf(&keystr, "%s/%s", SECRETS_DOMTRUST_ACCT_PASS, domain);
strupper_m(keystr);
return keystr;
}
/************************************************************************
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)
{
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;
}
db->ipc_cred = cli_credentials_init(ctx);
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;
}
for (kbuf = tdb_firstkey(tdb); kbuf.dptr; kbuf = tdb_nextkey(tdb, kbuf))
{
int i;
char *key;
vbuf = tdb_fetch(tdb, kbuf);
pass = (struct machine_acct_pass *)val.dptr;
if (pass_last_set_time) *pass_last_set_time = pass->mod_time;
memcpy(ret_pwd, pass->hash, 16);
return True;
}
/************************************************************************
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)
{
struct trusted_dom_pass pass;
/* unpacking structures */
int pass_len = 0;
TDB_DATA val;
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;
}
/************************************************************************
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)
{
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;
}
/*******************************************************************
find the ldap password
******************************************************************/
static BOOL fetch_ldap_pw(TDB_CONTEXT *tdb, const char *dn, char** pw)
{
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;
}
/**
* 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
**/
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)
{
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;
}
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;
}
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;
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;
}
/* 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++;
if (!secrets_handlers[i].prefix) {
DEBUG(0, ("Unable to find handler for string %s", kbuf.dptr));
}
}
DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n", *num_domains));
tdb_close(tdb);
/* free the results of searching the keys */
tdb_search_list_free(keys);
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);
keyfile = (struct afs_keyfile *)secrets_fetch(tdb, key, &size);
if (keyfile == NULL)
return False;
if (size != sizeof(struct afs_keyfile)) {
SAFE_FREE(keyfile);
return False;
}
i = ntohl(keyfile->nkeys);
if (i > SECRETS_AFS_MAXKEYS) {
SAFE_FREE(keyfile);
return False;
}
*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("");
}
}