+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;
+}