Round two of referrals/aliases: WORK IN PROGRESS, may not compile!

Basic support for "named referrals", manageDSAit control.
Disabled alias support for now.  Will implemented "named aliases"
to replace current alias/suffix-alias support.
This commit is contained in:
Kurt Zeilenga 1999-07-12 19:02:42 +00:00
parent 671888193b
commit 1a7ea74d55
41 changed files with 4325 additions and 1537 deletions

725
build/main.dsw Normal file
View file

@ -0,0 +1,725 @@
Microsoft Developer Studio Workspace File, Format Version 5.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "apitest"=..\libraries\libldap\apitest.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libldap
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
}}}
###############################################################################
Project: "apitest_r"=..\libraries\libldap_r\apitest_r.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libldap_r
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
}}}
###############################################################################
Project: "backldbm"="..\servers\slapd\back-ldbm\backldbm.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "build"=.\build.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name apitest
End Project Dependency
Begin Project Dependency
Project_Dep_Name apitest_r
End Project Dependency
Begin Project Dependency
Project_Dep_Name dtest
End Project Dependency
Begin Project Dependency
Project_Dep_Name etest
End Project Dependency
Begin Project Dependency
Project_Dep_Name ldapdelete
End Project Dependency
Begin Project Dependency
Project_Dep_Name ldapmodify
End Project Dependency
Begin Project Dependency
Project_Dep_Name ldapmodrdn
End Project Dependency
Begin Project Dependency
Project_Dep_Name ldappasswd
End Project Dependency
Begin Project Dependency
Project_Dep_Name ldapsearch
End Project Dependency
Begin Project Dependency
Project_Dep_Name ldbmcat
End Project Dependency
Begin Project Dependency
Project_Dep_Name ldbmtest
End Project Dependency
Begin Project Dependency
Project_Dep_Name ldif
End Project Dependency
Begin Project Dependency
Project_Dep_Name ldif2id2children
End Project Dependency
Begin Project Dependency
Project_Dep_Name ldif2id2entry
End Project Dependency
Begin Project Dependency
Project_Dep_Name ldif2index
End Project Dependency
Begin Project Dependency
Project_Dep_Name ldif2ldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name slapd
End Project Dependency
Begin Project Dependency
Project_Dep_Name testavl
End Project Dependency
Begin Project Dependency
Project_Dep_Name ud
End Project Dependency
}}}
###############################################################################
Project: "dtest"=..\libraries\liblber\dtest.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
}}}
###############################################################################
Project: "etest"=..\libraries\liblber\etest.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
}}}
###############################################################################
Project: "ldapdelete"=..\clients\tools\ldapdelete.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libldap
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
}}}
###############################################################################
Project: "ldapmodify"=..\clients\tools\ldapmodify.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libldap
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldif
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
}}}
###############################################################################
Project: "ldapmodrdn"=..\clients\tools\ldapmodrdn.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libldap
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
}}}
###############################################################################
Project: "ldappasswd"=..\clients\tools\ldappasswd.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libldap
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
}}}
###############################################################################
Project: "ldapsearch"=..\clients\tools\ldapsearch.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libldap
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldif
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
}}}
###############################################################################
Project: "ldbmcat"=..\servers\slapd\tools\ldbmcat.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name backldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name libslapd
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldap_r
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
}}}
###############################################################################
Project: "ldbmtest"=..\servers\slapd\tools\ldbmtest.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name backldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldap_r
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name libslapd
End Project Dependency
Begin Project Dependency
Project_Dep_Name libavl
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldif
End Project Dependency
}}}
###############################################################################
Project: "ldif"=..\servers\slapd\tools\ldif.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
}}}
###############################################################################
Project: "ldif2id2children"=..\servers\slapd\tools\ldif2id2children.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name backldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldap_r
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldif
End Project Dependency
Begin Project Dependency
Project_Dep_Name libavl
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name libslapd
End Project Dependency
}}}
###############################################################################
Project: "ldif2id2entry"=..\servers\slapd\tools\ldif2id2entry.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name backldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name libavl
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldap_r
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldif
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name libslapd
End Project Dependency
}}}
###############################################################################
Project: "ldif2index"=..\servers\slapd\tools\ldif2index.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name backldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldap_r
End Project Dependency
Begin Project Dependency
Project_Dep_Name libavl
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldif
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name libslapd
End Project Dependency
}}}
###############################################################################
Project: "ldif2ldbm"=..\servers\slapd\tools\ldif2ldbm.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name backldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name libavl
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldap_r
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldif
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
Begin Project Dependency
Project_Dep_Name libslapd
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldbm
End Project Dependency
}}}
###############################################################################
Project: "libavl"=..\libraries\libavl\libavl.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "liblber"=..\libraries\liblber\liblber.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "libldap"=..\libraries\libldap\libldap.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "libldap_r"=..\libraries\libldap_r\libldap_r.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "libldbm"=..\libraries\libldbm\libldbm.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "libldif"=..\libraries\libldif\libldif.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "liblutil"=..\libraries\liblutil\liblutil.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "libslapd"=..\servers\slapd\libslapd.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "ltest"=..\libraries\libldap\ltest.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libldap
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
}}}
###############################################################################
Project: "ltest_r"=..\libraries\libldap_r\ltest_r.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libldap_r
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
}}}
###############################################################################
Project: "setup"=..\include\setup.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "slapd"=..\servers\slapd\slapd.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name backldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldap_r
End Project Dependency
Begin Project Dependency
Project_Dep_Name libavl
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldif
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
Begin Project Dependency
Project_Dep_Name setup
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
Begin Project Dependency
Project_Dep_Name libldbm
End Project Dependency
Begin Project Dependency
Project_Dep_Name libslapd
End Project Dependency
}}}
###############################################################################
Project: "testavl"=..\libraries\libavl\testavl.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libavl
End Project Dependency
}}}
###############################################################################
Project: "ud"=..\clients\ud\ud.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name libldap
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblber
End Project Dependency
Begin Project Dependency
Project_Dep_Name liblutil
End Project Dependency
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View file

@ -0,0 +1,133 @@
# Microsoft Developer Studio Project File - Name="libldbm" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=libldbm - Win32 Single Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "libldbm.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "libldbm.mak" CFG="libldbm - Win32 Single Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "libldbm - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "libldbm - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "libldbm - Win32 Single Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "libldbm - Win32 Single Release" (based on\
"Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
!IF "$(CFG)" == "libldbm - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\Release"
# PROP Intermediate_Dir "Release\libldbm"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\Release\oldbm32.lib"
!ELSEIF "$(CFG)" == "libldbm - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\Debug"
# PROP Intermediate_Dir "Debug\libldbm"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\Debug\oldbm32.lib"
!ELSEIF "$(CFG)" == "libldbm - Win32 Single Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "libldbm_"
# PROP BASE Intermediate_Dir "libldbm_"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\SDebug"
# PROP Intermediate_Dir "SDebug\libldbm"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo /out:"..\Debug\oldbm32.lib"
# ADD LIB32 /nologo /out:"..\SDebug\oldbm32.lib"
!ELSEIF "$(CFG)" == "libldbm - Win32 Single Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "libldbm0"
# PROP BASE Intermediate_Dir "libldbm0"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\SRelease"
# PROP Intermediate_Dir "SRelease\libldbm"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo /out:"..\Release\oldbm32.lib"
# ADD LIB32 /nologo /out:"..\SRelease\oldbm32.lib"
!ENDIF
# Begin Target
# Name "libldbm - Win32 Release"
# Name "libldbm - Win32 Debug"
# Name "libldbm - Win32 Single Debug"
# Name "libldbm - Win32 Single Release"
# Begin Source File
SOURCE=.\ldbm.c
# End Source File
# Begin Source File
SOURCE=..\..\include\ldbm.h
# End Source File
# End Target
# End Project

View file

