mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
8528016978
try to include just the BASENAME.h files (containing only structs)
(This used to be commit 3dd477ca51
)
265 lines
8.9 KiB
C
265 lines
8.9 KiB
C
/*
|
|
Unix SMB/CIFS implementation.
|
|
Copyright (C) Andrew Tridgell 1992-2001
|
|
Copyright (C) Andrew Bartlett 2002
|
|
Copyright (C) Rafal Szczesniak 2002
|
|
Copyright (C) Tim Potter 2001
|
|
Copyright (C) Jelmer Vernooij 2005
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
/* the Samba secrets database stores any generated, private information
|
|
such as the local SID and machine trust password */
|
|
|
|
#include "includes.h"
|
|
#include "lib/tdb/include/tdb.h"
|
|
#include "lib/samba3/samba3.h"
|
|
#include "system/filesys.h"
|
|
#include "librpc/gen_ndr/security.h"
|
|
#include "lib/tdb/include/tdbutil.h"
|
|
#include "auth/credentials/credentials.h"
|
|
|
|
/**
|
|
* Unpack SID into a pointer
|
|
*
|
|
* @param pack_buf pointer to buffer with packed representation
|
|
* @param bufsize size of the buffer
|
|
* @param sid pointer to sid structure to be filled with unpacked data
|
|
*
|
|
* @return size of structure unpacked from buffer
|
|
**/
|
|
static size_t tdb_sid_unpack(TDB_CONTEXT *tdb, char* pack_buf, int bufsize, struct dom_sid* sid)
|
|
{
|
|
int idx, len = 0;
|
|
|
|
if (!sid || !pack_buf) return -1;
|
|
|
|
len += tdb_unpack(tdb, pack_buf + len, bufsize - len, "bb",
|
|
&sid->sid_rev_num, &sid->num_auths);
|
|
|
|
for (idx = 0; idx < 6; idx++) {
|
|
len += tdb_unpack(tdb, pack_buf + len, bufsize - len, "b", &sid->id_auth[idx]);
|
|
}
|
|
|
|
for (idx = 0; idx < 15; idx++) {
|
|
len += tdb_unpack(tdb, pack_buf + len, bufsize - len, "d", &sid->sub_auths[idx]);
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
static struct samba3_domainsecrets *secrets_find_domain(TALLOC_CTX *ctx, struct samba3_secrets *db, const char *key)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < db->domain_count; i++)
|
|
{
|
|
if (!strcasecmp_m(db->domains[i].name, key))
|
|
return &db->domains[i];
|
|
}
|
|
|
|
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(db->domains, key);
|
|
|
|
db->domain_count++;
|
|
|
|
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, (const char *)vbuf.dptr, CRED_SPECIFIED);
|
|
return NT_STATUS_OK;
|
|
}
|
|
|
|
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, (const char *)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, (const char *)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, (char *)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, (const char *)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, (const char *)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 random_seed (TDB_CONTEXT *tdb, const char *key, TDB_DATA vbuf, TALLOC_CTX *ctx, struct samba3_secrets *db)
|
|
{
|
|
/* Ignore */
|
|
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, (char *)vbuf.dptr, vbuf.dsize - len, "d", &pass.uni_name_len);
|
|
|
|
for (idx = 0; idx < 32; idx++)
|
|
len += tdb_unpack(tdb, (char *)(vbuf.dptr + len), vbuf.dsize - len, "w", &pass.uni_name[idx]);
|
|
|
|
len += tdb_unpack(tdb, (char *)(vbuf.dptr + len), vbuf.dsize - len, "d", &pass_len);
|
|
pass.pass = talloc_strdup(ctx, (char *)(vbuf.dptr+len));
|
|
len += strlen((const char *)vbuf.dptr)+1;
|
|
len += tdb_unpack(tdb, (char *)(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, (char *)(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 },
|
|
{ "INFO/random_seed", random_seed },
|
|
};
|
|
|
|
|
|
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 NT_STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
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((const char *)kbuf.dptr, secrets_handlers[i].prefix, strlen(secrets_handlers[i].prefix))) {
|
|
key = talloc_strndup(ctx, (const char *)(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 (!secrets_handlers[i].prefix) {
|
|
DEBUG(0, ("Unable to find handler for string %s\n", kbuf.dptr));
|
|
}
|
|
}
|
|
|
|
tdb_close(tdb);
|
|
|
|
return NT_STATUS_OK;
|
|
}
|