]> git.sur5r.net Git - openldap/commitdiff
Round two of referrals/aliases: WORK IN PROGRESS, may not compile!
authorKurt Zeilenga <kurt@openldap.org>
Mon, 12 Jul 1999 19:02:42 +0000 (19:02 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Mon, 12 Jul 1999 19:02:42 +0000 (19:02 +0000)
Basic support for "named referrals", manageDSAit control.
Disabled alias support for now.  Will implemented "named aliases"
to replace current alias/suffix-alias support.

41 files changed:
build/main.dsw [new file with mode: 0644]
libraries/libldbm/libldbm.dsp [new file with mode: 0644]
servers/slapd/acl.c
servers/slapd/aclparse.c
servers/slapd/add.c
servers/slapd/back-bdb2/search.c
servers/slapd/back-ldbm/add.c
servers/slapd/back-ldbm/alias.c
servers/slapd/back-ldbm/bind.c
servers/slapd/back-ldbm/compare.c
servers/slapd/back-ldbm/delete.c
servers/slapd/back-ldbm/dn2id.c
servers/slapd/back-ldbm/group.c [new file with mode: 0644]
servers/slapd/back-ldbm/modify.c
servers/slapd/back-ldbm/modrdn.c
servers/slapd/back-ldbm/proto-back-ldbm.h
servers/slapd/back-ldbm/search.c
servers/slapd/backend.c
servers/slapd/bind.c
servers/slapd/compare.c
servers/slapd/config.c
servers/slapd/configinfo.c
servers/slapd/controls.c
servers/slapd/delete.c
servers/slapd/extended.c
servers/slapd/libslapd.dsp [new file with mode: 0644]
servers/slapd/modify.c
servers/slapd/modrdn.c
servers/slapd/monitor.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/root_dse.c
servers/slapd/schema.c
servers/slapd/search.c
servers/slapd/slap.h
servers/slapd/slapd.dsp [new file with mode: 0644]
servers/slapd/tools/ldbmcat.dsp [new file with mode: 0644]
servers/slapd/tools/ldbmtest.c
servers/slapd/tools/ldbmtest.dsp [new file with mode: 0644]
servers/slapd/tools/mimic.c
servers/slapd/value.c

diff --git a/build/main.dsw b/build/main.dsw
new file mode 100644 (file)
index 0000000..e728552
--- /dev/null
@@ -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>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/libraries/libldbm/libldbm.dsp b/libraries/libldbm/libldbm.dsp
new file mode 100644 (file)
index 0000000..60e8320
--- /dev/null
@@ -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
index 6c3b22ee857b04b4f34b74b385891a2a84a66fc9..1520bca475ed4dfe000e4bec01f404a6427ab3cd 100644 (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 "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();
+#include <ac/regex.h>
+#include <ac/socket.h>
+#include <ac/string.h>
 
-int            acl_access_allowed();
-int            access_allowed();
-struct acl     *acl_get_applicable();
+#include "slap.h"
 
-static int     regex_matches();
+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);
 
-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 );
                }
+
+               matches[0].rm_so = matches[0].rm_eo = -1;
        }
-       Debug( LDAP_DEBUG_ACL, "<= acl_get: no match\n", 0, 0, 0 );
 
+       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 );
+                       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 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: 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 );
                                }