@ -1,35 +1,22 @@
/* acl.c - routines to parse and check acl's */
#include "portable.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#ifdef sunos5
#include "regexpr.h"
#else
#include "regex.h"
#endif
#include <ac/regex.h>
#include <ac/socket.h>
#include <ac/string.h>
#include "slap.h"
extern Attribute *attr_find();
extern char *re_comp();
extern struct acl *global_acl;
extern int global_default_access;
extern char *access2str();
extern char *dn_normalize_case();
static int regex_matches(char *pat, char *str, char *buf, regmatch_t *matches);
static void string_expand(char *newbuf, int bufsiz, char *pattern,
char *match, regmatch_t *matches);
int acl_access_allowed();
int access_allowed();
struct acl *acl_get_applicable();
static int regex_matches();
extern pthread_mutex_t regex_mutex;
/*
* access_allowed - check whether dn is allowed the requested access
* access_allowed - check whether op->o_ndn is allowed the requested access
* to entry e, attribute attr, value val. if val is null, access to
* the whole attribute is assumed (all values). this routine finds
* the applicable acl and calls acl_access_allowed() to make the
@ -47,19 +34,55 @@ access_allowed(
Entry *e,
char *attr,
struct berval *val,
char *dn,
int access
)
{
int rc;
struct acl *a;
int rc;
struct acl *a;
char *edn;
regmatch_t matches[MAXREMATCHES];
int i;
int n;
if ( be == NULL ) {
return( 0 );
}
a = acl_get_applicable( be, op, e, attr );
rc = acl_access_allowed( a, be, conn, e, val, op, access );
edn = e->e_ndn;
Debug( LDAP_DEBUG_ACL, "\n=> access_allowed: entry (%s) attr (%s)\n",
e->e_dn, attr, 0 );
/* the lastmod attributes are ignored by ACL checking */
if ( oc_check_no_usermod_attr( attr ) ) {
Debug( LDAP_DEBUG_ACL, "Operational attribute: %s access allowed\n",
attr, 0, 0 );
return(1);
}
memset(matches, 0, sizeof(matches));
a = acl_get_applicable( be, op, e, attr, MAXREMATCHES, matches );
if (a) {
for (i = 0; i < MAXREMATCHES && matches[i].rm_so > 0; i++) {
Debug( LDAP_DEBUG_ARGS, "=> match[%d]: %d %d ", i,
(int)matches[i].rm_so, (int)matches[i].rm_eo );
if( matches[i].rm_so <= matches[0].rm_eo ) {
for ( n = matches[i].rm_so; n < matches[i].rm_eo; n++) {
Debug( LDAP_DEBUG_ARGS, "%c", edn[n], 0, 0 );
}
}
Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 );
}
}
rc = acl_access_allowed( a, be, conn, e, val, op, access, edn, matches );
Debug( LDAP_DEBUG_ACL, "\n=> access_allowed: exit (%s) attr (%s)\n",
e->e_dn, attr, 0);
return( rc );
}
@ -75,72 +98,94 @@ acl_get_applicable(
Backend *be,
Operation *op,
Entry *e,
char *attr
char *attr,
int nmatch,
regmatch_t *matches
)
{
int i;
struct acl *a;
char *edn;
char *edn;
Debug( LDAP_DEBUG_ACL, "=> acl_get: entry (%s) attr (%s)\n", e->e_dn,
attr, 0 );
Debug( LDAP_DEBUG_ACL, "\n=> acl_get: entry (%s) attr (%s)\n",
e->e_dn, attr, 0 );
if ( be_isroot( be, op->o_dn ) ) {
if ( be_isroot( be, op->o_ndn ) ) {
Debug( LDAP_DEBUG_ACL,
"<= acl_get: no acl applicable to database root\n", 0, 0,
0 );
return( NULL );
}
edn = e->e_ndn;
Debug( LDAP_DEBUG_ARGS, "=> acl_get: edn %s\n", edn, 0, 0 );
/* check for a backend-specific acl that matches the entry */
for ( i = 1, a = be->be_acl; a != NULL; a = a->acl_next, i++ ) {
if ( a->acl_dnpat != NULL ) {
edn = dn_normalize_case( strdup( e->e_dn ) );
if ( ! regex_matches( a->acl_dnpat, edn ) ) {
free( edn );
if (a->acl_dnpat != NULL) {
Debug( LDAP_DEBUG_TRACE, "=> dnpat: [%d] %s nsub: %d\n",
i, a->acl_dnpat, (int) a->acl_dnre.re_nsub);
if (regexec(&a->acl_dnre, edn, nmatch, matches, 0))
continue;
}
free( edn );
else
Debug( LDAP_DEBUG_TRACE, "=> acl_get:[%d] backend ACL match\n",
i, 0, 0);
}
if ( a->acl_filter != NULL ) {
if ( test_filter( NULL, NULL, NULL, e, a->acl_filter )
!= 0 ) {
if ( test_filter( NULL, NULL, NULL, e, a->acl_filter ) != 0 ) {
continue;
}
}
Debug( LDAP_DEBUG_ARGS, "=> acl_get: [%d] check attr %s\n", i, attr, 0);
if ( attr == NULL || a->acl_attrs == NULL ||
charray_inlist( a->acl_attrs, attr ) ) {
Debug( LDAP_DEBUG_ACL, "<= acl_get: backend acl #%d\n",
i, e->e_dn, attr );
charray_inlist( a->acl_attrs, attr ) )
{
Debug( LDAP_DEBUG_ACL, "<= acl_get: [%d] backend acl %s attr: %s\n",
i, e->e_dn, attr );
return( a );
}
matches[0].rm_so = matches[0].rm_eo = -1;
}
/* check for a global acl that matches the entry */
for ( i = 1, a = global_acl; a != NULL; a = a->acl_next, i++ ) {
if ( a->acl_dnpat != NULL ) {
edn = dn_normalize_case( strdup( e->e_dn ) );
if ( ! regex_matches( a->acl_dnpat, edn ) ) {
free( edn );
if (a->acl_dnpat != NULL) {
Debug( LDAP_DEBUG_TRACE, "=> dnpat: [%d] %s nsub: %d\n",
i, a->acl_dnpat, (int) a->acl_dnre.re_nsub);
if (regexec(&a->acl_dnre, edn, nmatch, matches, 0)) {
continue;
} else {
Debug( LDAP_DEBUG_TRACE, "=> acl_get: [%d] global ACL match\n",
i, 0, 0);
}
free( edn );
}
if ( a->acl_filter != NULL ) {
if ( test_filter( NULL, NULL, NULL, e, a->acl_filter )
!= 0 ) {
if ( test_filter( NULL, NULL, NULL, e, a->acl_filter ) != 0 ) {
continue;
}
}
if ( attr == NULL || a->acl_attrs == NULL || charray_inlist(
a->acl_attrs, attr ) ) {
Debug( LDAP_DEBUG_ACL, "<= acl_get: global acl #%d\n",
i, e->e_dn, attr );
Debug( LDAP_DEBUG_ARGS, "=> acl_get: [%d] check attr\n", i, 0, 0);
if ( attr == NULL || a->acl_attrs == NULL ||
charray_inlist( a->acl_attrs, attr ) )
{
Debug( LDAP_DEBUG_ACL, "<= acl_get: [%d] global acl %s attr: %s\n",
i, e->e_dn, attr );
return( a );
}
}
Debug( LDAP_DEBUG_ACL, "<= acl_get: no match\n", 0, 0, 0 );
matches[0].rm_so = matches[0].rm_eo = -1;
}
Debug( LDAP_DEBUG_ACL, "<= acl_get: no match\n", 0, 0, 0 );
return( NULL );
}
@ -161,144 +206,182 @@ acl_access_allowed(
Entry *e,
struct berval *val,
Operation *op,
int access
int access,
char *edn,
regmatch_t *matches
)
{
int i;
char *edn, *odn;
struct access *b;
Attribute *at;
struct berval bv;
int default_access;
Debug( LDAP_DEBUG_ACL, "=> acl: %s access to value \"%s\" by \"%s\"\n",
access2str( access ), val ? val->bv_val : "any", op->o_dn ?
op->o_dn : "" );
Debug( LDAP_DEBUG_ACL,
"\n=> acl_access_allowed: %s access to entry \"%s\"\n",
access2str( access ), e->e_dn, 0 );
if ( be_isroot( be, op->o_dn ) ) {
Debug( LDAP_DEBUG_ACL, "<= acl: granted to database root\n",
Debug( LDAP_DEBUG_ACL,
"\n=> acl_access_allowed: %s access to value \"%s\" by \"%s\"\n",
access2str( access ),
val ? val->bv_val : "any",
op->o_ndn ? op->o_ndn : "" );
if ( be_isroot( be, op->o_ndn ) ) {
Debug( LDAP_DEBUG_ACL,
"<= acl_access_allowed: granted to database root\n",
0, 0, 0 );
return( 1 );
}
default_access = be->be_dfltaccess ? be->be_dfltaccess :
global_default_access;
default_access = be->be_dfltaccess ? be->be_dfltaccess : global_default_access;
if ( a == NULL ) {
Debug( LDAP_DEBUG_ACL,
"<= acl: %s by default (no matching to)\n",
"<= acl_access_allowed: %s by default (no matching to)\n",
default_access >= access ? "granted" : "denied", 0, 0 );
return( default_access >= access );
}
odn = NULL;
if ( op->o_dn != NULL ) {
odn = dn_normalize_case( strdup( op->o_dn ) );
bv.bv_val = odn;
bv.bv_len = strlen( odn );
if ( op->o_ndn != NULL ) {
bv.bv_val = op->o_ndn;
bv.bv_len = strlen( bv.bv_val );
}
for ( i = 1, b = a->acl_access; b != NULL; b = b->a_next, i++ ) {
if ( b->a_dnpat != NULL ) {
Debug( LDAP_DEBUG_TRACE, "<= check a_dnpat: %s\n",
b->a_dnpat, 0, 0);
/*
* if access applies to the entry itself, and the
* user is bound as somebody in the same namespace as
* the entry, OR the given dn matches the dn pattern
*/
if ( strcasecmp( b->a_dnpat, "self" ) == 0 && op->o_dn
!= NULL && *(op->o_dn) && e->e_dn != NULL ) {
edn = dn_normalize_case( strdup( e->e_dn ) );
if ( strcasecmp( edn, op->o_dn ) == 0 ) {
free( edn );
if ( odn ) free( odn );
Debug( LDAP_DEBUG_ACL,
"<= acl: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >=
access ? "granted" : "denied", 0 );
if ( strcasecmp( b->a_dnpat, "anonymous" ) == 0 &&
(op->o_ndn == NULL || *(op->o_ndn) == '\0' ) )
{
Debug( LDAP_DEBUG_ACL,
"<= acl_access_allowed: matched by clause #%d access %s\n",
i, ACL_GRANT(b->a_access, access)
? "granted" : "denied", 0 );
return( (b->a_access & ~ACL_SELF)
>= access );
return ACL_GRANT(b->a_access, access );
} else if ( strcasecmp( b->a_dnpat, "self" ) == 0 &&
op->o_ndn != NULL && *(op->o_ndn) && e->e_dn != NULL )
{
if ( strcmp( edn, op->o_ndn ) == 0 ) {
Debug( LDAP_DEBUG_ACL,
"<= acl_access_allowed: matched by clause #%d access %s\n",
i, ACL_GRANT(b->a_access, access)
? "granted" : "denied", 0 );
return ACL_GRANT(b->a_access, access );
}
free( edn );
} else {
if ( regex_matches( b->a_dnpat, odn ) ) {
if ( odn ) free( odn );
if ( regex_matches( b->a_dnpat, op->o_ndn, edn, matches ) ) {
Debug( LDAP_DEBUG_ACL,
"<= acl: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ?
"granted" : "denied", 0 );
"<= acl_access_allowed: matched by clause #%d access %s\n",
i, ACL_GRANT(b->a_access, access)
? "granted" : "denied", 0 );
return( (b->a_access & ~ACL_SELF)
>= access );
return ACL_GRANT(b->a_access, access );
}
}
}
if ( b->a_addrpat != NULL ) {
if ( regex_matches( b->a_addrpat, conn->c_addr ) ) {
if ( odn ) free( odn );
if ( regex_matches( b->a_addrpat, conn->c_client_addr,
edn, matches ) )
{
Debug( LDAP_DEBUG_ACL,
"<= acl: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ?
"granted" : "denied", 0 );
"<= acl_access_allowed: matched by clause #%d access %s\n",
i, ACL_GRANT(b->a_access, access)
? "granted" : "denied", 0 );
return( (b->a_access & ~ACL_SELF) >= access );
return ACL_GRANT(b->a_access, access );
}
}
if ( b->a_domainpat != NULL ) {
if ( regex_matches( b->a_domainpat, conn->c_domain ) ) {
if ( odn ) free( odn );
Debug( LDAP_DEBUG_ARGS, "<= check a_domainpath: %s\n",
b->a_domainpat, 0, 0 );
if ( regex_matches( b->a_domainpat, conn->c_client_name,
edn, matches ) )
{
Debug( LDAP_DEBUG_ACL,
"<= acl: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ?
"granted" : "denied", 0 );
"<= acl_access_allowed: matched by clause #%d access %s\n",
i, ACL_GRANT(b->a_access, access)
? "granted" : "denied", 0 );
return( (b->a_access & ~ACL_SELF) >= access );
return ACL_GRANT(b->a_access, access );
}
}
if ( b->a_dnattr != NULL && op->o_dn != NULL ) {
if ( b->a_dnattr != NULL && op->o_ndn != NULL ) {
Debug( LDAP_DEBUG_ARGS, "<= check a_dnattr: %s\n",
b->a_dnattr, 0, 0);
/* see if asker is listed in dnattr */
if ( (at = attr_find( e->e_attrs, b->a_dnattr ))
!= NULL && value_find( at->a_vals, &bv,
at->a_syntax, 3 ) == 0 )
if ( (at = attr_find( e->e_attrs, b->a_dnattr )) != NULL &&
value_find( at->a_vals, &bv, at->a_syntax, 1 ) == 0 )
{
if ( (b->a_access & ACL_SELF) && (val == NULL
|| value_cmp( &bv, val, at->a_syntax,
2 )) ) {
if ( ACL_IS_SELF(b->a_access) &&
(val == NULL || value_cmp( &bv, val, at->a_syntax, 2 )) )
{
continue;
}
if ( odn ) free( odn );
Debug( LDAP_DEBUG_ACL,
"<= acl: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ?
"granted" : "denied", 0 );
"<= acl_acces_allowed: matched by clause #%d access %s\n",
i, ACL_GRANT(b->a_access, access)
? "granted" : "denied", 0 );
return( (b->a_access & ~ACL_SELF) >= access );
return ACL_GRANT(b->a_access, access );
}
/* asker not listed in dnattr - check for self access */
if ( ! (b->a_access & ACL_SELF) || val == NULL ||
value_cmp( &bv, val, at->a_syntax, 2 ) != 0 ) {
if ( ! ACL_IS_SELF(b->a_access) || val == NULL ||
value_cmp( &bv, val, at->a_syntax, 2 ) != 0 )
{
continue;
}
if ( odn ) free( odn );
Debug( LDAP_DEBUG_ACL,
"<= acl: matched by clause #%d (self) access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ? "granted"
: "denied", 0 );
"<= acl_access_allowed: matched by clause #%d (self) access %s\n",
i, ACL_GRANT(b->a_access, access)
? "granted" : "denied", 0 );
return( (b->a_access & ~ACL_SELF) >= access );
return ACL_GRANT(b->a_access, access );
}
if ( b->a_group != NULL && op->o_ndn != NULL ) {
char buf[1024];
/* b->a_group is an unexpanded entry name, expanded it should be an
* entry with objectclass group* and we test to see if odn is one of
* the values in the attribute group
*/
/* see if asker is listed in dnattr */
string_expand(buf, sizeof(buf), b->a_group, edn, matches);
(void) dn_normalize_case(buf);
if (backend_group(be, e, buf, op->o_ndn,
b->a_group_oc, b->a_group_at) == 0)
{
Debug( LDAP_DEBUG_ACL,
"<= acl_access_allowed: matched by clause #%d (group) access granted\n",
i, 0, 0 );
return ACL_GRANT(b->a_access, access );
}
}
}
if ( odn ) free( odn );
Debug( LDAP_DEBUG_ACL, "<= acl: %s by default (no matching by)\n",
Debug( LDAP_DEBUG_ACL,
"<= acl_access_allowed: %s by default (no matching by)\n",
default_access >= access ? "granted" : "denied", 0, 0 );
return( default_access >= access );
}
/*
* acl_check_mods - check access control on the given entry to see if
* acl_check_modlist - check access control on the given entry to see if
* it allows the given modifications by the user associated with op.
* returns LDAP_SUCCESS mods allowed ok
* anything else mods not allowed - return is an error
@ -306,50 +389,59 @@ acl_access_allowed(
*/
int
acl_check_mods(
acl_check_modlist(
Backend *be,
Connection *conn,
Operation *op,
Entry *e,
LDAPMod *mods
LDAPModList *mlist
)
{
int i;
struct acl *a;
char *edn = e->e_ndn;
for ( ; mods != NULL; mods = mods->mod_next ) {
if ( strcasecmp( mods->mod_type, "modifiersname" ) == 0 ||
strcasecmp( mods->mod_type, "modifytimestamp" ) == 0 ) {
for ( ; mlist != NULL; mlist = mlist->ml_next ) {
regmatch_t matches[MAXREMATCHES];
/* the lastmod attributes are ignored by ACL checking */
if ( oc_check_no_usermod_attr( mlist->ml_type ) ) {
Debug( LDAP_DEBUG_ACL, "Operational attribute: %s access allowed\n",
mlist->ml_type, 0, 0 );
continue;
}
a = acl_get_applicable( be, op, e, mods->mod_type );
a = acl_get_applicable( be, op, e, mlist->ml_type,
MAXREMATCHES, matches );
switch ( mods->mod_op & ~LDAP_MOD_BVALUES ) {
switch ( mlist->ml_op & ~LDAP_MOD_BVALUES ) {
case LDAP_MOD_REPLACE:
case LDAP_MOD_ADD:
if ( mods->mod_bvalues == NULL ) {
if ( mlist->ml_bvalues == NULL ) {
break;
}
for ( i = 0; mods->mod_bvalues[i] != NULL; i++ ) {
if ( ! acl_access_allowed( a, be, conn, e,
mods->mod_bvalues[i], op, ACL_WRITE ) ) {
for ( i = 0; mlist->ml_bvalues[i] != NULL; i++ ) {
if ( ! acl_access_allowed( a, be, conn, e, mlist->ml_bvalues[i],
op, ACL_WRITE, edn, matches) )
{
return( LDAP_INSUFFICIENT_ACCESS );
}
}
break;
case LDAP_MOD_DELETE:
if ( mods->mod_bvalues == NULL ) {
if ( mlist->ml_bvalues == NULL ) {
if ( ! acl_access_allowed( a, be, conn, e,
NULL, op, ACL_WRITE ) ) {
NULL, op, ACL_WRITE, edn, matches) )
{
return( LDAP_INSUFFICIENT_ACCESS );
}
break;
}
for ( i = 0; mods->mod_bvalues[i] != NULL; i++ ) {
if ( ! acl_access_allowed( a, be, conn, e,
mods->mod_bvalues[i], op, ACL_WRITE ) ) {
for ( i = 0; mlist->ml_bvalues[i] != NULL; i++ ) {
if ( ! acl_access_allowed( a, be, conn, e, mlist->ml_bvalues[i],
op, ACL_WRITE, edn, matches) )
{
return( LDAP_INSUFFICIENT_ACCESS );
}
}
@ -360,45 +452,93 @@ acl_check_mods(
return( LDAP_SUCCESS );
}
#ifdef sunos5
static int
regex_matches( char *pat, char *str )
static void
string_expand(
char *newbuf,
int bufsiz,
char *pat,
char *match,
regmatch_t *matches)
{
char *e;
int rc;
int size;
char *sp;
char *dp;
int flag;
if ( (e = compile( pat, NULL, NULL )) == NULL ) {
Debug( LDAP_DEBUG_ANY,
"compile( \"%s\", \"%s\") failed\n", pat, str, 0 );
return( 0 );
size = 0;
newbuf[0] = '\0';
flag = 0;
for ( dp = newbuf, sp = pat; size < bufsiz && *sp ; sp++) {
/* did we previously see a $ */
if (flag) {
if (*sp == '$') {
*dp++ = '$';
size++;
} else if (*sp >= '0' && *sp <= '9' ) {
int n;
int i;
int l;
n = *sp - '0';
*dp = '\0';
i = matches[n].rm_so;
l = matches[n].rm_eo;
for ( ; size < 512 && i < l; size++, i++ ) {
*dp++ = match[i];
size++;
}
*dp = '\0';
}
flag = 0;
} else {
if (*sp == '$') {
flag = 1;
} else {
*dp++ = *sp;
size++;
}
}
}
rc = step( str ? str : "", e );
free( e );
*dp = '\0';
return( rc );
Debug( LDAP_DEBUG_TRACE, "=> string_expand: pattern: %s\n", pat, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "=> string_expand: expanded: %s\n", newbuf, 0, 0 );
}
#else /* sunos5 */
static int
regex_matches( char *pat, char *str )
regex_matches(
char *pat, /* pattern to expand and match against */
char *str, /* string to match against pattern */
char *buf, /* buffer with $N expansion variables */
regmatch_t *matches /* offsets in buffer for $N expansion variables */
)
{
char *e;
regex_t re;
char newbuf[512];
int rc;
pthread_mutex_lock( &regex_mutex );
if ( (e = re_comp( pat )) != NULL ) {
Debug( LDAP_DEBUG_ANY,
"re_comp( \"%s\", \"%s\") failed because (%s)\n", pat, str,
e );
pthread_mutex_unlock( &regex_mutex );
if(str == NULL) str = "";
string_expand(newbuf, sizeof(newbuf), pat, buf, matches);
if (( rc = regcomp(&re, newbuf, REG_EXTENDED|REG_ICASE))) {
char error[512];
regerror(rc, &re, error, sizeof(error));
Debug( LDAP_DEBUG_TRACE,
"compile( \"%s\", \"%s\") failed %s\n",
pat, str, error );
return( 0 );
}
rc = re_exec( str ? str : "" );
pthread_mutex_unlock( &regex_mutex );
return( rc == 1 );
rc = regexec(&re, str, 0, NULL, 0);
regfree( &re );
Debug( LDAP_DEBUG_TRACE,
"=> regex_matches: string: %s\n", str, 0, 0 );
Debug( LDAP_DEBUG_TRACE,
"=> regex_matches: rc: %d %s\n",
rc, !rc ? "matches" : "no matches", 0 );
return( !rc );
}
#endif /* sunos5 */

View file

@ -1,31 +1,82 @@
/* acl.c - routines to parse and check acl's */
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include "regex.h"
#include "slap.h"
#include "portable.h"
extern Filter *str2filter();
extern char *re_comp();
extern struct acl *global_acl;
extern char **str2charray();
extern char *dn_upcase();
#include <stdio.h>
static void split();
static void acl_append();
static void access_append();
static void acl_usage();
#include <ac/ctype.h>
#include <ac/regex.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/unistd.h>
#include "slap.h"
static void split(char *line, int splitchar, char **left, char **right);
static void acl_append(struct acl **l, struct acl *a);
static void access_append(struct access **l, struct access *a);
static void acl_usage(void);
#ifdef LDAP_DEBUG
static void print_acl();
static void print_access();
static void print_acl(struct acl *a);
static void print_access(struct access *b);
#endif
static int
regtest(char *fname, int lineno, char *pat) {
int e;
regex_t re;
char buf[512];
unsigned size;
char *sp;
char *dp;
int flag;
sp = pat;
dp = buf;
size = 0;
buf[0] = '\0';
for (size = 0, flag = 0; (size < sizeof(buf)) && *sp; sp++) {
if (flag) {
if (*sp == '$'|| (*sp >= '0' && *sp <= '9')) {
*dp++ = *sp;
size++;
}
flag = 0;
} else {
if (*sp == '$') {
flag = 1;
} else {
*dp++ = *sp;
size++;
}
}
}
*dp = '\0';
if ( size >= (sizeof(buf)-1) ) {
fprintf( stderr,
"%s: line %d: regular expression \"%s\" too large\n",
fname, lineno, pat, 0 );
acl_usage();
}
if ((e = regcomp(&re, buf, REG_EXTENDED|REG_ICASE))) {
char error[512];
regerror(e, &re, error, sizeof(error));
fprintf( stderr,
"%s: line %d: regular expression \"%s\" bad because of %s\n",
fname, lineno, pat, error );
acl_usage();
return(0);
}
regfree(&re);
return(1);
}
void
parse_acl(
Backend *be,
@ -36,7 +87,7 @@ parse_acl(
)
{
int i;
char *e, *left, *right;
char *left, *right;
struct acl *a;
struct access *b;
@ -58,7 +109,18 @@ parse_acl(
}
if ( strcasecmp( argv[i], "*" ) == 0 ) {
a->acl_dnpat = strdup( ".*" );
int e;
if ((e = regcomp( &a->acl_dnre, ".*",
REG_EXTENDED|REG_ICASE)))
{
char buf[512];
regerror(e, &a->acl_dnre, buf, sizeof(buf));
fprintf( stderr,
"%s: line %d: regular expression \"%s\" bad because of %s\n",
fname, lineno, right, buf );
acl_usage();
}
a->acl_dnpat = ch_strdup( ".*" );
continue;
}
@ -79,24 +141,29 @@ parse_acl(
acl_usage();
}
} else if ( strcasecmp( left, "dn" ) == 0 ) {
if ( (e = re_comp( right )) != NULL ) {
int e;
if ((e = regcomp(&a->acl_dnre, right,
REG_EXTENDED|REG_ICASE))) {
char buf[512];
regerror(e, &a->acl_dnre, buf, sizeof(buf));
fprintf( stderr,
"%s: line %d: regular expression \"%s\" bad because of %s\n",
fname, lineno, right, e );
"%s: line %d: regular expression \"%s\" bad because of %s\n",
fname, lineno, right, buf );
acl_usage();
} else {
a->acl_dnpat = dn_upcase(ch_strdup( right ));
}
a->acl_dnpat = dn_upcase( strdup(
right ) );
} else if ( strncasecmp( left, "attr", 4 )
== 0 ) {
char **alist;
alist = str2charray( right, "," );
charray_merge( &a->acl_attrs, alist );
free( alist );
charray_free( alist );
} else {
fprintf( stderr,
"%s: line %d: expecting <what> got \"%s\"\n",
"%s: line %d: expecting <what> got \"%s\"\n",
fname, lineno, left );
acl_usage();
}
@ -106,7 +173,7 @@ parse_acl(
} else if ( strcasecmp( argv[i], "by" ) == 0 ) {
if ( a == NULL ) {
fprintf( stderr,
"%s: line %d: to clause required before by clause in access line\n",
"%s: line %d: to clause required before by clause in access line\n",
fname, lineno );
acl_usage();
}
@ -114,8 +181,7 @@ parse_acl(
* by clause consists of <who> and <access>
*/
b = (struct access *) ch_calloc( 1,
sizeof(struct access) );
b = (struct access *) ch_calloc( 1, sizeof(struct access) );
if ( ++i == argc ) {
fprintf( stderr,
@ -127,43 +193,61 @@ parse_acl(
/* get <who> */
split( argv[i], '=', &left, &right );
if ( strcasecmp( argv[i], "*" ) == 0 ) {
b->a_dnpat = strdup( ".*" );
b->a_dnpat = ch_strdup( ".*" );
} else if ( strcasecmp( argv[i], "anonymous" ) == 0 ) {
b->a_dnpat = ch_strdup( "anonymous" );
} else if ( strcasecmp( argv[i], "self" ) == 0 ) {
b->a_dnpat = strdup( "self" );
b->a_dnpat = ch_strdup( "self" );
} else if ( strcasecmp( left, "dn" ) == 0 ) {
if ( (e = re_comp( right )) != NULL ) {
fprintf( stderr,
"%s: line %d: regular expression \"%s\" bad: %s\n",
fname, lineno, right, e );
acl_usage();
}
b->a_dnpat = dn_upcase( strdup( right ) );
} else if ( strcasecmp( left, "dnattr" )
== 0 ) {
b->a_dnattr = strdup( right );
} else if ( strcasecmp( left, "domain" )
== 0 ) {
char *s;
regtest(fname, lineno, right);
b->a_dnpat = dn_upcase( ch_strdup( right ) );
} else if ( strcasecmp( left, "dnattr" ) == 0 ) {
b->a_dnattr = ch_strdup( right );
if ( (e = re_comp( right )) != NULL ) {
fprintf( stderr,
"%s: line %d: regular expression \"%s\" bad: %s\n",
fname, lineno, right, e );
acl_usage();
} else if ( strncasecmp( left, "group", sizeof("group")-1 ) == 0 ) {
char *name = NULL;
char *value = NULL;
/* format of string is "group/objectClassValue/groupAttrName" */
if ((value = strchr(left, '/')) != NULL) {
*value++ = '\0';
if (value && *value
&& (name = strchr(value, '/')) != NULL)
{
*name++ = '\0';
}
}
b->a_domainpat = strdup( right );
regtest(fname, lineno, right);
b->a_group = dn_upcase(ch_strdup( right ));
if (value && *value) {
b->a_group_oc = ch_strdup(value);
*--value = '/';
} else {
b->a_group_oc = ch_strdup("groupOfNames");
if (name && *name) {
b->a_group_at = ch_strdup(name);
*--name = '/';
} else {
b->a_group_at = ch_strdup("member");
}
}
} else if ( strcasecmp( left, "domain" ) == 0 ) {
char *s;
regtest(fname, lineno, right);
b->a_domainpat = ch_strdup( right );
/* normalize the domain */
for ( s = b->a_domainpat; *s; s++ ) {
*s = TOLOWER( *s );
*s = TOLOWER( (unsigned char) *s );
}
} else if ( strcasecmp( left, "addr" ) == 0 ) {
if ( (e = re_comp( right )) != NULL ) {
fprintf( stderr,
"%s: line %d: regular expression \"%s\" bad: %s\n",
fname, lineno, right, e );
acl_usage();
}
b->a_addrpat = strdup( right );
regtest(fname, lineno, right);
b->a_addrpat = ch_strdup( right );
} else {
fprintf( stderr,
"%s: line %d: expecting <who> got \"%s\"\n",
@ -180,7 +264,7 @@ parse_acl(
/* get <access> */
split( argv[i], '=', &left, &right );
if ( (b->a_access = str2access( left )) == -1 ) {
if ( ACL_IS_INVALID(ACL_SET(b->a_access,str2access( left ))) ) {
fprintf( stderr,
"%s: line %d: expecting <access> got \"%s\"\n",
fname, lineno, left );
@ -198,16 +282,20 @@ parse_acl(
/* if we have no real access clause, complain and do nothing */
if ( a == NULL ) {
fprintf( stderr,
"%s: line %d: warning: no access clause(s) specified in access line\n",
"%s: line %d: warning: no access clause(s) specified in access line\n",
fname, lineno );
} else {
#ifdef LDAP_DEBUG
if (ldap_debug & LDAP_DEBUG_ACL)
print_acl(a);
#endif
if ( a->acl_access == NULL ) {
fprintf( stderr,
"%s: line %d: warning: no by clause(s) specified in access line\n",
"%s: line %d: warning: no by clause(s) specified in access line\n",
fname, lineno );
}
@ -224,22 +312,25 @@ access2str( int access )
{
static char buf[12];
if ( access & ACL_SELF ) {
if ( ACL_IS_SELF( access ) ) {
strcpy( buf, "self" );
} else {
buf[0] = '\0';
}
if ( access & ACL_NONE ) {
if ( ACL_IS_NONE(access) ) {
strcat( buf, "none" );
} else if ( access & ACL_COMPARE ) {
} else if ( ACL_IS_AUTH(access) ) {
strcat( buf, "auth" );
} else if ( ACL_IS_COMPARE(access) ) {
strcat( buf, "compare" );
} else if ( access & ACL_SEARCH ) {
} else if ( ACL_IS_SEARCH(access) ) {
strcat( buf, "search" );
} else if ( access & ACL_READ ) {
} else if ( ACL_IS_READ(access) ) {
strcat( buf, "read" );
} else if ( access & ACL_WRITE ) {
} else if ( ACL_IS_WRITE(access) ) {
strcat( buf, "write" );
} else {
strcat( buf, "unknown" );
}
@ -252,38 +343,45 @@ str2access( char *str )
{
int access;
access = 0;
ACL_CLR(access);
if ( strncasecmp( str, "self", 4 ) == 0 ) {
access |= ACL_SELF;
ACL_SET_SELF(access);
str += 4;
}
if ( strcasecmp( str, "none" ) == 0 ) {
access |= ACL_NONE;
ACL_SET_NONE(access);
} else if ( strcasecmp( str, "auth" ) == 0 ) {
ACL_SET_AUTH(access);
} else if ( strcasecmp( str, "compare" ) == 0 ) {
access |= ACL_COMPARE;
ACL_SET_COMPARE(access);
} else if ( strcasecmp( str, "search" ) == 0 ) {
access |= ACL_SEARCH;
ACL_SET_SEARCH(access);
} else if ( strcasecmp( str, "read" ) == 0 ) {
access |= ACL_READ;
ACL_SET_READ(access);
} else if ( strcasecmp( str, "write" ) == 0 ) {
access |= ACL_WRITE;
ACL_SET_WRITE(access);
} else {
access = -1;
ACL_SET_INVALID(access);
}
return( access );
}
static void
acl_usage()
acl_usage( void )
{
fprintf( stderr, "\n<access clause> ::= access to <what> [ by <who> <access> ]+ \n" );
fprintf( stderr, "<what> ::= * | [dn=<regex>] [filter=<ldapfilter>] [attrs=<attrlist>]\n" );
fprintf( stderr, "<attrlist> ::= <attr> | <attr> , <attrlist>\n" );
fprintf( stderr, "<attr> ::= <attrname> | entry | children\n" );
fprintf( stderr, "<who> ::= * | self | dn=<regex> | addr=<regex> |\n\tdomain=<regex> | dnattr=<dnattrname>\n" );
fprintf( stderr, "<access> ::= [self]{none | compare | search | read | write }\n" );
fprintf( stderr, "\n"
"<access clause> ::= access to <what> [ by <who> <access> ]+ \n"
"<what> ::= * | [dn=<regex>] [filter=<ldapfilter>] [attrs=<attrlist>]\n"
"<attrlist> ::= <attr> | <attr> , <attrlist>\n"
"<attr> ::= <attrname> | entry | children\n"
"<who> ::= * | anonymous | self | dn=<regex> | addr=<regex>\n"
"\t| domain=<regex> | dnattr=<dnattrname>\n"
"\t| group[/<objectclass>[/<attrname>]]=<regex>\n"
"<access> ::= [self]{none|auth|compare|search|read|write}\n"
);
exit( 1 );
}
@ -324,17 +422,32 @@ acl_append( struct acl **l, struct acl *a )
static void
print_access( struct access *b )
{
printf( "\tby" );
fprintf( stderr, "\tby" );
if ( b->a_dnpat != NULL ) {
printf( " dn=%s", b->a_dnpat );
if( strcmp(b->a_dnpat, "anonymous") == 0 ) {
fprintf( stderr, " anonymous" );
} else if( strcmp(b->a_dnpat, "self") == 0 ) {
fprintf( stderr, " self" );
} else {
fprintf( stderr, " dn=%s", b->a_dnpat );
}
} else if ( b->a_addrpat != NULL ) {
printf( " addr=%s", b->a_addrpat );
fprintf( stderr, " addr=%s", b->a_addrpat );
} else if ( b->a_domainpat != NULL ) {
printf( " domain=%s", b->a_domainpat );
fprintf( stderr, " domain=%s", b->a_domainpat );
} else if ( b->a_dnattr != NULL ) {
printf( " dnattr=%s", b->a_dnattr );
}
printf( " %s\n", access2str( b->a_access ) );
fprintf( stderr, " dnattr=%s", b->a_dnattr );
} else if ( b->a_group != NULL ) {
fprintf( stderr, " group: %s", b->a_group );
if ( b->a_group_oc ) {
fprintf( stderr, " objectClass: %s", b->a_group_oc );
if ( b->a_group_at ) {
fprintf( stderr, " attributeType: %s", b->a_group_at );
}
}
}
fprintf( stderr, "\n" );
}
static void
@ -344,33 +457,34 @@ print_acl( struct acl *a )
struct access *b;
if ( a == NULL ) {
printf( "NULL\n" );
fprintf( stderr, "NULL\n" );
}
printf( "access to" );
fprintf( stderr, "ACL: access to" );
if ( a->acl_filter != NULL ) {
printf( " filter=" );
fprintf( stderr," filter=" );
filter_print( a->acl_filter );
}
if ( a->acl_dnpat != NULL ) {
printf( " dn=" );
printf( a->acl_dnpat );
fprintf( stderr, " dn=" );
fprintf( stderr, a->acl_dnpat );
}
if ( a->acl_attrs != NULL ) {
int first = 1;
printf( " attrs=" );
fprintf( stderr, "\n attrs=" );
for ( i = 0; a->acl_attrs[i] != NULL; i++ ) {
if ( ! first ) {
printf( "," );
fprintf( stderr, "," );
}
printf( a->acl_attrs[i] );
fprintf( stderr, a->acl_attrs[i] );
first = 0;
}
}
printf( "\n" );
fprintf( stderr, "\n" );
for ( b = a->acl_access; b != NULL; b = b->a_next ) {
print_access( b );
}
fprintf( stderr, "\n" );
}
#endif
#endif /* LDAP_DEBUG */

View file

@ -38,7 +38,7 @@ do_add( Connection *conn, Operation *op )
if( op->o_bind_in_progress ) {
Debug( LDAP_DEBUG_ANY, "do_add: SASL bind in progress.\n", 0, 0, 0 );
send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS, NULL,
"SASL bind in progress", NULL );
"SASL bind in progress", NULL, NULL );
return LDAP_SASL_BIND_IN_PROGRESS;
}
@ -90,7 +90,7 @@ do_add( Connection *conn, Operation *op )
Debug( LDAP_DEBUG_ANY, "no values for type %s\n", type,
0, 0 );
send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
NULL, "no values for type", NULL );
NULL, "no values for type", NULL, NULL );
free( type );
entry_free( e );
return LDAP_PROTOCOL_ERROR;
@ -128,7 +128,7 @@ do_add( Connection *conn, Operation *op )
if ( be == NULL ) {
entry_free( e );
send_ldap_result( conn, op, LDAP_REFERRAL, NULL,
NULL, default_referral );
NULL, default_referral, NULL );
return rc;
}
@ -156,13 +156,13 @@ do_add( Connection *conn, Operation *op )
} else {
entry_free( e );
send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL,
NULL, default_referral );
NULL, default_referral, NULL );
}
} else {
Debug( LDAP_DEBUG_ARGS, " do_add: HHH\n", 0, 0, 0 );
entry_free( e );
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
NULL, "Function not implemented", NULL );
NULL, "Function not implemented", NULL, NULL );
}
return rc;

View file

@ -486,7 +486,7 @@ subtree_candidates(
f->f_or->f_avtype = ch_strdup( "objectclass" );
/* Patch to use normalized uppercase */
f->f_or->f_avvalue.bv_val = ch_strdup( "REFERRAL" );
f->f_or->f_avvalue.bv_len = strlen( "REFERRAL" );
f->f_or->f_avvalue.bv_len = sizeof( "REFERRAL" )-1;
filterarg_ptr = &f->f_or->f_next;
*filterarg_ptr = filter;
filter = f;
@ -501,7 +501,7 @@ subtree_candidates(
f->f_and->f_sub_initial = NULL;
f->f_and->f_sub_any = NULL;
f->f_and->f_sub_final = ch_strdup( base );
value_normalize( f->f_and->f_sub_final, SYNTAX_CIS );
value_normalize( f->f_and->f_sub_final, SYNTAX_DN|SYNTAX_CIS );
f->f_and->f_next = filter;
filter = f;
}

View file

@ -24,6 +24,7 @@ ldbm_back_add(
Entry *p = NULL;
int rootlock = 0;
int rc;
/* int manageDSAit = get_manageDSAit( op ); */
Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", e->e_dn, 0, 0);
@ -34,7 +35,7 @@ ldbm_back_add(
ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
entry_free( e );
send_ldap_result( conn, op, LDAP_ALREADY_EXISTS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
return( -1 );
}
@ -46,7 +47,7 @@ ldbm_back_add(
entry_free( e );
send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
return( -1 );
}
@ -59,20 +60,38 @@ ldbm_back_add(
pdn = dn_parent( be, e->e_ndn );
if( pdn != NULL && *pdn != '\0' && !be_issuffix(be, "") ) {
char *matched = NULL;
Entry *matched = NULL;
assert( *pdn != '\0' );
/* get parent with writer lock */
if ( (p = dn2entry_w( be, pdn, &matched )) == NULL ) {
char *matched_dn;
struct berval **refs;
ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
Debug( LDAP_DEBUG_TRACE, "parent does not exist\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
matched, NULL, NULL );
if ( matched != NULL ) {
free( matched );
matched_dn = ch_strdup( matched->e_dn );
refs = is_entry_referral( matched )
? get_entry_referrals( be, conn, op, matched )
: NULL;
cache_return_entry_r( &li->li_cache, matched );
} else {
matched_dn = NULL;
refs = default_referral;
}
Debug( LDAP_DEBUG_TRACE, "parent does not exist\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
if( matched != NULL ) {
ber_bvecfree( refs );
free( matched_dn );
}
entry_free( e );
@ -85,21 +104,55 @@ ldbm_back_add(
free(pdn);
if ( matched != NULL ) {
free( matched );
}
if ( ! access_allowed( be, conn, op, p,
"children", NULL, ACL_WRITE ) )
{
Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL );
/* free parent and writer lock */
cache_return_entry_w( &li->li_cache, p );
Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL, NULL );
entry_free( e );
return -1;
}
if ( is_entry_alias( p ) ) {
/* parent is an alias, don't allow add */
/* free parent and writer lock */
cache_return_entry_w( &li->li_cache, p );
Debug( LDAP_DEBUG_TRACE, "parent is alias\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
NULL, NULL, NULL, NULL );
entry_free( e );
return -1;
}
if ( is_entry_referral( p ) ) {
/* parent is a referral, don't allow add */
char *matched_dn = ch_strdup( p->e_dn );
struct berval **refs = is_entry_referral( p )
? get_entry_referrals( be, conn, op, p )
: NULL;
/* free parent and writer lock */
cache_return_entry_w( &li->li_cache, p );
Debug( LDAP_DEBUG_TRACE, "parent is referral\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
ber_bvecfree( refs );
free( matched_dn );
entry_free( e );
return -1;
}
@ -119,7 +172,7 @@ ldbm_back_add(
0, 0 );
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
entry_free( e );
return -1;
@ -161,11 +214,9 @@ ldbm_back_add(
/* free the entry */
entry_free( e );
if(rc > 0) {
send_ldap_result( conn, op, LDAP_ALREADY_EXISTS, NULL, NULL, NULL );
} else {
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, NULL, NULL );
}
send_ldap_result( conn, op,
rc > 0 ? LDAP_ALREADY_EXISTS : LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL, NULL );
return( -1 );
}
@ -179,7 +230,8 @@ ldbm_back_add(
if ( id2children_add( be, p, e ) != 0 ) {
Debug( LDAP_DEBUG_TRACE, "id2children_add failed\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, NULL, NULL );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -193,7 +245,8 @@ ldbm_back_add(
if ( index_add_entry( be, e ) != 0 ) {
Debug( LDAP_DEBUG_TRACE, "index_add_entry failed\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, NULL, NULL );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -202,7 +255,8 @@ ldbm_back_add(
if ( dn2id_add( be, e->e_ndn, e->e_id ) != 0 ) {
Debug( LDAP_DEBUG_TRACE, "dn2id_add failed\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, NULL, NULL );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -212,12 +266,14 @@ ldbm_back_add(
Debug( LDAP_DEBUG_TRACE, "id2entry_add failed\n", 0,
0, 0 );
(void) dn2id_delete( be, e->e_ndn );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL, NULL, NULL );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL, NULL );
goto return_results;
}
send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL );
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL, NULL );
rc = 0;
return_results:;

View file

@ -19,303 +19,359 @@
#include "back-ldbm.h"
#include "proto-back-ldbm.h"
#ifdef SLAPD_ALIASES
/*
* given an alias object, dereference it to its end point.
* Entry returned has reader lock or is NULL. Starting entry is not released.
* dereference alias
* input origEntry is should be locked/unlocked by caller.
*
* returns origEntry if origEntry is not an alias
* returns NULL if error
* otherwise returns read locked alias
*/
Entry *derefAlias_r ( Backend *be,
Connection *conn,
Operation *op,
Entry *e)
Entry *deref_alias_r (
Backend *be,
Connection *conn,
Operation *op,
Entry *origEntry,
int *err,
char **matched_dn
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private; /* to free cache entries */
Attribute *a;
int depth;
char *matched;
Entry *origDN = e;
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
unsigned depth;
Entry *e;
char **aliases = NULL;
char *newDN = NULL;
char *oldDN = NULL;
int rc = LDAP_SUCCESS;
if (!e) return NULL; /* be sure we have a starting entry */
/*
* Aliases are only deref'ed during search operations.
* if deref_alias_r (or deref_dn) is needed by other op,
* this will need to become argument
*/
const int access = ACL_SEARCH;
Debug( LDAP_DEBUG_TRACE, "<= checking for alias for dn %s\n", e->e_dn, 0, 0 );
/* be sure we have a starting entry */
if( origEntry != NULL ) {
return NULL;
}
/*
* try to deref fully, up to a maximum depth. If the max depth exceeded
* then send an error
*/
for ( depth = 0;
( ( a = attr_find( e->e_attrs, "aliasedobjectname" ) ) != NULL) &&
( depth < be->be_maxDerefDepth );
++depth)
{
Debug( LDAP_DEBUG_TRACE, "<= checking for alias for dn %s\n",
origEntry->e_dn, 0, 0 );
/*
* make sure there is a defined aliasedobjectname.
* can only have one value so just use first value (0) in the attr list.
*/
if (a->a_vals[0] && a->a_vals[0]->bv_val) {
char *newDN, *oldDN;
/*
* try to deref fully, up to a maximum depth. If the max depth exceeded
* then send an error
*/
e = origEntry;
for ( depth = 0; e != NULL; depth++ )
{
Attribute *a;
struct berval bv;
Debug( LDAP_DEBUG_TRACE, "<= %s is an alias for %s\n",
e->e_dn, a->a_vals[0]->bv_val, 0 );
newDN = ch_strdup (a->a_vals[0]->bv_val);
oldDN = ch_strdup (e->e_ndn);
if ( ! access_allowed( be, conn, op, e,
"entry", NULL, access ) )
{
Debug( LDAP_DEBUG_ACL,
"deref_alias_r: access to entry not allowed\n",
0, 0, 0 );
break;
}
/*
* release past lock if not original
*/
if ( (depth > 0) && e ) {
cache_return_entry_r(&li->li_cache, e);
}
/*
* aliased object names must be contained in an entry
* object class "alias".
*/
a = attr_find(e->e_attrs, "objectclass");
/* make sure new and old DN are not same to avoid loops */
dn_normalize_case (newDN);
if ( strcmp (newDN, oldDN) == 0 ) {
if( a == NULL ) {
/* no objectclass attribute */
break;
}
bv.bv_val = "REFERRAL";
bv.bv_len = sizeof("REFERRAL")-1;
Debug( LDAP_DEBUG_TRACE,
"<= %s alias is same as current %s\n",
oldDN, newDN, 0 );
send_ldap_result( conn, op, LDAP_ALIAS_DEREF_PROBLEM,
NULL, "circular alias", NULL );
free (newDN);
free (oldDN);
break;
}
if (value_find(a->a_vals, &bv, a->a_syntax, 1) == 0) {
/* is a referral */
break;
}
/* make sure new and original are not same to avoid deadlocks */
if ( strcmp (newDN, origDN->e_ndn) == 0 ) {
Debug( LDAP_DEBUG_TRACE,
"<= %s alias is same as original %s\n",
oldDN, origDN->e_ndn, 0 );
send_ldap_result( conn, op, LDAP_ALIAS_DEREF_PROBLEM,
NULL, "circular alias", NULL );
free (newDN);
free (oldDN);
break;
}
bv.bv_val = "ALIAS";
bv.bv_len = sizeof("ALIAS")-1;
if (value_find(a->a_vals, &bv, a->a_syntax, 1) != 0) {
/* not an alias */
break;
}
/*
* ok, so what happens if there is an alias in the DN of a dereferenced
* alias object?
*/
if ( (e = dn2entry_r( be, newDN, &matched )) == NULL ) {
if ( ! access_allowed( be, conn, op, e,
"aliasedobjectname", NULL, access ) )
{
Debug( LDAP_DEBUG_ACL,
"deref_alias_r: access to reference not allowed\n",
0, 0, 0 );
break;
}
/* could not deref return error */
Debug( LDAP_DEBUG_TRACE,
"<= %s is a dangling alias to %s\n",
oldDN, newDN, 0 );
send_ldap_result( conn, op, LDAP_ALIAS_DEREF_PROBLEM,
NULL, "dangling alias", NULL );
a = attr_find( e->e_attrs, "aliasedobjectname" );
if (matched != NULL) free(matched);
free (newDN);
free (oldDN);
break;
}
if( a == NULL ) {
/*
* there was an aliasedobjectname defined but no data.
*/
Debug( LDAP_DEBUG_TRACE,
"<= %s has no aliasedObjectName attribute\n",
e->e_dn, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_ALIAS_PROBLEM,
NULL, "alias missing aliasedObjectName", NULL, NULL );
break;
}
free (newDN);
free (oldDN);
}
else {
/*
* there was an aliasedobjectname defined but no data.
* this can't happen, right?
*/
Debug( LDAP_DEBUG_TRACE,
"<= %s has no data in aliasedobjectname attribute\n",
(e && e->e_dn) ? e->e_dn : "(null)", 0, 0 );
send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
NULL, "alias missing aliasedObjectName", NULL );
break;
}
}
/*
* aliasedObjectName should be SINGLE-VALUED with a single value.
*/
if ( a->a_vals[0] == NULL || a->a_vals[0]->bv_val != NULL ) {
/*
* there was an aliasedobjectname defined but no data.
*/
Debug( LDAP_DEBUG_TRACE,
"<= %s has no value aliasedObjectName attribute\n",
e->e_dn, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_ALIAS_PROBLEM,
NULL, "alias missing aliasedObjectName value", NULL, NULL );
break;
}
/*
* warn if we pulled out due to exceeding the maximum deref depth
*/
if ( depth >= be->be_maxDerefDepth ) {
Debug( LDAP_DEBUG_TRACE,
"<= deref(\"%s\") exceeded maximum deref depth (%d) at \"%s\"\n",
origDN->e_dn ? origDN->e_dn : "(null)",
be->be_maxDerefDepth,
(e && e->e_ndn) ? e->e_ndn : "(null)");
send_ldap_result( conn, op, LDAP_ALIAS_DEREF_PROBLEM,
NULL, "maximum alias dereference depth exceeded", NULL );
}
if( a->a_vals[1] != NULL ) {
Debug( LDAP_DEBUG_TRACE,
"<= %s alias has multiple values\n",
e->e_dn, 0, 0 );
send_ldap_result( conn, op, rc= LDAP_ALIAS_PROBLEM,
NULL, "multivalue aliasObjectName", NULL, NULL );
break;
}
return e;
if( depth >= be->be_max_deref_depth ) {
/* depth limit exceeded */
Debug( LDAP_DEBUG_TRACE,
"<= deref(\"%s\") exceeded maximum deref depth (%d) at \"%s\"\n",
origEntry->e_dn,
be->be_max_deref_depth,
e->e_ndn );
send_ldap_result( conn, op, rc = LDAP_ALIAS_DEREF_PROBLEM,
NULL, "maximum deref depth exceeded", NULL, NULL );
break;
}
charray_add( &aliases, e->e_ndn );
Debug( LDAP_DEBUG_TRACE, "<= %s is an alias for %s\n",
e->e_dn, a->a_vals[0]->bv_val, 0 );
if( oldDN != NULL ) free( oldDN );
oldDN = ch_strdup( e->e_ndn );
/*
* release past lock if not original
*/
if ( depth > 0 ) {
cache_return_entry_r(&li->li_cache, e);
}
e = NULL;
if( newDN != NULL ) free( newDN );
newDN = ch_strdup( a->a_vals[0]->bv_val );
dn_normalize_case (newDN);
/* make sure new and old DN are not same to avoid loops */
if ( charray_inlist( aliases, newDN ) ) {
Debug( LDAP_DEBUG_TRACE,
"<= %s has circular alias %s\n",
origEntry->e_dn, newDN, 0 );
send_ldap_result( conn, op, rc = LDAP_LOOP_DETECT,
NULL, "circular alias", NULL, NULL );
break;
}
/*
* ok, so what happens if there is an alias in the DN of a dereferenced
* alias object?
*/
if ( (e = dn2entry_r( be, newDN, NULL )) == NULL ) {
/* could not deref return error */
Debug( LDAP_DEBUG_TRACE,
"<= %s has dangling alias %s to %s\n",
origEntry->e_dn, oldDN, newDN );
send_ldap_result( conn, op, rc = LDAP_ALIAS_DEREF_PROBLEM,
NULL, "dangling alias", NULL, NULL );
break;
}
}
if( e != NULL && origEntry != e && rc != LDAP_SUCCESS ) {
cache_return_entry_r(&li->li_cache, e);
e = NULL;
}
charray_free( aliases );
if( newDN ) free(newDN);
if( oldDN ) free(oldDN);
return e;
}
/*
* given a DN fully deref it and return the real DN or original DN if it fails
* This involves finding the last matched part then reconstructing forward
* e.g.
* ou=MyOU,o=MyAliasedOrg,c=MyCountry where o=MyAliasedOrg is an alias for o=MyOrg
* loop starts with newDN = ou=MyOU,o=MyAliasedOrg,c=MyCountry
* dn2entry_r on newDN gives null entry and o=MyAliasedOrg,c=MyCountry matched
* dn2entry_r on matched gives o=MyAliasedOrg,c=MyCountry entry
* remainder is ou=MyOU
* dereferencing o=MyAliasedOrg,c=MyCountry yields entry o=MyOrg,c=MyCountry
* release lock on o=MyAliasedOrg,c=MyCountry entry
* reconstructed dn is ou=MyOU,o=MyOrg,c=MyCountry
* release lock on o=MyOrg,c=MyCountry entry
* This involves finding the last matched part then reconstructing forward.
*
* Example:
*
* "cn=AliasUser,ou=OU,o=AliasedOrg,c=CA" where
* "o=AliasedOrg,c=CA" is an alias for
* "o=Org,c=CA"
* and
* "cn=AliasUser,ou=OU,o=Org,c=CA" is an alias for
* "cn=User,ou=OU,o=Org,c=CA"
*
* 1) newDN = dn
* newDN is "cn=AliasUser,ou=OU,o=AliasedOrg,c=CA"
*
* 2) loop: e = d2entry_r( newDN, matched )
* e is NULL
* matched is entry("o=AliasOrg,c=CA")
*
* 3) rmdr = remainder(newDN, matched)
* rmdr is "cn=AliasUser,ou=OU"
*
* 4) alias = deref(matched)
* alias is entry("o=Org,c=CA")
*
* 5) oldDN=newDN; newDN = rmdr + alias
* oldDN is "cn=AliasUser,ou=OU,o=AliasedOrg,c=CA"
* newDN is "cn=AliasUser,ou=OU,o=Org,c=CA"
*
* 6) compare(oldDN,newDN)
* goto loop (step 2)
*
* 7) e = d2entry_r( newDN, matched )
* e is NULL
* matched is entry("ou=OU,o=Org,c=CA")
*
* 8) rmdr = remainder(newDN, matched)
* rmdr is "cn=AliasUser"
*
* 9) alias = deref(matched)
* alias is entry("ou=OU,o=Org,c=CA")
*
*10) oldDN=newDN; newDN = rmdr + alias
* oldDN is "cn=AliasUser,ou=OU,o=Org,c=CA"
* newDN is "cn=AliasUser,ou=OU,o=Org,c=CA"
*
*11) compare(oldDN,newDN)
* break loop (step 2)
*
*12) return newDN
*
*/
char *derefDN ( Backend *be,
Connection *conn,
Operation *op,
char *dn
char *deref_dn (
Backend *be,
Connection *conn,
Operation *op,
char *dn
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
char *matched = 0;
char *newDN = NULL;
int depth, i;
Entry *eMatched;
Entry *eDeref;
Entry *eNew;
if (!dn) return NULL;
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
unsigned depth;
char* remainder = NULL;
char* newDN;
Debug( LDAP_DEBUG_TRACE,
"<= dereferencing dn: \"%s\"\n",
dn, 0, 0 );
newDN = ch_strdup ( dn );
char **dns;
if (!dn) return NULL;
/* while we don't have a matched dn, deref the DN */
for ( depth = 0;
( (eMatched = dn2entry_r( be, newDN, &matched )) == NULL) &&
(depth < be->be_maxDerefDepth);
++depth ) {
if ((matched != NULL) && *matched) {
char *submatch;
/*
* make sure there actually is an entry for the matched part
*/
if ( (eMatched = dn2entry_r( be, matched, &submatch )) != NULL) {
char *remainder; /* part before the aliased part */
int rlen = strlen(newDN) - strlen(matched);
Debug( LDAP_DEBUG_TRACE,
"<= dereferencing dn: \"%s\"\n",
dn, 0, 0 );
charray_add( &dns, "" );
newDN = ch_strdup( dn );
for ( depth = 0; charray_inlist( dns, newDN ) != 0; depth++ )
{
Entry* e = NULL;
Entry* matched = NULL;
Entry* alias = NULL;
int rlen;
if( depth >= be->be_max_deref_depth ) {
/* depth limit exceeded */
break;
}
e = dn2entry_r( be, newDN, &matched );
if( e != NULL ) {
cache_return_entry_r(&li->li_cache, e);
break;
}
if ( matched == NULL ) {
/* nothing matched */
break;
}
charray_add( &dns, newDN );
Debug( LDAP_DEBUG_TRACE, "<= matched %s\n", matched->e_dn, 0, 0 );
rlen = strlen( newDN ) - strlen( matched->e_ndn );
remainder = ch_malloc( rlen + 1 );
strncpy( remainder, newDN, rlen );
remainder[rlen] = '\0';
Debug( LDAP_DEBUG_TRACE, "<= matched %s\n", matched, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "<= remainder %s\n", remainder, 0, 0 );
alias = deref_alias_r( be, conn, op, matched );
cache_return_entry_r(&li->li_cache, matched);
if( alias == matched ) {
/* matched isn't an alias */
break;
}
if( alias == NULL ) {
/* alias error */
break;
}
remainder = ch_malloc (rlen + 1);
strncpy ( remainder, newDN, rlen );
remainder[rlen] = '\0';
Debug( LDAP_DEBUG_TRACE, "<= remainder %s\n", remainder, 0, 0 );
if ((eNew = derefAlias_r( be, conn, op, eMatched )) == NULL) {
free (matched);
matched = NULL;
free (newDN);
newDN = NULL;
free (remainder);
remainder = NULL;
cache_return_entry_r(&li->li_cache, eMatched);
eMatched = NULL;
break; /* no associated entry, dont deref */
Debug( LDAP_DEBUG_TRACE, "<= derefenced to %s\n", alias->e_dn, 0, 0 );
free( newDN );
newDN = ch_malloc( rlen + strlen( alias->e_ndn ) + 1 );
sprintf("%s%s", remainder, alias->e_ndn );
free( remainder );
remainder = NULL;
Debug( LDAP_DEBUG_TRACE, "<= expanded to %s\n", newDN, 0, 0 );
cache_return_entry_r( &li->li_cache, alias );
}
else {
Debug( LDAP_DEBUG_TRACE, "<= l&g we have %s vs %s \n", matched, eNew->e_dn, 0 );
charray_free( dns );
i = strcasecmp (matched, eNew->e_dn);
/* free reader lock */
cache_return_entry_r(&li->li_cache, eNew);
free (matched);
matched = NULL;
if (! i) {
/* newDN same as old so not an alias, no need to go further */
free (newDN);
newDN = NULL;
free (remainder);
cache_return_entry_r(&li->li_cache, eMatched);
eMatched = NULL;
break;
}
/*
* we have dereferenced the aliased part so put
* the new dn together
*/
free (newDN);
newDN = ch_malloc (strlen(eMatched->e_dn) + rlen + 1);
strcpy (newDN, remainder);
strcat (newDN, eMatched->e_dn);
Debug( LDAP_DEBUG_TRACE, "<= expanded to %s\n", newDN, 0, 0 );
free (remainder);
if( remainder != NULL ) {
free( remainder );
}
/* free reader lock */
cache_return_entry_r(&li->li_cache, eMatched);
}
else {
if(submatch != NULL) free(submatch);
break; /* there was no entry for the matched part */
}
}
else {
break; /* there was no matched part */
}
}
/* release lock if a match terminated the loop, there should be no
* outstanding locks at this point
*/
if(eMatched != NULL) {
/* free reader lock */
cache_return_entry_r(&li->li_cache, eMatched);
}
/*
* the final part of the DN might be an alias so try to dereference it.
* e.g. if we had started with dn = o=MyAliasedOrg,c=MyCountry the dn would match
* and the above loop complete but we would still be left with an aliased DN.
*/
if (newDN != NULL) {
if ( (eNew = dn2entry_r( be, newDN, &matched )) != NULL) {
if ((eDeref = derefAlias_r( be, conn, op, eNew )) != NULL) {
free (newDN);
newDN = ch_strdup (eDeref->e_dn);
/* free reader lock */
cache_return_entry_r(&li->li_cache, eDeref);
}
/* free reader lock */
cache_return_entry_r(&li->li_cache, eNew);
}
}
if (matched != NULL) free(matched);
/*
* warn if we exceeded the max depth as the resulting DN may not be dereferenced
*/
if (depth >= be->be_maxDerefDepth) {
if (newDN) {
Debug( LDAP_DEBUG_TRACE,
"<= max deref depth exceeded in derefDN for \"%s\", result \"%s\"\n",
dn, newDN, 0 );
free (newDN);
newDN = NULL;
}
else {
Debug( LDAP_DEBUG_TRACE,
"<= max deref depth exceeded in derefDN for \"%s\", result NULL\n",
dn, 0, 0 );
}
send_ldap_result( conn, op, LDAP_ALIAS_DEREF_PROBLEM,
NULL, "maximum alias dereference depth exceeded for base", NULL );
}
Debug( LDAP_DEBUG_TRACE, "<= %s\n", newDN, 0, 0 );
if (newDN == NULL) {
newDN = ch_strdup ( dn );
}
Debug( LDAP_DEBUG_TRACE, "<= returning deref DN of \"%s\"\n", newDN, 0, 0 );
return newDN;
return newDN;
}
#endif

View file

@ -74,7 +74,7 @@ ldbm_back_bind(
Entry *e;
Attribute *a;
int rc;
char *matched;
Entry *matched;
#ifdef HAVE_KERBEROS
char krbname[MAX_K_NAME_SZ + 1];
AUTH_DAT ad;
@ -86,41 +86,57 @@ ldbm_back_bind(
/* get entry with reader lock */
if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
char *matched_dn = NULL;
struct berval **refs = NULL;
if( matched != NULL ) {
matched_dn = ch_strdup( matched->e_dn );
refs = is_entry_referral( matched )
? get_entry_referrals( be, conn, op, matched )
: NULL;
cache_return_entry_r( &li->li_cache, matched );
} else {
refs = default_referral;
}
/* allow noauth binds */
rc = 1;
if ( method == LDAP_AUTH_SIMPLE ) {
if( cred->bv_len == 0 ) {
/* SUCCESS */
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
} else if ( be_isroot_pw( be, dn, cred ) ) {
*edn = ch_strdup( be_root_dn( be ) );
rc = 0; /* front end will send result */
} else {
send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
matched, NULL, NULL );
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
}
} else if ( method == LDAP_AUTH_SASL ) {
if( mech != NULL && strcasecmp(mech,"DIGEST-MD5") == 0 ) {
/* insert DIGEST calls here */
send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
} else {
send_ldap_result( conn, op, LDAP_AUTH_METHOD_NOT_SUPPORTED,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
}
} else {
send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
matched, NULL, NULL );
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
}
if ( matched != NULL ) {
free( matched );
ber_bvecfree( refs );
free( matched_dn );
}
return( rc );
}
@ -133,7 +149,37 @@ ldbm_back_bind(
"entry", NULL, ACL_AUTH ) )
{
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
}
if ( is_entry_alias( e ) ) {
/* entry is an alias, don't allow bind */
Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
}
if ( is_entry_referral( e ) ) {
/* parent is a referral, don't allow add */
/* parent is an alias, don't allow add */
struct berval **refs = get_entry_referrals( be,
conn, op, e );
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_REFERRAL,
e->e_dn, NULL, refs, NULL );
ber_bvecfree( refs );
rc = 1;
goto return_results;
}
@ -142,7 +188,7 @@ ldbm_back_bind(
case LDAP_AUTH_SIMPLE:
if ( cred->bv_len == 0 ) {
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
/* stop front end from sending result */
rc = 1;
@ -162,14 +208,14 @@ ldbm_back_bind(
"userpassword", NULL, ACL_AUTH ) )
{
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
}
if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
/* stop front end from sending result */
rc = 1;
@ -179,7 +225,7 @@ ldbm_back_bind(
if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 )
{
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
/* stop front end from sending result */
rc = 1;
goto return_results;
@ -193,14 +239,15 @@ ldbm_back_bind(
if ( ! access_allowed( be, conn, op, e,
"krbname", NULL, ACL_AUTH ) )
{
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, NULL, NULL, NULL );
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
}
if ( krbv4_ldap_auth( be, cred, &ad ) != LDAP_SUCCESS ) {
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
}
@ -209,7 +256,7 @@ ldbm_back_bind(
"krbname", NULL, ACL_AUTH ) )
{
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
}
@ -227,7 +274,7 @@ ldbm_back_bind(
break;
}
send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
@ -239,7 +286,8 @@ ldbm_back_bind(
if ( value_find( a->a_vals, &krbval, a->a_syntax, 3 ) != 0 ) {
send_ldap_result( conn, op,
LDAP_INVALID_CREDENTIALS, NULL, NULL, NULL );
LDAP_INVALID_CREDENTIALS,
NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
}
@ -248,7 +296,8 @@ ldbm_back_bind(
break;
case LDAP_AUTH_KRBV42:
send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL );
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL, NULL );
/* stop front end from sending result */
rc = 1;
goto return_results;
@ -259,7 +308,7 @@ ldbm_back_bind(
default:
send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
NULL, "auth method not supported", NULL );
NULL, "auth method not supported", NULL, NULL );
rc = 1;
goto return_results;
}

View file

@ -21,43 +21,77 @@ ldbm_back_compare(
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
char *matched;
Entry *matched;
Entry *e;
Attribute *a;
int rc;
int manageDSAit = get_manageDSAit( op );
/* get entry with reader lock */
if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
matched, NULL, NULL );
char *matched_dn = NULL;
struct berval **refs = NULL;
if ( matched != NULL ) {
matched_dn = ch_strdup( matched->e_dn );
refs = is_entry_referral( matched )
? get_entry_referrals( be, conn, op, matched )
: NULL;
cache_return_entry_r( &li->li_cache, matched );
} else {
refs = default_referral;
}
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
if( matched != NULL ) {
ber_bvecfree( refs );
free( matched_dn );
}
if(matched == NULL) free(matched);
return( 1 );
}
/* check for deleted */
if (!manageDSAit && is_entry_referral( e ) ) {
/* entry is a referral, don't allow add */
struct berval **refs = get_entry_referrals( be,
conn, op, e );
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_REFERRAL,
e->e_dn, NULL, refs, NULL );
ber_bvecfree( refs );
rc = 1;
goto return_results;
}
if ( ! access_allowed( be, conn, op, e,
ava->ava_type, &ava->ava_value, ACL_COMPARE ) )
{
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
}
if ( (a = attr_find( e->e_attrs, ava->ava_type )) == NULL ) {
send_ldap_result( conn, op, LDAP_NO_SUCH_ATTRIBUTE,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
}
if ( value_find( a->a_vals, &ava->ava_value, a->a_syntax, 1 ) == 0 )
send_ldap_result( conn, op, LDAP_COMPARE_TRUE,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
else
send_ldap_result( conn, op, LDAP_COMPARE_FALSE,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
rc = 0;

View file

@ -20,36 +20,44 @@ ldbm_back_delete(
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
char *matched = NULL;
Entry *matched = NULL;
char *pdn = NULL;
Entry *e, *p = NULL;
int rootlock = 0;
int rc = -1;
int manageDSAit = get_manageDSAit( op );
Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_delete: %s\n", dn, 0, 0);
/* get entry with writer lock */
if ( (e = dn2entry_w( be, dn, &matched )) == NULL ) {
char *matched_dn = NULL;
struct berval **refs = NULL;
Debug(LDAP_DEBUG_ARGS, "<=- ldbm_back_delete: no such object %s\n",
dn, 0, 0);
send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
matched, NULL, NULL );
if ( matched != NULL ) {
free( matched );
matched_dn = ch_strdup( matched->e_dn );
refs = is_entry_referral( matched )
? get_entry_referrals( be, conn, op, matched )
: NULL;
cache_return_entry_r( &li->li_cache, matched );
} else {
refs = default_referral;
}
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
if ( matched != NULL ) {
ber_bvecfree( refs );
free( matched_dn );
}
return( -1 );
}
/* check for deleted */
if ( has_children( be, e ) ) {
Debug(LDAP_DEBUG_ARGS, "<=- ldbm_back_delete: non leaf %s\n",
dn, 0, 0);
send_ldap_result( conn, op, LDAP_NOT_ALLOWED_ON_NONLEAF,
NULL, NULL, NULL );
goto return_results;
}
#ifdef SLAPD_CHILD_MODIFICATION_WITH_ENTRY_ACL
if ( ! access_allowed( be, conn, op, e,
"entry", NULL, ACL_WRITE ) )
@ -58,11 +66,38 @@ ldbm_back_delete(
"<=- ldbm_back_delete: insufficient access %s\n",
dn, 0, 0);
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
#endif
if ( !manageDSAit && is_entry_referral( e ) ) {
/* parent is a referral, don't allow add */
/* parent is an alias, don't allow add */
struct berval **refs = get_entry_referrals( be,
conn, op, e );
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_REFERRAL,
e->e_dn, NULL, refs, NULL );
ber_bvecfree( refs );
rc = 1;
goto return_results;
}
if ( has_children( be, e ) ) {
Debug(LDAP_DEBUG_ARGS, "<=- ldbm_back_delete: non leaf %s\n",
dn, 0, 0);
send_ldap_result( conn, op, LDAP_NOT_ALLOWED_ON_NONLEAF,
NULL, NULL, NULL, NULL );
goto return_results;
}
/* delete from parent's id2children entry */
if( (pdn = dn_parent( be, e->e_ndn )) != NULL ) {
if( (p = dn2entry_w( be, pdn, &matched )) == NULL) {
@ -70,7 +105,7 @@ ldbm_back_delete(
"<=- ldbm_back_delete: parent does not exist\n",
0, 0, 0);
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -82,7 +117,7 @@ ldbm_back_delete(
"<=- ldbm_back_delete: no access to parent\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -93,7 +128,7 @@ ldbm_back_delete(
"<=- ldbm_back_delete: no parent & not root\n",
0, 0, 0);
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -106,7 +141,7 @@ ldbm_back_delete(
"<=- ldbm_back_delete: operations error %s\n",
dn, 0, 0);
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -116,7 +151,7 @@ ldbm_back_delete(
"<=- ldbm_back_delete: operations error %s\n",
dn, 0, 0);
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -126,12 +161,12 @@ ldbm_back_delete(
"<=- ldbm_back_delete: operations error %s\n",
dn, 0, 0);
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
rc = 0;
return_results:;

View file

@ -1,17 +1,15 @@
/* dn2id.c - routines to deal with the dn2id index */
#include "portable.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "slap.h"
#include "back-ldbm.h"
extern struct dbcache *ldbm_cache_open();
extern Entry *cache_find_entry_dn();
extern Entry *id2entry();
extern char *dn_parent();
extern Datum ldbm_cache_fetch();
#include "proto-back-ldbm.h"
int
dn2id_add(
@ -20,9 +18,13 @@ dn2id_add(
ID id
)
{
int rc;
int rc, flags;
struct dbcache *db;
Datum key, data;
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
ldbm_datum_init( key );
ldbm_datum_init( data );
Debug( LDAP_DEBUG_TRACE, "=> dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
@ -33,7 +35,7 @@ dn2id_add(
return( -1 );
}
dn = strdup( dn );
dn = ch_strdup( dn );
dn_normalize_case( dn );
key.dptr = dn;
@ -41,7 +43,10 @@ dn2id_add(
data.dptr = (char *) &id;
data.dsize = sizeof(ID);
rc = ldbm_cache_store( db, key, data, LDBM_INSERT );
flags = LDBM_INSERT;
if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
rc = ldbm_cache_store( db, key, data, flags );
free( dn );
ldbm_cache_close( be, db );
@ -58,31 +63,29 @@ dn2id(
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
struct dbcache *db;
Entry *e;
ID id;
Datum key, data;
Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 0, 0 );
ldbm_datum_init( key );
ldbm_datum_init( data );
dn = strdup( dn );
dn = ch_strdup( dn );
Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 0, 0 );
dn_normalize_case( dn );
/* first check the cache */
if ( (e = cache_find_entry_dn( &li->li_cache, dn )) != NULL ) {
id = e->e_id;
if ( (id = cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
free( dn );
Debug( LDAP_DEBUG_TRACE, "<= dn2id %d (in cache)\n", e->e_id,
0, 0 );
cache_return_entry( &li->li_cache, e );
Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld (in cache)\n", id,
0, 0 );
return( id );
}
if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
== NULL ) {
== NULL ) {
free( dn );
Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n",
LDBM_SUFFIX, 0, 0 );
LDBM_SUFFIX, 0, 0 );
return( NOID );
}
@ -103,7 +106,7 @@ dn2id(
ldbm_datum_free( db->dbc_db, data );
Debug( LDAP_DEBUG_TRACE, "<= dn2id %d\n", id, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", id, 0, 0 );
return( id );
}
@ -113,11 +116,12 @@ dn2id_delete(
char *dn
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
struct dbcache *db;
Datum key;
int rc;
ldbm_datum_init( key );
Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\" )\n", dn, 0, 0 );
if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
@ -128,12 +132,15 @@ dn2id_delete(
return( -1 );
}
dn = ch_strdup( dn );
dn_normalize_case( dn );
key.dptr = dn;
key.dsize = strlen( dn ) + 1;
rc = ldbm_cache_delete( db, key );
free( dn );
ldbm_cache_close( be, db );
Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
@ -146,37 +153,52 @@ dn2id_delete(
*/
Entry *
dn2entry(
dn2entry_rw(
Backend *be,
char *dn,
char **matched
Entry **matched,
int rw
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
ID id;
Entry *e;
Entry *e = NULL;
char *pdn;
if ( (id = dn2id( be, dn )) != NOID && (e = id2entry( be, id ))
!= NULL ) {
Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
rw ? "w" : "r", dn, 0);
if( matched != NULL ) {
/* caller care about match */
*matched = NULL;
}
if ( (id = dn2id( be, dn )) != NOID &&
(e = id2entry_rw( be, id, rw )) != NULL )
{
return( e );
}
*matched = NULL;
/* stop when we get to the suffix */
if ( be_issuffix( be, dn ) ) {
return( NULL );
if ( id != NOID ) {
Debug(LDAP_DEBUG_ANY,
"dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
rw ? "w" : "r", id, dn);
/* must have been deleted from underneath us */
/* treat as if NOID was found */
}
/* caller doesn't care about match */
if( matched == NULL ) return NULL;
/* entry does not exist - see how much of the dn does exist */
if ( (pdn = dn_parent( be, dn )) != NULL ) {
if ( (e = dn2entry( be, pdn, matched )) != NULL ) {
*matched = pdn;
cache_return_entry( &li->li_cache, e );
} else {
free( pdn );
/* get entry with reader lock */
if ( (e = dn2entry_r( be, pdn, matched )) != NULL ) {
*matched = e;
}
free( pdn );
}
return( NULL );
return NULL;
}

View file

@ -0,0 +1,150 @@
/* group.c - ldbm backend acl group routine */
#include "portable.h"
#include <stdio.h>
#include <ac/socket.h>
#include <ac/string.h>
#include "slap.h"
#include "back-ldbm.h"
#include "proto-back-ldbm.h"
/* return 0 IFF op_dn is a value in member attribute
* of entry with gr_dn AND that entry has an objectClass
* value of groupOfNames
*/
int
ldbm_back_group(
Backend *be,
Entry *target,
char *gr_ndn,
char *op_ndn,
char *objectclassValue,
char *groupattrName
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
Entry *e;
int rc = 1;
Attribute *attr;
struct berval bv;
Debug( LDAP_DEBUG_ARGS,
"=> ldbm_back_group: gr dn: \"%s\"\n",
gr_ndn, 0, 0 );
Debug( LDAP_DEBUG_ARGS,
"=> ldbm_back_group: op dn: \"%s\"\n",
op_ndn, 0, 0 );
Debug( LDAP_DEBUG_ARGS,
"=> ldbm_back_group: objectClass: \"%s\" attrName: \"%s\"\n",
objectclassValue, groupattrName, 0 );
Debug( LDAP_DEBUG_ARGS,
"=> ldbm_back_group: tr dn: \"%s\"\n",
target->e_ndn, 0, 0 );
if (strcmp(target->e_ndn, gr_ndn) == 0) {
/* we already have a LOCKED copy of the entry */
e = target;
Debug( LDAP_DEBUG_ARGS,
"=> ldbm_back_group: target is group: \"%s\"\n",
gr_ndn, 0, 0 );
} else {
/* can we find group entry with reader lock */
if ((e = dn2entry_r(be, gr_ndn, NULL )) == NULL) {
Debug( LDAP_DEBUG_ACL,
"=> ldbm_back_group: cannot find group: \"%s\"\n",
gr_ndn, 0, 0 );
return( 1 );
}
Debug( LDAP_DEBUG_ACL,
"=> ldbm_back_group: found group: \"%s\"\n",
gr_ndn, 0, 0 );
}
/* find it's objectClass and member attribute values
* make sure this is a group entry
* finally test if we can find op_dn in the member attribute value list *
*/
rc = 1;
if ((attr = attr_find(e->e_attrs, "objectclass")) == NULL) {
Debug( LDAP_DEBUG_ACL,
"<= ldbm_back_group: failed to find objectClass\n", 0, 0, 0 );
goto return_results;
}
bv.bv_val = "ALIAS";
bv.bv_len = sizeof("ALIAS")-1;
if ( value_find(attr->a_vals, &bv, attr->a_syntax, 1) == 0) {
Debug( LDAP_DEBUG_ACL,
"<= ldbm_back_group: group is an alias\n", 0, 0, 0 );
goto return_results;
}
bv.bv_val = "REFERRAL";
bv.bv_len = sizeof("REFERRAL")-1;
if ( value_find(attr->a_vals, &bv, attr->a_syntax, 1) == 0) {
Debug( LDAP_DEBUG_ACL,
"<= ldbm_back_group: group is a referral\n",
0, 0, 0 );
goto return_results;
}
bv.bv_val = objectclassValue;
bv.bv_len = strlen( bv.bv_val );
if (value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
Debug( LDAP_DEBUG_ACL,
"<= ldbm_back_group: failed to find %s in objectClass\n",
objectclassValue, 0, 0 );
goto return_results;
}
if ((attr = attr_find(e->e_attrs, groupattrName)) == NULL) {
Debug( LDAP_DEBUG_ACL,
"<= ldbm_back_group: failed to find %s\n",
groupattrName, 0, 0 );
goto return_results;
}
Debug( LDAP_DEBUG_ACL,
"<= ldbm_back_group: found objectClass and %s\n",
groupattrName, 0, 0 );
bv.bv_val = op_ndn;
bv.bv_len = strlen( op_ndn );
if( value_find( attr->a_vals, &bv, attr->a_syntax, 1) != 0 )
{
Debug( LDAP_DEBUG_ACL,
"<= ldbm_back_group: \"%s\" not in \"%s\": %s\n",
op_ndn, gr_ndn, groupattrName );
goto return_results;
}
Debug( LDAP_DEBUG_ACL,
"<= ldbm_back_group: \"%s\" is in \"%s\": %s\n",
op_ndn, gr_ndn, groupattrName );
rc = 0;
return_results:
if( target != e ) {
/* free entry and reader lock */
cache_return_entry_r( &li->li_cache, e );
}
Debug( LDAP_DEBUG_TRACE, "ldbm_back_group: rc=%d\n", rc, 0, 0 );
return(rc);
}

View file

@ -120,8 +120,10 @@ int ldbm_modify_internal(
if ( (err = acl_check_modlist( be, conn, op, e, modlist ))
!= LDAP_SUCCESS ) {
send_ldap_result( conn, op, err, NULL, NULL, NULL );
!= LDAP_SUCCESS )
{
send_ldap_result( conn, op, err,
NULL, NULL, NULL, NULL );
return -1;
}
@ -173,7 +175,8 @@ int ldbm_modify_internal(
if ( err != LDAP_SUCCESS ) {
/* unlock entry, delete from cache */
send_ldap_result( conn, op, err, NULL, NULL, NULL );
send_ldap_result( conn, op, err,
NULL, NULL, NULL, NULL );
return -1;
}
}
@ -182,7 +185,7 @@ int ldbm_modify_internal(
if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
Debug( LDAP_DEBUG_ANY, "entry failed schema check\n", 0, 0, 0 );
send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
return -1;
}
@ -197,7 +200,7 @@ int ldbm_modify_internal(
/* modify indexes */
if ( index_add_mods( be, modlist, e->e_id ) != 0 ) {
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
return -1;
}
@ -224,21 +227,55 @@ ldbm_back_modify(
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
char *matched;
Entry *matched;
Entry *e;
int manageDSAit = get_manageDSAit( op );
Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0);
/* acquire and lock entry */
if ( (e = dn2entry_w( be, dn, &matched )) == NULL ) {
send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
matched, NULL, NULL );
char* matched_dn = NULL;
struct berval **refs = NULL;
if ( matched != NULL ) {
free( matched );
matched_dn = ch_strdup( matched->e_dn );
refs = is_entry_referral( matched )
? get_entry_referrals( be, conn, op, matched )
: NULL;
cache_return_entry_r( &li->li_cache, matched );
} else {
refs = default_referral;
}
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
if ( matched != NULL ) {
ber_bvecfree( refs );
free( matched_dn );
}
return( -1 );
}
if ( !manageDSAit && is_entry_referral( e ) ) {
/* parent is a referral, don't allow add */
/* parent is an alias, don't allow add */
struct berval **refs = get_entry_referrals( be,
conn, op, e );
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_REFERRAL,
e->e_dn, NULL, refs, NULL );
ber_bvecfree( refs );
goto error_return;
}
/* Modify the entry */
if ( ldbm_modify_internal( be, conn, op, dn, modlist, e ) != 0 ) {
goto error_return;
@ -247,12 +284,12 @@ ldbm_back_modify(
/* change the entry itself */
if ( id2entry_add( be, e ) != 0 ) {
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto error_return;
}
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
cache_return_entry_w( &li->li_cache, e );
return( 0 );

View file

@ -39,10 +39,10 @@ ldbm_back_modrdn(
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
char *matched = NULL;
char *p_dn = NULL, *p_ndn = NULL;
char *new_dn = NULL, *new_ndn = NULL;
Entry *e, *p = NULL;
Entry *matched = NULL;
int rootlock = 0;
int rc = -1;
/* Added to support LDAP v2 correctly (deleteoldrdn thing) */
@ -62,7 +62,7 @@ ldbm_back_modrdn(
struct berval del_bv; /* Stores old rdn att */
struct berval *del_bvals[2]; /* Stores old rdn att */
LDAPModList mod[2]; /* Used to delete old rdn */
int manageDSAit = get_manageDSAit( op );
Debug( LDAP_DEBUG_TRACE, "==>ldbm_back_modrdn(newSuperior=%s)\n",
(newSuperior ? newSuperior : "NULL"),
@ -70,30 +70,62 @@ ldbm_back_modrdn(
/* get entry with writer lock */
if ( (e = dn2entry_w( be, dn, &matched )) == NULL ) {
send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
matched, NULL, NULL );
if ( matched != NULL ) {
free( matched );
char* matched_dn = NULL;
struct berval** refs = NULL;
if( matched != NULL ) {
matched_dn = strdup( matched->e_dn );
refs = is_entry_referral( matched )
? get_entry_referrals( be, conn, op, matched )
: NULL;
cache_return_entry_r( &li->li_cache, matched );
} else {
refs = default_referral;
}
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
if ( matched != NULL ) {
ber_bvecfree( refs );
free( matched_dn );
}
return( -1 );
}
#ifdef SLAPD_CHILD_MODIFICATION_WITH_ENTRY_ACL
/* check parent for "children" acl */
if ( ! access_allowed( be, conn, op, e,
"entry", NULL, ACL_WRITE ) )
{
Debug( LDAP_DEBUG_TRACE, "no access to entry\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
"", "" );
NULL, NULL, NULL, NULL );
goto return_results;
}
#endif
if (!manageDSAit && is_entry_referral( e ) ) {
/* parent is a referral, don't allow add */
/* parent is an alias, don't allow add */
struct berval **refs = get_entry_referrals( be,
conn, op, e );
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_REFERRAL,
e->e_dn, NULL, refs, NULL );
ber_bvecfree( refs );
goto return_results;
}
if ( (p_ndn = dn_parent( be, e->e_ndn )) != NULL ) {
/* Make sure parent entry exist and we can write its
/* Make sure parent entry exist and we can write its
* children.
*/
@ -101,7 +133,7 @@ ldbm_back_modrdn(
Debug( LDAP_DEBUG_TRACE, "parent does not exist\n",
0, 0, 0);
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -112,7 +144,7 @@ ldbm_back_modrdn(
Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -132,7 +164,7 @@ ldbm_back_modrdn(
Debug( LDAP_DEBUG_TRACE, "no parent & not root\n",
0, 0, 0);
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -163,12 +195,11 @@ ldbm_back_modrdn(
/* Get Entry with dn=newSuperior. Does newSuperior exist? */
if( (np = dn2entry_w( be, np_ndn, &matched )) == NULL) {
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: newSup(ndn=%s) not here!\n",
np_ndn, 0, 0);
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -184,7 +215,30 @@ ldbm_back_modrdn(
"ldbm_back_modrdn: no wr to newSup children\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
if ( is_entry_alias( np ) ) {
/* entry is an alias, don't allow bind */
Debug( LDAP_DEBUG_TRACE, "entry is alias\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_ALIAS_PROBLEM,
NULL, NULL, NULL, NULL );
goto return_results;
}
if ( is_entry_referral( np ) ) {
/* parent is a referral, don't allow add */
/* parent is an alias, don't allow add */
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -192,9 +246,7 @@ ldbm_back_modrdn(
"ldbm_back_modrdn: wr to new parent's children OK\n",
0, 0 , 0 );
new_parent_dn = np_dn;
}
/* Build target dn and make sure target entry doesn't exist already. */
@ -209,7 +261,7 @@ ldbm_back_modrdn(
if (dn2id ( be, new_ndn ) != NOID) {
send_ldap_result( conn, op, LDAP_ALREADY_EXISTS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -228,7 +280,7 @@ ldbm_back_modrdn(
/* delete old one */
if ( dn2id_delete( be, e->e_ndn ) != 0 ) {
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -241,7 +293,7 @@ ldbm_back_modrdn(
/* add new one */
if ( dn2id_add( be, e->e_ndn, e->e_id ) != 0 ) {
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -256,7 +308,7 @@ ldbm_back_modrdn(
"ldbm_back_modrdn: can't figure out type of newrdn\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -267,7 +319,7 @@ ldbm_back_modrdn(
"ldbm_back_modrdn: can't figure out val of newrdn\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -284,7 +336,7 @@ ldbm_back_modrdn(
"ldbm_back_modrdn: can't figure out old_rdn from dn\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -295,7 +347,7 @@ ldbm_back_modrdn(
"ldbm_back_modrdn: can't figure out the old_rdn type\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -331,7 +383,6 @@ ldbm_back_modrdn(
/* Remove old rdn value if required */
if (deleteoldrdn) {
/* Get value of old rdn */
if ((old_rdn_val = rdn_attr_value( old_rdn ))
@ -340,12 +391,9 @@ ldbm_back_modrdn(
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: can't figure out old_rdn_val from old_rdn\n",
0, 0, 0 );
send_ldap_result( conn, op,
LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL, NULL );
goto return_results;
}
del_bvals[0] = &del_bv; /* Array of bervals */
@ -383,7 +431,7 @@ ldbm_back_modrdn(
0, 0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results;
}
@ -406,11 +454,12 @@ ldbm_back_modrdn(
if ( id2entry_add( be, e ) != 0 ) {
entry_free( e );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
goto return_results_after;
}
send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL );
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL, NULL );
rc = 0;
goto return_results_after;

View file

@ -1,107 +1,191 @@
#ifndef _PROTO_BACK_LDBM
#define _PROTO_BACK_LDBM
#include <ldap_cdefs.h>
#include "external.h"
LDAP_BEGIN_DECL
/*
* alias.c
*/
Entry *deref_alias_r LDAP_P((
Backend *be,
Connection *conn,
Operation *op,
Entry *e ));
char *deref_dn LDAP_P((
Backend *be,
Connection *conn,
Operation *op,
char *dn ));
Entry *alias_dn2entry_r LDAP_P((
Backend *be,
char *dn,
Entry **matched,
int *err ));
Entry *alias_id2entry_r LDAP_P((
Backend *be,
ID id,
Entry **matched,
int *err ));
/*
* attr.c
*/
void attr_masks( struct ldbminfo *li, char *type, int *indexmask,
int *syntaxmask );
void attr_index_config( struct ldbminfo *li, char *fname, int lineno,
int argc, char **argv, int init );
void attr_masks LDAP_P(( struct ldbminfo *li, char *type, int *indexmask,
int *syntaxmask ));
void attr_index_config LDAP_P(( struct ldbminfo *li, char *fname, int lineno,
int argc, char **argv, int init ));
#ifdef SLAP_CLEANUP
void attr_index_destroy LDAP_P(( Avlnode *tree ));
#endif
/*
* cache.c
*/
void cache_set_state( struct cache *cache, Entry *e, int state );
void cache_return_entry( struct cache *cache, Entry *e );
int cache_add_entry_lock( struct cache *cache, Entry *e, int state );
Entry * cache_find_entry_dn( struct cache *cache, char *dn );
Entry * cache_find_entry_id( struct cache *cache, ID id );
int cache_delete_entry( struct cache *cache, Entry *e );
int cache_add_entry_rw LDAP_P(( struct cache *cache, Entry *e, int rw ));
int cache_update_entry LDAP_P(( struct cache *cache, Entry *e ));
void cache_return_entry_rw LDAP_P(( struct cache *cache, Entry *e, int rw ));
#define cache_return_entry_r(c, e) cache_return_entry_rw((c), (e), 0)
#define cache_return_entry_w(c, e) cache_return_entry_rw((c), (e), 1)
ID cache_find_entry_dn2id LDAP_P(( Backend *be, struct cache *cache, char *dn ));
Entry * cache_find_entry_id LDAP_P(( struct cache *cache, ID id, int rw ));
int cache_delete_entry LDAP_P(( struct cache *cache, Entry *e ));
#ifdef SLAP_CLEANUP
void cache_release_all LDAP_P(( struct cache *cache ));
#endif
/*
* dbcache.c
*/
struct dbcache * ldbm_cache_open( Backend *be, char *name, char *suffix,
int flags );
void ldbm_cache_close( Backend *be, struct dbcache *db );
void ldbm_cache_flush_all( Backend *be );
Datum ldbm_cache_fetch( struct dbcache *db, Datum key );
int ldbm_cache_store( struct dbcache *db, Datum key, Datum data, int flags );
int ldbm_cache_delete( struct dbcache *db, Datum key );
struct dbcache * ldbm_cache_open LDAP_P(( Backend *be, char *name, char *suffix,
int flags ));
void ldbm_cache_close LDAP_P(( Backend *be, struct dbcache *db ));
void ldbm_cache_really_close LDAP_P(( Backend *be, struct dbcache *db ));
void ldbm_cache_flush_all LDAP_P(( Backend *be ));
Datum ldbm_cache_fetch LDAP_P(( struct dbcache *db, Datum key ));
int ldbm_cache_store LDAP_P(( struct dbcache *db, Datum key, Datum data, int flags ));
int ldbm_cache_delete LDAP_P(( struct dbcache *db, Datum key ));
/*
* dn2id.c
*/
int dn2id_add( Backend *be, char *dn, ID id );
ID dn2id( Backend *be, char *dn );
int dn2id_delete( Backend *be, char *dn );
Entry * dn2entry( Backend *be, char *dn, char **matched );
int dn2id_add LDAP_P(( Backend *be, char *dn, ID id ));
ID dn2id LDAP_P(( Backend *be, char *dn ));
int dn2id_delete LDAP_P(( Backend *be, char *dn ));
Entry * dn2entry_rw LDAP_P(( Backend *be, char *dn, Entry **matched, int rw ));
#define dn2entry_r(be, dn, m) dn2entry_rw((be), (dn), (m), 0)
#define dn2entry_w(be, dn, m) dn2entry_rw((be), (dn), (m), 1)
/*
* entry.c
*/
int ldbm_back_entry_release_rw LDAP_P(( Backend *be, Entry *e, int rw ));
/*
* filterindex.c
*/
IDList * filter_candidates( Backend *be, Filter *f );
ID_BLOCK * filter_candidates LDAP_P(( Backend *be, Filter *f ));
/*
* id2children.c
*/
int id2children_add( Backend *be, Entry *p, Entry *e );
int has_children( Backend *be, Entry *p );
int id2children_add LDAP_P(( Backend *be, Entry *p, Entry *e ));
int id2children_remove LDAP_P(( Backend *be, Entry *p, Entry *e ));
int has_children LDAP_P(( Backend *be, Entry *p ));
/*
* id2entry.c
*/
int id2entry_add( Backend *be, Entry *e );
int id2entry_delete( Backend *be, Entry *e );
Entry * id2entry( Backend *be, ID id );
int id2entry_add LDAP_P(( Backend *be, Entry *e ));
int id2entry_delete LDAP_P(( Backend *be, Entry *e ));
Entry * id2entry_rw LDAP_P(( Backend *be, ID id, int rw ));
#define id2entry_r(be, id) id2entry_rw((be), (id), 0)
#define id2entry_w(be, id) id2entry_rw((be), (id), 1)
/*
* idl.c
*/
IDList * idl_alloc( int nids );
IDList * idl_allids( Backend *be );
void idl_free( IDList *idl );
IDList * idl_fetch( Backend *be, struct dbcache *db, Datum key );
int idl_insert_key( Backend *be, struct dbcache *db, Datum key, ID id );
int idl_insert( IDList **idl, ID id, int maxids );
IDList * idl_intersection( Backend *be, IDList *a, IDList *b );
IDList * idl_union( Backend *be, IDList *a, IDList *b );
IDList * idl_notin( Backend *be, IDList *a, IDList *b );
ID idl_firstid( IDList *idl );
ID idl_nextid( IDList *idl, ID id );
ID_BLOCK * idl_alloc LDAP_P(( unsigned int nids ));
ID_BLOCK * idl_allids LDAP_P(( Backend *be ));
void idl_free LDAP_P(( ID_BLOCK *idl ));
ID_BLOCK * idl_fetch LDAP_P(( Backend *be, struct dbcache *db, Datum key ));
int idl_insert_key LDAP_P(( Backend *be, struct dbcache *db, Datum key, ID id ));
int idl_insert LDAP_P(( ID_BLOCK **idl, ID id, unsigned int maxids ));
int idl_delete_key LDAP_P(( Backend *be, struct dbcache *db, Datum key, ID id ));
ID_BLOCK * idl_intersection LDAP_P(( Backend *be, ID_BLOCK *a, ID_BLOCK *b ));
ID_BLOCK * idl_union LDAP_P(( Backend *be, ID_BLOCK *a, ID_BLOCK *b ));
ID_BLOCK * idl_notin LDAP_P(( Backend *be, ID_BLOCK *a, ID_BLOCK *b ));
ID idl_firstid LDAP_P(( ID_BLOCK *idl ));
ID idl_nextid LDAP_P(( ID_BLOCK *idl, ID id ));
/*
* index.c
*/
int index_add_entry( Backend *be, Entry *e );
int index_add_mods( Backend *be, LDAPMod *mods, ID id );
IDList * index_read( Backend *be, char *type, int indextype, char *val );
int index_add_values( Backend *be, char *type, struct berval **vals, ID id );
int index_add_entry LDAP_P(( Backend *be, Entry *e ));
int index_add_mods LDAP_P(( Backend *be, LDAPModList *ml, ID id ));
ID_BLOCK * index_read LDAP_P(( Backend *be, char *type, int indextype, char *val ));
/* Possible operations supported (op) by index_change_values() */
#define __INDEX_ADD_OP 0x0001
#define __INDEX_DELETE_OP 0x0002
int index_change_values LDAP_P(( Backend *be,
char *type,
struct berval **vals,
ID id,
unsigned int op ));
/*
* kerberos.c
*/
#ifdef KERBEROS
/* krbv4_ldap_auth( Backend *be, struct berval *cred, AUTH_DAT *ad ); */
#ifdef HAVE_KERBEROS
/* krbv4_ldap_auth LDAP_P(( Backend *be, struct berval *cred, AUTH_DAT *ad )); */
#endif
/*
* modify.c
* These prototypes are placed here because they are used by modify and
* modify rdn which are implemented in different files.
*
* We need ldbm_internal_modify here because of LDAP modrdn & modify use
* it. If we do not add this, there would be a bunch of code replication
* here and there and of course the likelihood of bugs increases.
* Juan C. Gomez (gomez@engr.sgi.com) 05/18/99
*
*/
int add_values LDAP_P(( Entry *e, LDAPMod *mod, char *dn ));
int delete_values LDAP_P(( Entry *e, LDAPMod *mod, char *dn ));
int replace_values LDAP_P(( Entry *e, LDAPMod *mod, char *dn ));
int ldbm_modify_internal LDAP_P((Backend *be, Connection *conn, Operation *op,
char *dn, LDAPModList *mods, Entry *e));
/*
* nextid.c
*/
ID next_id( Backend *be );
void next_id_return( Backend *be, ID id );
ID next_id_get( Backend *be );
ID next_id LDAP_P(( Backend *be ));
void next_id_return LDAP_P(( Backend *be, ID id ));
ID next_id_get LDAP_P(( Backend *be ));
int next_id_save LDAP_P(( Backend *be ));
LDAP_END_DECL
#endif

View file

@ -11,9 +11,13 @@
#include "back-ldbm.h"
#include "proto-back-ldbm.h"
static ID_BLOCK *base_candidates(Backend *be, Connection *conn, Operation *op, char *base, Filter *filter, char **attrs, int attrsonly, char **matched, int *err);
static ID_BLOCK *onelevel_candidates(Backend *be, Connection *conn, Operation *op, char *base, Filter *filter, char **attrs, int attrsonly, char **matched, int *err);
static ID_BLOCK *subtree_candidates(Backend *be, Connection *conn, Operation *op, char *base, Filter *filter, char **attrs, int attrsonly, char **matched, Entry *e, int *err, int lookupbase);
static ID_BLOCK *base_candidate(
Backend *be, Entry *e );
static ID_BLOCK *search_candidates(
Backend *be, Entry *e, Filter *filter,
int scope, int deref, int manageDSAit );
int
ldbm_back_search(
@ -37,13 +41,71 @@ ldbm_back_search(
ID_BLOCK *candidates;
ID id;
Entry *e;
Attribute *ref;
struct berval **refs;
char *matched = NULL;
struct berval **v2refs = NULL;
Entry *matched = NULL;
char *matched_dn = NULL;
int nentries = 0;
char *realBase;
int manageDSAit = get_manageDSAit( op );
Debug(LDAP_DEBUG_ARGS, "=> ldbm_back_search\n", 0, 0, 0);
Debug(LDAP_DEBUG_TRACE, "=> ldbm_back_search\n", 0, 0, 0);
/* get entry with reader lock */
switch ( deref ) {
#ifdef SLAPD_ALIASES
case LDAP_DEREF_FINDING:
case LDAP_DEREF_ALWAYS:
e = alias_dn2entry_r( be, base, &matched, &err );
break;
#endif
default:
e = dn2entry_r( be, base, &matched );
err = e != NULL ? LDAP_SUCCESS : LDAP_REFERRAL;
}
if ( e == NULL ) {
char *matched_dn = NULL;
struct berval **refs = NULL;
if ( matched != NULL ) {
matched_dn = ch_strdup( matched->e_dn );
refs = is_entry_referral( matched )
? get_entry_referrals( be, conn, op, matched )
: NULL;
cache_return_entry_r( &li->li_cache, matched );
} else {
refs = default_referral;
}
send_ldap_result( conn, op, err,
matched_dn, NULL, refs, NULL );
if( matched != NULL ) {
ber_bvecfree( refs );
free( matched_dn );
}
return 1;
}
if (!manageDSAit && is_entry_referral( e ) ) {
/* entry is a referral, don't allow add */
char *matched_dn = ch_strdup( e->e_dn );
struct berval **refs = get_entry_referrals( be,
conn, op, e );
cache_return_entry_r( &li->li_cache, matched );
Debug( LDAP_DEBUG_TRACE, "entry is referral\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
ber_bvecfree( refs );
free( matched_dn );
return 1;
}
if ( tlimit == 0 && be_isroot( be, op->o_ndn ) ) {
tlimit = -1; /* allow root to set no limit */
@ -52,6 +114,7 @@ ldbm_back_search(
be->be_timelimit : tlimit;
stoptime = op->o_time + tlimit;
}
if ( slimit == 0 && be_isroot( be, op->o_ndn ) ) {
slimit = -1; /* allow root to set no limit */
} else {
@ -59,68 +122,29 @@ ldbm_back_search(
be->be_sizelimit : slimit;
}
/*
* check and apply aliasing where the dereferencing applies to
* the subordinates of the base
*/
if ( scope == LDAP_SCOPE_BASE) {
candidates = base_candidate( be, e );
switch ( deref ) {
case LDAP_DEREF_FINDING:
case LDAP_DEREF_ALWAYS:
realBase = derefDN ( be, conn, op, base );
break;
default:
realBase = ch_strdup(base);
} else {
candidates = search_candidates( be, e, filter,
scope, deref, manageDSAit );
}
(void) dn_normalize_case( realBase );
Debug( LDAP_DEBUG_TRACE, "using base \"%s\"\n",
realBase, 0, 0 );
switch ( scope ) {
case LDAP_SCOPE_BASE:
candidates = base_candidates( be, conn, op, realBase, filter,
attrs, attrsonly, &matched, &err );
break;
case LDAP_SCOPE_ONELEVEL:
candidates = onelevel_candidates( be, conn, op, realBase, filter,
attrs, attrsonly, &matched, &err );
break;
case LDAP_SCOPE_SUBTREE:
candidates = subtree_candidates( be, conn, op, realBase, filter,
attrs, attrsonly, &matched, NULL, &err, 1 );
break;
default:
send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
"", "Bad search scope", NULL );
if( realBase != NULL) {
free( realBase );
}
return( -1 );
}
matched_dn = ch_strdup( e->e_dn );
cache_return_entry_r( &li->li_cache, e );
/* null candidates means we could not find the base object */
if ( candidates == NULL ) {
send_ldap_result( conn, op, err,
matched, NULL, NULL );
if ( matched != NULL ) {
free( matched );
}
if( realBase != NULL) {
free( realBase );
}
return( -1 );
}
/* return a NO SUCH OBJECT */
Debug( LDAP_DEBUG_TRACE, "no candidates\n", 0,
0, 0 );
if ( matched != NULL ) {
free( matched );
}
send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
matched_dn, "no search candidates", NULL, NULL );
refs = NULL;
free( matched_dn );
return 1;
}
for ( id = idl_firstid( candidates ); id != NOID;
id = idl_nextid( candidates, id ) ) {
@ -130,10 +154,8 @@ ldbm_back_search(
if ( op->o_abandon ) {
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
idl_free( candidates );
ber_bvecfree( refs );
if( realBase != NULL) {
free( realBase );
}
ber_bvecfree( v2refs );
free( matched_dn );
return( 0 );
}
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
@ -141,17 +163,27 @@ ldbm_back_search(
/* check time limit */
if ( tlimit != -1 && slap_get_time() > stoptime ) {
send_search_result( conn, op, LDAP_TIMELIMIT_EXCEEDED,
NULL, NULL, refs, nentries );
NULL, NULL, v2refs, NULL, nentries );
idl_free( candidates );
ber_bvecfree( refs );
if( realBase != NULL) {
free( realBase );
}
ber_bvecfree( v2refs );
free( matched_dn );
return( 0 );
}
/* get the entry with reader lock */
if ( (e = id2entry_r( be, id )) == NULL ) {
switch ( deref ) {
#ifdef SLAPD_ALIASES
case LDAP_DEREF_SEARCHING:
case LDAP_DEREF_ALWAYS:
e = alias_id2entry_r( be, id, &matched, &err );
break;
#endif
default:
e = dn2entry_r( be, base, &matched );
err = e != NULL ? LDAP_SUCCESS : LDAP_REFERRAL;
}
if ( e == NULL ) {
Debug( LDAP_DEBUG_ARGS, "candidate %ld not found\n",
id, 0, 0 );
continue;
@ -162,13 +194,15 @@ ldbm_back_search(
* this for subtree searches, and don't check the filter
* explicitly here since it's only a candidate anyway.
*/
if ( scope == LDAP_SCOPE_SUBTREE &&
e->e_ndn != NULL &&
strncmp( e->e_ndn, "REF=", 4 ) == 0 &&
(ref = attr_find( e->e_attrs, "ref" )) != NULL )
if ( !manageDSAit && scope != LDAP_SCOPE_BASE &&
is_entry_referral( e ) )
{
struct berval **refs = get_entry_referrals( be, conn, op, e );
send_search_reference( be, conn, op,
e, ref->a_vals, &refs );
e, refs, NULL, &v2refs );
ber_bvecfree( refs );
/* otherwise it's an entry - see if it matches the filter */
} else {
@ -178,21 +212,22 @@ ldbm_back_search(
char *dn;
/* check scope */
scopeok = 1;
if ( scope == LDAP_SCOPE_ONELEVEL ) {
if ( (dn = dn_parent( be, e->e_dn )) != NULL ) {
(void) dn_normalize_case( dn );
scopeok = (dn == realBase)
scopeok = (dn == matched_dn)
? 1
: (strcmp( dn, realBase ) ? 0 : 1 );
: (strcmp( dn, matched_dn ) ? 0 : 1 );
free( dn );
} else {
scopeok = (realBase == NULL || *realBase == '\0');
scopeok = (matched_dn == NULL || *matched_dn == '\0');
}
} else if ( scope == LDAP_SCOPE_SUBTREE ) {
dn = ch_strdup( e->e_ndn );
scopeok = dn_issuffix( dn, realBase );
scopeok = dn_issuffix( dn, matched_dn );
free( dn );
} else {
scopeok = 1;
}
if ( scopeok ) {
@ -201,39 +236,16 @@ ldbm_back_search(
cache_return_entry_r( &li->li_cache, e );
send_search_result( conn, op,
LDAP_SIZELIMIT_EXCEEDED, NULL, NULL,
refs, nentries );
v2refs, NULL, nentries );
idl_free( candidates );
ber_bvecfree( refs );
if( realBase != NULL) {
free( realBase );
}
ber_bvecfree( v2refs );
free( matched_dn );
return( 0 );
}
/*
* check and apply aliasing where the dereferencing applies to
* the subordinates of the base
*/
switch ( deref ) {
case LDAP_DEREF_SEARCHING:
case LDAP_DEREF_ALWAYS:
{
Entry *newe = derefAlias_r( be, conn, op, e );
if ( newe == NULL ) { /* problem with the alias */
cache_return_entry_r( &li->li_cache, e );
e = NULL;
}
else if ( newe != e ) { /* reassign e */
cache_return_entry_r( &li->li_cache, e );
e = newe;
}
}
break;
}
if (e) {
switch ( send_search_entry( be, conn, op, e,
attrs, attrsonly, 0 ) ) {
attrs, attrsonly, 0, NULL ) ) {
case 0: /* entry sent ok */
nentries++;
break;
@ -242,11 +254,8 @@ ldbm_back_search(
case -1: /* connection closed */
cache_return_entry_r( &li->li_cache, e );
idl_free( candidates );
ber_bvecfree( refs );
if( realBase != NULL) {
free( realBase );
}
ber_bvecfree( v2refs );
free( matched_dn );
return( 0 );
}
}
@ -264,204 +273,120 @@ ldbm_back_search(
idl_free( candidates );
send_search_result( conn, op,
refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
NULL, NULL, refs, nentries );
v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
NULL, NULL, v2refs, NULL, nentries );
ber_bvecfree( refs );
if( realBase != NULL) {
free( realBase );
}
ber_bvecfree( v2refs );
return( 0 );
}
static ID_BLOCK *
base_candidates(
base_candidate(
Backend *be,
Connection *conn,
Operation *op,
char *base,
Filter *filter,
char **attrs,
int attrsonly,
char **matched,
int *err
Entry *e
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
ID_BLOCK *idl;
Entry *e;
Debug(LDAP_DEBUG_TRACE, "base_candidates: base: \"%s\"\n", base, 0, 0);
*err = LDAP_SUCCESS;
/* get entry with reader lock */
if ( (e = dn2entry_r( be, base, matched )) == NULL ) {
*err = LDAP_NO_SUCH_OBJECT;
return( NULL );
}
/* check for deleted */
Debug(LDAP_DEBUG_TRACE, "base_candidates: base: \"%s\"\n",
e->e_dn, 0, 0);
idl = idl_alloc( 1 );
idl_insert( &idl, e->e_id, 1 );
/* free reader lock */
cache_return_entry_r( &li->li_cache, e );
return( idl );
}
static ID_BLOCK *
onelevel_candidates(
search_candidates(
Backend *be,
Connection *conn,
Operation *op,
char *base,
Filter *filter,
char **attrs,
int attrsonly,
char **matched,
int *err
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
Entry *e = NULL;
Filter *f;
char buf[20];
ID_BLOCK *candidates;
Debug(LDAP_DEBUG_TRACE, "onelevel_candidates: base: \"%s\"\n", base, 0, 0);
*err = LDAP_SUCCESS;
/* get the base object with reader lock */
if ( base != NULL && *base != '\0' &&
(e = dn2entry_r( be, base, matched )) == NULL )
{
*err = LDAP_NO_SUCH_OBJECT;
return( NULL );
}
/*
* modify the filter to be something like this:
*
* parent=baseobject & originalfilter
*/
f = (Filter *) ch_malloc( sizeof(Filter) );
f->f_next = NULL;
f->f_choice = LDAP_FILTER_AND;
f->f_and = (Filter *) ch_malloc( sizeof(Filter) );
f->f_and->f_choice = LDAP_FILTER_EQUALITY;
f->f_and->f_ava.ava_type = ch_strdup( "id2children" );
sprintf( buf, "%ld", e != NULL ? e->e_id : 0 );
f->f_and->f_ava.ava_value.bv_val = ch_strdup( buf );
f->f_and->f_ava.ava_value.bv_len = strlen( buf );
f->f_and->f_next = filter;
/* from here, it's just like subtree_candidates */
candidates = subtree_candidates( be, conn, op, base, f, attrs,
attrsonly, matched, e, err, 0 );
/* free up just the filter stuff we allocated above */
f->f_and->f_next = NULL;
filter_free( f );
/* free entry and reader lock */
if( e != NULL ) {
cache_return_entry_r( &li->li_cache, e );
}
return( candidates );
}
static ID_BLOCK *
subtree_candidates(
Backend *be,
Connection *conn,
Operation *op,
char *base,
Filter *filter,
char **attrs,
int attrsonly,
char **matched,
Entry *e,
int *err,
int lookupbase
Filter *filter,
int scope,
int deref,
int manageDSAit
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
Filter *f, **filterarg_ptr;
ID_BLOCK *candidates;
Filter *f, *rf, *af, *lf;
Debug(LDAP_DEBUG_TRACE, "subtree_candidates: base: \"%s\" %s\n",
base ? base : "NULL", lookupbase ? "lookupbase" : "", 0);
Debug(LDAP_DEBUG_TRACE, "search_candidates: base: \"%s\" %s\n",
e->e_dn, 0, 0 );
/*
* get the base object - unless we already have it (from one-level).
* also, unless this is a one-level search or a subtree search
* starting at the very top of our subtree, we need to modify the
* filter to be something like this:
*
* dn=*baseobjectdn & (originalfilter | ref=*)
*
* the "objectclass=referral" part is used to select referrals to return
*/
*err = LDAP_SUCCESS;
f = NULL;
if ( lookupbase ) {
e = NULL;
if ( base != NULL && *base != '\0' &&
(e = dn2entry_r( be, base, matched )) == NULL )
{
*err = LDAP_NO_SUCH_OBJECT;
return( NULL );
}
if (e) {
cache_return_entry_r( &li->li_cache, e );
}
f = (Filter *) ch_malloc( sizeof(Filter) );
f->f_next = NULL;
f->f_choice = LDAP_FILTER_OR;
f->f_or = (Filter *) ch_malloc( sizeof(Filter) );
f->f_or->f_choice = LDAP_FILTER_EQUALITY;
f->f_or->f_avtype = ch_strdup( "objectclass" );
/* Patch to use normalized uppercase */
f->f_or->f_avvalue.bv_val = ch_strdup( "REFERRAL" );
f->f_or->f_avvalue.bv_len = strlen( "REFERRAL" );
filterarg_ptr = &f->f_or->f_next;
*filterarg_ptr = filter;
filter = f;
if ( ! be_issuffix( be, base ) ) {
f = (Filter *) ch_malloc( sizeof(Filter) );
f->f_next = NULL;
f->f_choice = LDAP_FILTER_AND;
f->f_and = (Filter *) ch_malloc( sizeof(Filter) );
f->f_and->f_choice = LDAP_FILTER_SUBSTRINGS;
f->f_and->f_sub_type = ch_strdup( "dn" );
f->f_and->f_sub_initial = NULL;
f->f_and->f_sub_any = NULL;
f->f_and->f_sub_final = ch_strdup( base );
value_normalize( f->f_and->f_sub_final, SYNTAX_CIS );
f->f_and->f_next = filter;
filter = f;
}
if( !manageDSAit ) {
/* match referrals */
rf = (Filter *) ch_malloc( sizeof(Filter) );
rf->f_next = NULL;
rf->f_choice = LDAP_FILTER_OR;
rf->f_or = (Filter *) ch_malloc( sizeof(Filter) );
rf->f_or->f_choice = LDAP_FILTER_EQUALITY;
rf->f_or->f_avtype = ch_strdup( "objectclass" );
rf->f_or->f_avvalue.bv_val = ch_strdup( "REFERRAL" );
rf->f_or->f_avvalue.bv_len = sizeof("REFERRAL")-1;
rf->f_or->f_next = filter;
f = rf;
} else {
rf = NULL;
f = filter;
}
candidates = filter_candidates( be, filter );
if( deref == LDAP_DEREF_SEARCHING || deref == LDAP_DEREF_ALWAYS ) {
/* match aliases */
af = (Filter *) ch_malloc( sizeof(Filter) );
af->f_next = NULL;
af->f_choice = LDAP_FILTER_OR;
af->f_or = (Filter *) ch_malloc( sizeof(Filter) );
af->f_or->f_choice = LDAP_FILTER_EQUALITY;
af->f_or->f_avtype = ch_strdup( "objectclass" );
af->f_or->f_avvalue.bv_val = ch_strdup( "ALIAS" );
af->f_or->f_avvalue.bv_len = sizeof("ALIAS")-1;
af->f_or->f_next = f;
f = af;
} else {
af = NULL;
}
/* free up just the parts we allocated above */
if ( f != NULL ) {
*filterarg_ptr = NULL;
filter_free( f );
lf = (Filter *) ch_malloc( sizeof(Filter) );
lf->f_next = NULL;
lf->f_choice = LDAP_FILTER_AND;
lf->f_and = (Filter *) ch_malloc( sizeof(Filter) );
lf->f_and->f_next = f;
if ( scope == LDAP_SCOPE_SUBTREE ) {
lf->f_and->f_choice = LDAP_FILTER_SUBSTRINGS;
lf->f_and->f_sub_type = ch_strdup( "dn" );
lf->f_and->f_sub_initial = NULL;
lf->f_and->f_sub_any = NULL;
lf->f_and->f_sub_final = ch_strdup( e->e_ndn );
value_normalize( lf->f_and->f_sub_final, SYNTAX_DN|SYNTAX_CIS );
} else {
char buf[16];
lf->f_and->f_choice = LDAP_FILTER_EQUALITY;
lf->f_and->f_ava.ava_type = ch_strdup( "id2children" );
sprintf( buf, "%ld", e != NULL ? e->e_id : 0 );
lf->f_and->f_ava.ava_value.bv_val = ch_strdup( buf );
lf->f_and->f_ava.ava_value.bv_len = strlen( buf );
}
candidates = filter_candidates( be, lf );
/* free up filter additions we allocated above */
lf->f_and->f_next = NULL;
filter_free( lf );
if( af != NULL ) {
af->f_or->f_next = NULL;
filter_free( af );
}
if( rf != NULL ) {
rf->f_or->f_next = NULL;
filter_free( rf );
}
return( candidates );

View file

@ -1,146 +1,419 @@
/* backend.c - routines for dealing with back-end databases */
#include "portable.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ac/string.h>
#include <ac/socket.h>
#include <sys/stat.h>
#include "slap.h"
#include "lutil.h"
#ifdef LDAP_LDBM
extern int ldbm_back_bind();
extern int ldbm_back_unbind();
extern int ldbm_back_search();
extern int ldbm_back_compare();
extern int ldbm_back_modify();
extern int ldbm_back_modrdn();
extern int ldbm_back_add();
extern int ldbm_back_delete();
extern int ldbm_back_abandon();
extern int ldbm_back_config();
extern int ldbm_back_init();
extern int ldbm_back_close();
#ifdef SLAPD_LDAP
#include "back-ldap/external.h"
#endif
#ifdef SLAPD_LDBM
#include "back-ldbm/external.h"
#endif
#ifdef SLAPD_BDB2
#include "back-bdb2/external.h"
#endif
#ifdef SLAPD_PASSWD
#include "back-passwd/external.h"
#endif
#ifdef SLAPD_PERL
#include "back-perl/external.h"
#endif
#ifdef SLAPD_SHELL
#include "back-shell/external.h"
#endif
#ifdef SLAPD_TCL
#include "back-tcl/external.h"
#endif
#ifdef LDAP_PASSWD
extern int passwd_back_search();
extern int passwd_back_config();
static BackendInfo binfo[] = {
#if defined(SLAPD_LDAP) && !defined(SLAPD_LDAP_DYNAMIC)
{"ldap", ldap_back_initialize},
#endif
#ifdef LDAP_SHELL
extern int shell_back_bind();
extern int shell_back_unbind();
extern int shell_back_search();
extern int shell_back_compare();
extern int shell_back_modify();
extern int shell_back_modrdn();
extern int shell_back_add();
extern int shell_back_delete();
extern int shell_back_abandon();
extern int shell_back_config();
extern int shell_back_init();
#if defined(SLAPD_LDBM) && !defined(SLAPD_LDBM_DYNAMIC)
{"ldbm", ldbm_back_initialize},
#endif
#if defined(SLAPD_BDB2) && !defined(SLAPD_BDB2_DYNAMIC)
{"bdb2", bdb2_back_initialize},
#endif
#if defined(SLAPD_PASSWD) && !defined(SLAPD_PASSWD_DYNAMIC)
{"passwd", passwd_back_initialize},
#endif
#if defined(SLAPD_PERL) && !defined(SLAPD_PERL_DYNAMIC)
{"perl", perl_back_initialize},
#endif
#if defined(SLAPD_SHELL) && !defined(SLAPD_SHELL_DYNAMIC)
{"shell", shell_back_initialize},
#endif
#if defined(SLAPD_TCL) && !defined(SLAPD_LDAP_TCL)
{"tcl", tcl_back_initialize},
#endif
{NULL}
};
extern int defsize;
extern int deftime;
int nBackendInfo = 0;
BackendInfo *backendInfo = NULL;
#define BACKEND_GRAB_SIZE 10
int nBackendDB = 0;
BackendDB *backendDB = NULL;
int nbackends;
Backend *backends;
static int maxbackends;
int backend_init(void)
{
int rc = -1;
Backend *
new_backend(
if((nBackendInfo != 0) || (backendInfo != NULL)) {
/* already initialized */
Debug( LDAP_DEBUG_ANY,
"backend_init: already initialized.\n", 0, 0, 0 );
return -1;
}
for( ;
binfo[nBackendInfo].bi_type != NULL;
nBackendInfo++ )
{
rc = binfo[nBackendInfo].bi_init(
&binfo[nBackendInfo] );
if(rc != 0) {
Debug( LDAP_DEBUG_ANY,
"backend_init: initialized for type \"%s\"\n",
binfo[nBackendInfo].bi_type, 0, 0 );
/* destroy those we've already inited */
for( nBackendInfo--;
nBackendInfo >= 0 ;
nBackendInfo-- )
{
if ( binfo[nBackendInfo].bi_destroy ) {
binfo[nBackendInfo].bi_destroy(
&binfo[nBackendInfo] );
}
}
return rc;
}
}
if ( nBackendInfo > 0) {
backendInfo = binfo;
return 0;
}
#ifdef SLAPD_MODULES
return 0;
#else
Debug( LDAP_DEBUG_ANY,
"backend_init: failed\n",
0, 0, 0 );
return rc;
#endif /* SLAPD_MODULES */
}
int backend_add(BackendInfo *aBackendInfo)
{
int rc = 0;
if ((rc = aBackendInfo->bi_init(aBackendInfo)) != 0) {
Debug( LDAP_DEBUG_ANY,
"backend_add: initialization for type \"%s\" failed\n",
aBackendInfo->bi_type, 0, 0 );
return rc;
}
/* now add the backend type to the Backend Info List */
{
BackendInfo *newBackendInfo = 0;
/* if backendInfo == binfo no deallocation of old backendInfo */
if (backendInfo == binfo) {
newBackendInfo = ch_calloc(nBackendInfo + 1, sizeof(BackendInfo));
memcpy(newBackendInfo, backendInfo, sizeof(BackendInfo) *
nBackendInfo);
} else {
newBackendInfo = ch_realloc(backendInfo, sizeof(BackendInfo) *
(nBackendInfo + 1));
}
memcpy(&newBackendInfo[nBackendInfo], aBackendInfo,
sizeof(BackendInfo));
backendInfo = newBackendInfo;
nBackendInfo++;
return 0;
}
}
int backend_startup(int n)
{
int i;
int rc = 0;
if( ! ( nBackendDB > 0 ) ) {
/* no databases */
Debug( LDAP_DEBUG_ANY,
"backend_startup: %d databases to startup.\n",
nBackendDB, 0, 0 );
return 1;
}
if(n >= 0) {
/* startup a specific backend database */
Debug( LDAP_DEBUG_TRACE,
"backend_startup: starting database %d\n",
n, 0, 0 );
/* make sure, n does not exceed the number of backend databases */
if ( n >= nbackends ) {
Debug( LDAP_DEBUG_ANY,
"backend_startup: database number %d exceeding maximum (%d)\n",
n, nbackends, 0 );
return 1;
}
if ( backendDB[n].bd_info->bi_open ) {
rc = backendDB[n].bd_info->bi_open(
backendDB[n].bd_info );
}
if(rc != 0) {
Debug( LDAP_DEBUG_ANY,
"backend_startup: bi_open failed!\n",
0, 0, 0 );
return rc;
}
if ( backendDB[n].bd_info->bi_db_open ) {
rc = backendDB[n].bd_info->bi_db_open(
&backendDB[n] );
}
if(rc != 0) {
Debug( LDAP_DEBUG_ANY,
"backend_startup: bi_db_open failed!\n",
0, 0, 0 );
return rc;
}
return rc;
}
/* open each backend type */
for( i = 0; i < nBackendInfo; i++ ) {
if( backendInfo[i].bi_nDB == 0) {
/* no database of this type, don't open */
continue;
}
if( backendInfo[i].bi_open ) {
rc = backendInfo[i].bi_open(
&backendInfo[i] );
}
if(rc != 0) {
Debug( LDAP_DEBUG_ANY,
"backend_startup: bi_open %d failed!\n",
i, 0, 0 );
return rc;
}
}
/* open each backend database */
for( i = 0; i < nBackendDB; i++ ) {
if ( backendDB[i].bd_info->bi_db_open ) {
rc = backendDB[i].bd_info->bi_db_open(
&backendDB[i] );
}
if(rc != 0) {
Debug( LDAP_DEBUG_ANY,
"backend_startup: bi_db_open %d failed!\n",
i, 0, 0 );
return rc;
}
}
return rc;
}
int backend_shutdown(int n)
{
int i;
int rc = 0;
if(n >= 0) {
/* shutdown a specific backend database */
/* make sure, n does not exceed the number of backend databases */
if ( n >= nbackends ) {
Debug( LDAP_DEBUG_ANY,
"backend_startup: database number %d exceeding maximum (%d)\n",
n, nbackends, 0 );
return 1;
}
if ( backendDB[n].bd_info->bi_nDB == 0 ) {
/* no database of this type, we never opened it */
return 0;
}
if ( backendDB[n].bd_info->bi_db_close ) {
backendDB[n].bd_info->bi_db_close(
&backendDB[n] );
}
if( backendDB[n].bd_info->bi_close ) {
backendDB[n].bd_info->bi_close(
backendDB[n].bd_info );
}
return 0;
}
/* close each backend database */
for( i = 0; i < nBackendDB; i++ ) {
BackendInfo *bi;
if ( backendDB[i].bd_info->bi_db_close ) {
backendDB[i].bd_info->bi_db_close(
&backendDB[i] );
}
if(rc != 0) {
Debug( LDAP_DEBUG_ANY,
"backend_close: bi_close %s failed!\n",
bi->bi_type, 0, 0 );
}
}
/* close each backend type */
for( i = 0; i < nBackendInfo; i++ ) {
if( backendInfo[i].bi_nDB == 0 ) {
/* no database of this type */
continue;
}
if( backendInfo[i].bi_close ) {
backendInfo[i].bi_close(
&backendInfo[i] );
}
}
return 0;
}
int backend_destroy(void)
{
int i;
/* destroy each backend database */
for( i = 0; i < nBackendDB; i++ ) {
if ( backendDB[i].bd_info->bi_db_destroy ) {
backendDB[i].bd_info->bi_db_destroy(
&backendDB[i] );
}
}
/* destroy each backend type */
for( i = 0; i < nBackendInfo; i++ ) {
if( backendInfo[i].bi_destroy ) {
backendInfo[i].bi_destroy(
&backendInfo[i] );
}
}
#ifdef SLAPD_MODULES
if (backendInfo != binfo) {
free(backendInfo);
}
#endif /* SLAPD_MODULES */
nBackendInfo = 0;
backendInfo = NULL;
return 0;
}
BackendInfo* backend_info(char *type)
{
int i;
/* search for the backend type */
for( i = 0; i < nBackendInfo; i++ ) {
if( strcasecmp(backendInfo[i].bi_type, type) == 0 ) {
return &backendInfo[i];
}
}
return NULL;
}
BackendDB *
backend_db_init(
char *type
)
{
Backend *be;
int foundit;
BackendInfo *bi = backend_info(type);
int rc = 0;
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) );
if( bi == NULL ) {
fprintf( stderr, "Unrecognized database type (%s)\n", type );
return NULL;
}
backendDB = (BackendDB *) ch_realloc(
(char *) backendDB,
(nBackendDB + 1) * sizeof(Backend) );
memset( &backendDB[nbackends], '\0', sizeof(Backend) );
be = &backends[nbackends++];
be->bd_info = bi;
be->be_sizelimit = defsize;
be->be_timelimit = deftime;
foundit = 0;
#ifdef LDAP_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;
be->be_type = "ldbm";
foundit = 1;
}
#endif
be->be_realm = global_realm != NULL
? ch_strdup( global_realm ) : NULL;
#ifdef LDAP_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;
be->be_type = "passwd";
foundit = 1;
}
#endif
#ifdef LDAP_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;
be->be_type = "shell";
foundit = 1;
}
#endif
if ( be->be_init != NULL ) {
(*be->be_init)( be );
if(bi->bi_db_init) {
rc = bi->bi_db_init( be );
}
if ( foundit == 0 ) {
fprintf( stderr, "Unrecognized database type (%s)\n", type );
exit( 1 );
if(rc != 0) {
fprintf( stderr, "database init failed (%s)\n", type );
nbackends--;
return NULL;
}
bi->bi_nDB++;
return( be );
}
void
be_db_close( void )
{
int i;
for ( i = 0; i < nbackends; i++ ) {
if ( backends[i].bd_info->bi_db_close ) {
(*backends[i].bd_info->bi_db_close)( &backends[i] );
}
}
}
Backend *
select_backend( char * dn )
{
@ -148,21 +421,36 @@ select_backend( char * dn )
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] );
for ( j = 0; backends[i].be_nsuffix != NULL &&
backends[i].be_nsuffix[j] != NULL; j++ )
{
len = strlen( backends[i].be_nsuffix[j] );
if ( len > dnlen ) {
continue;
}
if ( strcasecmp( backends[i].be_suffix[j],
if ( strcmp( backends[i].be_nsuffix[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 );
}
@ -174,8 +462,8 @@ be_issuffix(
{
int i;
for ( i = 0; be->be_suffix != NULL && be->be_suffix[i] != NULL; i++ ) {
if ( strcasecmp( be->be_suffix[i], suffix ) == 0 ) {
for ( i = 0; be->be_nsuffix != NULL && be->be_nsuffix[i] != NULL; i++ ) {
if ( strcmp( be->be_nsuffix[i], suffix ) == 0 ) {
return( 1 );
}
}
@ -184,41 +472,66 @@ be_issuffix(
}
int
be_isroot( Backend *be, char *dn )
be_isroot( Backend *be, char *ndn )
{
if ( dn == NULL ) {
int rc;
if ( ndn == NULL || be->be_root_ndn == NULL ) {
return( 0 );
}
return( be->be_rootdn ? strcasecmp( be->be_rootdn, dn ) == 0
: 0 );
rc = strcmp( be->be_root_ndn, ndn ) ? 0 : 1;
return(rc);
}
char *
be_root_dn( Backend *be )
{
if ( be->be_root_dn == NULL ) {
return( "" );
}
return be->be_root_dn;
}
int
be_isroot_pw( Backend *be, char *dn, struct berval *cred )
be_isroot_pw( Backend *be, char *ndn, struct berval *cred )
{
if ( ! be_isroot( be, dn ) || be->be_rootpw == NULL ) {
int result;
if ( ! be_isroot( be, ndn ) ) {
return( 0 );
}
return( strcmp( be->be_rootpw, cred->bv_val ) == 0 );
#ifdef SLAPD_CRYPT
ldap_pvt_thread_mutex_lock( &crypt_mutex );
#endif
result = lutil_passwd( cred->bv_val, be->be_root_pw, NULL );
#ifdef SLAPD_CRYPT
ldap_pvt_thread_mutex_unlock( &crypt_mutex );
#endif
return result == 0;
}
void
be_close()
int
be_entry_release_rw( Backend *be, Entry *e, int rw )
{
int i;
for ( i = 0; i < nbackends; i++ ) {
if ( backends[i].be_close != NULL ) {
(*backends[i].be_close)( &backends[i] );
}
if ( be->be_release ) {
/* free and release entry from backend */
return be->be_release( be, e, rw );
} else {
/* free entry */
entry_free( e );
return 0;
}
}
void
be_unbind(
int
backend_unbind(
Connection *conn,
Operation *op
)
@ -226,8 +539,59 @@ be_unbind(
int i;
for ( i = 0; i < nbackends; i++ ) {
if ( backends[i].be_unbind != NULL ) {
if ( backends[i].be_unbind ) {
(*backends[i].be_unbind)( &backends[i], conn, op );
}
}
return 0;
}
int
backend_connection_init(
Connection *conn
)
{
int i;
for ( i = 0; i < nbackends; i++ ) {
if ( backends[i].be_connection_init ) {
(*backends[i].be_connection_init)( &backends[i], conn);
}
}
return 0;
}
int
backend_connection_destroy(
Connection *conn
)
{
int i;
for ( i = 0; i < nbackends; i++ ) {
if ( backends[i].be_connection_destroy ) {
(*backends[i].be_connection_destroy)( &backends[i], conn);
}
}
return 0;
}
int
backend_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);
}

View file

@ -159,7 +159,7 @@ do_bind(
if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) {
Debug( LDAP_DEBUG_ANY, "unknown version %d\n", version, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
NULL, "version not supported", NULL );
NULL, "version not supported", NULL, NULL );
goto cleanup;
}
@ -178,7 +178,7 @@ do_bind(
"do_bind: no sasl mechanism provided\n",
version, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
NULL, "no sasl mechanism provided", NULL );
NULL, "no sasl mechanism provided", NULL, NULL );
goto cleanup;
}
@ -187,7 +187,7 @@ do_bind(
"do_bind: sasl mechanism \"%s\" not supported.\n",
mech, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_AUTH_METHOD_NOT_SUPPORTED,
NULL, "sasl mechanism not supported", NULL );
NULL, "sasl mechanism not supported", NULL, NULL );
goto cleanup;
}
@ -242,7 +242,8 @@ do_bind(
* we already forced connection to "anonymous", we just
* need to send success
*/
send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL );
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL, NULL );
goto cleanup;
}
@ -255,15 +256,15 @@ do_bind(
if ( (be = select_backend( ndn )) == NULL ) {
if ( cred.bv_len == 0 ) {
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
} else if ( default_referral ) {
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
NULL, NULL, default_referral );
NULL, NULL, default_referral, NULL );
} else {
send_ldap_result( conn, op, rc = LDAP_INVALID_CREDENTIALS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
}
goto cleanup;
@ -273,8 +274,6 @@ do_bind(
/* alias suffix */
char *edn;
ndn = suffixAlias( ndn, op, be );
if ( (*be->be_bind)( be, conn, op, ndn, method, mech, &cred, &edn ) == 0 ) {
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
@ -295,7 +294,7 @@ do_bind(
/* send this here to avoid a race condition */
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
} else if (edn != NULL) {
free( edn );
@ -303,7 +302,7 @@ do_bind(
} else {
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
NULL, "Function not implemented", NULL );
NULL, "Function not implemented", NULL, NULL );
}
cleanup:

View file

@ -35,7 +35,7 @@ do_compare(
Debug( LDAP_DEBUG_ANY, "do_compare: SASL bind in progress.\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS,
NULL, "SASL bind in progress", NULL );
NULL, "SASL bind in progress", NULL, NULL );
return LDAP_SASL_BIND_IN_PROGRESS;
}
@ -86,18 +86,15 @@ do_compare(
ava_free( &ava, 0 );
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
NULL, NULL, default_referral );
NULL, NULL, default_referral, NULL );
return 1;
}
/* alias suffix if approp */
ndn = suffixAlias( ndn, op, be );
if ( be->be_compare ) {
(*be->be_compare)( be, conn, op, ndn, &ava );
} else {
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
NULL, "Function not implemented", NULL );
NULL, "Function not implemented", NULL, NULL );
}
free( ndn );

View file

@ -127,7 +127,7 @@ read_config( char *fname )
be = backend_db_init( cargv[1] );
/* assign a default depth limit for alias deref */
be->be_maxDerefDepth = SLAPD_DEFAULT_MAXDEREFDEPTH;
be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH;
/* get pid file name */
} else if ( strcasecmp( cargv[0], "pidfile" ) == 0 ) {
@ -225,54 +225,9 @@ read_config( char *fname )
free( dn );
}
/* set database suffixAlias */
} else if ( strcasecmp( cargv[0], "suffixAlias" ) == 0 ) {
if ( cargc < 2 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing alias and aliased_dn in \"suffixAlias <alias> <aliased_dn>\" line\n",
fname, lineno, 0 );
return( 1 );
} else if ( cargc < 3 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing aliased_dn in \"suffixAlias <alias> <aliased_dn>\" line\n",
fname, lineno, 0 );
return( 1 );
} else if ( cargc > 3 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: extra cruft in suffixAlias line (ignored)\n",
fname, lineno, 0 );
}
if ( be == NULL ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: suffixAlias line must appear inside a database definition (ignored)\n",
fname, lineno, 0 );
} else {
char *alias, *aliased_dn;
alias = ch_strdup( cargv[1] );
(void) dn_normalize( alias );
aliased_dn = ch_strdup( cargv[2] );
(void) dn_normalize( aliased_dn );
if ( strcasecmp( alias, aliased_dn) == 0 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: suffixAlias %s is not different from aliased dn (ignored)\n",
fname, lineno, alias );
} else {
(void) dn_normalize_case( alias );
(void) dn_normalize_case( aliased_dn );
charray_add( &be->be_suffixAlias, alias );
charray_add( &be->be_suffixAlias, aliased_dn );
}
free(alias);
free(aliased_dn);
}
/* set max deref depth */
} else if ( strcasecmp( cargv[0], "maxDerefDepth" ) == 0 ) {
int i;
if ( cargc < 2 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing depth in \"maxDerefDepth <depth>\" line\n",
@ -283,9 +238,14 @@ read_config( char *fname )
Debug( LDAP_DEBUG_ANY,
"%s: line %d: depth line must appear inside a database definition (ignored)\n",
fname, lineno, 0 );
} else if ((i = atoi(cargv[i])) < 0) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: depth must be positive (ignored)\n",
fname, lineno, 0 );
} else {
be->be_maxDerefDepth = atoi (cargv[1]);
}
be->be_max_deref_depth = i;
}
/* set magic "root" dn for this database */

View file

@ -56,8 +56,10 @@ config_info( Connection *conn, Operation *op )
attr_merge( e, "database", vals );
}
send_search_entry( &backends[0], conn, op, e, NULL, 0, 1 );
send_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, 1 );
send_search_entry( &backends[0], conn, op, e,
NULL, 0, 1, NULL );
send_search_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL, NULL, 1 );
entry_free( e );
}

View file

@ -155,9 +155,29 @@ return_results:
if( rc == -1 ) {
send_ldap_disconnect( conn, op, rc, errmsg );
} else {
send_ldap_result( conn, op, rc, NULL, errmsg, NULL );
send_ldap_result( conn, op, rc,
NULL, errmsg, NULL, NULL );
}
}
return rc;
}
int get_manageDSAit( Operation *op )
{
int i;
if( op == NULL || op->o_ctrls == NULL ) {
return 0;
}
for( i=0; op->o_ctrls[i] != NULL; i++ ) {
if( strcmp( LDAP_CONTROL_MANAGEDSAIT, op->o_ctrls[i]->ldctl_oid )
== 0 )
{
return 1;
}
}
return 0;
}

View file

@ -35,7 +35,7 @@ do_delete(
Debug( LDAP_DEBUG_ANY, "do_delete: SASL bind in progress.\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS,
NULL, "SASL bind in progress", NULL );
NULL, "SASL bind in progress", NULL, NULL );
return LDAP_SASL_BIND_IN_PROGRESS;
}
@ -72,13 +72,10 @@ do_delete(
if ( (be = select_backend( ndn )) == NULL ) {
free( ndn );
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
NULL, NULL, default_referral );
NULL, NULL, default_referral, NULL );
return rc;
}
/* alias suffix if approp */
ndn = suffixAlias( ndn, op, be );
/*
* do the delete if 1 && (2 || 3)
* 1) there is a delete function implemented in this backend;
@ -95,11 +92,11 @@ do_delete(
}
} else {
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
NULL, NULL, default_referral );
NULL, NULL, default_referral, NULL );
}
} else {
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
NULL, "Function not implemented", NULL );
NULL, "Function not implemented", NULL, NULL );
}
free( ndn );

View file

@ -74,7 +74,7 @@ do_extended(
Debug( LDAP_DEBUG_ANY, "do_extended: unsupported operation \"%s\"\n",
reqoid, 0 ,0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
NULL, "unsuppored extended operation", NULL );
NULL, "unsuppored extended operation", NULL, NULL );
goto done;
}
@ -98,7 +98,7 @@ do_extended(
Debug( LDAP_DEBUG_ARGS, "do_extended: oid \"%s\"\n", reqoid, 0 ,0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
NULL, "unsupported extended operation", NULL );
NULL, "unsupported extended operation", NULL, NULL );
done:
if ( reqoid != NULL ) {

290
servers/slapd/libslapd.dsp Normal file
View file

@ -0,0 +1,290 @@
# Microsoft Developer Studio Project File - Name="libslapd" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=libslapd - Win32 Single Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "libslapd.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "libslapd.mak" CFG="libslapd - Win32 Single Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "libslapd - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "libslapd - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "libslapd - Win32 Single Debug" (based on\
"Win32 (x86) Static Library")
!MESSAGE "libslapd - Win32 Single Release" (based on\
"Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
!IF "$(CFG)" == "libslapd - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "libslapd"
# PROP BASE Intermediate_Dir "libslapd"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release\libslapd"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "libslapd - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "libslap0"
# PROP BASE Intermediate_Dir "libslap0"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug\libslapd"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "libslapd - Win32 Single Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "libslap1"
# PROP BASE Intermediate_Dir "libslap1"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "SDebug"
# PROP Intermediate_Dir "SDebug\libslapd"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /Z7 /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "libslapd - Win32 Single Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "libslap2"
# PROP BASE Intermediate_Dir "libslap2"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "SRelease"
# PROP Intermediate_Dir "SRelease\libslapd"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "libslapd - Win32 Release"
# Name "libslapd - Win32 Debug"
# Name "libslapd - Win32 Single Debug"
# Name "libslapd - Win32 Single Release"
# Begin Source File
SOURCE=.\abandon.c
# End Source File
# Begin Source File
SOURCE=.\acl.c
# End Source File
# Begin Source File
SOURCE=.\aclparse.c
# End Source File
# Begin Source File
SOURCE=.\add.c
# End Source File
# Begin Source File
SOURCE=.\attr.c
# End Source File
# Begin Source File
SOURCE=.\ava.c
# End Source File
# Begin Source File
SOURCE=.\backend.c
# End Source File
# Begin Source File
SOURCE=.\bind.c
# End Source File
# Begin Source File
SOURCE=.\ch_malloc.c
# End Source File
# Begin Source File
SOURCE=.\charray.c
# End Source File
# Begin Source File
SOURCE=.\compare.c
# End Source File
# Begin Source File
SOURCE=.\config.c
# End Source File
# Begin Source File
SOURCE=.\configinfo.c
# End Source File
# Begin Source File
SOURCE=.\connection.c
# End Source File
# Begin Source File
SOURCE=.\controls.c
# End Source File
# Begin Source File
SOURCE=.\daemon.c
# End Source File
# Begin Source File
SOURCE=.\delete.c
# End Source File
# Begin Source File
SOURCE=.\dn.c
# End Source File
# Begin Source File
SOURCE=.\entry.c
# End Source File
# Begin Source File
SOURCE=.\extended.c
# End Source File
# Begin Source File
SOURCE=.\filter.c
# End Source File
# Begin Source File
SOURCE=.\filterentry.c
# End Source File
# Begin Source File
SOURCE=.\init.c
# End Source File
# Begin Source File
SOURCE=.\lock.c
# End Source File
# Begin Source File
SOURCE=.\modify.c
# End Source File
# Begin Source File
SOURCE=.\modrdn.c
# End Source File
# Begin Source File
SOURCE=.\monitor.c
# End Source File
# Begin Source File
SOURCE=.\operation.c
# End Source File
# Begin Source File
SOURCE=.\phonetic.c
# End Source File
# Begin Source File
SOURCE=".\proto-slap.h"
# End Source File
# Begin Source File
SOURCE=.\repl.c
# End Source File
# Begin Source File
SOURCE=.\root_dse.c
# End Source File
# Begin Source File
SOURCE=.\schema.c
# End Source File
# Begin Source File
SOURCE=.\schemaparse.c
# End Source File
# Begin Source File
SOURCE=.\search.c
# End Source File
# Begin Source File
SOURCE=.\slap.h
# End Source File
# Begin Source File
SOURCE=.\str2filter.c
# End Source File
# Begin Source File
SOURCE=.\unbind.c
# End Source File
# Begin Source File
SOURCE=.\user.c
# End Source File
# Begin Source File
SOURCE=.\value.c
# End Source File
# Begin Source File
SOURCE=.\wsa_err.c
# End Source File
# End Target
# End Project

View file

@ -45,8 +45,8 @@ do_modify(
if( op->o_bind_in_progress ) {
Debug( LDAP_DEBUG_ANY, "do_modify: SASL bind in progress.\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS, NULL,
"SASL bind in progress", NULL );
send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS,
NULL, "SASL bind in progress", NULL, NULL );
return LDAP_SASL_BIND_IN_PROGRESS;
}
@ -112,7 +112,7 @@ do_modify(
(*modtail)->ml_op != LDAP_MOD_REPLACE )
{
send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
NULL, "unrecognized modify operation", NULL );
NULL, "unrecognized modify operation", NULL, NULL );
free( ndn );
modlist_free( modlist );
return LDAP_PROTOCOL_ERROR;
@ -122,7 +122,7 @@ do_modify(
&& (*modtail)->ml_op != LDAP_MOD_DELETE )
{
send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
NULL, "unrecognized modify operation", NULL );
NULL, "unrecognized modify operation", NULL, NULL );
free( ndn );
modlist_free( modlist );
return LDAP_PROTOCOL_ERROR;
@ -162,13 +162,10 @@ do_modify(
free( ndn );
modlist_free( modlist );
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
NULL, NULL, default_referral );
NULL, NULL, default_referral, NULL );
return rc;
}
/* alias suffix if approp */
ndn = suffixAlias ( ndn, op, be );
/*
* do the modify if 1 && (2 || 3)
* 1) there is a modify function implemented in this backend;
@ -187,11 +184,11 @@ do_modify(
/* send a referral */
} else {
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
NULL, NULL, default_referral );
NULL, NULL, default_referral, NULL );
}
} else {
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
NULL, "Function not implemented", NULL );
NULL, "Function not implemented", NULL, NULL );
}
free( ndn );

View file

@ -53,8 +53,8 @@ do_modrdn(
if( op->o_bind_in_progress ) {
Debug( LDAP_DEBUG_ANY, "do_modrdn: SASL bind in progress.\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS, NULL,
"SASL bind in progress", NULL );
send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS,
NULL, "SASL bind in progress", NULL, NULL );
return LDAP_SASL_BIND_IN_PROGRESS;
}
@ -162,7 +162,7 @@ do_modrdn(
free( newSuperior );
free( nnewSuperior );
send_ldap_result( conn, op, LDAP_REFERRAL,
NULL, NULL, default_referral );
NULL, NULL, default_referral, NULL );
return 0;
}
}
@ -184,7 +184,7 @@ do_modrdn(
free( newSuperior );
free( nnewSuperior );
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
NULL, NULL, default_referral );
NULL, NULL, default_referral, NULL );
return rc;
}
@ -203,16 +203,12 @@ do_modrdn(
free( nnewSuperior );
send_ldap_result( conn, op, rc = LDAP_AFFECTS_MULTIPLE_DSAS,
NULL, NULL, NULL );
NULL, NULL, NULL, NULL );
return rc;
}
/* alias suffix if approp */
ndn = suffixAlias( ndn, op, be );
/*
* do the add if 1 && (2 || 3)
* 1) there is an add function implemented in this backend;
@ -232,11 +228,11 @@ do_modrdn(
}
} else {
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
NULL, NULL, default_referral );
NULL, NULL, default_referral, NULL );
}
} else {
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
NULL, "Function not implemented", NULL );
NULL, "Function not implemented", NULL, NULL );
}
free( ndn );

View file

@ -242,8 +242,10 @@ monitor_info( Connection *conn, Operation *op )
attr_merge( e, "concurrency", vals );
#endif
send_search_entry( &backends[0], conn, op, e, NULL, 0, 1 );
send_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, 1 );
send_search_entry( &backends[0], conn, op, e,
NULL, 0, 1, NULL );
send_search_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL, NULL, 1 );
entry_free( e );
}

View file

@ -129,6 +129,8 @@ int get_ctrls LDAP_P((
Operation *op,
int senderrors ));
int get_manageDSAit LDAP_P(( Operation *op ));
/*
* config.c
*/
@ -258,10 +260,15 @@ void replog LDAP_P(( Backend *be, int optype, char *dn, void *change, int flag )
* result.c
*/
struct berval **get_entry_referrals LDAP_P((
Backend *be, Connection *conn, Operation *op,
Entry *e ));
void send_ldap_result LDAP_P((
Connection *conn, Operation *op,
int err, char *matched, char *text,
struct berval **refs ));
struct berval **refs,
LDAPControl **ctrls ));
void send_ldap_disconnect LDAP_P((
Connection *conn, Operation *op,
@ -271,16 +278,19 @@ void send_search_result LDAP_P((
Connection *conn, Operation *op,
int err, char *matched, char *text,
struct berval **refs,
LDAPControl **ctrls,
int nentries ));
int send_search_reference LDAP_P((
Backend *be, Connection *conn, Operation *op,
Entry *e, struct berval **refs,
LDAPControl **ctrls,
struct berval ***v2refs ));
int send_search_entry LDAP_P((
Backend *be, Connection *conn, Operation *op,
Entry *e, char **attrs, int attrsonly, int opattrs ));
Entry *e, char **attrs, int attrsonly, int opattrs,
LDAPControl **ctrls ));
int str2result LDAP_P(( char *s,
int *code, char **matched, char **info ));
@ -302,6 +312,10 @@ int mr_add LDAP_P((LDAP_MATCHING_RULE *mr, slap_mr_normalize_func *normalize, sl
void schema_info LDAP_P((Connection *conn, Operation *op, char **attrs, int attrsonly));
int schema_init LDAP_P((void));
int is_entry_objectclass LDAP_P(( Entry *, char* objectclass ));
#define is_entry_alias(e) is_entry_objectclass((e), "ALIAS")
#define is_entry_referral(e) is_entry_objectclass((e), "REFERRAL")
/*
* schemaparse.c
@ -330,11 +344,6 @@ int value_cmp LDAP_P(( struct berval *v1, struct berval *v2, int syntax,
int value_find LDAP_P(( struct berval **vals, struct berval *v, int syntax,
int normalize ));
/*
* suffixAlias.c
*/
char *suffixAlias LDAP_P(( char *dn, Operation *op, Backend *be ));
/*
* user.c
*/

View file

@ -69,29 +69,19 @@ static ber_tag_t req2res( ber_tag_t tag )
return tag;
}
void trim_refs(
struct berval **refs,
int trimurl )
static void trim_refs_urls(
struct berval **refs )
{
int i;
unsigned i;
assert( refs != NULL );
for( i=0; refs[i] != NULL; i++ ) {
unsigned long j;
/* trim URI label */
for( j=0; j<refs[i]->bv_len; j++ ) {
if( isspace(refs[i]->bv_val[j]) ) {
refs[i]->bv_val[j] = '\0';
refs[i]->bv_len = j;
break;
}
}
if( trimurl && refs[i]->bv_len > sizeof("ldap://") &&
if( refs[i]->bv_len > sizeof("ldap://") &&
strncasecmp( refs[i]->bv_val, "ldap://",
sizeof("ldap://")-1 ) == 0 )
{
unsigned j;
for( j=sizeof("ldap://"); j<refs[i]->bv_len ; j++ ) {
if( refs[i]->bv_val[j] = '/' ) {
refs[i]->bv_val[j] = '\0';
@ -103,7 +93,63 @@ void trim_refs(
}
}
long send_ldap_ber(
struct berval **get_entry_referrals(
Backend *be, Connection *conn, Operation *op, Entry *e )
{
Attribute *attr;
struct berval **refs;
unsigned i, j;
if( is_entry_referral( e ) ) {
return NULL;
}
attr = attr_find( e->e_attrs, "ref" );
if( attr == NULL ) return NULL;
for( i=0; attr->a_vals[i] != NULL; i++ ) {
/* count references */
}
if( i < 1 ) return NULL;
refs = ch_malloc( i + 1 );
for( i=0, j=0; attr->a_vals[i] != NULL; i++ ) {
unsigned k;
struct berval *ref = ber_bvdup( attr->a_vals[i] );
/* trim the label */
for( k=0; k<ref->bv_len; k++ ) {
if( isspace(ref->bv_val[k]) ) {
ref->bv_val[k] = '\0';
ref->bv_len = k;
break;
}
}
if( ref->bv_len > 0 ) {
refs[j++] = ref;
} else {
ber_bvfree( ref );
}
}
refs[j] = NULL;
if( j == 0 ) {
ber_bvecfree( refs );
refs = NULL;
}
/* we should check that a referral value exists... */
return refs;
}
static long send_ldap_ber(
Connection *conn,
BerElement *ber )
{
@ -174,13 +220,16 @@ send_ldap_response(
char *text,
struct berval **ref,
char *resoid,
struct berval *resdata
struct berval *resdata,
LDAPControl **ctrls
)
{
BerElement *ber;
int rc;
long bytes;
assert( ctrls == NULL ); /* ctrls not implemented */
ber = ber_alloc_t( LBER_USE_DER );
Debug( LDAP_DEBUG_TRACE, "send_ldap_response: tag=%ld msgid=%ld err=%ld\n",
@ -290,7 +339,7 @@ send_ldap_disconnect(
#endif
send_ldap_response( conn, op, tag, msgid,
err, NULL, text, NULL,
reqoid, NULL );
reqoid, NULL, NULL );
Statslog( LDAP_DEBUG_STATS,
"conn=%ld op=%ld DISCONNECT err=%ld tag=%lu text=%s\n",
@ -305,7 +354,8 @@ send_ldap_result(
ber_int_t err,
char *matched,
char *text,
struct berval **ref
struct berval **ref,
LDAPControl **ctrls
)
{
ber_tag_t tag;
@ -319,10 +369,6 @@ send_ldap_result(
assert( err != LDAP_PARTIAL_RESULTS );
if ( ref != NULL ) {
trim_refs( ref, 0 );
}
if ( err == LDAP_REFERRAL ) {
if( ref == NULL ) {
err = LDAP_NO_SUCH_OBJECT;
@ -349,7 +395,7 @@ send_ldap_result(
send_ldap_response( conn, op, tag, msgid,
err, matched, text, ref,
NULL, NULL );
NULL, NULL, ctrls );
Statslog( LDAP_DEBUG_STATS,
"conn=%ld op=%ld RESULT err=%ld tag=%lu text=%s\n",
@ -370,6 +416,7 @@ send_search_result(
char *matched,
char *text,
struct berval **refs,
LDAPControl **ctrls,
int nentries
)
{
@ -383,9 +430,7 @@ send_search_result(
assert( err != LDAP_PARTIAL_RESULTS );
if ( refs != NULL ) {
trim_refs( refs, 1 );
}
trim_refs_urls( refs );
if( op->o_protocol < LDAP_VERSION3 ) {
/* send references in search results */
@ -419,7 +464,7 @@ send_search_result(
send_ldap_response( conn, op, tag, msgid,
err, matched, text, refs,
NULL, NULL );
NULL, NULL, ctrls );
Statslog( LDAP_DEBUG_STATS,
"conn=%ld op=%ld SEARCH RESULT err=%ld tag=%lu text=%s\n",
@ -437,7 +482,8 @@ send_search_entry(
Entry *e,
char **attrs,
int attrsonly,
int opattrs
int opattrs,
LDAPControl **ctrls
)
{
BerElement *ber;
@ -474,7 +520,7 @@ send_search_entry(
if ( ber == NULL ) {
Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, "allocating BER error", NULL );
NULL, "allocating BER error", NULL, NULL );
goto error_return;
}
@ -485,7 +531,7 @@ send_search_entry(
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, "encoding dn error", NULL );
NULL, "encoding dn error", NULL, NULL );
goto error_return;
}
@ -520,7 +566,7 @@ send_search_entry(
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, "encoding type error", NULL );
NULL, "encoding type error", NULL, NULL );
goto error_return;
}
@ -538,7 +584,7 @@ send_search_entry(
"ber_printf failed\n", 0, 0, 0 );
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, "encoding value error", NULL );
NULL, "encoding value error", NULL, NULL );
goto error_return;
}
}
@ -548,7 +594,7 @@ send_search_entry(
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, "encode end error", NULL );
NULL, "encode end error", NULL, NULL );
goto error_return;
}
}
@ -559,7 +605,7 @@ send_search_entry(
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, "encode entry end error", NULL );
NULL, "encode entry end error", NULL, NULL );
return( 1 );
}
@ -596,6 +642,7 @@ send_search_reference(
Operation *op,
Entry *e,
struct berval **refs,
LDAPControl **ctrls,
struct berval ***v2refs
)
{
@ -644,7 +691,7 @@ send_search_reference(
Debug( LDAP_DEBUG_ANY,
"send_search_reference: ber_alloc failed\n", 0, 0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, "alloc BER error", NULL );
NULL, "alloc BER error", NULL, NULL );
return -1;
}
@ -656,7 +703,7 @@ send_search_reference(
"send_search_reference: ber_printf failed\n", 0, 0, 0 );
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, "encode dn error", NULL );
NULL, "encode dn error", NULL, NULL );
return -1;
}

View file

@ -97,8 +97,10 @@ root_dse_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
attr_merge( e, "ref", default_referral );
}
send_search_entry( &backends[0], conn, op, e, attrs, attrsonly, 1 );
send_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, 1 );
send_search_entry( &backends[0], conn, op,
e, attrs, attrsonly, 1, NULL );
send_search_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL, NULL, 1 );
entry_free( e );
}

View file

@ -1143,8 +1143,10 @@ schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
return;
}
send_search_entry( &backends[0], conn, op, e, attrs, attrsonly, 0 );
send_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, 1 );
send_search_entry( &backends[0], conn, op,
e, attrs, attrsonly, 0, NULL );
send_search_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL, NULL, 1 );
entry_free( e );
}
@ -1179,3 +1181,35 @@ oc_print( ObjectClass *oc )
}
#endif
int is_entry_objectclass(
Entry* e,
char* oc)
{
Attribute *attr;
struct berval bv;
if( e == NULL || oc == NULL || *oc == '\0' )
return 0;
/*
* find objectClass attribute
*/
attr = attr_find(e->e_attrs, "objectclass");
if( attr == NULL ) {
/* no objectClass attribute */
return 0;
}
bv.bv_val = oc;
bv.bv_len = strlen( bv.bv_val );
if( value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
/* entry is not of this objectclass */
return 0;
}
return 1;
}

View file

@ -41,8 +41,8 @@ do_search(
if( op->o_bind_in_progress ) {
Debug( LDAP_DEBUG_ANY, "do_search: SASL bind in progress.\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS, NULL,
"SASL bind in progress", NULL );
send_ldap_result( conn, op, LDAP_SASL_BIND_IN_PROGRESS,
NULL, "SASL bind in progress", NULL, NULL );
return LDAP_SASL_BIND_IN_PROGRESS;
}
@ -80,10 +80,27 @@ do_search(
goto return_results;
}
if ( scope != LDAP_SCOPE_BASE && scope != LDAP_SCOPE_ONELEVEL
&& scope != LDAP_SCOPE_SUBTREE ) {
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
switch( scope ) {
case LDAP_SCOPE_BASE:
case LDAP_SCOPE_ONELEVEL:
case LDAP_SCOPE_SUBTREE:
break;
default:
send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
NULL, "invalid scope", NULL, NULL );
rc = -1;
goto return_results;
}
switch( deref ) {
case LDAP_DEREF_NEVER:
case LDAP_DEREF_FINDING:
case LDAP_DEREF_SEARCHING:
case LDAP_DEREF_ALWAYS:
break;
default:
send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
NULL, "invalid deref", NULL, NULL );
rc = -1;
goto return_results;
}
@ -101,7 +118,7 @@ do_search(
LDAP_PROTOCOL_ERROR, "decode error" );
} else {
send_ldap_result( conn, op, err,
NULL, "Bad search filter", NULL );
NULL, "Bad search filter", NULL, NULL );
}
goto return_results;
}
@ -161,8 +178,14 @@ do_search(
}
#endif /* monitor or config or schema dn */
if ( strcmp( base, LDAP_ROOT_DSE ) == 0 && scope == LDAP_SCOPE_BASE ) {
root_dse_info( conn, op, attrs, attrsonly );
if ( strcmp( base, LDAP_ROOT_DSE ) == 0 ) {
if( scope == LDAP_SCOPE_BASE ) {
root_dse_info( conn, op, attrs, attrsonly );
} else {
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
NULL, NULL, default_referral, NULL );
}
goto return_results;
}
@ -173,21 +196,18 @@ do_search(
*/
if ( (be = select_backend( base )) == NULL ) {
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
NULL, NULL, default_referral );
NULL, NULL, default_referral, NULL );
goto return_results;
}
/* translate the base if it matches an aliased base part */
base = suffixAlias ( base, op, be );
/* actually do the search and send the result(s) */
if ( be->be_search ) {
(*be->be_search)( be, conn, op, base, scope, deref, sizelimit,
timelimit, filter, fstr, attrs, attrsonly );
} else {
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
NULL, "Function not implemented", NULL );
NULL, "Function not implemented", NULL, NULL );
}
return_results:;

View file

@ -193,11 +193,11 @@ typedef struct entry {
struct access {
#define ACL_NONE 0x0001
#define ACL_AUTH 0x0002
#define ACL_COMPARE 0x0004
#define ACL_SEARCH 0x0008
#define ACL_READ 0x0010
#define ACL_WRITE 0x0020
#define ACL_AUTH 0x0004
#define ACL_COMPARE 0x0008
#define ACL_SEARCH 0x0010
#define ACL_READ 0x0020
#define ACL_WRITE 0x0040
#define ACL_PRIV_MASK 0x00ff
#define ACL_SELF 0x4000
@ -394,12 +394,11 @@ struct backend_db {
/* these should be renamed from be_ to bd_ */
char **be_suffix; /* the DN suffixes of data in this backend */
char **be_nsuffix; /* the normalized DN suffixes in this backend */
char **be_suffixAlias; /* the DN suffix aliases of data in this backend */
char *be_root_dn; /* the magic "root" dn for this db */
char *be_root_ndn; /* the magic "root" normalized dn for this db */
char *be_root_pw; /* the magic "root" password for this db */
int be_readonly; /* 1 => db is in "read only" mode */
int be_maxDerefDepth; /* limit for depth of an alias deref */
unsigned int be_max_deref_depth; /* limit for depth of an alias deref */
int be_sizelimit; /* size limit for this backend */
int be_timelimit; /* time limit for this backend */
struct acl *be_acl; /* access control list for this backend */

165
servers/slapd/slapd.dsp Normal file
View file

@ -0,0 +1,165 @@
# Microsoft Developer Studio Project File - Name="slapd" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=slapd - Win32 Single Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "slapd.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "slapd.mak" CFG="slapd - Win32 Single Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "slapd - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "slapd - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "slapd - Win32 Single Debug" (based on\
"Win32 (x86) Console Application")
!MESSAGE "slapd - Win32 Single Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "slapd - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release\slapd"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "slapd - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug\slapd"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 hs_regex.lib libdb.lib ws2_32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "slapd - Win32 Single Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "slapd___"
# PROP BASE Intermediate_Dir "slapd___"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "SDebug"
# PROP Intermediate_Dir "SDebug\slapd"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 hs_regexd.lib libdbs.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "slapd - Win32 Single Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "slapd__0"
# PROP BASE Intermediate_Dir "slapd__0"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "SRelease"
# PROP Intermediate_Dir "SRelease\slapd"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 hs_regex.lib libdb.lib wsock32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 hs_regex.lib libdb.lib ws2_32.lib /nologo /subsystem:console /machine:I386
!ENDIF
# Begin Target
# Name "slapd - Win32 Release"
# Name "slapd - Win32 Debug"
# Name "slapd - Win32 Single Debug"
# Name "slapd - Win32 Single Release"
# Begin Source File
SOURCE=.\daemon.c
# End Source File
# Begin Source File
SOURCE=.\main.c
# End Source File
# Begin Source File
SOURCE=.\nt_svc.c
# End Source File
# Begin Source File
SOURCE=".\proto-slap.h"
# End Source File
# Begin Source File
SOURCE=.\result.c
# End Source File
# Begin Source File
SOURCE=.\slap.h
# End Source File
# End Target
# End Project

View file

@ -0,0 +1,148 @@
# Microsoft Developer Studio Project File - Name="ldbmcat" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=ldbmcat - Win32 Single Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ldbmcat.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ldbmcat.mak" CFG="ldbmcat - Win32 Single Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ldbmcat - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "ldbmcat - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "ldbmcat - Win32 Single Debug" (based on\
"Win32 (x86) Console Application")
!MESSAGE "ldbmcat - Win32 Single Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "ldbmcat - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\Release"
# PROP Intermediate_Dir "..\Release\ldbmcat"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 libdb.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\libraries\Release"
!ELSEIF "$(CFG)" == "ldbmcat - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "ldbmcat_"
# PROP BASE Intermediate_Dir "ldbmcat_"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\Debug"
# PROP Intermediate_Dir "..\Debug\ldbmcat"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 libdb.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\libraries\Debug"
!ELSEIF "$(CFG)" == "ldbmcat - Win32 Single Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "ldbmcat_"
# PROP BASE Intermediate_Dir "ldbmcat_"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\Sdebug"
# PROP Intermediate_Dir "..\SDebug\ldbmcat"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 oldbm32.lib libdb.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\libraries\Debug"
# ADD LINK32 libdb.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\libraries\Debug"
!ELSEIF "$(CFG)" == "ldbmcat - Win32 Single Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "ldbmcat0"
# PROP BASE Intermediate_Dir "ldbmcat0"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\SRelease"
# PROP Intermediate_Dir "..\SRelease\ldbmcat"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libdb.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\libraries\Release"
# ADD LINK32 libdbs.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\libraries\Release"
!ENDIF
# Begin Target
# Name "ldbmcat - Win32 Release"
# Name "ldbmcat - Win32 Debug"
# Name "ldbmcat - Win32 Single Debug"
# Name "ldbmcat - Win32 Single Release"
# Begin Source File
SOURCE=.\ldbmcat.c
# End Source File
# Begin Source File
SOURCE=.\mimic.c
# End Source File
# End Target
# End Project

View file

@ -1,68 +1,66 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <limits.h>
#include "portable.h"
#include "ldapconfig.h"
#include <stdio.h>
#include <limits.h>
#include <ac/stdlib.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/ctype.h>
#include <ac/time.h>
#include <ac/unistd.h>
#include <ac/wait.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include <sys/stat.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_IO_H
#include <io.h>
#endif
#include "ldap_defaults.h"
#include "../slap.h"
#include "../back-ldbm/back-ldbm.h"
#define EDITOR "/usr/ucb/vi"
static struct dbcache *openchoice(char c, int mode, int verbose, char **fname);
static void print_entry(FILE *fp, char c, Datum *key, char *klabel, Datum *data, char *dlabel);
static void free_and_close(struct dbcache *dbc, Datum key, Datum data);
static void edit_entry(char c, Datum *data);
static void get_keydata(FILE *fp, char c, Datum *key, Datum *data);
extern IDList *idl_fetch();
extern Backend *select_backend();
extern struct dbcache *ldbm_cache_open();
static struct dbcache *dbc;
static LDBM dbp;
static Backend *be = NULL;
static struct dbcache *openchoice();
static void print_entry();
static void free_and_close();
static void edit_entry();
static void get_keydata();
struct dbcache *dbc;
LDBM dbp;
char *tailorfile;
Backend *be = NULL;
int ldap_debug;
int ldap_syslog;
int ldap_syslog_level;
int global_schemacheck;
int num_entries_sent;
int num_bytes_sent;
int active_threads;
char *default_referral;
struct objclass *global_oc;
time_t currenttime;
pthread_t listener_tid;
pthread_mutex_t num_sent_mutex;
pthread_mutex_t entry2str_mutex;
pthread_mutex_t active_threads_mutex;
pthread_mutex_t new_conn_mutex;
pthread_mutex_t currenttime_mutex;
pthread_mutex_t replog_mutex;
pthread_mutex_t ops_mutex;
pthread_mutex_t regex_mutex;
main( argc, argv )
int argc;
char **argv;
int
main( int argc, char **argv )
{
char buf[256];
Datum savekey, key, data, last;
char *fname;
ID id;
IDList *idl;
ID_BLOCK *idl;
Backend *tbe;
int i;
extern char *optarg;
char *tailorfile;
#ifdef HAVE_BERKELEY_DB2
DBC *cursorp;
#endif
ldbm_datum_init( savekey );
ldbm_datum_init( key );
ldbm_datum_init( data );
ldbm_datum_init( last );
tailorfile = SLAPD_DEFAULT_CONFIGFILE;
while ( (i = getopt( argc, argv, "d:f:" )) != EOF ) {
@ -88,8 +86,9 @@ main( argc, argv )
* initialize stuff and figure out which backend we're dealing with
*/
init();
read_config( tailorfile, &be, NULL );
slap_init(SLAP_TOOL_MODE, "ldbmtest");
read_config( tailorfile );
slap_startup(-1);
while ( 1 ) {
printf( "dbtest: " );
@ -135,7 +134,7 @@ main( argc, argv )
get_keydata( stdin, buf[1], &key, NULL );
if ( (idl = idl_fetch( be, dbc, key )) != NULL ) {
data.dptr = (char *) idl;
data.dsize = (idl->b_nmax + 1) * sizeof(ID);
data.dsize = (ID_BLOCK_NMAX(idl) + 1) * sizeof(ID);
print_entry( stdout, buf[1], &key, "key: ",
&data, "data:\n" );
}
@ -151,9 +150,16 @@ main( argc, argv )
}
savekey.dptr = NULL;
#ifdef HAVE_BERKELEY_DB2
for ( key = ldbm_firstkey( dbc->dbc_db, &cursorp );
key.dptr != NULL;
key = ldbm_nextkey( dbc->dbc_db, key, cursorp ) )
#else
for ( key = ldbm_firstkey( dbc->dbc_db );
key.dptr != NULL;
key = ldbm_nextkey( dbc->dbc_db, key ) ) {
key = ldbm_nextkey( dbc->dbc_db, key ) )
#endif
{
if ( savekey.dptr != NULL )
ldbm_datum_free( dbc->dbc_db, savekey );
savekey = key;
@ -168,7 +174,9 @@ main( argc, argv )
"key: ", NULL, NULL );
}
ldbm_datum_free( dbc->dbc_db, data );
if ( data.dptr != NULL ) {
ldbm_datum_free( dbc->dbc_db, data );
}
}
if ( savekey.dptr != NULL )
ldbm_datum_free( dbc->dbc_db, savekey );
@ -197,6 +205,7 @@ main( argc, argv )
free_and_close( dbc, key, data );
break;
#ifndef HAVE_WINSOCK
case 'e': /* edit an entry */
if ( (dbc = openchoice( buf[1], LDBM_WRITER, 1, NULL ))
== NULL ) {
@ -235,6 +244,7 @@ main( argc, argv )
free_and_close( dbc, key, data );
break;
#endif
case 'a': /* add an entry */
if ( (dbc = openchoice( buf[1], LDBM_WRITER, 1, NULL ))
@ -265,13 +275,13 @@ main( argc, argv )
get_keydata( stdin, buf[1], &key, &data );
idl = (IDList *) data.dptr;
idl = (ID_BLOCK *) data.dptr;
for ( id = idl_firstid( idl ); id != NOID;
id = idl_nextid( idl, id ) ) {
if ( idl_insert_key( be, dbc, key, id )
!= 0 ) {
fprintf( stderr,
"idl_insert_key (%s) %d failed\n",
"idl_insert_key (%s) %ld failed\n",
key.dptr, id );
continue;
}
@ -288,7 +298,7 @@ main( argc, argv )
} else {
buf[strlen( buf ) - 1] = '\0';
}
(void) dn_normalize( buf );
(void) dn_normalize_case( buf );
if ( (tbe = select_backend( buf )) == NULL ) {
fprintf( stderr, "unknown suffix \"%s\"\n",
buf );
@ -313,8 +323,16 @@ main( argc, argv )
}
last.dptr = NULL;
#ifdef HAVE_BERKELEY_DB2
for ( key = ldbm_firstkey( dbp, &cursorp );
key.dptr != NULL;
key = ldbm_nextkey( dbp, last, cursorp ) )
#else
for ( key = ldbm_firstkey( dbp ); key.dptr != NULL;
key = ldbm_nextkey( dbp, last ) ) {
key = ldbm_nextkey( dbp, last ) )
#endif
{
if ( last.dptr != NULL ) {
ldbm_datum_free( dbp, last );
}
@ -348,14 +366,14 @@ main( argc, argv )
}
}
slap_shutdown(-1);
slap_destroy();
return( 0 );
}
static void
free_and_close( dbc, key, data )
struct dbcache *dbc;
Datum key;
Datum data;
free_and_close( struct dbcache *dbc, Datum key, Datum data )
{
ldbm_cache_really_close( be, dbc );
if ( key.dptr != NULL )
@ -365,17 +383,13 @@ free_and_close( dbc, key, data )
}
static int
dnid_cmp( a, b )
long *a;
long *b;
dnid_cmp( const void *a, const void *b )
{
return( *a - *b );
return( *(const long int *)a - *(const long int *)b );
}
static char *
myrealloc( p, size )
char *p;
int size;
myrealloc( char *p, int size )
{
if ( p == NULL )
return( (char *) malloc( size ) );
@ -384,15 +398,13 @@ myrealloc( p, size )
}
static void
get_idlist( fp, data )
FILE *fp;
Datum *data;
get_idlist( FILE *fp, Datum *data )
{
char buf[20];
int i, j, fd, tty;
IDList *p;
int psize, pmax;
int nmax, nids;
int i, fd, tty;
ID_BLOCK *p;
unsigned int psize, pmax;
unsigned int nmax, nids;
fd = fileno( fp );
tty = isatty( fd );
@ -415,7 +427,7 @@ get_idlist( fp, data )
if ( psize + sizeof(ID) > pmax ) {
pmax += BUFSIZ;
p = (IDList *) myrealloc( (char *) p, pmax );
p = (ID_BLOCK *) myrealloc( (char *) p, pmax );
}
if ( strncmp( buf, "nids=0", 6 ) == 0 ) {
@ -423,7 +435,7 @@ get_idlist( fp, data )
continue;
}
p->b_ids[i++] = atol( buf );
ID_BLOCK_ID(p,i++) = atol( buf );
psize += sizeof(ID);
}
if ( nmax == 0 ) {
@ -432,7 +444,7 @@ get_idlist( fp, data )
printf( "%d IDs entered. Max number of ids? [%d] ", i,
i );
if ( fgets( buf, sizeof(buf), fp ) != NULL &&
isdigit( buf[0] ) ) {
isdigit( (unsigned char) buf[0] ) ) {
nmax = atol( buf );
}
} else {
@ -440,29 +452,27 @@ get_idlist( fp, data )
}
}
if ( i > 0 ) {
p->b_nmax = nmax;
ID_BLOCK_NMAX(p) = nmax;
if ( nids != 0 ) {
p->b_nids = 0;
p->b_ids[i] = NOID;
ID_BLOCK_NIDS(p) = 0;
ID_BLOCK_ID(p,i) = NOID;
} else {
p->b_nids = i;
ID_BLOCK_NIDS(p) = i;
}
qsort( (void *) p->b_ids, i, sizeof(ID), (void *) dnid_cmp );
qsort( (void *) &ID_BLOCK_ID(p, 0), i, sizeof(ID), dnid_cmp );
}
data->dptr = (char *) p;
data->dsize = (nmax + 2) * sizeof(ID);
data->dsize = (nmax + ID_BLOCK_IDS_OFFSET) * sizeof(ID);
}
static void
get_entry( fp, data )
FILE *fp;
Datum *data;
get_entry( FILE *fp, Datum *data )
{
char buf[BUFSIZ];
char *p;
int pmax, psize, len;
unsigned int pmax, psize, len;
int fd;
fd = fileno( fp );
@ -491,18 +501,19 @@ get_entry( fp, data )
data->dsize = psize + 1;
}
#ifndef HAVE_WINSOCK
static void
edit_entry( c, data )
char c;
Datum *data;
edit_entry( char c, Datum *data )
{
int fd, pid;
char tmpname[20];
FILE *fp;
#ifndef HAVE_WAITPID
WAITSTATUSTYPE status;
#endif
strcpy( tmpname, "/tmp/dbtestXXXXXX" );
#ifdef ultrix
#ifndef HAVE_MKSTEMP
if ( (fd = open( mktemp( tmpname ), O_RDWR, 0600 )) == -1 ) {
perror( tmpname );
return;
@ -527,7 +538,7 @@ edit_entry( c, data )
char *editor;
if ( (editor = getenv( "EDITOR" )) == NULL ) {
editor = EDITOR;
editor = LDAP_EDITOR;
}
execl( editor, editor, tmpname, NULL );
perror( "execl" );
@ -536,11 +547,12 @@ edit_entry( c, data )
fclose( fp );
#ifdef USE_WAITPID
if ( waitpid( (pid_t) -1, 0, WAIT_FLAGS ) < 0 ) {
#ifdef HAVE_WAITPID
if ( waitpid( (pid_t) -1, NULL, WAIT_FLAGS ) < 0 )
#else
if ( wait3( &status, WAIT_FLAGS, 0 ) < 0 ) {
if ( wait3( (pid_t) -1, &status, WAIT_FLAGS, 0 ) < 0 )
#endif
{
perror( "wait" );
return;
}
@ -549,19 +561,17 @@ edit_entry( c, data )
perror( tmpname );
return;
}
ldbm_datum_free( NULL, *data );
if ( data->dptr != NULL ) {
ldbm_datum_free( NULL, *data );
}
get_keydata( fp, c, NULL, data );
fclose( fp );
unlink( tmpname );
}
#endif
static struct dbcache *
openfile( name, namesiz, mode, verbose, c )
char *name;
int namesiz;
int mode;
int verbose;
char c;
openfile( char *name, int namesiz, int mode, int verbose, char c )
{
struct dbcache *dbc;
@ -590,11 +600,7 @@ openfile( name, namesiz, mode, verbose, c )
}
static struct dbcache *
openchoice( c, mode, verbose, fname )
char c;
int mode;
int verbose;
char **fname;
openchoice( char c, int mode, int verbose, char **fname )
{
static char name[MAXPATHLEN];
@ -629,17 +635,18 @@ openchoice( c, mode, verbose, fname )
}
static void
print_entry( fp, c, key, klabel, data, dlabel )
FILE *fp;
char c;
Datum *key;
char *klabel;
Datum *data;
char *dlabel;
print_entry(
FILE *fp,
char c,
Datum *key,
char *klabel,
Datum *data,
char *dlabel
)
{
ID id;
IDList *idl;
int i;
ID_BLOCK *idl;
unsigned int i;
char msg[2];
if ( data != NULL && data->dptr == NULL ) {
@ -661,14 +668,14 @@ print_entry( fp, c, key, klabel, data, dlabel )
key->dsize );
if ( data != NULL ) {
SAFEMEMCPY( (char *) &id, data->dptr, sizeof(ID) );
fprintf( fp, "%s%d\n", dlabel ? dlabel : "", id );
fprintf( fp, "%s%ld\n", dlabel ? dlabel : "", id );
}
break;
case 'e': /* id2entry - key is dnid, data is entry */
if ( key != NULL ) {
SAFEMEMCPY( (char *) &id, key->dptr, sizeof(ID) );
fprintf( fp, "%s %d\n", klabel, id );
fprintf( fp, "%s %ld\n", klabel, id );
}
if ( data != NULL ) {
if ( dlabel ) {
@ -685,22 +692,22 @@ print_entry( fp, c, key, klabel, data, dlabel )
fprintf( fp, "%s%s (len %d)\n", klabel, key->dptr,
key->dsize );
if ( data != NULL ) {
idl = (IDList *) data->dptr;
idl = (ID_BLOCK *) data->dptr;
if ( dlabel )
fprintf( fp, "%s\tnmax=%d\n\tncur=%d\n", dlabel,
idl->b_nmax, idl->b_nids );
fprintf( fp, "%s\tnmax=%ld\n\tncur=%ld\n", dlabel,
ID_BLOCK_NMAX(idl), ID_BLOCK_NIDS(idl) );
if ( INDIRECT_BLOCK( idl ) ) {
for ( i = 0; idl->b_ids[i] != NOID; i++ ) {
fprintf( fp, "\t%d\n", idl->b_ids[i] );
if ( ID_BLOCK_INDIRECT( idl ) ) {
for ( i = 0; !ID_BLOCK_NOID(idl, i); i++ ) {
fprintf( fp, "\t%ld\n", ID_BLOCK_ID(idl, i) );
}
} else if ( ALLIDS( idl ) ) {
fprintf( fp, "\tALLIDS (1..%d)\n",
idl->b_nids - 1 );
} else if ( ID_BLOCK_ALLIDS( idl ) ) {
fprintf( fp, "\tALLIDS (1..%ld)\n",
ID_BLOCK_NIDS(idl) - 1 );
} else {
for ( i = 0; i < idl->b_nids; i++ ) {
fprintf( fp, "\t%d\n", idl->b_ids[i] );
for ( i = 0; i < ID_BLOCK_NIDS(idl); i++ ) {
fprintf( fp, "\t%ld\n", ID_BLOCK_ID(idl,i) );
}
}
}
@ -722,11 +729,7 @@ print_entry( fp, c, key, klabel, data, dlabel )
}
static void
get_keydata( fp, c, key, data )
FILE *fp;
char c;
Datum *key;
Datum *data;
get_keydata( FILE *fp, char c, Datum *key, Datum *data )
{
static char kbuf[BUFSIZ], dbuf[BUFSIZ];
long n;

View file

@ -0,0 +1,148 @@
# Microsoft Developer Studio Project File - Name="ldbmtest" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 5.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=ldbmtest - Win32 Single Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "ldbmtest.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "ldbmtest.mak" CFG="ldbmtest - Win32 Single Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "ldbmtest - Win32 Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE "ldbmtest - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE "ldbmtest - Win32 Single Debug" (based on\
"Win32 (x86) Console Application")
!MESSAGE "ldbmtest - Win32 Single Release" (based on\
"Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "ldbmtest - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\Release"
# PROP Intermediate_Dir "..\Release\ldbmtest"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 libdb.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "ldbmtest - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\Debug"
# PROP Intermediate_Dir "..\Debug\ldbmtest"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 libdb.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "ldbmtest - Win32 Single Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "ldbmtest"
# PROP BASE Intermediate_Dir "ldbmtest"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "..\SDebug"
# PROP Intermediate_Dir "..\SDebug\ldbmtest"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 libdbs.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "ldbmtest - Win32 Single Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "ldbmtes0"
# PROP BASE Intermediate_Dir "ldbmtes0"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "..\SRelease"
# PROP Intermediate_Dir "..\SRelease\ldbmtest"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\include" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 libdbs.lib hs_regex.lib ws2_32.lib /nologo /subsystem:console /machine:I386
!ENDIF
# Begin Target
# Name "ldbmtest - Win32 Release"
# Name "ldbmtest - Win32 Debug"
# Name "ldbmtest - Win32 Single Debug"
# Name "ldbmtest - Win32 Single Release"
# Begin Source File
SOURCE=.\ldbmtest.c
# End Source File
# Begin Source File
SOURCE=.\mimic.c
# End Source File
# End Target
# End Project

View file

@ -23,6 +23,17 @@ int str2result(
return 0;
}
void
send_ldap_disconnect(
Connection *conn,
Operation *op,
ber_int_t err,
char *text
)
{
assert(0);
}
void
send_ldap_result(
Connection *conn,
@ -30,7 +41,8 @@ send_ldap_result(
int err,
char *matched,
char *text,
struct berval **refs
struct berval **refs,
LDAPControl **ctrls
)
{
assert(0);
@ -44,6 +56,7 @@ send_search_result(
char *matched,
char *text,
struct berval **refs,
LDAPControl **ctrls,
int nentries
)
{
@ -58,7 +71,8 @@ send_search_entry(
Entry *e,
char **attrs,
int attrsonly,
int opattrs
int opattrs,
LDAPControl **ctrls
)
{
assert(0);
@ -71,9 +85,17 @@ int send_search_reference(
Operation *op,
Entry *e,
struct berval **refs,
LDAPControl **ctrls,
struct berval ***v2refs
)
{
assert(0);
return -1;
}
struct berval **get_entry_referrals(
Backend *be, Connection *conn, Operation *op, Entry *e )
{
assert(0);
return NULL;
}

View file

@ -1,12 +1,16 @@
/* value.c - routines for dealing with values */
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include "portable.h"
#include <stdio.h>
#include <ac/ctype.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/time.h>
#include <sys/stat.h>
#include "slap.h"
int
@ -85,7 +89,7 @@ value_normalize(
}
if ( syntax & SYNTAX_DN ) {
(void) dn_normalize_case( s );
(void) dn_normalize( s );
return;
}
@ -94,13 +98,11 @@ value_normalize(
if ( (syntax & SYNTAX_TEL) && (*s == ' ' || *s == '-') ) {
continue;
}
*d++ = TOUPPER( *s );
*d++ = TOUPPER( (unsigned char) *s );
}
*d = '\0';
}
#define MIN( a, b ) (a < b ? a : b )
int
value_cmp(
struct berval *v1,
@ -110,7 +112,6 @@ value_cmp(
)
{
int rc;
struct stat st1, st2;
if ( normalize & 1 ) {
v1 = ber_bvdup( v1 );
@ -133,8 +134,9 @@ value_cmp(
break;
case SYNTAX_BIN:
rc = memcmp( v1->bv_val, v2->bv_val, MIN( v1->bv_len,
v2->bv_len ) );
rc = (v1->bv_len == v2->bv_len
? memcmp( v1->bv_val, v2->bv_val, v1->bv_len )
: v1->bv_len > v2->bv_len ? 1 : -1);
break;
}
@ -148,50 +150,6 @@ value_cmp(
return( rc );
}
int
value_ncmp(
struct berval *v1,
struct berval *v2,
int syntax,
int len,
int normalize
)
{
int rc;
if ( normalize & 1 ) {
v1 = ber_bvdup( v1 );
value_normalize( v1->bv_val, syntax );
}
if ( normalize & 2 ) {
v2 = ber_bvdup( v2 );
value_normalize( v2->bv_val, syntax );
}
switch ( syntax ) {
case SYNTAX_CIS:
case (SYNTAX_CIS | SYNTAX_TEL):
rc = strncasecmp( v1->bv_val, v2->bv_val, len );
break;
case SYNTAX_CES:
rc = strncmp( v1->bv_val, v2->bv_val, len );
break;
case SYNTAX_BIN:
rc = memcmp( v1->bv_val, v2->bv_val, len );
}
if ( normalize & 1 ) {
ber_bvfree( v1 );
}
if ( normalize & 2 ) {
ber_bvfree( v2 );
}
return( rc );
}
int
value_find(
struct berval **vals,