summaryrefslogtreecommitdiff
path: root/source4/lib/samba3/secrets.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/samba3/secrets.c')
-rw-r--r--source4/lib/samba3/secrets.c160
1 files changed, 104 insertions, 56 deletions
diff --git a/source4/lib/samba3/secrets.c b/source4/lib/samba3/secrets.c
index ccd53c0398..ab19f166ee 100644
--- a/source4/lib/samba3/secrets.c
+++ b/source4/lib/samba3/secrets.c
@@ -42,6 +42,7 @@
#include "tdb.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 */
@@ -57,6 +58,78 @@ struct afs_key {
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
+ *
+ * @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;
+}
+
+/**
+ * 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)
+{
+ int idx, len = 0;
+
+ if (!pack_buf || !pass) return -1;
+
+ /* 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]);
+
+ 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);
+
+ return len;
+}
+
+
static TDB_CONTEXT *secrets_open(const char *fname)
{
TDB_CONTEXT *tdb = tdb_open(fname, 0, TDB_DEFAULT, O_RDONLY, 0600);
@@ -69,31 +142,18 @@ static TDB_CONTEXT *secrets_open(const char *fname)
return tdb;
}
-/* 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(TDB_CONTEXT *tdb, const char *key, size_t *size)
-{
- TDB_DATA kbuf, dbuf;
-
- kbuf.dptr = strdup(key);
- kbuf.dsize = strlen(key);
- dbuf = tdb_fetch(tdb, kbuf);
- if (size)
- *size = dbuf.dsize;
- free(kbuf.dptr);
- return dbuf.dptr;
-}
-
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);
- dyn_sid = (struct dom_sid *)secrets_fetch(tdb, key, &size);
+
+ val = tdb_fetch_bystring(tdb, key);
+ /* FIXME: Convert val to dyn_sid */
SAFE_FREE(key);
if (dyn_sid == NULL)
@@ -114,17 +174,20 @@ static BOOL secrets_fetch_domain_guid(TDB_CONTEXT *tdb, const char *domain, stru
{
struct GUID *dyn_guid;
char *key;
+ TDB_DATA val;
size_t size;
asprintf(&key, "%s/%s", SECRETS_DOMAIN_GUID, domain);
strupper_m(key);
- dyn_guid = (struct GUID *)secrets_fetch(tdb, key, &size);
+ val = tdb_fetch_bystring(tdb, key);
+
+ dyn_guid = (struct GUID *)val.dptr;
if (!dyn_guid) {
return False;
}
- if (size != sizeof(struct GUID))
+ if (val.dsize != sizeof(struct GUID))
{
DEBUG(1,("GUID size %d is wrong!\n", (int)size));
SAFE_FREE(dyn_guid);
@@ -183,7 +246,7 @@ static BOOL secrets_fetch_trust_account_password(TDB_CONTEXT *tdb,
{
struct machine_acct_pass *pass;
char *plaintext;
- size_t size;
+ TDB_DATA val;
plaintext = secrets_fetch_machine_password(tdb, domain, pass_last_set_time,
channel);
@@ -193,23 +256,22 @@ static BOOL secrets_fetch_trust_account_password(TDB_CONTEXT *tdb,
SAFE_FREE(plaintext);
return True;
}
-
- if (!(pass = secrets_fetch(tdb, trust_keystr(domain), &size))) {
- DEBUG(5, ("secrets_fetch failed!\n"));
+
+ val = tdb_fetch_bystring(tdb, trust_keystr(domain));
+ if (!val.dptr) {
+ DEBUG(5, ("tdb_fetch_bystring failed!\n"));
return False;
}
- if (size != sizeof(*pass)) {
+ if (val.dsize != sizeof(*pass)) {
DEBUG(0, ("secrets were of incorrect size!\n"));
return False;
}
+ 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);
- SAFE_FREE(pass);
-
- if (channel)
- *channel = get_default_sec_channel();
return True;
}
@@ -221,25 +283,24 @@ static BOOL secrets_fetch_trust_account_password(TDB_CONTEXT *tdb,
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;
- size_t size;
/* unpacking structures */
- char* pass_buf;
int pass_len = 0;
+ TDB_DATA val;
ZERO_STRUCT(pass);
/* fetching trusted domain password structure */
- if (!(pass_buf = secrets_fetch(tdb, trustdom_keystr(domain), &size))) {
+ 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(pass_buf, size, &pass);
- SAFE_FREE(pass_buf);
+ pass_len = tdb_trusted_dom_pass_unpack(val.dptr, val.dsize, &pass);
- if (pass_len != size) {
+ if (pass_len != val.dsize) {
DEBUG(5, ("Invalid secrets size. Unpacked data doesn't match trusted_dom_pass structure.\n"));
return False;
}
@@ -272,38 +333,23 @@ static char *secrets_fetch_machine_password(TDB_CONTEXT *tdb, const char *domain
{
char *key = NULL;
char *ret;
+ TDB_DATA val;
asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
strupper_m(key);
- ret = (char *)secrets_fetch(tdb, key, NULL);
+ val = tdb_fetch_bystring(tdb, key);
SAFE_FREE(key);
if (pass_last_set_time) {
- size_t size;
- uint32_t *last_set_time;
asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
strupper_m(key);
- last_set_time = secrets_fetch(tdb, key, &size);
- if (last_set_time) {
- *pass_last_set_time = IVAL(last_set_time,0);
- SAFE_FREE(last_set_time);
- } else {
- *pass_last_set_time = 0;
- }
+ tdb_fetch_uint32(tdb, key, (uint32_t *)pass_last_set_time);
SAFE_FREE(key);
}
if (channel) {
- size_t size;
- uint32_t *channel_type;
asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
strupper_m(key);
- channel_type = secrets_fetch(tdb, key, &size);
- if (channel_type) {
- *channel = IVAL(channel_type,0);
- SAFE_FREE(channel_type);
- } else {
- *channel = get_default_sec_channel();
- }
+ tdb_fetch_uint32(tdb, key, channel);
SAFE_FREE(key);
}
@@ -317,12 +363,14 @@ 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"));
}
- *pw=secrets_fetch(tdb, key, &size);
+ val = tdb_fetch_bystring(tdb, key);
+ *pw = val.dptr;
SAFE_FREE(key);
if (!size) {
@@ -363,8 +411,6 @@ static NTSTATUS secrets_get_trusted_domains(TDB_CONTEXT *tdb, TALLOC_CTX* ctx, i
struct trusted_dom_pass *pass = talloc(ctx, struct trusted_dom_pass);
NTSTATUS status;
- if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
-
if (!pass) {
DEBUG(0, ("talloc_zero failed!\n"));
return NT_STATUS_NO_MEMORY;
@@ -540,3 +586,5 @@ static void secrets_fetch_ipc_userpass(TDB_CONTEXT *tdb, char **username, char *
*password = smb_xstrdup("");
}
}
+
+