bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington/*
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews * ldapdb.c version 1.0-beta
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews *
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews * Copyright (C) 2002, 2004 Stig Venaas
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington *
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington * Permission to use, copy, modify, and distribute this software for any
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington * purpose with or without fee is hereby granted, provided that the above
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington * copyright notice and this permission notice appear in all copies.
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews *
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews * Contributors: Jeremy C. McDermond
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews */
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews/*
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews * If you want to use TLS, uncomment the define below
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington */
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews/* #define LDAPDB_TLS */
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews/*
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews * If you are using an old LDAP API uncomment the define below. Only do this
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews * if you know what you're doing or get compilation errors on ldap_memfree().
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews * This also forces LDAPv2.
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews */
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews/* #define LDAPDB_RFC1823API */
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews/* Using LDAPv3 by default, change this if you want v2 */
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#ifndef LDAPDB_LDAP_VERSION
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#define LDAPDB_LDAP_VERSION 3
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#endif
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include <config.h>
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include <string.h>
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include <stdio.h>
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include <stdlib.h>
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include <ctype.h>
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include <isc/mem.h>
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include <isc/print.h>
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include <isc/result.h>
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include <isc/util.h>
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington#include <isc/thread.h>
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include <dns/sdb.h>
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include <named/globals.h>
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews#include <named/log.h>
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include <ldap.h>
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington#include "ldapdb.h"
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington/*
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews * A simple database driver for LDAP
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington */
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews/* enough for name with 8 labels of max length */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews#define MAXNAMELEN 519
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellingtonstatic dns_sdbimplementation_t *ldapdb = NULL;
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellingtonstruct ldapdb_data {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington char *hostport;
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington char *hostname;
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington int portno;
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington char *base;
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington int defaultttl;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews char *filterall;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews int filteralllen;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews char *filterone;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews int filteronelen;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews char *filtername;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews char *bindname;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews char *bindpw;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#ifdef LDAPDB_TLS
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews int tls;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#endif
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington};
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington/* used by ldapdb_getconn */
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellingtonstruct ldapdb_entry {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington void *index;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington size_t size;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington void *data;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington struct ldapdb_entry *next;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington};
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellingtonstatic struct ldapdb_entry *ldapdb_find(struct ldapdb_entry *stack,
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington const void *index, size_t size) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington while (stack != NULL) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (stack->size == size && !memcmp(stack->index, index, size))
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington return stack;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington stack = stack->next;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington }
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington return NULL;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington}
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellingtonstatic void ldapdb_insert(struct ldapdb_entry **stack,
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington struct ldapdb_entry *item) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington item->next = *stack;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington *stack = item;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington}
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellingtonstatic void ldapdb_lock(int what) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington static isc_mutex_t lock;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington switch (what) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington case 0:
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington isc_mutex_init(&lock);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington break;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington case 1:
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington LOCK(&lock);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington break;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington case -1:
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington UNLOCK(&lock);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington break;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington }
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington}
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington/* data == NULL means cleanup */
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellingtonstatic LDAP **
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellingtonldapdb_getconn(struct ldapdb_data *data)
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington{
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington static struct ldapdb_entry *allthreadsdata = NULL;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington struct ldapdb_entry *threaddata, *conndata;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington unsigned long threadid;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (data == NULL) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington /* cleanup */
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington /* lock out other threads */
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldapdb_lock(1);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington while (allthreadsdata != NULL) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington threaddata = allthreadsdata;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington free(threaddata->index);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington while (threaddata->data != NULL) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington conndata = threaddata->data;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (conndata->data != NULL)
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldap_unbind((LDAP *)conndata->data);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington threaddata->data = conndata->next;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington free(conndata);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington }
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington allthreadsdata = threaddata->next;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington free(threaddata);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington }
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldapdb_lock(-1);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington return (NULL);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington }
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington /* look for connection data for current thread */
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington threadid = isc_thread_self();
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington threaddata = ldapdb_find(allthreadsdata, &threadid, sizeof(threadid));
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (threaddata == NULL) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington /* no data for this thread, create empty connection list */
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington threaddata = malloc(sizeof(*threaddata));
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (threaddata == NULL)
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington return (NULL);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington threaddata->index = malloc(sizeof(threadid));
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (threaddata->index == NULL) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington free(threaddata);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington return (NULL);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington }
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington *(unsigned long *)threaddata->index = threadid;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington threaddata->size = sizeof(threadid);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington threaddata->data = NULL;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington /* need to lock out other threads here */
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldapdb_lock(1);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldapdb_insert(&allthreadsdata, threaddata);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldapdb_lock(-1);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington }
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington /* threaddata points at the connection list for current thread */
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington /* look for existing connection to our server */
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington conndata = ldapdb_find((struct ldapdb_entry *)threaddata->data,
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington data->hostport, strlen(data->hostport));
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (conndata == NULL) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington /* no connection data structure for this server, create one */
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington conndata = malloc(sizeof(*conndata));
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (conndata == NULL)
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington return (NULL);
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews conndata->index = data->hostport;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington conndata->size = strlen(data->hostport);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington conndata->data = NULL;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldapdb_insert((struct ldapdb_entry **)&threaddata->data,
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington conndata);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington }
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington return (LDAP **)&conndata->data;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington}
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellingtonstatic void
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellingtonldapdb_bind(struct ldapdb_data *data, LDAP **ldp)
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington{
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#ifndef LDAPDB_RFC1823API
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews const int ver = LDAPDB_LDAP_VERSION;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#endif
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (*ldp != NULL)
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldap_unbind(*ldp);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington *ldp = ldap_open(data->hostname, data->portno);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (*ldp == NULL)
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington return;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#ifndef LDAPDB_RFC1823API
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews ldap_set_option(*ldp, LDAP_OPT_PROTOCOL_VERSION, &ver);
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#endif
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#ifdef LDAPDB_TLS
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (data->tls) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews ldap_start_tls_s(*ldp, NULL, NULL);
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#endif
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (ldap_simple_bind_s(*ldp, data->bindname, data->bindpw) != LDAP_SUCCESS) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldap_unbind(*ldp);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington *ldp = NULL;
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington}
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt#ifdef DNS_CLIENTINFO_VERSION
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellingtonstatic isc_result_t
793814f80703afdd69b59ade91e63efa81ae4178Evan Huntldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo)
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt#else
793814f80703afdd69b59ade91e63efa81ae4178Evan Huntstatic isc_result_t
793814f80703afdd69b59ade91e63efa81ae4178Evan Huntldapdb_search(const char *zone, const char *name, void *dbdata, void *retdata,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt void *methods, void *clientinfo)
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt#endif /* DNS_CLIENTINFO_VERSION */
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington{
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington struct ldapdb_data *data = dbdata;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews isc_result_t result = ISC_R_NOTFOUND;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington LDAP **ldp;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington LDAPMessage *res, *e;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews char *fltr, *a, **vals = NULL, **names = NULL;
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington char type[64];
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#ifdef LDAPDB_RFC1823API
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews void *ptr;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews#else
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington BerElement *ptr;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews#endif
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews int i, j, errno, msgid;
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt UNUSED(methods);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt UNUSED(clientinfo);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldp = ldapdb_getconn(data);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (ldp == NULL)
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington return (ISC_R_FAILURE);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (*ldp == NULL) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldapdb_bind(data, ldp);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (*ldp == NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews "LDAP sdb zone '%s': bind failed", zone);
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington return (ISC_R_FAILURE);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (name == NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews fltr = data->filterall;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews } else {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (strlen(name) > MAXNAMELEN) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews "LDAP sdb zone '%s': name %s too long", zone, name);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_FAILURE);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews sprintf(data->filtername, "%s))", name);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews fltr = data->filterone;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews msgid = ldap_search(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (msgid == -1) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldapdb_bind(data, ldp);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (*ldp != NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews msgid = ldap_search(*ldp, data->base, LDAP_SCOPE_SUBTREE, fltr, NULL, 0);
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (*ldp == NULL || msgid == -1) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews "LDAP sdb zone '%s': search failed, filter %s", zone, fltr);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_FAILURE);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews /* Get the records one by one as they arrive and return them to bind */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews while ((errno = ldap_result(*ldp, msgid, 0, NULL, &res)) != LDAP_RES_SEARCH_RESULT ) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington LDAP *ld = *ldp;
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington int ttl = data->defaultttl;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews /* not supporting continuation references at present */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (errno != LDAP_RES_SEARCH_ENTRY) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews "LDAP sdb zone '%s': ldap_result returned %d", zone, errno);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ldap_msgfree(res);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_FAILURE);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews /* only one entry per result message */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews e = ldap_first_entry(ld, res);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (e == NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ldap_msgfree(res);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews "LDAP sdb zone '%s': ldap_first_entry failed", zone);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_FAILURE);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (name == NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews names = ldap_get_values(ld, e, "relativeDomainName");
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (names == NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews continue;
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews vals = ldap_get_values(ld, e, "dNSTTL");
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (vals != NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ttl = atoi(vals[0]);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ldap_value_free(vals);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews for (a = ldap_first_attribute(ld, e, &ptr); a != NULL; a = ldap_next_attribute(ld, e, ptr)) {
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington char *s;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington for (s = a; *s; s++)
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington *s = toupper(*s);
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington s = strstr(a, "RECORD");
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if ((s == NULL) || (s == a) || (s - a >= (signed int)sizeof(type))) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#ifndef LDAPDB_RFC1823API
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington ldap_memfree(a);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews#endif
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington continue;
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington strncpy(type, a, s - a);
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington type[s - a] = '\0';
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington vals = ldap_get_values(ld, e, a);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (vals != NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews for (i = 0; vals[i] != NULL; i++) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (name != NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews result = dns_sdb_putrr(retdata, type, ttl, vals[i]);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews } else {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews for (j = 0; names[j] != NULL; j++) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews result = dns_sdb_putnamedrr(retdata, names[j], type, ttl, vals[i]);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (result != ISC_R_SUCCESS)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews break;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews; if (result != ISC_R_SUCCESS) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews "LDAP sdb zone '%s': dns_sdb_put... failed for %s", zone, vals[i]);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ldap_value_free(vals);
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#ifndef LDAPDB_RFC1823API
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ldap_memfree(a);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (ptr != NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ber_free(ptr, 0);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews#endif
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (name == NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ldap_value_free(names);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ldap_msgfree(res);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_FAILURE);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ldap_value_free(vals);
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#ifndef LDAPDB_RFC1823API
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington ldap_memfree(a);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews#endif
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#ifndef LDAPDB_RFC1823API
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (ptr != NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ber_free(ptr, 0);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews#endif
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (name == NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ldap_value_free(names);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews /* free this result */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews ldap_msgfree(res);
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews /* free final result */
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews ldap_msgfree(res);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (result);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews}
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews/* callback routines */
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt#ifdef DNS_CLIENTINFO_VERSION
793814f80703afdd69b59ade91e63efa81ae4178Evan Huntstatic isc_result_t
793814f80703afdd69b59ade91e63efa81ae4178Evan Huntldapdb_lookup(const char *zone, const char *name, void *dbdata,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt dns_sdblookup_t *lookup, dns_clientinfomethods_t *methods,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt dns_clientinfo_t *clientinfo)
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt{
58f1ac8dadf2c1f215343a0b2d1df2df954c4b19Mark Andrews UNUSED(methods);
58f1ac8dadf2c1f215343a0b2d1df2df954c4b19Mark Andrews UNUSED(clientinfo);
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt return (ldapdb_search(zone, name, dbdata, lookup, NULL, NULL));
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt}
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt#else
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrewsstatic isc_result_t
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrewsldapdb_lookup(const char *zone, const char *name, void *dbdata,
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews dns_sdblookup_t *lookup)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews{
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt return (ldapdb_search(zone, name, dbdata, lookup, methods,
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt clientinfo));
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington}
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt#endif /* DNS_CLIENTINFO_VERSION */
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellingtonstatic isc_result_t
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellingtonldapdb_allnodes(const char *zone, void *dbdata,
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews dns_sdballnodes_t *allnodes)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews{
793814f80703afdd69b59ade91e63efa81ae4178Evan Hunt return (ldapdb_search(zone, NULL, dbdata, allnodes, NULL, NULL));
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews}
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrewsstatic char *
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrewsunhex(char *in)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews{
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews static const char hexdigits[] = "0123456789abcdef";
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews char *p, *s = in;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews int d1, d2;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews while ((s = strchr(s, '%'))) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (!(s[1] && s[2]))
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return NULL;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if ((p = strchr(hexdigits, tolower(s[1]))) == NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return NULL;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews d1 = p - hexdigits;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if ((p = strchr(hexdigits, tolower(s[2]))) == NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return NULL;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews d2 = p - hexdigits;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews *s++ = d1 << 4 | d2;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews memmove(s, s + 2, strlen(s) - 1);
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return in;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews}
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews/* returns 0 for ok, -1 for bad syntax, -2 for unknown critical extension */
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrewsstatic int
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrewsparseextensions(char *extensions, struct ldapdb_data *data)
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews{
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews char *s, *next, *name, *value;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews int critical;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews while (extensions != NULL) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews s = strchr(extensions, ',');
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (s != NULL) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews *s++ = '\0';
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews next = s;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews } else {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews next = NULL;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (*extensions != '\0') {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews s = strchr(extensions, '=');
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (s != NULL) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews *s++ = '\0';
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews value = *s != '\0' ? s : NULL;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews } else {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews value = NULL;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews name = extensions;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews critical = *name == '!';
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (critical) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews name++;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (*name == '\0') {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews return -1;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (!strcasecmp(name, "bindname")) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews data->bindname = value;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews } else if (!strcasecmp(name, "x-bindpw")) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews data->bindpw = value;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#ifdef LDAPDB_TLS
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews } else if (!strcasecmp(name, "x-tls")) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews data->tls = value == NULL || !strcasecmp(value, "true");
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews#endif
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews } else if (critical) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews return -2;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews extensions = next;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews return 0;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews}
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrewsstatic void
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrewsfree_data(struct ldapdb_data *data)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews{
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (data->hostport != NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews isc_mem_free(ns_g_mctx, data->hostport);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (data->hostname != NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews isc_mem_free(ns_g_mctx, data->hostname);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (data->filterall != NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews isc_mem_put(ns_g_mctx, data->filterall, data->filteralllen);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (data->filterone != NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews isc_mem_put(ns_g_mctx, data->filterone, data->filteronelen);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews isc_mem_put(ns_g_mctx, data, sizeof(struct ldapdb_data));
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews}
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrewsstatic isc_result_t
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrewsldapdb_create(const char *zone, int argc, char **argv,
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews void *driverdata, void **dbdata)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews{
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews struct ldapdb_data *data;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews char *s, *filter = NULL, *extensions = NULL;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews int defaultttl;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews UNUSED(driverdata);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews /* we assume that only one thread will call create at a time */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews /* want to do this only once for all instances */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if ((argc < 2)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews || (argv[0] != strstr( argv[0], "ldap://"))
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews || ((defaultttl = atoi(argv[1])) < 1))
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_FAILURE);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data = isc_mem_get(ns_g_mctx, sizeof(struct ldapdb_data));
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (data == NULL)
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_NOMEMORY);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews memset(data, 0, sizeof(struct ldapdb_data));
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->hostport = isc_mem_strdup(ns_g_mctx, argv[0] + strlen("ldap://"));
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (data->hostport == NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews free_data(data);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_NOMEMORY);
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->defaultttl = defaultttl;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews s = strchr(data->hostport, '/');
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (s != NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews *s++ = '\0';
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->base = s;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews /* attrs, scope, filter etc? */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews s = strchr(s, '?');
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (s != NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews *s++ = '\0';
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews /* ignore attributes */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews s = strchr(s, '?');
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (s != NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews *s++ = '\0';
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews /* ignore scope */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews s = strchr(s, '?');
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (s != NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews *s++ = '\0';
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews /* filter */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews filter = s;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews s = strchr(s, '?');
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (s != NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews *s++ = '\0';
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews /* extensions */
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews extensions = s;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews s = strchr(s, '?');
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (s != NULL) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews *s++ = '\0';
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (*extensions == '\0') {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews extensions = NULL;
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (*filter == '\0') {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews filter = NULL;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (*data->base == '\0') {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->base = NULL;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews /* parse extensions */
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (extensions != NULL) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews int err;
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews err = parseextensions(extensions, data);
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (err < 0) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews /* err should be -1 or -2 */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews free_data(data);
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if (err == -1) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews "LDAP sdb zone '%s': URL: extension syntax error", zone);
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews } else if (err == -2) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews "LDAP sdb zone '%s': URL: unknown critical extension", zone);
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_FAILURE);
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington }
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews if ((data->base != NULL && unhex(data->base) == NULL) ||
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews (filter != NULL && unhex(filter) == NULL) ||
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews (data->bindname != NULL && unhex(data->bindname) == NULL) ||
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews (data->bindpw != NULL && unhex(data->bindpw) == NULL)) {
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews free_data(data);
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews "LDAP sdb zone '%s': URL: bad hex values", zone);
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews return (ISC_R_FAILURE);
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews }
9cc53f2a0819301c2de7ab93197eee11e8a365e7Mark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews /* compute filterall and filterone once and for all */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (filter == NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->filteralllen = strlen(zone) + strlen("(zoneName=)") + 1;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->filteronelen = strlen(zone) + strlen("(&(zoneName=)(relativeDomainName=))") + MAXNAMELEN + 1;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews } else {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->filteralllen = strlen(filter) + strlen(zone) + strlen("(&(zoneName=))") + 1;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->filteronelen = strlen(filter) + strlen(zone) + strlen("(&(zoneName=)(relativeDomainName=))") + MAXNAMELEN + 1;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->filterall = isc_mem_get(ns_g_mctx, data->filteralllen);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (data->filterall == NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews free_data(data);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_NOMEMORY);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->filterone = isc_mem_get(ns_g_mctx, data->filteronelen);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (data->filterone == NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews free_data(data);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_NOMEMORY);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (filter == NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews sprintf(data->filterall, "(zoneName=%s)", zone);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews sprintf(data->filterone, "(&(zoneName=%s)(relativeDomainName=", zone);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews } else {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews sprintf(data->filterall, "(&%s(zoneName=%s))", filter, zone);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews sprintf(data->filterone, "(&%s(zoneName=%s)(relativeDomainName=", filter, zone);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->filtername = data->filterone + strlen(data->filterone);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews /* support URLs with literal IPv6 addresses */
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->hostname = isc_mem_strdup(ns_g_mctx, data->hostport + (*data->hostport == '[' ? 1 : 0));
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (data->hostname == NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews free_data(data);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_NOMEMORY);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews }
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (*data->hostport == '[' &&
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews (s = strchr(data->hostname, ']')) != NULL )
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews *s++ = '\0';
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews else
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews s = data->hostname;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews s = strchr(s, ':');
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews if (s != NULL) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews *s++ = '\0';
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->portno = atoi(s);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews } else
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews data->portno = LDAP_PORT;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews *dbdata = data;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews return (ISC_R_SUCCESS);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews}
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrewsstatic void
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrewsldapdb_destroy(const char *zone, void *driverdata, void **dbdata) {
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews struct ldapdb_data *data = *dbdata;
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews UNUSED(zone);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews UNUSED(driverdata);
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews
0ae34c3f6222ece01e0f710c7c0311f5cf9d9c0fMark Andrews free_data(data);
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington}
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellingtonstatic dns_sdbmethods_t ldapdb_methods = {
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington ldapdb_lookup,
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington NULL, /* authority */
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington ldapdb_allnodes,
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington ldapdb_create,
58f1ac8dadf2c1f215343a0b2d1df2df954c4b19Mark Andrews ldapdb_destroy,
58f1ac8dadf2c1f215343a0b2d1df2df954c4b19Mark Andrews NULL /* lookup2 */
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington};
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington/* Wrapper around dns_sdb_register() */
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellingtonisc_result_t
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellingtonldapdb_init(void) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington unsigned int flags =
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington DNS_SDBFLAG_RELATIVEOWNER |
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington DNS_SDBFLAG_RELATIVERDATA |
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington DNS_SDBFLAG_THREADSAFE;
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldapdb_lock(0);
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington return (dns_sdb_register("ldap", &ldapdb_methods, NULL, flags,
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington ns_g_mctx, &ldapdb));
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington}
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington/* Wrapper around dns_sdb_unregister() */
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellingtonvoid
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellingtonldapdb_clear(void) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington if (ldapdb != NULL) {
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington /* clean up thread data */
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington ldapdb_getconn(NULL);
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington dns_sdb_unregister(&ldapdb);
adf16bbdb65f8c0845d7c7a8ebc0836ec07bbfeeBrian Wellington }
bf49a52178db60df60f2316a3977b2249f7c0edbBrian Wellington}