03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Copyright (C) 2002 Stichting NLnet, Netherlands, stichting@nlnet.nl.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Permission to use, copy, modify, and distribute this software for any
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * purpose with or without fee is hereby granted, provided that the
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * above copyright notice and this permission notice appear in all
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * copies.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND STICHTING NLNET
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * STICHTING NLNET BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * USE OR PERFORMANCE OF THIS SOFTWARE.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt * The development of Dynamically Loadable Zones (DLZ) for BIND 9 was
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * conceived and contributed by Rob Butler.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Permission to use, copy, modify, and distribute this software for any
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * purpose with or without fee is hereby granted, provided that the
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * above copyright notice and this permission notice appear in all
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * copies.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ROB BUTLER
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * ROB BUTLER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * USE OR PERFORMANCE OF THIS SOFTWARE.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*
02d54949f0f1db4729e14c3322b207f58d2578a4Mark Andrews * Copyright (C) 1999-2001, 2016 Internet Systems Consortium, Inc. ("ISC")
02d54949f0f1db4729e14c3322b207f58d2578a4Mark Andrews *
02d54949f0f1db4729e14c3322b207f58d2578a4Mark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
02d54949f0f1db4729e14c3322b207f58d2578a4Mark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
02d54949f0f1db4729e14c3322b207f58d2578a4Mark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef DLZ_LDAP
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <config.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <stdio.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <string.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <stdlib.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <dns/log.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <dns/sdlz.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <dns/result.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/mem.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/platform.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/print.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/result.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/string.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <isc/util.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <named/globals.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <dlz/sdlz_helper.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <dlz/dlz_ldap_driver.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Need older API functions from ldap.h.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define LDAP_DEPRECATED 1
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#include <ldap.h>
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define SIMPLE "simple"
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define KRB41 "krb41"
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define KRB42 "krb42"
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define V2 "v2"
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define V3 "v3"
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic dns_sdlzimplementation_t *dlz_ldap = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define dbc_search_limit 30
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define ALLNODES 1
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define ALLOWXFR 2
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define AUTHORITY 3
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define FINDZONE 4
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#define LOOKUP 5
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Structure to hold everthing needed by this "instance" of the LDAP
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * driver remember, the driver code is only loaded once, but may have
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * many separate instances.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewstypedef struct {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews db_list_t *db; /*%< handle to a list of DB */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#else
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbinstance_t *db; /*%< handle to db */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int method; /*%< security authentication method */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *user; /*%< who is authenticating */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *cred; /*%< password for simple authentication method */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int protocol; /*%< LDAP communication protocol version */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *hosts; /*%< LDAP server hosts */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews} ldap_instance_t;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/* forward references */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
abff0f462a758383d012887d3a97da4dac0c5a94Evan Huntdlz_ldap_findzone(void *driverarg, void *dbdata, const char *name,
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt dns_clientinfomethods_t *methods,
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt dns_clientinfo_t *clientinfo);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic void
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsdlz_ldap_destroy(void *driverarg, void *dbdata);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Private methods
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*% checks that the LDAP URL parameters make sense */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsdlz_ldap_checkURL(char *URL, int attrCnt, const char *msg) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result = ISC_R_SUCCESS;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int ldap_result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews LDAPURLDesc *ldap_url = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (!ldap_is_ldap_url(URL)) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "%s query is not a valid LDAP URL", msg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_result = ldap_url_parse(URL, &ldap_url);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_result != LDAP_SUCCESS || ldap_url == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "parsing %s query failed", msg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_count_values(ldap_url->lud_attrs) < attrCnt) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "%s query must specify at least "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "%d attributes to return",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews msg, attrCnt);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_url->lud_host != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "%s query must not specify a host", msg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_url->lud_port != 389) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "%s query must not specify a port", msg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_url->lud_dn == NULL || strlen (ldap_url->lud_dn) < 1) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "%s query must specify a search base", msg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_url->lud_exts != NULL || ldap_url->lud_crit_exts != 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "%s uses extensions. "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "The driver does not support LDAP extensions.",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews msg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews cleanup:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_url != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_free_urldesc(ldap_url);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt/*% Connects / reconnects to LDAP server */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsdlz_ldap_connect(ldap_instance_t *dbi, dbinstance_t *dbc) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int ldap_result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* if we have a connection, get ride of it. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbc->dbconn != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_unbind_s((LDAP *) dbc->dbconn);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbc->dbconn = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* now connect / reconnect. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* initialize. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbc->dbconn = ldap_init(dbi->hosts, LDAP_PORT);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbc->dbconn == NULL)
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (ISC_R_NOMEMORY);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* set protocol version. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_result = ldap_set_option((LDAP *) dbc->dbconn,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews LDAP_OPT_PROTOCOL_VERSION,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews &(dbi->protocol));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_result != LDAP_SUCCESS) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOPERM;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* "bind" to server. i.e. send username / pass */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_result = ldap_bind_s((LDAP *) dbc->dbconn, dbi->user,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi->cred, dbi->method);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_result != LDAP_SUCCESS) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (ISC_R_SUCCESS);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews cleanup:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* cleanup if failure. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbc->dbconn != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_unbind_s((LDAP *) dbc->dbconn);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbc->dbconn = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Properly cleans up a list of database instances.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * This function is only used when the driver is compiled for
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * multithreaded operation.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic void
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Huntldap_destroy_dblist(db_list_t *dblist) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbinstance_t *ndbi = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbinstance_t *dbi = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get the first DBI in the list */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ndbi = ISC_LIST_HEAD(*dblist);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* loop through the list */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews while (ndbi != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi = ndbi;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get the next DBI in the list */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ndbi = ISC_LIST_NEXT(dbi, link);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* release DB connection */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->dbconn != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_unbind_s((LDAP *) dbi->dbconn);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* release all memory that comprised a DBI */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews destroy_sqldbinstance(dbi);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* release memory for the list structure */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_put(ns_g_mctx, dblist, sizeof(db_list_t));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Loops through the list of DB instances, attempting to lock
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * on the mutex. If successful, the DBI is reserved for use
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * and the thread can perform queries against the database.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * If the lock fails, the next one in the list is tried.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * looping continues until a lock is obtained, or until
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * the list has been searched dbc_search_limit times.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * This function is only used when the driver is compiled for
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * multithreaded operation.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic dbinstance_t *
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Huntldap_find_avail_conn(db_list_t *dblist) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbinstance_t *dbi = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbinstance_t *head;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int count = 0;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get top of list */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews head = dbi = ISC_LIST_HEAD(*dblist);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* loop through list */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews while (count < dbc_search_limit) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* try to lock on the mutex */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (isc_mutex_trylock(&dbi->instance_lock) == ISC_R_SUCCESS)
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (dbi); /* success, return the DBI for use. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* not successful, keep trying */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi = ISC_LIST_NEXT(dbi, link);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* check to see if we have gone to the top of the list. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews count++;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi = head;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_INFO,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver unable to find available connection "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "after searching %d times",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews count);
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (NULL);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif /* ISC_PLATFORM_USETHREADS */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsldap_process_results(LDAP *dbc, LDAPMessage *msg, char ** attrs,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews void *ptr, isc_boolean_t allnodes)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result = ISC_R_SUCCESS;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int i = 0;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int j;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int len;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *attribute = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews LDAPMessage *entry;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *endp = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *host = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *type = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *data = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char **vals = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int ttl;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* make sure there are at least some attributes to process. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews REQUIRE(attrs != NULL || attrs[0] != NULL);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get the first entry to process */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews entry = ldap_first_entry(dbc, msg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (entry == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_INFO,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP no entries to process.");
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (ISC_R_FAILURE);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* loop through all entries returned */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews while (entry != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* reset for this loop */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ttl = 0;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews len = 0;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews i = 0;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews attribute = attrs[i];
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* determine how much space we need for data string */
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt for (j = 0; attrs[j] != NULL; j++) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get the list of values for this attribute. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews vals = ldap_get_values(dbc, entry, attrs[j]);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* skip empty attributes. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (vals == NULL || ldap_count_values(vals) < 1)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews continue;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * we only use the first value. this driver
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * does not support multi-valued attributes.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews len = len + strlen(vals[0]) + 1;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* free vals for next loop */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_value_free(vals);
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt } /* end for (j = 0; attrs[j] != NULL, j++) loop */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* allocate memory for data string */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews data = isc_mem_allocate(ns_g_mctx, len + 1);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (data == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver unable to allocate memory "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "while processing results");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Make sure data is null termed at the beginning so
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * we can check if any data was stored to it later.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews data[0] = '\0';
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* reset j to re-use below */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews j = 0;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* loop through the attributes in the order specified. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews while (attribute != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get the list of values for this attribute. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews vals = ldap_get_values(dbc, entry, attribute);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* skip empty attributes. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (vals == NULL || vals[0] == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* increment attibute pointer */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews attribute = attrs[++i];
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* start loop over */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews continue;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * j initially = 0. Increment j each time we
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * set a field that way next loop will set
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * next field.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews switch(j) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 0:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews j++;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * convert text to int, make sure it
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * worked right
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ttl = strtol(vals[0], &endp, 10);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (*endp != '\0' || ttl < 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver ttl must "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "be a postive number");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 1:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews j++;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews type = isc_mem_strdup(ns_g_mctx, vals[0]);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 2:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews j++;
41bbb34bc20f189af62e7047ce42822615417f15Evan Hunt if (allnodes)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews host = isc_mem_strdup(ns_g_mctx,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews vals[0]);
41bbb34bc20f189af62e7047ce42822615417f15Evan Hunt else
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strcpy(data, vals[0]);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 3:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews j++;
41bbb34bc20f189af62e7047ce42822615417f15Evan Hunt if (allnodes)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strcpy(data, vals[0]);
41bbb34bc20f189af62e7047ce42822615417f15Evan Hunt else {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strcat(data, " ");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strcat(data, vals[0]);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews default:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strcat(data, " ");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews strcat(data, vals[0]);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } /* end switch(j) */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* free values */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_value_free(vals);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews vals = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* increment attibute pointer */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews attribute = attrs[++i];
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } /* end while (attribute != NULL) */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (type == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver unable "
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt "to retrieve DNS type");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (strlen(data) < 1) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver unable "
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt "to retrieve DNS data");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt
41bbb34bc20f189af62e7047ce42822615417f15Evan Hunt if (allnodes && host != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (strcasecmp(host, "~") == 0)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_sdlz_putnamedrr(
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews (dns_sdlzallnodes_t *) ptr,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "*", type, ttl, data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews else
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_sdlz_putnamedrr(
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews (dns_sdlzallnodes_t *) ptr,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews host, type, ttl, data);
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt if (result != ISC_R_SUCCESS)
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt isc_log_write(dns_lctx,
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt DNS_LOGCATEGORY_DATABASE,
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt "dlz-ldap: putnamedrr failed "
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt "for \"%s %s %u %s\", %s",
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt host, type, ttl, data,
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt isc_result_totext(result));
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt } else {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_sdlz_putrr((dns_sdlzlookup_t *) ptr,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews type, ttl, data);
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt if (result != ISC_R_SUCCESS)
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt isc_log_write(dns_lctx,
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt DNS_LOGCATEGORY_DATABASE,
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt "dlz-ldap: putrr failed "
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt "for \"%s %u %s\", %s",
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt type, ttl, data,
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt isc_result_totext(result));
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver failed "
f02b5d87a561ba669bd368a8a6422f364f7702ecEvan Hunt "while sending data to BIND.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* free memory for type, data and host for next loop */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx, type);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx, data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (host != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx, host);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get the next entry to process */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews entry = ldap_next_entry(dbc, entry);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } /* end while (entry != NULL) */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews cleanup:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* de-allocate memory */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (vals != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_value_free(vals);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (host != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx, host);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (type != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx, type);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (data != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx, data);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * This function is the real core of the driver. Zone, record
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * and client strings are passed in (or NULL is passed if the
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * string is not available). The type of query we want to run
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * is indicated by the query flag, and the dbdata object is passed
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * passed in to. dbdata really holds either:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * 1) a list of database instances (in multithreaded mode) OR
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * 2) a single database instance (in single threaded mode)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * The function will construct the query and obtain an available
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * database instance (DBI). It will then run the query and hopefully
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * obtain a result set.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsldap_get_results(const char *zone, const char *record,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews const char *client, unsigned int query,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews void *dbdata, void *ptr)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbinstance_t *dbi = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *querystring = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews LDAPURLDesc *ldap_url = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int ldap_result = 0;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews LDAPMessage *ldap_msg = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int i;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int entries;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get db instance / connection */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* find an available DBI from the list */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi = ldap_find_avail_conn((db_list_t *)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ((ldap_instance_t *)dbdata)->db);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#else /* ISC_PLATFORM_USETHREADS */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * only 1 DBI - no need to lock instance lock either
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * only 1 thread in the whole process, no possible contention.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi = (dbinstance_t *) ((ldap_instance_t *)dbdata)->db;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif /* ISC_PLATFORM_USETHREADS */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* if DBI is null, can't do anything else */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi == NULL)
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (ISC_R_FAILURE);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* set fields */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (zone != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi->zone = isc_mem_strdup(ns_g_mctx, zone);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->zone == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOMEMORY;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi->zone = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (record != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi->record = isc_mem_strdup(ns_g_mctx, record);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->record == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOMEMORY;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi->record = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (client != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi->client = isc_mem_strdup(ns_g_mctx, client);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->client == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOMEMORY;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi->client = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* what type of query are we going to run? */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews switch(query) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case ALLNODES:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * if the query was not passed in from the config file
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * then we can't run it. return not_implemented, so
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * it's like the code for that operation was never
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * built into the driver.... AHHH flexibility!!!
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->allnodes_q == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOTIMPLEMENTED;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews querystring = build_querystring(ns_g_mctx,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi->allnodes_q);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case ALLOWXFR:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* same as comments as ALLNODES */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->allowxfr_q == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOTIMPLEMENTED;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews querystring = build_querystring(ns_g_mctx,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi->allowxfr_q);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case AUTHORITY:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* same as comments as ALLNODES */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->authority_q == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOTIMPLEMENTED;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews querystring = build_querystring(ns_g_mctx,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi->authority_q);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case FINDZONE:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* this is required. It's the whole point of DLZ! */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->findzone_q == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "No query specified for findzone. "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "Findzone requires a query");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews querystring = build_querystring(ns_g_mctx,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi->findzone_q);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case LOOKUP:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* this is required. It's also a major point of DLZ! */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->lookup_q == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "No query specified for lookup. "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "Lookup requires a query");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews querystring = build_querystring(ns_g_mctx,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi->lookup_q);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews default:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * this should never happen. If it does, the code is
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * screwed up!
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNEXPECTED_ERROR(__FILE__, __LINE__,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "Incorrect query flag passed to "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "ldap_get_results");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_UNEXPECTED;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* if the querystring is null, Bummer, outta RAM. UPGRADE TIME!!! */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (querystring == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOMEMORY;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * output the full query string during debug so we can see
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * what lame error the query has.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "\nQuery String: %s\n", querystring);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* break URL down into it's component parts, if error cleanup */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_result = ldap_url_parse(querystring, &ldap_url);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_result != LDAP_SUCCESS || ldap_url == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt for (i = 0; i < 3; i++) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * dbi->dbconn may be null if trying to reconnect on a
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * previous query failed.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->dbconn == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_INFO,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver attempting to re-connect");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dlz_ldap_connect((ldap_instance_t *) dbdata,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews continue;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* perform ldap search syncronously */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_result = ldap_search_s((LDAP *) dbi->dbconn,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_url->lud_dn,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_url->lud_scope,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_url->lud_filter,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_url->lud_attrs, 0, &ldap_msg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * check return code. No such object is ok, just
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * didn't find what we wanted
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews switch(ldap_result) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case LDAP_NO_SUCH_OBJECT:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "No object found matching "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "query requirements");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOTFOUND;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case LDAP_SUCCESS: /* on success do nothing */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_SUCCESS;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews i = 3;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case LDAP_SERVER_DOWN:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_INFO,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver attempting to re-connect");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dlz_ldap_connect((ldap_instance_t *) dbdata,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews default:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * other errors not ok. Log error message and
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * get out
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP error: %s",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_err2string(ldap_result));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } /* close switch(ldap_result) */
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt } /* end for (int i = 0 i < 3; i++) */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews switch(query) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case ALLNODES:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ldap_process_results((LDAP *) dbi->dbconn, ldap_msg,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_url->lud_attrs,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ptr, isc_boolean_true);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case AUTHORITY:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case LOOKUP:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ldap_process_results((LDAP *) dbi->dbconn, ldap_msg,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_url->lud_attrs,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ptr, isc_boolean_false);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case ALLOWXFR:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews entries = ldap_count_entries((LDAP *) dbi->dbconn, ldap_msg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (entries == 0)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOPERM;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews else if (entries > 0)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_SUCCESS;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews else
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case FINDZONE:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews entries = ldap_count_entries((LDAP *) dbi->dbconn, ldap_msg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (entries == 0)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOTFOUND;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews else if (entries > 0)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_SUCCESS;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews else
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews default:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * this should never happen. If it does, the code is
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * screwed up!
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNEXPECTED_ERROR(__FILE__, __LINE__,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "Incorrect query flag passed to "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "ldap_get_results");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_UNEXPECTED;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews cleanup:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* it's always good to cleanup after yourself */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* if we retrieved results, free them */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_msg != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_msgfree(ldap_msg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_url != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_free_urldesc(ldap_url);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* cleanup */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->zone != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx, dbi->zone);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->record != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx, dbi->record);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbi->client != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx, dbi->client);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* release the lock so another thread can use this dbi */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mutex_unlock(&dbi->instance_lock);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif /* ISC_PLATFORM_USETHREADS */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* release query string */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (querystring != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx, querystring );
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* return result */
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * DLZ methods
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsdlz_ldap_allowzonexfr(void *driverarg, void *dbdata, const char *name,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews const char *client)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(driverarg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* check to see if we are authoritative for the zone first */
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt result = dlz_ldap_findzone(driverarg, dbdata, name, NULL, NULL);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS) {
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* get all the zone data */
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt result = ldap_get_results(name, NULL, client, ALLOWXFR, dbdata, NULL);
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsdlz_ldap_allnodes(const char *zone, void *driverarg, void *dbdata,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_sdlzallnodes_t *allnodes)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(driverarg);
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (ldap_get_results(zone, NULL, NULL, ALLNODES, dbdata, allnodes));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsdlz_ldap_authority(const char *zone, void *driverarg, void *dbdata,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_sdlzlookup_t *lookup)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(driverarg);
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (ldap_get_results(zone, NULL, NULL, AUTHORITY, dbdata, lookup));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
abff0f462a758383d012887d3a97da4dac0c5a94Evan Huntdlz_ldap_findzone(void *driverarg, void *dbdata, const char *name,
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt dns_clientinfomethods_t *methods,
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt dns_clientinfo_t *clientinfo)
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(driverarg);
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt UNUSED(methods);
abff0f462a758383d012887d3a97da4dac0c5a94Evan Hunt UNUSED(clientinfo);
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (ldap_get_results(name, NULL, NULL, FINDZONE, dbdata, NULL));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsdlz_ldap_lookup(const char *zone, const char *name, void *driverarg,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt void *dbdata, dns_sdlzlookup_t *lookup,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt isc_result_t result;
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(driverarg);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt UNUSED(methods);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt UNUSED(clientinfo);
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (strcmp(name, "*") == 0)
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt result = ldap_get_results(zone, "~", NULL, LOOKUP,
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt dbdata, lookup);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews else
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt result = ldap_get_results(zone, name, NULL, LOOKUP,
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt dbdata, lookup);
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic isc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsdlz_ldap_create(const char *dlzname, unsigned int argc, char *argv[],
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews void *driverarg, void **dbdata)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews{
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_instance_t *ldap_inst = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbinstance_t *dbi = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int protocol;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int method;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* if multi-threaded, we need a few extra variables. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int dbcount;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews char *endp;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/* db_list_t *dblist = NULL; */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews int i;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif /* ISC_PLATFORM_USETHREADS */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(dlzname);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(driverarg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* if debugging, let user know we are multithreaded. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver running multithreaded");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#else /* ISC_PLATFORM_USETHREADS */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* if debugging, let user know we are single threaded. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(1),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver running single threaded");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif /* ISC_PLATFORM_USETHREADS */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (argc < 9) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver requires at least "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "8 command line args.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return (ISC_R_FAILURE);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* no more than 13 arg's should be passed to the driver */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (argc > 12) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver cannot accept more than "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "11 command line args.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return (ISC_R_FAILURE);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* determine protocol version. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (strncasecmp(argv[2], V2, strlen(V2)) == 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews protocol = 2;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else if (strncasecmp(argv[2], V3, strlen(V3)) == 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews protocol = 3;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver protocol must be either %s or %s",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews V2, V3);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return (ISC_R_FAILURE);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* determine connection method. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (strncasecmp(argv[3], SIMPLE, strlen(SIMPLE)) == 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews method = LDAP_AUTH_SIMPLE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else if (strncasecmp(argv[3], KRB41, strlen(KRB41)) == 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews method = LDAP_AUTH_KRBV41;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else if (strncasecmp(argv[3], KRB42, strlen(KRB42)) == 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews method = LDAP_AUTH_KRBV42;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver authentication method must be "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "one of %s, %s or %s",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews SIMPLE, KRB41, KRB42);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return (ISC_R_FAILURE);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* multithreaded build can have multiple DB connections */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* check how many db connections we should create */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbcount = strtol(argv[1], &endp, 10);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (*endp != '\0' || dbcount < 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver database connection count "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "must be positive.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return (ISC_R_FAILURE);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* check that LDAP URL parameters make sense */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews switch(argc) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 12:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dlz_ldap_checkURL(argv[11], 0, "allow zone transfer");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 11:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dlz_ldap_checkURL(argv[10], 3, "all nodes");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 10:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (strlen(argv[9]) > 0) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dlz_ldap_checkURL(argv[9], 3, "authority");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 9:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dlz_ldap_checkURL(argv[8], 3, "lookup");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dlz_ldap_checkURL(argv[7], 0, "find zone");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS)
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews default:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* not really needed, should shut up compiler. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* allocate memory for LDAP instance */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_inst = isc_mem_get(ns_g_mctx, sizeof(ldap_instance_t));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_inst == NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return (ISC_R_NOMEMORY);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews memset(ldap_inst, 0, sizeof(ldap_instance_t));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* store info needed to automatically re-connect. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_inst->protocol = protocol;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_inst->method = method;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_inst->hosts = isc_mem_strdup(ns_g_mctx, argv[6]);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_inst->hosts == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOMEMORY;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_inst->user = isc_mem_strdup(ns_g_mctx, argv[4]);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_inst->user == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOMEMORY;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_inst->cred = isc_mem_strdup(ns_g_mctx, argv[5]);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_inst->cred == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOMEMORY;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* allocate memory for database connection list */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_inst->db = isc_mem_get(ns_g_mctx, sizeof(db_list_t));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (ldap_inst->db == NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_NOMEMORY;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* initialize DB connection list */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ISC_LIST_INIT(*(ldap_inst->db));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * create the appropriate number of database instances (DBI)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * append each new DBI to the end of the list
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews for (i = 0; i < dbcount; i++) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif /* ISC_PLATFORM_USETHREADS */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* how many queries were passed in from config file? */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews switch(argc) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 9:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = build_sqldbinstance(ns_g_mctx, NULL, NULL,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews NULL, argv[7], argv[8],
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews NULL, &dbi);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 10:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = build_sqldbinstance(ns_g_mctx, NULL, NULL,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews argv[9], argv[7], argv[8],
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews NULL, &dbi);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 11:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = build_sqldbinstance(ns_g_mctx, argv[10], NULL,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews argv[9], argv[7], argv[8],
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews NULL, &dbi);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case 12:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = build_sqldbinstance(ns_g_mctx, argv[10],
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews argv[11], argv[9],
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews argv[7], argv[8],
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews NULL, &dbi);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews default:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* not really needed, should shut up compiler. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result == ISC_R_SUCCESS) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver created "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "database instance object.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } else { /* unsuccessful?, log err msg and cleanup. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver could not create "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "database instance object.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* when multithreaded, build a list of DBI's */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ISC_LINK_INIT(dbi, link);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ISC_LIST_APPEND(*(ldap_inst->db), dbi, link);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#else
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * when single threaded, hold onto the one connection
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * instance.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_inst->db = dbi;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* attempt to connect */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dlz_ldap_connect(ldap_inst, dbi);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * if db connection cannot be created, log err msg and
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * cleanup.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews switch(result) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* success, do nothing */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case ISC_R_SUCCESS:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * no memory means ldap_init could not
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * allocate memory
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case ISC_R_NOMEMORY:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver could not allocate memory "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "for connection number %u",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews i+1);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#else
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver could not allocate memory "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "for connection");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * no perm means ldap_set_option could not set
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * protocol version
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case ISC_R_NOPERM:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver could not "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "set protocol version.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_FAILURE;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* failure means couldn't connect to ldap server */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews case ISC_R_FAILURE:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver could not "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bind connection number %u to server.",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews i+1);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#else
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "LDAP driver could not "
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "bind connection to server.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * default should never happen. If it does,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * major errors.
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews default:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNEXPECTED_ERROR(__FILE__, __LINE__,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "dlz_ldap_create() failed: %s",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_totext(result));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_UNEXPECTED;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews goto cleanup;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews break;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } /* end switch(result) */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* set DBI = null for next loop through. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dbi = NULL;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews } /* end for loop */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif /* ISC_PLATFORM_USETHREADS */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* set dbdata to the ldap_instance we created. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews *dbdata = ldap_inst;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* hey, we got through all of that ok, return success. */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return(ISC_R_SUCCESS);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews cleanup:
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dlz_ldap_destroy(NULL, ldap_inst);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews return(ISC_R_FAILURE);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsvoid
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Huntdlz_ldap_destroy(void *driverarg, void *dbdata) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNUSED(driverarg);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dbdata != NULL) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#ifdef ISC_PLATFORM_USETHREADS
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* cleanup the list of DBI's */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_destroy_dblist((db_list_t *)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ((ldap_instance_t *)dbdata)->db);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#else /* ISC_PLATFORM_USETHREADS */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (((ldap_instance_t *)dbdata)->db->dbconn != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ldap_unbind_s((LDAP *)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ((ldap_instance_t *)dbdata)->db->dbconn);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /* destroy single DB instance */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews destroy_sqldbinstance(((ldap_instance_t *)dbdata)->db);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif /* ISC_PLATFORM_USETHREADS */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (((ldap_instance_t *)dbdata)->hosts != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ((ldap_instance_t *)dbdata)->hosts);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (((ldap_instance_t *)dbdata)->user != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ((ldap_instance_t *)dbdata)->user);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (((ldap_instance_t *)dbdata)->cred != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_free(ns_g_mctx,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ((ldap_instance_t *)dbdata)->cred);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_mem_put(ns_g_mctx, dbdata, sizeof(ldap_instance_t));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsstatic dns_sdlzmethods_t dlz_ldap_methods = {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dlz_ldap_create,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dlz_ldap_destroy,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dlz_ldap_findzone,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dlz_ldap_lookup,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dlz_ldap_authority,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dlz_ldap_allnodes,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt dlz_ldap_allowzonexfr,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
71bd858d8ed62672e7c23999dc7c02fd16a55089Evan Hunt NULL,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews};
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Wrapper around dns_sdlzregister().
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsisc_result_t
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsdlz_ldap_init(void) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_t result;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Write debugging message to log
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "Registering DLZ ldap driver.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = dns_sdlzregister("ldap", &dlz_ldap_methods, NULL,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_SDLZFLAG_RELATIVEOWNER |
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_SDLZFLAG_RELATIVERDATA,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews ns_g_mctx, &dlz_ldap);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (result != ISC_R_SUCCESS) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews UNEXPECTED_ERROR(__FILE__, __LINE__,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "dns_sdlzregister() failed: %s",
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_result_totext(result));
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews result = ISC_R_UNEXPECTED;
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews }
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
5d35a7a2fbcf6bd060b0ce7deb349e427cb59fc1Evan Hunt return (result);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews/*%
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Wrapper around dns_sdlzunregister().
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsvoid
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrewsdlz_ldap_clear(void) {
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews /*
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews * Write debugging message to log
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews */
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews "Unregistering DLZ ldap driver.");
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews if (dlz_ldap != NULL)
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews dns_sdlzunregister(&dlz_ldap);
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews}
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews
03e200df5dc283f24a6a349f0b31d3eab26da893Mark Andrews#endif