+ return state->ld;
+}
+
+int pdb_ads_search_fmt(struct pdb_ads_state *state, const char *base,
+ int scope, const char *attrs[], int num_attrs,
+ int attrsonly,
+ TALLOC_CTX *mem_ctx, struct tldap_message ***res,
+ const char *fmt, ...)
+{
+ struct tldap_context *ld;
+ va_list ap;
+ int ret;
+
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return TLDAP_SERVER_DOWN;
+ }
+
+ va_start(ap, fmt);
+ ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
+ mem_ctx, res, fmt, ap);
+ va_end(ap);
+
+ if (ret != TLDAP_SERVER_DOWN) {
+ return ret;
+ }
+
+ /* retry once */
+ ld = pdb_ads_ld(state);
+ if (ld == NULL) {
+ return TLDAP_SERVER_DOWN;
+ }
+
+ va_start(ap, fmt);
+ ret = tldap_search_va(ld, base, scope, attrs, num_attrs, attrsonly,
+ mem_ctx, res, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
+static NTSTATUS pdb_ads_connect(struct pdb_ads_state *state,
+ const char *location)
+{
+ const char *rootdse_attrs[2] = {
+ "defaultNamingContext", "configurationNamingContext" };
+ const char *domain_attrs[1] = { "objectSid" };
+ const char *ncname_attrs[1] = { "netbiosname" };
+ struct tldap_message **rootdse, **domain, **ncname;
+ TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS status;
+ int num_domains;
+ int rc;
+
+ ZERO_STRUCT(state->socket_address);
+ state->socket_address.sun_family = AF_UNIX;
+ strncpy(state->socket_address.sun_path, location,
+ sizeof(state->socket_address.sun_path) - 1);
+
+ rc = pdb_ads_search_fmt(
+ state, "", TLDAP_SCOPE_BASE,