summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/ldb_modules/samba_dsdb.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/samba_dsdb.c b/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
index ee7f694c73..ac993db4d7 100644
--- a/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
+++ b/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
@@ -37,6 +37,9 @@
#include "dsdb/samdb/ldb_modules/util.h"
#include "dsdb/samdb/samdb.h"
#include "librpc/ndr/libndr.h"
+#include "auth/credentials/credentials.h"
+#include "param/secrets.h"
+#include "lib/ldb-samba/ldb_wrap.h"
static int read_at_rootdse_record(struct ldb_context *ldb, struct ldb_module *module, TALLOC_CTX *mem_ctx,
struct ldb_message **msg, struct ldb_request *parent)
@@ -129,7 +132,94 @@ static int prepare_modules_line(struct ldb_context *ldb,
return ret;
}
+/*
+ * Force overwrite of the credentials with those
+ * specified in secrets.ldb, to connect across the
+ * ldapi socket to an LDAP backend
+ */
+static int set_ldap_credentials(struct ldb_context *ldb)
+{
+ const char *secrets_ldb_path, *sam_ldb_path;
+ char *private_dir, *p, *error_string;
+ struct ldb_context *secrets_ldb;
+ struct cli_credentials *cred;
+ struct loadparm_context *lp_ctx = ldb_get_opaque(ldb, "loadparm");
+ TALLOC_CTX *tmp_ctx = talloc_new(ldb);
+
+ if (!tmp_ctx) {
+ return ldb_oom(ldb);
+ }
+
+ cred = cli_credentials_init(ldb);
+ if (!cred) {
+ talloc_free(tmp_ctx);
+ return ldb_oom(ldb);
+ }
+ cli_credentials_set_anonymous(cred);
+
+ /*
+ * We don't want to use krb5 to talk to our samdb - recursion
+ * here would be bad, and this account isn't in the KDC
+ * anyway
+ */
+ cli_credentials_set_kerberos_state(cred, CRED_DONT_USE_KERBEROS);
+
+ /*
+ * Work out where *our* secrets.ldb is. It must be in
+ * the same directory as sam.ldb
+ */
+ sam_ldb_path = (const char *)ldb_get_opaque(ldb, "ldb_url");
+ if (!sam_ldb_path) {
+ talloc_free(tmp_ctx);
+ return ldb_operr(ldb);
+ }
+ if (strncmp("tdb://", sam_ldb_path, 6) == 0) {
+ sam_ldb_path += 6;
+ }
+ private_dir = talloc_strdup(tmp_ctx, sam_ldb_path);
+ p = strrchr(private_dir, '/');
+ if (p) {
+ *p = '\0';
+ } else {
+ private_dir = talloc_strdup(tmp_ctx, ".");
+ }
+
+ secrets_ldb_path = talloc_asprintf(private_dir, "tdb://%s/secrets.ldb",
+ private_dir);
+
+ if (!secrets_ldb_path) {
+ talloc_free(tmp_ctx);
+ return ldb_oom(ldb);
+ }
+
+ /*
+ * Now that we have found the location, connect to
+ * secrets.ldb so we can read the SamDB Credentials
+ * record
+ */
+ secrets_ldb = ldb_wrap_connect(tmp_ctx, NULL, lp_ctx, secrets_ldb_path,
+ NULL, NULL, 0);
+
+ if (!NT_STATUS_IS_OK(cli_credentials_set_secrets(cred, NULL, secrets_ldb, NULL,
+ SECRETS_LDAP_FILTER, &error_string))) {
+ ldb_asprintf_errstring(ldb, "Failed to read LDAP backend password from %s", secrets_ldb_path);
+ talloc_free(tmp_ctx);
+ return LDB_ERR_STRONG_AUTH_REQUIRED;
+ }
+
+ /*
+ * Finally overwrite any supplied credentials with
+ * these ones, as only secrets.ldb contains the magic
+ * credentials to talk on the ldapi socket
+ */
+ if (ldb_set_opaque(ldb, "credentials", cred)) {
+ talloc_free(tmp_ctx);
+ return ldb_operr(ldb);
+ }
+ talloc_free(tmp_ctx);
+ return LDB_SUCCESS;
+}
static int samba_dsdb_init(struct ldb_module *module)
{
@@ -257,6 +347,7 @@ static int samba_dsdb_init(struct ldb_module *module)
extended_dn_module = extended_dn_module_ldb;
link_modules = tdb_modules_list;
} else {
+ struct cli_credentials *cred;
if (strcasecmp(backendType, "fedora-ds") == 0) {
link_modules = fedora_ds_modules;
backend_modules = fedora_ds_backend_modules;
@@ -272,6 +363,14 @@ static int samba_dsdb_init(struct ldb_module *module)
if (ret != LDB_SUCCESS) {
ldb_set_errstring(ldb, "Failed to set readOnlySchema opaque");
}
+
+ cred = ldb_get_opaque(ldb, "credentials");
+ if (!cred || !cli_credentials_authentication_requested(cred)) {
+ ret = set_ldap_credentials(ldb);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
}
#define CHECK_MODULE_LIST \