Basic support for "named referrals", manageDSAit control.
Disabled alias support for now. Will implemented "named aliases"
to replace current alias/suffix-alias support.
--- /dev/null
+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>
+{{{
+}}}
+
+###############################################################################
+
--- /dev/null
+# 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
/* 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
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 );
}
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 );
}
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
*/
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 );
}
}
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( ®ex_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( ®ex_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( ®ex_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 */
/* 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,
)
{
int i;
- char *e, *left, *right;
+ char *left, *right;
struct acl *a;
struct access *b;
}
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;
}
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();
}
} 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();
}
* 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,
/* 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",
/* 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 );
/* 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 );
}
{
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" );
}
{
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 );
}
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
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 */
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;
}
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;
if ( be == NULL ) {
entry_free( e );
send_ldap_result( conn, op, LDAP_REFERRAL, NULL,
- NULL, default_referral );
+ NULL, default_referral, NULL );
return rc;
}
} 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;
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;
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;
}
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);
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 );
}
entry_free( e );
send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
- NULL, NULL, NULL );
+ NULL, NULL, NULL, NULL );
return( -1 );
}
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 );
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' );
0, 0 );
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
- NULL, NULL, NULL );
+ NULL, NULL, NULL, NULL );
entry_free( e );
return -1;
/* 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 );
}
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;
}
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;
}
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;
}
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:;
#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
Entry *e;
Attribute *a;
int rc;
- char *matched;
+ Entry *matched;
#ifdef HAVE_KERBEROS
char krbname[MAX_K_NAME_SZ + 1];
AUTH_DAT ad;
/* 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 );
}
"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;
}
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;
"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;
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;
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;
}
"krbname", NULL, ACL_AUTH ) )
{
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
- NULL, NULL, NULL );
+ NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
}
break;
}
send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
- NULL, NULL, NULL );
+ NULL, NULL, NULL, NULL );
rc = 1;
goto return_results;
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;
}
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;
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;
}
)
{
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;
)
{
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
"<=- 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) {
"<=- 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;
}
"<=- 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;
}
"<=- 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;
}
"<=- 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;
}
"<=- 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;
}
"<=- 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:;
/* 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(
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 );
return( -1 );
}
- dn = strdup( dn );
+ dn = ch_strdup( dn );
dn_normalize_case( dn );
key.dptr = dn;
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 );
{
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 );
}
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 );
}
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 ))
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 );
*/
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;
}
+
--- /dev/null
+/* 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);
+}
+
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;
}
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;
}
}
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;
}
/* 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;
}
)
{
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;
/* 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 );
)
{
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) */
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"),
/* 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.
*/
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;
}
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;
}
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;
}
/* 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;
}
"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;
}
"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. */
if (dn2id ( be, new_ndn ) != NOID) {
send_ldap_result( conn, op, LDAP_ALREADY_EXISTS,
- NULL, NULL, NULL );
+ NULL, NULL, NULL, NULL );
goto return_results;
}
/* 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;
}
/* 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;
}
"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;
}
"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;
}
"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;
}
"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;
}
/* Remove old rdn value if required */
if (deleteoldrdn) {
-
/* Get value of old rdn */
if ((old_rdn_val = rdn_attr_value( old_rdn ))
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 */
0, 0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
- NULL, NULL, NULL );
+ NULL, NULL, NULL, NULL );
goto return_results;
}
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;
#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
#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(
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 */
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 {
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 ) ) {
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 );
/* 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;
* 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 {
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 ) {
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;
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 );
}
}
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 );
/* 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 )
{
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 );
}
{
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 );
}
}
}
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);
}
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;
}
"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;
}
"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;
}
* 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;
}
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;
/* 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 );
/* 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 );
} else {
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
- NULL, "Function not implemented", NULL );
+ NULL, "Function not implemented", NULL, NULL );
}
cleanup:
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;
}
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 );
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 ) {
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",
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 */
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 );
}
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
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;
}
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;
}
} 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 );
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;
}
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 ) {
--- /dev/null
+# 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
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;
}
(*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;
&& (*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;
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;
/* 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 );
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;
}
free( newSuperior );
free( nnewSuperior );
send_ldap_result( conn, op, LDAP_REFERRAL,
- NULL, NULL, default_referral );
+ NULL, NULL, default_referral, NULL );
return 0;
}
}
free( newSuperior );
free( nnewSuperior );
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
- NULL, NULL, default_referral );
+ NULL, NULL, default_referral, NULL );
return rc;
}
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;
}
} 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 );
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 );
}
Operation *op,
int senderrors ));
+int get_manageDSAit LDAP_P(( Operation *op ));
+
/*
* config.c
*/
* 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,
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 ));
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
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
*/
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';
}
}
-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 )
{
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",
#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",
ber_int_t err,
char *matched,
char *text,
- struct berval **ref
+ struct berval **ref,
+ LDAPControl **ctrls
)
{
ber_tag_t tag;
assert( err != LDAP_PARTIAL_RESULTS );
- if ( ref != NULL ) {
- trim_refs( ref, 0 );
- }
-
if ( err == LDAP_REFERRAL ) {
if( ref == NULL ) {
err = LDAP_NO_SUCH_OBJECT;
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",
char *matched,
char *text,
struct berval **refs,
+ LDAPControl **ctrls,
int nentries
)
{
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 */
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",
Entry *e,
char **attrs,
int attrsonly,
- int opattrs
+ int opattrs,
+ LDAPControl **ctrls
)
{
BerElement *ber;
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;
}
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;
}
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;
}
"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;
}
}
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;
}
}
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 );
}
Operation *op,
Entry *e,
struct berval **refs,
+ LDAPControl **ctrls,
struct berval ***v2refs
)
{
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;
}
"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;
}
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 );
}
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 );
}
}
#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
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;
}
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;
}
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;
}
}
#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;
}
*/
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:;
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
/* 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 */
--- /dev/null
+# 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
--- /dev/null
+# 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
+#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 ) {
* 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: " );
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" );
}
}
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;
"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 );
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 ) {
free_and_close( dbc, key, data );
break;
+#endif
case 'a': /* add an entry */
if ( (dbc = openchoice( buf[1], LDBM_WRITER, 1, NULL ))
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;
}
} 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 );
}
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 );
}
}
}
+ 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 )
}
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 ) );
}
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 );
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 ) {
continue;
}
- p->b_ids[i++] = atol( buf );
+ ID_BLOCK_ID(p,i++) = atol( buf );
psize += sizeof(ID);
}
if ( nmax == 0 ) {
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 {
}
}
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 );
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;
char *editor;
if ( (editor = getenv( "EDITOR" )) == NULL ) {
- editor = EDITOR;
+ editor = LDAP_EDITOR;
}
execl( editor, editor, tmpname, NULL );
perror( "execl" );
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;
}
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;
}
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];
}
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 ) {
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 ) {
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) );
}
}
}
}
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;
--- /dev/null
+# 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
return 0;
}
+void
+send_ldap_disconnect(
+ Connection *conn,
+ Operation *op,
+ ber_int_t err,
+ char *text
+)
+{
+ assert(0);
+}
+
void
send_ldap_result(
Connection *conn,
int err,
char *matched,
char *text,
- struct berval **refs
+ struct berval **refs,
+ LDAPControl **ctrls
)
{
assert(0);
char *matched,
char *text,
struct berval **refs,
+ LDAPControl **ctrls,
int nentries
)
{
Entry *e,
char **attrs,
int attrsonly,
- int opattrs
+ int opattrs,
+ LDAPControl **ctrls
)
{
assert(0);
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;
+}
/* 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
}
if ( syntax & SYNTAX_DN ) {
- (void) dn_normalize_case( s );
+ (void) dn_normalize( s );
return;
}
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,
)
{
int rc;
- struct stat st1, st2;
if ( normalize & 1 ) {
v1 = ber_bvdup( v1 );
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;
}
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,