mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-06 23:19:59 -05:00
Update slap_op to maintain dn and ndn (derived from conn->c_dn). Update ldbm_back_bind to return actual bound dn (including rootdn) for use in slapd_conn. Other backends use client dn. Modify other codes to use ndn (normalized uppercase dn) most everywhere. Aliasing, Suffixing and modrdn could use more work. Applied suffixing to compare and modrdn.
318 lines
6.1 KiB
C
318 lines
6.1 KiB
C
/* backend.c - routines for dealing with back-end databases */
|
|
|
|
|
|
#include "portable.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <ac/string.h>
|
|
#include <ac/socket.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include "slap.h"
|
|
|
|
|
|
#define BACKEND_GRAB_SIZE 10
|
|
|
|
int nbackends;
|
|
Backend *backends;
|
|
static int maxbackends;
|
|
|
|
Backend *
|
|
new_backend(
|
|
char *type
|
|
)
|
|
{
|
|
Backend *be;
|
|
int foundit;
|
|
|
|
if ( nbackends == maxbackends ) {
|
|
maxbackends += BACKEND_GRAB_SIZE;
|
|
backends = (Backend *) ch_realloc( (char *) backends,
|
|
maxbackends * sizeof(Backend) );
|
|
memset( &backends[nbackends], '\0', BACKEND_GRAB_SIZE *
|
|
sizeof(Backend) );
|
|
}
|
|
|
|
be = &backends[nbackends++];
|
|
be->be_sizelimit = defsize;
|
|
be->be_timelimit = deftime;
|
|
foundit = 0;
|
|
|
|
#ifdef SLAPD_LDBM
|
|
if ( strcasecmp( type, "ldbm" ) == 0 ) {
|
|
be->be_bind = ldbm_back_bind;
|
|
be->be_unbind = ldbm_back_unbind;
|
|
be->be_search = ldbm_back_search;
|
|
be->be_compare = ldbm_back_compare;
|
|
be->be_modify = ldbm_back_modify;
|
|
be->be_modrdn = ldbm_back_modrdn;
|
|
be->be_add = ldbm_back_add;
|
|
be->be_delete = ldbm_back_delete;
|
|
be->be_abandon = ldbm_back_abandon;
|
|
be->be_config = ldbm_back_config;
|
|
be->be_init = ldbm_back_init;
|
|
be->be_close = ldbm_back_close;
|
|
#ifdef SLAPD_ACLGROUPS
|
|
be->be_group = ldbm_back_group;
|
|
#endif
|
|
be->be_type = "ldbm";
|
|
foundit = 1;
|
|
}
|
|
#endif
|
|
|
|
#ifdef SLAPD_PASSWD
|
|
if ( strcasecmp( type, "passwd" ) == 0 ) {
|
|
be->be_bind = NULL;
|
|
be->be_unbind = NULL;
|
|
be->be_search = passwd_back_search;
|
|
be->be_compare = NULL;
|
|
be->be_modify = NULL;
|
|
be->be_modrdn = NULL;
|
|
be->be_add = NULL;
|
|
be->be_delete = NULL;
|
|
be->be_abandon = NULL;
|
|
be->be_config = passwd_back_config;
|
|
be->be_init = NULL;
|
|
be->be_close = NULL;
|
|
#ifdef SLAPD_ACLGROUPS
|
|
be->be_group = NULL;
|
|
#endif
|
|
be->be_type = "passwd";
|
|
foundit = 1;
|
|
}
|
|
#endif
|
|
|
|
#ifdef SLAPD_SHELL
|
|
if ( strcasecmp( type, "shell" ) == 0 ) {
|
|
be->be_bind = shell_back_bind;
|
|
be->be_unbind = shell_back_unbind;
|
|
be->be_search = shell_back_search;
|
|
be->be_compare = shell_back_compare;
|
|
be->be_modify = shell_back_modify;
|
|
be->be_modrdn = shell_back_modrdn;
|
|
be->be_add = shell_back_add;
|
|
be->be_delete = shell_back_delete;
|
|
be->be_abandon = shell_back_abandon;
|
|
be->be_config = shell_back_config;
|
|
be->be_init = shell_back_init;
|
|
be->be_close = NULL;
|
|
#ifdef SLAPD_ACLGROUPS
|
|
be->be_group = NULL;
|
|
#endif
|
|
be->be_type = "shell";
|
|
foundit = 1;
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef SLAPD_PERL
|
|
if ( strcasecmp( type, "perl" ) == 0 ) {
|
|
#ifdef notdef
|
|
be->be_abandon = perl_back_abandon;
|
|
be->be_bind = perl_back_bind;
|
|
#else
|
|
be->be_abandon = NULL;
|
|
be->be_bind = NULL;
|
|
#endif
|
|
be->be_unbind = perl_back_unbind;
|
|
be->be_search = perl_back_search;
|
|
be->be_compare = perl_back_compare;
|
|
be->be_modify = perl_back_modify;
|
|
be->be_modrdn = perl_back_modrdn;
|
|
be->be_add = perl_back_add;
|
|
be->be_delete = perl_back_delete;
|
|
be->be_config = perl_back_config;
|
|
be->be_init = perl_back_init;
|
|
be->be_close = perl_back_close;
|
|
be->be_type = "perl";
|
|
foundit = 1;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
if ( be->be_init != NULL ) {
|
|
(*be->be_init)( be );
|
|
}
|
|
|
|
if ( foundit == 0 ) {
|
|
fprintf( stderr, "Unrecognized database type (%s)\n", type );
|
|
exit( 1 );
|
|
}
|
|
|
|
return( be );
|
|
}
|
|
|
|
Backend *
|
|
select_backend( char * dn )
|
|
{
|
|
int i, j, len, dnlen;
|
|
|
|
dnlen = strlen( dn );
|
|
for ( i = 0; i < nbackends; i++ ) {
|
|
for ( j = 0; backends[i].be_suffix != NULL &&
|
|
backends[i].be_suffix[j] != NULL; j++ )
|
|
{
|
|
len = strlen( backends[i].be_suffix[j] );
|
|
|
|
if ( len > dnlen ) {
|
|
continue;
|
|
}
|
|
|
|
if ( strcasecmp( backends[i].be_suffix[j],
|
|
dn + (dnlen - len) ) == 0 ) {
|
|
return( &backends[i] );
|
|
}
|
|
}
|
|
}
|
|
|
|
/* if no proper suffix could be found then check for aliases */
|
|
for ( i = 0; i < nbackends; i++ ) {
|
|
for ( j = 0;
|
|
backends[i].be_suffixAlias != NULL &&
|
|
backends[i].be_suffixAlias[j] != NULL;
|
|
j += 2 )
|
|
{
|
|
len = strlen( backends[i].be_suffixAlias[j] );
|
|
|
|
if ( len > dnlen ) {
|
|
continue;
|
|
}
|
|
|
|
if ( strcasecmp( backends[i].be_suffixAlias[j],
|
|
dn + (dnlen - len) ) == 0 ) {
|
|
return( &backends[i] );
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef LDAP_ALLOW_NULL_SEARCH_BASE
|
|
/* Add greg@greg.rim.or.jp
|
|
* It's quick hack for cheap client
|
|
* Some browser offer a NULL base at ldap_search
|
|
*
|
|
* Should only be used as a last resort. -Kdz
|
|
*/
|
|
if(dnlen == 0) {
|
|
Debug( LDAP_DEBUG_TRACE,
|
|
"select_backend: use default backend\n", 0, 0, 0 );
|
|
return( &backends[0] );
|
|
}
|
|
#endif /* LDAP_ALLOW_NULL_SEARCH_BASE */
|
|
|
|
return( NULL );
|
|
}
|
|
|
|
int
|
|
be_issuffix(
|
|
Backend *be,
|
|
char *suffix
|
|
)
|
|
{
|
|
int i;
|
|
|
|
for ( i = 0; be->be_suffix != NULL && be->be_suffix[i] != NULL; i++ ) {
|
|
if ( strcasecmp( be->be_suffix[i], suffix ) == 0 ) {
|
|
return( 1 );
|
|
}
|
|
}
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
int
|
|
be_isroot( Backend *be, char *ndn )
|
|
{
|
|
int rc;
|
|
|
|
if ( ndn == NULL || be->be_root_ndn == NULL ) {
|
|
return( 0 );
|
|
}
|
|
|
|
rc = strcmp( be->be_root_ndn, ndn ) ? 0 : 1;
|
|
|
|
return(rc);
|
|
}
|
|
|
|
char *
|
|
be_root_dn( Backend *be )
|
|
{
|
|
int rc;
|
|
|
|
if ( be->be_root_dn == NULL ) {
|
|
return( "" );
|
|
}
|
|
|
|
return be->be_root_dn;
|
|
}
|
|
|
|
int
|
|
be_isroot_pw( Backend *be, char *ndn, struct berval *cred )
|
|
{
|
|
int result;
|
|
|
|
if ( ! be_isroot( be, ndn ) ) {
|
|
return( 0 );
|
|
}
|
|
|
|
#ifdef SLAPD_CRYPT
|
|
pthread_mutex_lock( &crypt_mutex );
|
|
#endif
|
|
|
|
result = lutil_passwd( cred->bv_val, be->be_root_pw );
|
|
|
|
#ifdef SLAPD_CRYPT
|
|
pthread_mutex_unlock( &crypt_mutex );
|
|
#endif
|
|
|
|
return result == 0;
|
|
}
|
|
|
|
void
|
|
be_close( void )
|
|
{
|
|
int i;
|
|
|
|
for ( i = 0; i < nbackends; i++ ) {
|
|
if ( backends[i].be_close != NULL ) {
|
|
(*backends[i].be_close)( &backends[i] );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
be_unbind(
|
|
Connection *conn,
|
|
Operation *op
|
|
)
|
|
{
|
|
int i;
|
|
|
|
for ( i = 0; i < nbackends; i++ ) {
|
|
if ( backends[i].be_unbind != NULL ) {
|
|
(*backends[i].be_unbind)( &backends[i], conn, op );
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef SLAPD_ACLGROUPS
|
|
int
|
|
be_group(
|
|
Backend *be,
|
|
Entry *target,
|
|
char *gr_ndn,
|
|
char *op_ndn,
|
|
char *objectclassValue,
|
|
char *groupattrName
|
|
)
|
|
{
|
|
if (be->be_group)
|
|
return( be->be_group(be, target, gr_ndn, op_ndn,
|
|
objectclassValue, groupattrName) );
|
|
else
|
|
return(1);
|
|
}
|
|
#endif
|