-                               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;
-
-       if ( (e = compile( pat, NULL, NULL )) == NULL ) {
-               Debug( LDAP_DEBUG_ANY,
-                   "compile( \"%s\", \"%s\") failed\n", pat, str, 0 );
-               return( 0 );
+       int     size;
+       char   *sp;
+       char   *dp;
+       int     flag;
+
+       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 */
index 10fa6a07210cd7681b2599953df1ceabeee7d107..3c69482fce31c16db8b448f813eea942b9d04d2f 100644 (file)
@@ -1,31 +1,82 @@
 /* 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>
-#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 <ac/ctype.h>
+#include <ac/regex.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
 
-static void            split();
-static void            acl_append();
-static void            access_append();
-static void            acl_usage();
+#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();
+                               regtest(fname, lineno, right);
+                               b->a_dnpat = dn_upcase( ch_strdup( right ) );
+                       } else if ( strcasecmp( left, "dnattr" ) == 0 ) {
+                               b->a_dnattr = ch_strdup( right );
+
+                       } 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_dnpat = dn_upcase( strdup( right ) );
-                       } else if ( strcasecmp( left, "dnattr" )
-                           == 0 ) {
-                               b->a_dnattr = strdup( right );
-                       } else if ( strcasecmp( left, "domain" )
-                           == 0 ) {
-                               char    *s;
 
-                               if ( (e = re_comp( right )) != NULL ) {
-                                       fprintf( stderr,
-                       "%s: line %d: regular expression \"%s\" bad: %s\n",
-                                           fname, lineno, right, e );
-                                       acl_usage();
+                               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");
+                                       }
                                }
-                               b->a_domainpat = strdup( right );
+
+                       } 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 */
index 962374c32a0061a06def30825ede34f0f105eab9..2c7905a046ae721d1cc90dc09322c3804389a5bd 100644 (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;
index 49335a61ad1fbff6ca5f51c284293e7803ff81e5..77197e849e5536b5d1daf720a0f42b31bbb477f9 100644 (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;
                }
index b28fc55a48470365e9b807263900b21c0c75110c..941ca191439b11eb3f9d5bcf14de1dbcdffb4eb0 100644 (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,25 +104,59 @@ ldbm_back_add(
 
                free(pdn);
 
-               if ( matched != NULL ) {
-                       free( matched );
-               }
-
                if ( ! access_allowed( be, conn, op, p,
                        "children", NULL, ACL_WRITE ) )
                {
+                       /* 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, 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 ); 
+                       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;
+               }
+
        } else {
                if(pdn != NULL) {
                        assert( *pdn == '\0' );
@@ -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:;
index 9717dc336f68397c284aa27079268bcb1cb84fa4..e93f6b5256b186ea122977727958f7bd7489efec 100644 (file)
 #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;
-
-  if (!e) return NULL;  /* be sure we have a starting entry */
-
-  Debug( LDAP_DEBUG_TRACE, "<= checking for alias for dn %s\n", e->e_dn, 0, 0 );
-
-  /*
-   * 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) 
-  {
-
-    /* 
-     * 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;
-
-      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);
-
-      /* 
-       * release past lock if not original
-       */
-      if ( (depth > 0) && e ) {
-          cache_return_entry_r(&li->li_cache, e);      
-      }
-
-      /* make sure new and old DN are not same to avoid loops */
-      dn_normalize_case (newDN);
-      if ( strcmp (newDN, oldDN) == 0 ) {
+       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;
+
+       /*
+        * 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;
+
+       /* be sure we have a starting entry */
+       if( origEntry != NULL ) {
+               return NULL;
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "<= checking for alias for dn %s\n",
+               origEntry->e_dn, 0, 0 );
+
+       /*
+        * 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;
+
+               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;
+               }
+
+               /*
+                * aliased object names must be contained in an entry
+                * object class "alias".
+                */
+               a = attr_find(e->e_attrs, "objectclass");
+
+               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;
-      }
-
-      /* 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;
-      }
-
-      /*
-       * 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 ) {
-
-       /* 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 );
-
-       if (matched != NULL) free(matched);
-       free (newDN);
-       free (oldDN);
-       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;
-    }
-  }
-
-  /*
-   * 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 );
-  }
-
-  return e;
+               if (value_find(a->a_vals, &bv, a->a_syntax, 1) == 0) {
+                       /* is a referral */
+                       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;
+               }
+
+               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;
+               }
+
+               a = attr_find( e->e_attrs, "aliasedobjectname" );
+
+               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;
+               }
+
+               /* 
+                * 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;
+               }
+
+               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;
+               }
+
+               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; 
-
-  Debug( LDAP_DEBUG_TRACE, 
-        "<= dereferencing dn: \"%s\"\n", 
-        dn, 0, 0 );
-  
-  newDN = ch_strdup ( dn );
-
-  /* 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, "<= matched %s\n", matched, 0, 0 );
+       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
+       unsigned        depth;
+       char*   remainder = NULL;
+       char*   newDN;
+
+       char    **dns;
        
-       remainder = ch_malloc (rlen + 1);
-       strncpy ( remainder, newDN, rlen );
-       remainder[rlen] = '\0';
+       if (!dn) return NULL; 
+
+       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, "<= remainder %s\n", remainder, 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;
+               }
        
-       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 );
-
-         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);
+
+       charray_free( dns );
+
+       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 );
-  }
-
-  if (newDN == NULL) {
-    newDN = ch_strdup ( dn );
-  }
-  
-  Debug( LDAP_DEBUG_TRACE, "<= returning deref DN of \"%s\"\n", newDN, 0, 0 ); 
-
-  return newDN;
+
+       Debug( LDAP_DEBUG_TRACE, "<= %s\n", newDN, 0, 0 );
+
+       return newDN;
 }
+#endif
\ No newline at end of file
index 6ed9272383ef7002d8a94eb09678217e6fe1aef3..34f10812a49f44c8ca5e88e2b0f5bfa2624890f8 100644 (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;
        }
index 160d5fab91f412e0c4799d8889528150407e8d7a..acc5571e5addbdac4cc7d7ae9e0c5bf0c40406c4 100644 (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;
 
index 2324f16b0087cbde0b8f2289aef2e3b9ee79d2fe..53bdd22f7ce89163521825ce43b44903e1bece9a 100644 (file)
@@ -20,34 +20,42 @@ 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;
                }
-               return( -1 );
-       }
 
-       /* check for deleted */
+               send_ldap_result( conn, op, LDAP_REFERRAL,
+                       matched_dn, NULL, refs, NULL );
 
-       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;
+               if ( matched != NULL ) {
+                       ber_bvecfree( refs );
+                       free( matched_dn );
+               }
+
+               return( -1 );
        }
 
 #ifdef SLAPD_CHILD_MODIFICATION_WITH_ENTRY_ACL
@@ -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:;
index c4116086b00d5aab3d143a14f045956a3737c51d..71b97641bbf5ff3754b2abf20e07ee5f8d748993 100644 (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;
 }
+
diff --git a/servers/slapd/back-ldbm/group.c b/servers/slapd/back-ldbm/group.c
new file mode 100644 (file)
index 0000000..aee659e
--- /dev/null
@@ -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);
+}
+
index 941203a1007d2a9625d7f275ba6b212e1c4b416e..d9e9b8ed4c9b2e7935f8d47d037c9e886690ab0a 100644 (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 ) {
+                       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 ) {
-                       free( matched );
+                       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 );
 
