summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2014-08-15 15:01:31 +1200
committerAndrew Bartlett <abartlet@samba.org>2014-09-01 00:36:42 +0200
commit735615293b24d19ef279cff1970bd65999bb9de7 (patch)
tree7ebdc5806ee479c94a7cd730bed6ded842ba5eae /source3/passdb
parent80be6993c9d21c91ce8b3d9941b93a7f1c6ba579 (diff)
downloadsamba-735615293b24d19ef279cff1970bd65999bb9de7.tar.gz
passdb: Use sam_get_results_trust() and implement pdb_samba_dsdb_get_trusteddom_pw
We now return the plaintext passwords for trusted domains so winbindd can use them. Change-Id: Ifcd59b0be815d25b73bdbc41db7477895461c7b6 Pair-programmed-with: Garming Sam <garming@catalyst.net.nz> Signed-off-by: Garming Sam <garming@catalyst.net.nz> Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org> Reviewed-By: Jelmer Vernooij <jelmer@samba.org>
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/pdb_samba_dsdb.c125
1 files changed, 124 insertions, 1 deletions
diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c
index 7d7bd8d6173..465cc24dfd1 100644
--- a/source3/passdb/pdb_samba_dsdb.c
+++ b/source3/passdb/pdb_samba_dsdb.c
@@ -28,6 +28,8 @@
#include "libcli/security/dom_sid.h"
#include "source4/winbind/idmap.h"
#include "librpc/gen_ndr/ndr_security.h"
+#include "librpc/gen_ndr/ndr_drsblobs.h"
+#include "librpc/gen_ndr/ndr_lsa.h"
#include "libds/common/flag_mapping.h"
#include "source4/lib/events/events.h"
#include "source4/auth/session.h"
@@ -35,6 +37,7 @@
#include "lib/param/param.h"
#include "source4/dsdb/common/util.h"
#include "source3/include/secrets.h"
+#include "source4/auth/auth_sam.h"
struct pdb_samba_dsdb_state {
struct tevent_context *ev;
@@ -2140,7 +2143,127 @@ static bool pdb_samba_dsdb_get_trusteddom_pw(struct pdb_methods *m,
struct dom_sid *sid,
time_t *pass_last_set_time)
{
- return false;
+ struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
+ m->private_data, struct pdb_samba_dsdb_state);
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+ const char * const attrs[] = {
+ "securityIdentifier",
+ "trustPartner",
+ "trustAuthOutgoing",
+ "whenCreated",
+ "msDS-SupportedEncryptionTypes",
+ "trustAttributes",
+ "trustDirection",
+ "trustType",
+ NULL
+ };
+ struct ldb_message *msg;
+ const struct ldb_val *password_val;
+ int trust_direction_flags;
+ int trust_type;
+ int i;
+ DATA_BLOB password_utf16;
+ struct trustAuthInOutBlob password_blob;
+ struct AuthenticationInformationArray *auth_array;
+ char *password_talloc;
+ size_t password_len;
+ enum ndr_err_code ndr_err;
+ NTSTATUS status;
+
+ status = sam_get_results_trust(state->ldb, tmp_ctx, domain,
+ NULL, attrs, &msg);
+ if (!NT_STATUS_IS_OK(status)) {
+ /*
+ * This can be called to work out of a domain is
+ * trusted, rather than just to get the password
+ */
+ DEBUG(2, ("Failed to get trusted domain password for %s. "
+ "It may not be a trusted domain.\n", domain));
+ TALLOC_FREE(tmp_ctx);
+ return false;
+ }
+
+ trust_direction_flags = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
+ if (!(trust_direction_flags & LSA_TRUST_DIRECTION_OUTBOUND)) {
+ DEBUG(2, ("Trusted domain %s is is not an outbound trust.\n",
+ domain));
+ TALLOC_FREE(tmp_ctx);
+ return false;
+ }
+
+ trust_type = ldb_msg_find_attr_as_int(msg, "trustType", 0);
+ if (trust_type == LSA_TRUST_TYPE_MIT) {
+ DEBUG(1, ("Trusted domain %s is is not an AD trust "
+ "(trustType == LSA_TRUST_TYPE_MIT).\n",
+ domain));
+ TALLOC_FREE(tmp_ctx);
+ return false;
+ }
+
+ password_val = ldb_msg_find_ldb_val(msg, "trustAuthOutgoing");
+ if (password_val == NULL) {
+ DEBUG(2, ("Failed to get trusted domain password for %s, "
+ "attribute trustAuthOutgoing not returned.\n", domain));
+ TALLOC_FREE(tmp_ctx);
+ return false;
+ }
+
+ ndr_err = ndr_pull_struct_blob(password_val, tmp_ctx, &password_blob,
+ (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0, ("Failed to get trusted domain password for %s, "
+ "attribute trustAuthOutgoing coult not be parsed %s.\n",
+ domain,
+ ndr_map_error2string(ndr_err)));
+ TALLOC_FREE(tmp_ctx);
+ return false;
+ }
+
+ auth_array = &password_blob.current;
+
+ for (i=0; i < auth_array->count; i++) {
+ if (auth_array->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) {
+ break;
+ }
+ }
+
+ if (i == auth_array->count) {
+ DEBUG(0, ("Trusted domain %s does not have a "
+ "clear-text password stored\n",
+ domain));
+ TALLOC_FREE(tmp_ctx);
+ return false;
+ }
+
+ password_utf16 = data_blob_const(auth_array->array[i].AuthInfo.clear.password,
+ auth_array->array[i].AuthInfo.clear.size);
+
+ /*
+ * In the future, make this function return a
+ * cli_credentials that can store a MD4 hash with cli_credential_set_nt_hash()
+ * but for now convert to UTF8 and fail if the string can not be converted.
+ *
+ * We can't safely convert the random strings windows uses into
+ * utf8.
+ */
+ if (!convert_string_talloc(tmp_ctx,
+ CH_UTF16, CH_UTF8,
+ password_utf16.data, password_utf16.length,
+ (void *)&password_talloc,
+ &password_len)) {
+ DEBUG(0, ("FIXME: Could not convert password for trusted domain %s"
+ " to UTF8. This may be a password set from Windows.\n",
+ domain));
+ TALLOC_FREE(tmp_ctx);
+ return false;
+ }
+ *pwd = SMB_STRNDUP(password_talloc, password_len);
+ if (pass_last_set_time) {
+ *pass_last_set_time = nt_time_to_unix(auth_array->array[i].LastUpdateTime);
+ }
+
+ TALLOC_FREE(tmp_ctx);
+ return true;
}
static bool pdb_samba_dsdb_set_trusteddom_pw(struct pdb_methods *m,