Commit 967d1dcb authored by Howard Chu's avatar Howard Chu
Browse files

For ITS#157: Added LDAP backend for slapd, which also required adding

LDAP_OPT_MATCH_STRING to ldap.h and libldap/options.c.
parent 25316719
......@@ -198,6 +198,9 @@
/* define this for crypt(3) password support */
#undef SLAPD_CRYPT
/* define this to use SLAPD LDAP backend */
#undef SLAPD_LDAP
/* define this to use SLAPD LDBM backend */
#undef SLAPD_LDBM
......
This diff is collapsed.
......@@ -92,6 +92,7 @@ OL_ARG_ENABLE(wrappers,[ --enable-wrappers enable tcp wrapper support], no)dn
dnl SLAPD Backend options
OL_ARG_ENABLE(bdb2,[ --enable-bdb2 enable bdb2 backend], no)dnl
OL_ARG_ENABLE(ldap,[ --enable-ldap enable ldap backend], no)dnl
OL_ARG_ENABLE(ldbm,[ --enable-ldbm enable ldbm backend], yes)dnl
OL_ARG_WITH(ldbm_api,[ --with-ldbm-api use LDBM API], auto,
[auto db2 db mdbm gdbm ndbm manual])
......@@ -273,6 +274,7 @@ BUILD_SLAPD=no
BUILD_SLURPD=no
BUILD_BDB2=no
BUILD_LDAP=no
BUILD_LDBM=no
BUILD_PASSWD=no
BUILD_PERL=no
......@@ -1655,6 +1657,12 @@ if test "$ol_link_bdb2" != no ; then
BUILD_BDB2=yes
fi
if test "$ol_link_ldap" != no ; then
AC_DEFINE(SLAPD_LDAP,1)
BUILD_SLAPD=yes
BUILD_LDAP=yes
fi
if test "$ol_link_ldbm" != no ; then
AC_DEFINE(SLAPD_LDBM,1)
BUILD_SLAPD=yes
......@@ -1699,6 +1707,7 @@ dnl ----------------------------------------------------------------
AC_SUBST(BUILD_LDAPD)
AC_SUBST(BUILD_SLAPD)
AC_SUBST(BUILD_BDB2)
AC_SUBST(BUILD_LDAP)
AC_SUBST(BUILD_LDBM)
AC_SUBST(BUILD_PASSWD)
AC_SUBST(BUILD_PERL)
......@@ -1758,6 +1767,7 @@ servers/Makefile:build/top.mk:servers/Makefile.in:build/dir.mk \
servers/ldapd/Makefile:build/top.mk:servers/ldapd/Makefile.in:build/srv.mk \
servers/slapd/Makefile:build/top.mk:servers/slapd/Makefile.in:build/srv.mk \
servers/slapd/back-bdb2/Makefile:build/top.mk:servers/slapd/back-bdb2/Makefile.in:build/srv.mk \
servers/slapd/back-ldap/Makefile:build/top.mk:servers/slapd/back-ldap/Makefile.in:build/srv.mk \
servers/slapd/back-ldbm/Makefile:build/top.mk:servers/slapd/back-ldbm/Makefile.in:build/srv.mk \
servers/slapd/back-passwd/Makefile:build/top.mk:servers/slapd/back-passwd/Makefile.in:build/srv.mk \
servers/slapd/back-perl/Makefile:build/top.mk:servers/slapd/back-perl/Makefile.in:build/srv.mk \
......
......@@ -106,6 +106,7 @@ LDAP_BEGIN_DECL
#define LDAP_OPT_DEBUG_LEVEL 0x5001 /* debug level */
#define LDAP_OPT_TIMEOUT 0x5002 /* default timeout */
#define LDAP_OPT_REFHOPLIMIT 0x5003 /* ref hop limit */
#define LDAP_OPT_MATCH_STRING 0x5004 /* should have been in draft */
/* on/off values */
#define LDAP_OPT_ON ((void *) 1)
......
......@@ -172,6 +172,9 @@
/* define this for crypt(3) password support */
#undef SLAPD_CRYPT
/* define this to use SLAPD LDAP backend */
#undef SLAPD_LDAP
/* define this to use SLAPD LDBM backend */
#undef SLAPD_LDBM
......
......@@ -257,6 +257,9 @@ typedef char * caddr_t;
/* define this for crypt(3) password support */
/* #undef SLAPD_CRYPT */
/* define this to use SLAPD LDAP backend */
/* #undef SLAPD_LDAP */
/* define this to use SLAPD LDBM backend */
#define SLAPD_LDBM 1
......
......@@ -231,6 +231,25 @@ ldap_get_option(
return 0;
case LDAP_OPT_MATCH_STRING:
if(ld == NULL) {
/* bad param */
break;
}
/*
* draft-ietf-ldapext-ldap-c-api-01 doesn't require
* the client to have to free error strings, we do
*/
if( ld->ld_matched == NULL ) {
* (char **) outvalue = NULL;
} else {
* (char **) outvalue = strdup(ld->ld_matched);
}
return 0;
case LDAP_OPT_API_FEATURE_INFO: {
LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
int i;
......
Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
Permission is granted to anyone to use this software for any purpose
on any computer system, and to alter it and redistribute it, subject
to the following restrictions:
1. The author is not responsible for the consequences of use of this
software, no matter how awful, even if they arise from flaws in it.
2. The origin of this software must not be misrepresented, either by
explicit claim or by omission. Since few users ever read sources,
credits should appear in the documentation.
3. Altered versions must be plainly marked as such, and must not be
misrepresented as being the original software. Since few users
ever read sources, credits should appear in the documentation.
4. This notice may not be removed or altered.
XSRCS = version.c
SRCS = init.c config.c search.c bind.c unbind.c add.c compare.c delete.c \
modify.c modrdn.c
OBJS = init.o config.o search.o bind.o unbind.o add.o compare.o delete.o \
modify.o modrdn.o
LDAP_INCDIR= ../../../include
LDAP_LIBDIR= ../../../libraries
BUILD_OPT = "--enable-ldap"
BUILD_SRV = @BUILD_LDAP@
PROGRAMS = libback-ldap.a
XINCPATH = -I.. -I$(srcdir)/..
all-local-srv: FORCE
$(MAKE) $(MFLAGS) libback-ldap.a
libback-ldap.a: version.o
$(AR) ruv $@ $(OBJS) version.o
@$(RANLIB) $@
@touch ../.backend
version.c: $(OBJS) $(LDAP_LIBDEPEND)
@-$(RM) $@
$(MKVERSION) back-ldap > $@
/*
* Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to alter it and redistribute it, subject
* to the following restrictions:
*
* 1. The author is not responsible for the consequences of use of this
* software, no matter how awful, even if they arise from flaws in it.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits should appear in the documentation.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits should appear in the documentation.
*
* 4. This notice may not be removed or altered.
*/
static char Versionstr[] = " ldap backend %VERSION% (%WHEN%)\n\t%WHOANDWHERE%\n";
/* add.c - ldap backend add function */
/*
* Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to alter it and redistribute it, subject
* to the following restrictions:
*
* 1. The author is not responsible for the consequences of use of this
* software, no matter how awful, even if they arise from flaws in it.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits should appear in the documentation.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits should appear in the documentation.
*
* 4. This notice may not be removed or altered.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "slap.h"
#include "back-ldap.h"
int
ldap_back_add(
Backend *be,
Connection *conn,
Operation *op,
Entry *e
)
{
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
struct ldapconn *lc;
int i;
Attribute *a;
LDAPMod **attrs;
lc = ldap_back_getconn(li, conn, op);
if (!lc)
return( -1 );
if (!lc->bound) {
ldap_back_dobind(lc, op);
if (!lc->bound)
return( -1 );
}
/* Count number of attributes in entry */
for (i=1, a=e->e_attrs; a; i++, a=a->a_next)
;
/* Create array of LDAPMods for ldap_add() */
attrs = (LDAPMod **)ch_malloc(sizeof(LDAPMod *)*i);
attrs[i-1] = 0;
for (i=0, a=e->e_attrs; a; i++, a=a->a_next) {
attrs[i] = (LDAPMod *)ch_malloc(sizeof(LDAPMod));
attrs[i]->mod_op = LDAP_MOD_BVALUES;
attrs[i]->mod_type = a->a_type;
attrs[i]->mod_vals.modv_bvals = a->a_vals;
}
ldap_add_s(lc->ld, e->e_dn, attrs);
for (--i; i>= 0; --i)
free(attrs[i]);
free(attrs);
return( ldap_back_op_result( lc, op ));
}
/* back-ldap.h - ldap backend header file */
/*
* Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to alter it and redistribute it, subject
* to the following restrictions:
*
* 1. The author is not responsible for the consequences of use of this
* software, no matter how awful, even if they arise from flaws in it.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits should appear in the documentation.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits should appear in the documentation.
*
* 4. This notice may not be removed or altered.
*/
#ifndef SLAPD_LDAP_H
#define SLAPD_LDAP_H
#include "external.h"
LDAP_BEGIN_DECL
struct slap_conn;
struct slap_op;
struct ldapconn {
struct ldapconn *next;
struct slap_conn *conn;
LDAP *ld;
int bound;
};
struct ldapinfo {
char *host;
int port;
char *suffix;
ldap_pvt_thread_mutex_t conn_mutex;
struct ldapconn *lcs;
};
struct ldapconn *ldap_back_getconn(struct ldapinfo *li, struct slap_conn *conn,
struct slap_op *op);
LDAP_END_DECL
#endif
/* bind.c - ldap backend bind function */
/*
* Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to alter it and redistribute it, subject
* to the following restrictions:
*
* 1. The author is not responsible for the consequences of use of this
* software, no matter how awful, even if they arise from flaws in it.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits should appear in the documentation.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits should appear in the documentation.
*
* 4. This notice may not be removed or altered.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/socket.h>
#include <ac/string.h>
#include "slap.h"
#include "back-ldap.h"
int
ldap_back_bind(
Backend *be,
Connection *conn,
Operation *op,
char *dn,
int method,
struct berval *cred,
char **edn
)
{
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
struct ldapconn *lc;
*edn = NULL;
lc = ldap_back_getconn(li, conn, op);
if (!lc)
return( -1 );
if (ldap_bind_s(lc->ld, dn, cred->bv_val, method) != LDAP_SUCCESS)
return( ldap_back_op_result(lc, op) );
lc->bound = 1;
return( 0 );
}
struct ldapconn *
ldap_back_getconn(struct ldapinfo *li, Connection *conn, Operation *op)
{
struct ldapconn *lc;
LDAP *ld;
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
for (lc = li->lcs; lc; lc=lc->next)
if (lc->conn == conn)
break;
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
/* Looks like we didn't get a bind. Open a new session... */
if (!lc) {
ld = ldap_init(li->host, li->port);
if (!ld) {
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL,
"ldap_init failed" );
return( NULL );
}
lc = (struct ldapconn *)ch_malloc(sizeof(struct ldapconn));
lc->conn = conn;
lc->ld = ld;
lc->bound = 0;
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
lc->next = li->lcs;
li->lcs = lc;
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
}
return( lc );
}
ldap_back_dobind(struct ldapconn *lc, Operation *op)
{
if (lc->bound)
return;
if (ldap_bind_s(lc->ld, lc->conn->c_cdn, NULL, LDAP_AUTH_SIMPLE) !=
LDAP_SUCCESS)
ldap_back_op_result(lc, op);
else
lc->bound = 1;
}
ldap_back_op_result(struct ldapconn *lc, Operation *op)
{
int err;
char *msg;
char *match;
ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &err);
ldap_get_option(lc->ld, LDAP_OPT_ERROR_STRING, &msg);
ldap_get_option(lc->ld, LDAP_OPT_MATCH_STRING, &match);
send_ldap_result( lc->conn, op, err, match, msg);
free(match);
free(msg);
return( (err==LDAP_SUCCESS) ? 0 : -1 );
}
/* compare.c - ldap backend compare function */
/*
* Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to alter it and redistribute it, subject
* to the following restrictions:
*
* 1. The author is not responsible for the consequences of use of this
* software, no matter how awful, even if they arise from flaws in it.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits should appear in the documentation.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits should appear in the documentation.
*
* 4. This notice may not be removed or altered.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "slap.h"
#include "back-ldap.h"
int
ldap_back_compare(
Backend *be,
Connection *conn,
Operation *op,
char *dn,
Ava *ava
)
{
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
struct ldapconn *lc;
lc = ldap_back_getconn(li, conn, op);
if (!lc)
return( -1 );
if (!lc->bound) {
ldap_back_dobind(lc, op);
if (!lc->bound)
return( -1 );
}
ldap_compare_s( lc->ld, dn, ava->ava_type, ava->ava_value.bv_val );
return( ldap_back_op_result( lc, op ) );
}
/* config.c - ldap backend configuration file routine */
/*
* Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to alter it and redistribute it, subject
* to the following restrictions:
*
* 1. The author is not responsible for the consequences of use of this
* software, no matter how awful, even if they arise from flaws in it.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits should appear in the documentation.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits should appear in the documentation.
*
* 4. This notice may not be removed or altered.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "slap.h"
#include "back-ldap.h"
int
ldap_back_db_config(
BackendDB *be,
char *fname,
int lineno,
int argc,
char **argv
)
{
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
char *port;
if ( li == NULL ) {
fprintf( stderr, "%s: line %d: ldap backend info is null!\n",
fname, lineno );
return( 1 );
}
/* server address to query */
if ( strcasecmp( argv[0], "server" ) == 0 ) {
if (argc != 2) {
fprintf( stderr,
"%s: line %d: missing address in \"server <address>\" line\n",
fname, lineno );
return( 1 );
}
port=strchr(argv[1],':');
if (port) {
*port++ = '\0';
li->port = atoi(port);
}
li->host = ch_strdup(argv[1]);
/* anything else */
} else {
fprintf( stderr,
"%s: line %d: unknown directive \"%s\" in ldap database definition (ignored)\n",
fname, lineno, argv[0] );
}
return 0;
}
/* delete.c - ldap backend delete function */
/*
* Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to alter it and redistribute it, subject
* to the following restrictions:
*
* 1. The author is not responsible for the consequences of use of this
* software, no matter how awful, even if they arise from flaws in it.
*
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits should appear in the documentation.
*
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits should appear in the documentation.
*
* 4. This notice may not be removed or altered.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "slap.h"
#include "back-ldap.h"
int
ldap_back_delete(
Backend *be,
Connection *conn,
Operation *op,
char *dn
)
{
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
struct ldapconn *lc;
lc = ldap_back_getconn( li, conn, op );
if (!lc)
return( -1 );
if (!lc->bound) {
ldap_back_dobind(lc, op);
if (!lc->bound)
return( -1 );