From e583dd6278fedf9ad45b551dccf94fbe6c785119 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Fri, 14 Mar 2003 17:12:40 +0000 Subject: Fresh meat in trusted domains code: - packing/unpacking utility functions for trusted domain password struct; can be used to prepare buffer to store in secrets.tdb or (soon) passdb backend - similiar functions for DOM_SID - respectively modified secrets_(fetch|store) routines - new auth mapping code utilising introduced is_trusted_domain function - added tdb (un)packing of single bytes Rafal (This used to be commit 5281ee7e84421b9be746aed2f1718ceaf2a2fe3d) --- source3/auth/auth_util.c | 26 ++------ source3/include/secrets.h | 4 +- source3/passdb/secrets.c | 77 ++++++++++++++--------- source3/tdb/tdbutil.c | 153 +++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 201 insertions(+), 59 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 7d85153bd0..a6ad2b883b 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -227,27 +227,13 @@ NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, domain = client_domain; - if ((smb_name) && (*smb_name)) { /* Don't do this for guests */ - char *user = NULL; - if (asprintf(&user, "%s%s%s", - client_domain, lp_winbind_separator(), - smb_name) < 0) { - DEBUG(0, ("make_user_info_map: asprintf() failed!\n")); - return NT_STATUS_NO_MEMORY; - } - - DEBUG(5, ("make_user_info_map: testing for user %s\n", user)); - - if (Get_Pwnam(user) == NULL) { - DEBUG(5, ("make_user_info_map: test for user %s failed\n", user)); - domain = lp_workgroup(); - DEBUG(5, ("make_user_info_map: trusted domain %s doesn't appear to exist, using %s\n", - client_domain, domain)); - } else { - DEBUG(5, ("make_user_info_map: using trusted domain %s\n", domain)); - } - SAFE_FREE(user); + if (is_trusted_domain(domain)) { + return make_user_info(user_info, smb_name, internal_username, + client_domain, domain, wksta_name, + lm_pwd, nt_pwd, plaintext, ntlmssp_flags, + encrypted); } + } else { domain = lp_workgroup(); } diff --git a/source3/include/secrets.h b/source3/include/secrets.h index 183b29d7a8..07faf28d43 100644 --- a/source3/include/secrets.h +++ b/source3/include/secrets.h @@ -57,14 +57,14 @@ struct machine_acct_pass { /* * storage structure for trusted domain */ -struct trusted_dom_pass { +typedef struct trusted_dom_pass { size_t uni_name_len; smb_ucs2_t uni_name[32]; /* unicode domain name */ size_t pass_len; fstring pass; /* trust relationship's password */ time_t mod_time; DOM_SID domain_sid; /* remote domain's sid */ -}; +} TRUSTED_DOM_PASS; /* * trusted domain entry/entries returned by secrets_get_trusted_domains diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index 2b944a9941..4b0913a624 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -265,38 +265,44 @@ BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16], ************************************************************************/ BOOL secrets_fetch_trusted_domain_password(const char *domain, char** pwd, - DOM_SID *sid, time_t *pass_last_set_time) + DOM_SID *sid, time_t *pass_last_set_time) { - struct trusted_dom_pass *pass; + struct trusted_dom_pass pass; size_t size; + + /* unpacking structures */ + char* pass_buf; + int pass_len = 0; + + ZERO_STRUCT(pass); /* fetching trusted domain password structure */ - if (!(pass = secrets_fetch(trustdom_keystr(domain), &size))) { + if (!(pass_buf = secrets_fetch(trustdom_keystr(domain), &size))) { DEBUG(5, ("secrets_fetch failed!\n")); return False; } - if (size != sizeof(*pass)) { - DEBUG(0, ("secrets were of incorrect size!\n")); + /* unpack trusted domain password */ + pass_len = tdb_trusted_dom_pass_unpack(pass_buf, size, &pass); + if (pass_len != size) { + 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); + *pwd = strdup(pass.pass); if (!*pwd) { return False; } } /* last change time */ - if (pass_last_set_time) *pass_last_set_time = pass->mod_time; + if (pass_last_set_time) *pass_last_set_time = pass.mod_time; /* domain sid */ - memcpy(&sid, &(pass->domain_sid), sizeof(sid)); - - SAFE_FREE(pass); - + sid_copy(sid, &pass.domain_sid); + return True; } @@ -315,7 +321,7 @@ BOOL secrets_store_trust_account_password(const char *domain, uint8 new_pwd[16]) } /** - * Routine to set the password for trusted domain + * Routine to store the password for trusted domain * * @param domain remote domain name * @param pwd plain text password of trust relationship @@ -325,12 +331,17 @@ BOOL secrets_store_trust_account_password(const char *domain, uint8 new_pwd[16]) **/ BOOL secrets_store_trusted_domain_password(const char* domain, smb_ucs2_t *uni_dom_name, - size_t uni_name_len, const char* pwd, - DOM_SID sid) -{ + size_t uni_name_len, const char* pwd, + DOM_SID sid) +{ + /* packing structures */ + pstring pass_buf; + int pass_len = 0; + int pass_buf_len = sizeof(pass_buf); + struct trusted_dom_pass pass; ZERO_STRUCT(pass); - + /* unicode domain name and its length */ if (!uni_dom_name) return False; @@ -346,9 +357,11 @@ BOOL secrets_store_trusted_domain_password(const char* domain, smb_ucs2_t *uni_d fstrcpy(pass.pass, pwd); /* domain sid */ - memcpy(&(pass.domain_sid), &sid, sizeof(sid)); + sid_copy(&pass.domain_sid, &sid); + + pass_len = tdb_trusted_dom_pass_pack(pass_buf, pass_buf_len, &pass); - return secrets_store(trustdom_keystr(domain), (void *)&pass, sizeof(pass)); + return secrets_store(trustdom_keystr(domain), (void *)&pass_buf, pass_len); } /************************************************************************ @@ -475,9 +488,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned in char *pattern; unsigned int start_idx; uint32 idx = 0; - size_t size; + size_t size, packed_size = 0; fstring dom_name; - struct trusted_dom_pass *pass; + char *packed_pass; + struct trusted_dom_pass *pass = talloc_zero(ctx, sizeof(struct trusted_dom_pass)); NTSTATUS status; if (!secrets_init()) return NT_STATUS_ACCESS_DENIED; @@ -505,7 +519,7 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned in */ status = NT_STATUS_NO_MORE_ENTRIES; - /* searching for keys in sectrets db -- way to go ... */ + /* searching for keys in secrets db -- way to go ... */ for (k = keys; k; k = k->next) { char *secrets_key; @@ -516,14 +530,20 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned in return NT_STATUS_NO_MEMORY; } - pass = secrets_fetch(secrets_key, &size); - - if (size != sizeof(*pass)) { + packed_pass = secrets_fetch(secrets_key, &size); + packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size, pass); + + if (size != packed_size) { DEBUG(2, ("Secrets record %s is invalid!\n", secrets_key)); SAFE_FREE(pass); - continue; + if (size) SAFE_FREE(packed_pass); + + return NT_STATUS_UNSUCCESSFUL; } + /* packed representation isn't needed anymore */ + SAFE_FREE(packed_pass); + 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))); @@ -569,10 +589,7 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned in start_idx, max_num_domains)); } - idx++; - - /* free returned tdb record */ - SAFE_FREE(pass); + idx++; } DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n", *num_domains)); diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c index 0d8f6128cc..b153d442bd 100644 --- a/source3/tdb/tdbutil.c +++ b/source3/tdb/tdbutil.c @@ -42,7 +42,7 @@ static void gotalarm_sig(void) static TDB_DATA make_tdb_data(const char *dptr, size_t dsize) { TDB_DATA ret; - ret.dptr = dptr; + ret.dptr = smb_xstrdup(dptr); ret.dsize = dsize; return ret; } @@ -387,6 +387,7 @@ BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, const char *keystr, uint32 *oldv size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...) { va_list ap; + uint8 bt; uint16 w; uint32 d; int i; @@ -402,40 +403,46 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...) while (*fmt) { switch ((c = *fmt++)) { - case 'w': + case 'b': /* unsigned 8-bit integer */ + len = 1; + bt = (uint8)va_arg(ap, int); + if (bufsize >= len) + SSVAL(buf, 0, bt); + break; + case 'w': /* unsigned 16-bit integer */ len = 2; w = (uint16)va_arg(ap, int); if (bufsize >= len) SSVAL(buf, 0, w); break; - case 'd': + case 'd': /* signed 32-bit integer (standard int in most systems) */ len = 4; d = va_arg(ap, uint32); if (bufsize >= len) SIVAL(buf, 0, d); break; - case 'p': + case 'p': /* pointer */ len = 4; p = va_arg(ap, void *); d = p?1:0; if (bufsize >= len) SIVAL(buf, 0, d); break; - case 'P': + case 'P': /* null-terminated string */ s = va_arg(ap,char *); w = strlen(s); len = w + 1; if (bufsize >= len) memcpy(buf, s, len); break; - case 'f': + case 'f': /* null-terminated string */ s = va_arg(ap,char *); w = strlen(s); len = w + 1; if (bufsize >= len) memcpy(buf, s, len); break; - case 'B': + case 'B': /* fixed-length string */ i = va_arg(ap, int); s = va_arg(ap, char *); len = 4+i; @@ -471,6 +478,7 @@ size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...) int tdb_unpack(char *buf, int bufsize, const char *fmt, ...) { va_list ap; + uint8 *bt; uint16 *w; uint32 *d; int len; @@ -486,6 +494,13 @@ int tdb_unpack(char *buf, int bufsize, const char *fmt, ...) while (*fmt) { switch ((c=*fmt++)) { + case 'b': + len = 1; + bt = va_arg(ap, uint8 *); + if (bufsize < len) + goto no_space; + *bt = SVAL(buf, 0); + break; case 'w': len = 2; w = va_arg(ap, uint16 *); @@ -563,6 +578,130 @@ int tdb_unpack(char *buf, int bufsize, const char *fmt, ...) return -1; } + +/** + * Pack SID passed by pointer + * + * @param pack_buf pointer to buffer which is to be filled with packed data + * @param bufsize size of packing buffer + * @param sid pointer to sid to be packed + * + * @return length of the packed representation of the whole structure + **/ +size_t tdb_sid_pack(char* pack_buf, int bufsize, DOM_SID* sid) +{ + int idx; + size_t len = 0; + + if (!sid || !pack_buf) return -1; + + len += tdb_pack(pack_buf + len, bufsize - len, "bb", sid->sid_rev_num, + sid->num_auths); + + for (idx = 0; idx < 6; idx++) { + len += tdb_pack(pack_buf + len, bufsize - len, "b", sid->id_auth[idx]); + } + + for (idx = 0; idx < MAXSUBAUTHS; idx++) { + len += tdb_pack(pack_buf + len, bufsize - len, "d", sid->sub_auths[idx]); + } + + return len; +} + + +/** + * 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 + **/ +size_t tdb_sid_unpack(char* pack_buf, int bufsize, DOM_SID* sid) +{ + int idx, len = 0; + + if (!sid || !pack_buf) return -1; + + len += tdb_unpack(pack_buf + len, bufsize - len, "bb", + &sid->sid_rev_num, &sid->num_auths); + + for (idx = 0; idx < 6; idx++) { + len += tdb_unpack(pack_buf + len, bufsize - len, "b", &sid->id_auth[idx]); + } + + for (idx = 0; idx < MAXSUBAUTHS; idx++) { + len += tdb_unpack(pack_buf + len, bufsize - len, "d", &sid->sub_auths[idx]); + } + + return len; +} + + +/** + * Pack TRUSTED_DOM_PASS passed by pointer + * + * @param pack_buf pointer to buffer which is to be filled with packed data + * @param bufsize size of the buffer + * @param pass pointer to trusted domain password to be packed + * + * @return length of the packed representation of the whole structure + **/ +size_t tdb_trusted_dom_pass_pack(char* pack_buf, int bufsize, TRUSTED_DOM_PASS* pass) +{ + int idx, len = 0; + + if (!pack_buf || !pass) return -1; + + /* packing unicode domain name and password */ + len += tdb_pack(pack_buf + len, bufsize - len, "d", pass->uni_name_len); + + for (idx = 0; idx < 32; idx++) + len += tdb_pack(pack_buf + len, bufsize - len, "w", pass->uni_name[idx]); + + len += tdb_pack(pack_buf + len, bufsize - len, "dPd", pass->pass_len, + pass->pass, pass->mod_time); + + /* packing SID structure */ + len += tdb_sid_pack(pack_buf + len, bufsize - len, &pass->domain_sid); + + 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 + **/ +size_t tdb_trusted_dom_pass_unpack(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(pack_buf, bufsize - len, "d", &pass->uni_name_len); + + for (idx = 0; idx < 32; idx++) + len += tdb_unpack(pack_buf + len, bufsize - len, "w", &pass->uni_name[idx]); + + len += tdb_unpack(pack_buf + len, bufsize - len, "dPd", &pass->pass_len, &pass->pass, + &pass->mod_time); + + /* unpack domain sid */ + len += tdb_sid_unpack(pack_buf + len, bufsize - len, &pass->domain_sid); + + return len; +} + + /**************************************************************************** Log tdb messages via DEBUG(). ****************************************************************************/ -- cgit