index e724b9c18b8f20cc9f34a3ea3727cdc4f0138f56..4f743c473c16a9352ff905dec096e9d108c0e36c 100644 (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 );
+               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 ) {
-                       free( matched );
+                       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;      
 
index acc69ca33c83c30abd2c4371e85d1d19597539c9..19da03905516b9e8be7721e74bcbd8dc408f0bd2 100644 (file)
 #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
index 6fa1d9b7dc0ff30ab2ac84c956b3016259fd819d..0fdbe926b9d9ada8fe03f1c07472ddafb88abf64 100644 (file)
 #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_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;
+       }
 
-       Debug(LDAP_DEBUG_ARGS, "=> ldbm_back_search\n", 0, 0, 0);
+       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,
+    Entry      *e,
     Filter     *filter,
-    char       **attrs,
-    int                attrsonly,
-    char       **matched,
-    int                *err
+    int                scope,
+       int             deref,
+       int             manageDSAit
 )
 {
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       Entry           *e = NULL;
-       Filter          *f;
-       char            buf[20];
        ID_BLOCK                *candidates;
+       Filter          *f, *rf, *af, *lf;
 
-       Debug(LDAP_DEBUG_TRACE, "onelevel_candidates: base: \"%s\"\n", base, 0, 0);
+       Debug(LDAP_DEBUG_TRACE, "search_candidates: base: \"%s\" %s\n",
+               e->e_dn, 0, 0 );
 
-       *err = LDAP_SUCCESS;
+       f = NULL;
 
-       /* 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 );
+       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;
        }
 
-       /*
-        * 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 );
+       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;
        }
-       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
-)
-{
-       struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-       Filter          *f, **filterarg_ptr;
-       ID_BLOCK                *candidates;
+       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;
 
-       Debug(LDAP_DEBUG_TRACE, "subtree_candidates: base: \"%s\" %s\n",
-               base ? base : "NULL", lookupbase ? "lookupbase" : "", 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 ( 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 );
 
-               if ( base != NULL && *base != '\0' &&
-                       (e = dn2entry_r( be, base, matched )) == NULL )
-               {
-                       *err = LDAP_NO_SUCH_OBJECT;
-                       return( NULL );
-               }
+       } 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 );
+       }
 
-               if (e) {
-                       cache_return_entry_r( &li->li_cache, e );
-               }
+       candidates = filter_candidates( be, lf );
 
-               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;
-               }
-       }
+       /* free up filter additions we allocated above */
+       lf->f_and->f_next = NULL;
+       filter_free( lf );
 
-       candidates = filter_candidates( be, filter );
+       if( af != NULL ) {
+               af->f_or->f_next = NULL;
+               filter_free( af );
+       }
 
-       /* free up just the parts we allocated above */
-       if ( f != NULL ) {
-               *filterarg_ptr = NULL;
-               filter_free( f );
+       if( rf != NULL ) {
+               rf->f_or->f_next = NULL;
+               filter_free( rf );
        }
 
        return( candidates );
index 998bfa8c6acc215d0e6a1240cb494210580d55a1..3b5b51fe77898d4efd32be601ed969918dfba6cf 100644 (file)
 /* 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();
-#endif
-
-#ifdef LDAP_PASSWD
-extern int     passwd_back_search();
-extern int     passwd_back_config();
-#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();
-#endif
-
-extern int     defsize;
-extern int     deftime;
-
-#define BACKEND_GRAB_SIZE      10
-
-int            nbackends;
-Backend                *backends;
-static int     maxbackends;
+#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
 
-Backend *
-new_backend(
+static BackendInfo binfo[] = {
+#if defined(SLAPD_LDAP) && !defined(SLAPD_LDAP_DYNAMIC)
+       {"ldap",        ldap_back_initialize},
+#endif
+#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}
+};
+
+int                    nBackendInfo = 0;
+BackendInfo    *backendInfo = NULL;
+
+int                    nBackendDB = 0; 
+BackendDB      *backendDB = NULL;
+
+int backend_init(void)
+{
+       int rc = -1;
+
+       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
-
-#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 ( foundit == 0 ) {
-               fprintf( stderr, "Unrecognized database type (%s)\n", type );
-               exit( 1 );
+
+       be->be_realm = global_realm != NULL
+               ? ch_strdup( global_realm ) : NULL;
+
+       if(bi->bi_db_init) {
+               rc = bi->bi_db_init( be );
+       }
+
+       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,50 +472,126 @@ 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 )
+{
+       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;
+       }
+}
+
+int
+backend_unbind(
+       Connection   *conn,
+       Operation    *op
+)
 {
        int     i;
 
        for ( i = 0; i < nbackends; i++ ) {
-               if ( backends[i].be_close != NULL ) {
-                       (*backends[i].be_close)( &backends[i] );
+               if ( backends[i].be_unbind ) {
+                       (*backends[i].be_unbind)( &backends[i], conn, op );
                }
        }
+
+       return 0;
 }
 
+int
+backend_connection_init(
+       Connection   *conn
+)
+{
+       int     i;
 
-void
-be_unbind(
-       Connection   *conn,
-       Operation    *op
+       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_unbind != NULL ) {
-                       (*backends[i].be_unbind)( &backends[i], conn, op );
+               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);
 }
index df2a1845deb7cedf7ad8bae1d0010927bb319b64..c8daed7bfe2bab60394ff27c11edfd81d114a4d0 100644 (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:
index 6430dcf1348e694c69d4a45ddceded57df48d69c..29a7c8096231a3af61bd4ae902584c6591309169 100644 (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 );
index 0b169a5c1dc4cbf737a706588d743bb2f59c5edd..6554f3cf563969d6f1d7543563004b5157e583ce 100644 (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 */
index a8051991bb8137afa52817b8e30e5c89286ead75..4d85b2b62764c17f89be0c2741433165f2ed821d 100644 (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 );
 }
index 9580ea0fd4e01519069223a3045f6b79c3bde9de..37361cb47cde7e2493b63fdea4aec6e0afb12cda 100644 (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;
+}
\ No newline at end of file
index 53d3f5007795279ff965c5f1dc3ed0cc93188b48..5f13cd90f5293ee85ca67a43757a7bad4684e677 100644 (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 );
index 7082448fca9737e5be58313a469a7d16ad1b2b0e..4b38c60c36582de2373dd0e35d7ffc76836eab24 100644 (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 ) {
diff --git a/servers/slapd/libslapd.dsp b/servers/slapd/libslapd.dsp
new file mode 100644 (file)
index 0000000..9c6ddef
--- /dev/null
@@ -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
index cfc62e8d697aa1034f3427c606a2aba6a45f8f32..0d475655b86c7253bdbda00be7f7874082647f7f 100644 (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 );
index 439fb41452c82f827a5c2274b5a180065c47b41b..a09cbb413789b1fa37a999cd260588db5b38b1a3 100644 (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 );
index 251f8b5ec3d0df99cd7ae2b87c3902e220dc2041..855a2e8dc047852be6fd9064b114e79851f7c99a 100644 (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 );
 }
index 6e29f71056c9486a8039e1d8773ca8d48c4c31ab..847f9475151f39af9cb8247e561ef19ec15c2fa0 100644 (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
  */
index 00cbca44d36dd7bd9423537e1fe5ea6439d8379b..32899631df9089852f09450d3686473400c34823 100644 (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;
        }
 
index edb655c24dbe6be0b29d475c2ac3e7184c83ccdf..25d5f7ddbfdd9ba9bf1353bc52d7f2960ddfa29e 100644 (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 );
 }
index fc2ce4188c59dbe851a62c77562bb3cd8af49e19..e2e2294d56093413c6d85a73b8ca5a6f34f5737d 100644 (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;
+}
\ No newline at end of file
index dbdff19a1d08892acdde2b6e18634c775a580e66..09d1591666bd498c53febdc9a3f00265903507de 100644 (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:;
index 41438d271df089b16798ad2b7da7bd51c21a6721..ea4b6ff4a66223b5e3a5579ca6dde92f21e2c18a 100644 (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    */
diff --git a/servers/slapd/slapd.dsp b/servers/slapd/slapd.dsp
new file mode 100644 (file)
index 0000000..ebe7203
--- /dev/null
@@ -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
diff --git a/servers/slapd/tools/ldbmcat.dsp b/servers/slapd/tools/ldbmcat.dsp
new file mode 100644 (file)
index 0000000..e74b773
--- /dev/null
@@ -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
index 56513ab5b84a11a7922ac31b82601349b0e88456..afe0588fca31997e07ac074b5d35b5cf1d6c74d6 100644 (file)
@@ -1,68 +1,66 @@
+#include "portable.h"
+
 #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 <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>
-#include <sys/wait.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
+#endif
 #include <sys/stat.h>
-#include <limits.h>
-#include "portable.h"
-#include "ldapconfig.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"
-
-extern IDList          *idl_fetch();
-extern Backend         *select_backend();
-extern struct dbcache  *ldbm_cache_open();
-
-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;
+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);
+
+static struct dbcache *dbc;
+static LDBM           dbp;
+static Backend         *be = NULL;
+
+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;
diff --git a/servers/slapd/tools/ldbmtest.dsp b/servers/slapd/tools/ldbmtest.dsp
new file mode 100644 (file)
index 0000000..6bd91f1
--- /dev/null
@@ -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
index b5e80c58030e47e694516a0a7bfa73995296cda3..251f0dcb5441d72256b2f54b87ad534a18da9f52 100644 (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;
+}
index c9e6fbb5774a1560f88990c63cab8a1e528fed5b..7ef0c62cd5be93fdb4b422695d3009593a21990e 100644 (file)
@@ -1,12 +1,16 @@
 /* value.c - routines for dealing with values */
 
+#include "portable.h"
+
 #include <stdio.h>
-#include <string.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
+
+#include <ac/ctype.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/time.h>
+
 #include <sys/stat.h>
-#include "portable.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,