/*
* ldapdb.c version 1.0-beta
*
* Copyright (C) 2002, 2004 Stig Venaas
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* Contributors: Jeremy C. McDermond
*/
/*
* If you want to use TLS, uncomment the define below
*/
/* #define LDAPDB_TLS */
/*
* If you are using an old LDAP API uncomment the define below. Only do this
* if you know what you're doing or get compilation errors on ldap_memfree().
* This also forces LDAPv2.
*/
/* #define LDAPDB_RFC1823API */
/* Using LDAPv3 by default, change this if you want v2 */
#ifndef LDAPDB_LDAP_VERSION
#endif
#include <config.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <ldap.h>
#include "ldapdb.h"
/*
* A simple database driver for LDAP
*/
/* enough for name with 8 labels of max length */
struct ldapdb_data {
char *hostport;
char *hostname;
int portno;
char *base;
int defaultttl;
char *filterall;
int filteralllen;
char *filterone;
int filteronelen;
char *filtername;
char *bindname;
char *bindpw;
#ifdef LDAPDB_TLS
int tls;
#endif
};
/* used by ldapdb_getconn */
struct ldapdb_entry {
void *index;
void *data;
};
return stack;
}
return NULL;
}
struct ldapdb_entry *item) {
}
switch (what) {
case 0:
break;
case 1:
break;
case -1:
break;
}
}
/* data == NULL means cleanup */
static LDAP **
{
unsigned long threadid;
/* cleanup */
/* lock out other threads */
ldapdb_lock(1);
while (allthreadsdata != NULL) {
}
}
ldapdb_lock(-1);
return (NULL);
}
/* look for connection data for current thread */
threadid = isc_thread_self();
if (threaddata == NULL) {
/* no data for this thread, create empty connection list */
if (threaddata == NULL)
return (NULL);
return (NULL);
}
/* need to lock out other threads here */
ldapdb_lock(1);
ldapdb_lock(-1);
}
/* threaddata points at the connection list for current thread */
/* look for existing connection to our server */
/* no connection data structure for this server, create one */
return (NULL);
conndata);
}
}
static void
{
#ifndef LDAPDB_RFC1823API
#endif
ldap_unbind(*ldp);
return;
#ifndef LDAPDB_RFC1823API
#endif
#ifdef LDAPDB_TLS
}
#endif
ldap_unbind(*ldp);
}
}
static isc_result_t
{
#ifdef LDAPDB_RFC1823API
void *ptr;
#else
#endif
return (ISC_R_FAILURE);
"LDAP sdb zone '%s': bind failed", zone);
return (ISC_R_FAILURE);
}
}
} else {
return (ISC_R_FAILURE);
}
}
if (msgid == -1) {
}
return (ISC_R_FAILURE);
}
/* Get the records one by one as they arrive and return them to bind */
/* not supporting continuation references at present */
if (errno != LDAP_RES_SEARCH_ENTRY) {
return (ISC_R_FAILURE);
}
/* only one entry per result message */
if (e == NULL) {
"LDAP sdb zone '%s': ldap_first_entry failed", zone);
return (ISC_R_FAILURE);
}
continue;
}
}
char *s;
for (s = a; *s; s++)
*s = toupper(*s);
s = strstr(a, "RECORD");
#ifndef LDAPDB_RFC1823API
ldap_memfree(a);
#endif
continue;
}
type[s - a] = '\0';
} else {
if (result != ISC_R_SUCCESS)
break;
}
}
; if (result != ISC_R_SUCCESS) {
#ifndef LDAPDB_RFC1823API
ldap_memfree(a);
#endif
return (ISC_R_FAILURE);
}
}
}
#ifndef LDAPDB_RFC1823API
ldap_memfree(a);
#endif
}
#ifndef LDAPDB_RFC1823API
#endif
/* free this result */
}
/* free final result */
return (result);
}
/* callback routines */
static isc_result_t
{
}
static isc_result_t
{
}
static char *
{
char *p, *s = in;
while ((s = strchr(s, '%'))) {
if (!(s[1] && s[2]))
return NULL;
return NULL;
return NULL;
}
return in;
}
/* returns 0 for ok, -1 for bad syntax, -2 for unknown critical extension */
static int
{
int critical;
while (extensions != NULL) {
if (s != NULL) {
*s++ = '\0';
next = s;
} else {
}
if (*extensions != '\0') {
if (s != NULL) {
*s++ = '\0';
} else {
}
name = extensions;
if (critical) {
name++;
}
if (*name == '\0') {
return -1;
}
#ifdef LDAPDB_TLS
#endif
} else if (critical) {
return -2;
}
}
extensions = next;
}
return 0;
}
static void
{
}
static isc_result_t
void *driverdata, void **dbdata)
{
int defaultttl;
/* we assume that only one thread will call create at a time */
/* want to do this only once for all instances */
if ((argc < 2)
return (ISC_R_FAILURE);
return (ISC_R_NOMEMORY);
return (ISC_R_NOMEMORY);
}
if (s != NULL) {
*s++ = '\0';
/* attrs, scope, filter etc? */
s = strchr(s, '?');
if (s != NULL) {
*s++ = '\0';
/* ignore attributes */
s = strchr(s, '?');
if (s != NULL) {
*s++ = '\0';
/* ignore scope */
s = strchr(s, '?');
if (s != NULL) {
*s++ = '\0';
/* filter */
filter = s;
s = strchr(s, '?');
if (s != NULL) {
*s++ = '\0';
/* extensions */
extensions = s;
s = strchr(s, '?');
if (s != NULL) {
*s++ = '\0';
}
if (*extensions == '\0') {
extensions = NULL;
}
}
if (*filter == '\0') {
}
}
}
}
}
}
/* parse extensions */
if (extensions != NULL) {
int err;
if (err < 0) {
/* err should be -1 or -2 */
if (err == -1) {
"LDAP sdb zone '%s': URL: extension syntax error", zone);
} else if (err == -2) {
"LDAP sdb zone '%s': URL: unknown critical extension", zone);
}
return (ISC_R_FAILURE);
}
}
"LDAP sdb zone '%s': URL: bad hex values", zone);
return (ISC_R_FAILURE);
}
/* compute filterall and filterone once and for all */
} else {
data->filteronelen = strlen(filter) + strlen(zone) + strlen("(&(zoneName=)(relativeDomainName=))") + MAXNAMELEN + 1;
}
return (ISC_R_NOMEMORY);
}
return (ISC_R_NOMEMORY);
}
} else {
}
/* support URLs with literal IPv6 addresses */
return (ISC_R_NOMEMORY);
}
*s++ = '\0';
else
s = strchr(s, ':');
if (s != NULL) {
*s++ = '\0';
} else
return (ISC_R_SUCCESS);
}
static void
}
NULL, /* authority */
};
/* Wrapper around dns_sdb_register() */
ldapdb_init(void) {
unsigned int flags =
ldapdb_lock(0);
}
/* Wrapper around dns_sdb_unregister() */
void
ldapdb_clear(void) {
/* clean up thread data */
}
}