diff options
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/samba_dsdb.c | 99 |
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 \ |