From 1e436aba370d47ab738c5ea320a440b1042698f8 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Wed, 18 May 2005 18:29:20 +0000 Subject: [PATCH] Sync with HEAD --- build/mkrelease | 7 +++ build/top.mk | 4 +- doc/man/man3/ldap_first_attribute.3 | 4 +- doc/man/man3/ldap_search.3 | 1 - include/ldap.h | 3 + include/ldif.h | 19 +++++- libraries/libldap/cyrus.c | 2 +- libraries/liblutil/Makefile.in | 3 + libraries/liblutil/fetch.c | 46 +++++++++------ libraries/liblutil/ldif.c | 91 +++++++++++++++++++++++++++-- libraries/librewrite/Makefile.in | 11 +++- servers/slapd/attr.c | 4 +- servers/slapd/back-bdb/index.c | 10 ++++ servers/slapd/back-ldap/search.c | 47 +++++---------- servers/slapd/back-meta/Makefile.in | 3 +- servers/slapd/back-meta/search.c | 44 ++++++-------- servers/slapd/back-sql/add.c | 2 +- servers/slapd/back-sql/back-sql.h | 3 + servers/slapd/back-sql/config.c | 38 ++++++++++-- servers/slapd/back-sql/entry-id.c | 78 ++++++++++++++++--------- servers/slapd/back-sql/init.c | 3 +- servers/slapd/back-sql/modify.c | 2 +- servers/slapd/back-sql/modrdn.c | 2 +- servers/slapd/bconfig.c | 26 +++------ servers/slapd/controls.c | 9 +-- servers/slapd/entry.c | 21 ++++--- servers/slapd/modify.c | 2 +- servers/slapd/overlays/Makefile.in | 9 ++- servers/slapd/overlays/rwm.c | 18 ++++-- servers/slapd/proto-slap.h | 1 - servers/slapd/root_dse.c | 21 ++++--- servers/slapd/schema_check.c | 3 - servers/slapd/schemaparse.c | 2 - servers/slapd/slap.h | 10 ++-- servers/slapd/slapcat.c | 5 +- servers/slapd/slapcommon.c | 8 ++- servers/slapd/slapcommon.h | 2 +- 37 files changed, 364 insertions(+), 200 deletions(-) diff --git a/build/mkrelease b/build/mkrelease index 0b8554061e..368e6ed86a 100755 --- a/build/mkrelease +++ b/build/mkrelease @@ -51,6 +51,13 @@ if test ! -d $RELNAME ; then exit 1 fi +if test -e $RELNAME/doc/guide/admin/guide.sdf ; then + echo "build guide..." + ( cd $RELNAME/doc/guide/admin ; make guide.html ) +else + echo "No guide" +fi + if test ! -e $RELNAME/build/version.sh ; then echo "No build version" OL_STRING="something" diff --git a/build/top.mk b/build/top.mk index afdac27b59..c458e4d704 100644 --- a/build/top.mk +++ b/build/top.mk @@ -162,7 +162,7 @@ LDAP_LIBLBER_LA = $(LDAP_LIBDIR)/liblber/liblber.la LDAP_LIBLDAP_LA = $(LDAP_LIBDIR)/libldap/libldap.la LDAP_LIBLDAP_R_LA = $(LDAP_LIBDIR)/libldap_r/libldap_r.la -LDAP_LIBREWRITE_A = $(LDAP_LIBDIR)/librewrite/librewrite.a +LDAP_LIBLREWRITE_LA = $(LDAP_LIBDIR)/librewrite/liblrewrite.la LDAP_LIBLUNICODE_A = $(LDAP_LIBDIR)/liblunicode/liblunicode.a LDAP_LIBLUTIL_A = $(LDAP_LIBDIR)/liblutil/liblutil.a @@ -170,7 +170,7 @@ LDAP_L = $(LDAP_LIBLUTIL_A) \ $(LDAP_LIBLDAP_LA) $(LDAP_LIBLBER_LA) SLURPD_L = $(LDAP_LIBLUTIL_A) \ $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA) -SLAPD_L = $(LDAP_LIBLUNICODE_A) $(LDAP_LIBREWRITE_A) \ +SLAPD_L = $(LDAP_LIBLUNICODE_A) $(LDAP_LIBLREWRITE_LA) \ $(SLURPD_L) WRAP_LIBS = @WRAP_LIBS@ diff --git a/doc/man/man3/ldap_first_attribute.3 b/doc/man/man3/ldap_first_attribute.3 index ede0f79075..921f4a18e7 100644 --- a/doc/man/man3/ldap_first_attribute.3 +++ b/doc/man/man3/ldap_first_attribute.3 @@ -13,11 +13,11 @@ OpenLDAP LDAP (libldap, -lldap) .LP .ft B char *ldap_first_attribute( - LDAP *ld, LDAPMessage entry, BerElement **berptr ) + LDAP *ld, LDAPMessage *entry, BerElement **berptr ) .LP .ft B char *ldap_next_attribute( - LDAP *ld, LDAPMessage entry, BerElement *ber ) + LDAP *ld, LDAPMessage *entry, BerElement *ber ) .SH DESCRIPTION The .B ldap_first_attribute() diff --git a/doc/man/man3/ldap_search.3 b/doc/man/man3/ldap_search.3 index dcdd07ad84..18d678c368 100644 --- a/doc/man/man3/ldap_search.3 +++ b/doc/man/man3/ldap_search.3 @@ -123,7 +123,6 @@ routines. Return values are contained in . .SH SEE ALSO .BR ldap (3), .BR ldap_result (3), -.BR ldap_getfilter (3), .BR ldap_error (3) .SH ACKNOWLEDGEMENTS .B OpenLDAP diff --git a/include/ldap.h b/include/ldap.h index 4817393590..a4f3ed2f3b 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -220,6 +220,9 @@ typedef struct ldapcontrol { #define LDAP_CONTROL_NOOP "1.3.6.1.4.1.4203.666.5.2" #define LDAP_CONTROL_PRE_READ "1.3.6.1.4.1.4203.666.5.10.1" #define LDAP_CONTROL_POST_READ "1.3.6.1.4.1.4203.666.5.10.2" +#define LDAP_CONTROL_NO_SUBORDINATES "1.3.6.1.4.1.4203.666.5.11" +#define LDAP_CONTROL_MANAGEDIT "1.3.6.1.4.1.4203.666.5.12" +#define LDAP_CONTROL_SLURP "1.3.6.1.4.1.4203.666.5.13" /* LDAP Duplicated Entry Control Extension *//* not implemented in slapd(8) */ #define LDAP_CONTROL_DUPENT_REQUEST "2.16.840.1.113719.1.27.101.1" diff --git a/include/ldif.h b/include/ldif.h index a51e1cf4d3..0b2eaed130 100644 --- a/include/ldif.h +++ b/include/ldif.h @@ -66,6 +66,9 @@ ldif_parse_line2 LDAP_P(( struct berval *value, int *freeval )); +LDAP_LDIF_F( FILE * ) +ldif_open_url LDAP_P(( LDAP_CONST char *urlstr )); + LDAP_LDIF_F( int ) ldif_fetch_url LDAP_P(( LDAP_CONST char *line, @@ -78,9 +81,23 @@ ldif_getline LDAP_P(( char **next )); LDAP_LDIF_F( int ) ldif_countlines LDAP_P(( LDAP_CONST char *line )); +/* ldif_ropen, rclose, read_record - just for reading LDIF files, + * no special open/close needed to write LDIF files. + */ +typedef struct LDIFFP { + FILE *fp; + struct LDIFFP *prev; +} LDIFFP; + +LDAP_LDIF_F( LDIFFP * ) +ldif_open LDAP_P(( char *file, char *mode )); + +LDAP_LDIF_F( void ) +ldif_close LDAP_P(( LDIFFP * )); + LDAP_LDIF_F( int ) ldif_read_record LDAP_P(( - FILE *fp, + LDIFFP *fp, int *lineno, char **bufp, int *buflen )); diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c index c88ad94cc2..553d39faa9 100644 --- a/libraries/libldap/cyrus.c +++ b/libraries/libldap/cyrus.c @@ -807,7 +807,7 @@ ldap_int_sasl_bind( sasl_dispose( &oldctx ); ldap_pvt_sasl_remove( ld->ld_defconn->lconn_sb ); } - ldap_pvt_sasl_install( ld->ld_conns->lconn_sb, ctx ); + ldap_pvt_sasl_install( ld->ld_defconn->lconn_sb, ctx ); ld->ld_defconn->lconn_sasl_sockctx = ctx; } } diff --git a/libraries/liblutil/Makefile.in b/libraries/liblutil/Makefile.in index 545b85eaa3..d112de8f0a 100644 --- a/libraries/liblutil/Makefile.in +++ b/libraries/liblutil/Makefile.in @@ -45,6 +45,9 @@ testavl: $(XLIBS) testavl.o # It's ok for them to be here because the clean rule is harmless, and # slapdmsg.res won't get built unless it's declared in OBJS. +slapdmsg.bin: FORCE + @if [ ! -f $@ ]; then cp $(srcdir)/$@ .; fi + slapdmsg.res: slapdmsg.rc slapdmsg.bin windres $< -O coff -o $@ diff --git a/libraries/liblutil/fetch.c b/libraries/liblutil/fetch.c index 49a72c6e4c..904966619d 100644 --- a/libraries/liblutil/fetch.c +++ b/libraries/liblutil/fetch.c @@ -38,22 +38,13 @@ #include "ldap_config.h" #include "ldif.h" -int -ldif_fetch_url( - LDAP_CONST char *urlstr, - char **valuep, - ber_len_t *vlenp +FILE * +ldif_open_url( + LDAP_CONST char *urlstr ) { FILE *url; - char buffer[1024]; char *p = NULL; - size_t total; - size_t bytes; - - *valuep = NULL; - *vlenp = 0; - #ifdef HAVE_FETCH url = fetchGetURL( (char*) urlstr, "" ); @@ -61,24 +52,43 @@ ldif_fetch_url( if( strncasecmp( "file://", urlstr, sizeof("file://")-1 ) == 0 ) { p = strchr( &urlstr[sizeof("file://")-1], '/' ); if( p == NULL ) { - return -1; + return NULL; } /* we don't check for LDAP_DIRSEP since URLs should contain '/' */ - if( *p != '/' ) { - /* skip over false root */ - p++; - } + /* skip over false root */ + p++; p = ber_strdup( p ); ldap_pvt_hex_unescape( p ); url = fopen( p, "rb" ); + ber_memfree( p ); } else { - return -1; + return NULL; } #endif + return url; +} + +int +ldif_fetch_url( + LDAP_CONST char *urlstr, + char **valuep, + ber_len_t *vlenp +) +{ + FILE *url; + char buffer[1024]; + char *p = NULL; + size_t total; + size_t bytes; + + *valuep = NULL; + *vlenp = 0; + + url = ldif_open_url( urlstr ); if( url == NULL ) { return -1; diff --git a/libraries/liblutil/ldif.c b/libraries/liblutil/ldif.c index cc0225c090..01ac9dbf5b 100644 --- a/libraries/liblutil/ldif.c +++ b/libraries/liblutil/ldif.c @@ -745,12 +745,44 @@ int ldif_is_not_printable( return 1; } +LDIFFP * +ldif_open( + char *file, + char *mode +) +{ + FILE *fp = fopen( file, mode ); + LDIFFP *lfp = NULL; + + if ( fp ) { + lfp = ber_memalloc( sizeof( LDIFFP )); + lfp->fp = fp; + lfp->prev = NULL; + } + return lfp; +} + +void +ldif_close( + LDIFFP *lfp +) +{ + LDIFFP *prev; + + while ( lfp ) { + fclose( lfp->fp ); + prev = lfp->prev; + ber_memfree( lfp ); + lfp = prev; + } +} + /* - * slap_read_ldif - read an ldif record. Return 1 for success, 0 for EOF. + * ldif_read_record - read an ldif record. Return 1 for success, 0 for EOF. */ int ldif_read_record( - FILE *fp, + LDIFFP *lfp, int *lno, /* ptr to line number counter */ char **bufp, /* ptr to malloced output buffer */ int *buflenp ) /* ptr to length of *bufp */ @@ -762,8 +794,25 @@ ldif_read_record( line = linebuf; linesize = sizeof( linebuf ); - for ( stop = feof( fp ); !stop; last_ch = line[len-1] ) { - if ( fgets( line, linesize, fp ) == NULL ) { + for ( stop = 0; !stop; last_ch = line[len-1] ) { + /* If we're at the end of this file, see if we should pop + * back to a previous file. (return from an include) + */ + while ( feof( lfp->fp )) { + if ( lfp->prev ) { + LDIFFP *tmp = lfp->prev; + fclose( lfp->fp ); + *lfp = *tmp; + ber_memfree( tmp ); + } else { + stop = 1; + break; + } + } + if ( stop ) + break; + + if ( fgets( line, linesize, lfp->fp ) == NULL ) { stop = 1; /* Add \n in case the file does not end with newline */ line = "\n"; @@ -793,6 +842,40 @@ ldif_read_record( /* skip index */ continue; } + if ( !strncasecmp( line, "include:", + STRLENOF("include:"))) { + FILE *fp2; + char *ptr; + found_entry = 0; + + if ( line[len-1] == '\n' ) { + len--; + line[len] = '\0'; + } + if ( line[len-1] == '\r' ) { + len--; + line[len] = '\0'; + } + + ptr = line + STRLENOF("include:"); + while (isspace(*ptr)) ptr++; + fp2 = ldif_open_url( ptr ); + if ( fp2 ) { + LDIFFP *lnew = ber_memalloc( sizeof( LDIFFP )); + lnew->prev = lfp->prev; + lnew->fp = lfp->fp; + lfp->prev = lnew; + lfp->fp = fp2; + line[len] = '\n'; + len++; + continue; + } else { + /* We failed to open the file, this should + * be reported as an error somehow. + */ + break; + } + } } } } diff --git a/libraries/librewrite/Makefile.in b/libraries/librewrite/Makefile.in index 7c32249068..bb3b8272f2 100644 --- a/libraries/librewrite/Makefile.in +++ b/libraries/librewrite/Makefile.in @@ -20,13 +20,13 @@ SRCS = config.c context.c info.c ldapmap.c map.c params.c rule.c \ session.c subst.c var.c xmap.c \ parse.c rewrite.c XSRCS = version.c -OBJS = config.o context.o info.o ldapmap.o map.o params.o rule.o \ - session.o subst.o var.o xmap.o +OBJS = config.lo context.lo info.lo ldapmap.lo map.lo params.lo rule.lo \ + session.lo subst.lo var.lo xmap.lo LDAP_INCDIR= ../../include LDAP_LIBDIR= ../../libraries -LIBRARY = librewrite.a +LIBRARY = liblrewrite.la PROGRAMS = rewrite XLIBS = $(LIBRARY) $(LDAP_LIBLUTIL_A) \ $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA) @@ -35,3 +35,8 @@ XXXLIBS = $(LTHREAD_LIBS) rewrite: $(XLIBS) rewrite.o parse.o $(LTLINK) -o $@ rewrite.o parse.o $(LIBS) + +install-local: FORCE + -$(MKDIR) $(DESTDIR)$(libdir) + $(LTINSTALL) $(INSTALLFLAGS) -m 644 $(LIBRARY) $(DESTDIR)$(libdir) + $(LTFINISH) $(DESTDIR)$(libdir) diff --git a/servers/slapd/attr.c b/servers/slapd/attr.c index 5e0b3e6e99..cdfb3a2fe5 100644 --- a/servers/slapd/attr.c +++ b/servers/slapd/attr.c @@ -46,7 +46,9 @@ attr_free( Attribute *a ) if ( a->a_nvals && a->a_nvals != a->a_vals ) { ber_bvarray_free( a->a_nvals ); } - ber_bvarray_free( a->a_vals ); + if ( a->a_vals != &slap_dummy_bv ) { + ber_bvarray_free( a->a_vals ); + } free( a ); } diff --git a/servers/slapd/back-bdb/index.c b/servers/slapd/back-bdb/index.c index ea78c1098e..91c5a74626 100644 --- a/servers/slapd/back-bdb/index.c +++ b/servers/slapd/back-bdb/index.c @@ -254,6 +254,16 @@ static int indexer( } done: + switch( rc ) { + /* The callers all know how to deal with these results */ + case 0: + case DB_LOCK_DEADLOCK: + case DB_LOCK_NOTGRANTED: + break; + /* Anything else is bad news */ + default: + rc = LDAP_OTHER; + } return rc; } diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 144e27f601..2c6d296f5c 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -38,8 +38,7 @@ static int ldap_build_entry( Operation *op, LDAPMessage *e, Entry *ent, - struct berval *bdn, int flags ); -#define LDAP_BUILD_ENTRY_PRIVATE 0x01 + struct berval *bdn ); /* * Quick'n'dirty rewrite of filter in case of error, to deal with @@ -269,35 +268,23 @@ fail:; do_retry = 0; e = ldap_first_entry( lc->lc_ld, res ); - rc = ldap_build_entry( op, e, &ent, &bdn, - LDAP_BUILD_ENTRY_PRIVATE ); + rc = ldap_build_entry( op, e, &ent, &bdn ); if ( rc == LDAP_SUCCESS ) { rs->sr_entry = &ent; rs->sr_attrs = op->ors_attrs; rs->sr_operational_attrs = NULL; rs->sr_flags = 0; abort = send_search_entry( op, rs ); - while ( ent.e_attrs ) { - Attribute *a; - - a = ent.e_attrs; - ent.e_attrs = a->a_next; - - if ( a->a_nvals != a->a_vals ) { - ber_bvarray_free( a->a_nvals ); - } - if ( a->a_vals != &slap_dummy_bv ) { - ber_bvarray_free( a->a_vals ); - } - ch_free( a ); - } - - if ( ent.e_dn && ( ent.e_dn != bdn.bv_val ) ) { - free( ent.e_dn ); + if ( !BER_BVISNULL( &ent.e_name ) && ( ent.e_name.bv_val != bdn.bv_val ) ) + { + free( ent.e_name.bv_val ); + BER_BVZERO( &ent.e_name ); } - if ( ent.e_ndn ) { - free( ent.e_ndn ); + if ( !BER_BVISNULL( &ent.e_nname ) ) { + free( ent.e_nname.bv_val ); + BER_BVZERO( &ent.e_nname ); } + entry_clean( &ent ); } ldap_msgfree( res ); if ( abort ) { @@ -445,15 +432,13 @@ ldap_build_entry( Operation *op, LDAPMessage *e, Entry *ent, - struct berval *bdn, - int flags ) + struct berval *bdn ) { struct berval a; BerElement ber = *e->lm_ber; Attribute *attr, **attrp; const char *text; int last; - int private = flags & LDAP_BUILD_ENTRY_PRIVATE; /* safe assumptions ... */ assert( ent ); @@ -530,13 +515,7 @@ ldap_build_entry( * Note: attr->a_vals can be null when using * values result filter */ - if ( private ) { - attr->a_vals = (struct berval *)&slap_dummy_bv; - - } else { - attr->a_vals = ch_malloc( sizeof( struct berval ) ); - BER_BVZERO( &attr->a_vals[ 0 ] ); - } + attr->a_vals = (struct berval *)&slap_dummy_bv; last = 0; } else { @@ -708,7 +687,7 @@ retry: *ent = ch_calloc( 1, sizeof( Entry ) ); - rc = ldap_build_entry( op, e, *ent, &bdn, 0 ); + rc = ldap_build_entry( op, e, *ent, &bdn ); if ( rc != LDAP_SUCCESS ) { ch_free( *ent ); diff --git a/servers/slapd/back-meta/Makefile.in b/servers/slapd/back-meta/Makefile.in index 1292b4c858..46be0895a5 100644 --- a/servers/slapd/back-meta/Makefile.in +++ b/servers/slapd/back-meta/Makefile.in @@ -29,7 +29,8 @@ BUILD_MOD = @BUILD_META@ mod_DEFS = -DSLAPD_IMPORT MOD_DEFS = $(@BUILD_META@_DEFS) -shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA) +shared_LDAP_LIBS = $(LDAP_LIBLDAP_R_LA) $(LDAP_LIBLBER_LA) \ + $(LDAP_LIBLREWRITE_LA) NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) UNIX_LINK_LIBS = $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS) diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index ae30ba1d9f..34c23de511 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -342,16 +342,6 @@ meta_back_search( Operation *op, SlapReply *rs ) break; } - if ( op->ors_slimit > 0 && rs->sr_nentries == op->ors_slimit ) - { - rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; - savepriv = op->o_private; - op->o_private = (void *)i; - send_ldap_result( op, rs ); - op->o_private = savepriv; - goto finish; - } - /* * FIXME: handle time limit as well? * Note that target servers are likely @@ -388,6 +378,18 @@ really_bad:; goto finish; } else if ( rc == LDAP_RES_SEARCH_ENTRY ) { + if ( --op->ors_slimit == -1 ) { + ldap_msgfree( res ); + res = NULL; + + rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; + savepriv = op->o_private; + op->o_private = (void *)i; + send_ldap_result( op, rs ); + op->o_private = savepriv; + goto finish; + } + is_ok++; e = ldap_first_entry( msc->msc_ld, res ); @@ -939,24 +941,16 @@ meta_send_entry( send_search_entry( op, rs ); rs->sr_entry = NULL; rs->sr_attrs = NULL; - while ( ent.e_attrs ) { - attr = ent.e_attrs; - ent.e_attrs = attr->a_next; - if ( attr->a_vals != &slap_dummy_bv ) { - if ( attr->a_nvals != attr->a_vals ) { - ber_bvarray_free( attr->a_nvals ); - } - ber_bvarray_free( attr->a_vals ); - } - free( attr ); - } - if ( ent.e_dn && ent.e_dn != bdn.bv_val ) { - free( ent.e_dn ); + if ( !BER_BVISNULL( &ent.e_name ) && ent.e_name.bv_val != bdn.bv_val ) { + free( ent.e_name.bv_val ); + BER_BVZERO( &ent.e_name ); } - if ( ent.e_ndn ) { - free( ent.e_ndn ); + if ( !BER_BVISNULL( &ent.e_nname ) ) { + free( ent.e_nname.bv_val ); + BER_BVZERO( &ent.e_nname ); } + entry_clean( &ent ); return LDAP_SUCCESS; } diff --git a/servers/slapd/back-sql/add.c b/servers/slapd/back-sql/add.c index 40aac5a3e4..03accfc5ea 100644 --- a/servers/slapd/back-sql/add.c +++ b/servers/slapd/back-sql/add.c @@ -986,7 +986,7 @@ backsql_add( Operation *op, SlapReply *rs ) op->ora_e->e_name.bv_val, 0, 0 ); /* check schema */ - if ( global_schemacheck ) { + if ( BACKSQL_CHECK_SCHEMA( bi ) ) { char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' }; rs->sr_err = entry_schema_check( op->o_bd, op->ora_e, diff --git a/servers/slapd/back-sql/back-sql.h b/servers/slapd/back-sql/back-sql.h index d905d2bf23..9945a615db 100644 --- a/servers/slapd/back-sql/back-sql.h +++ b/servers/slapd/back-sql/back-sql.h @@ -508,6 +508,7 @@ typedef struct backsql_info { #define BSQLF_FETCH_ALL_USERATTRS 0x0200 #define BSQLF_FETCH_ALL_OPATTRS 0x0400 #define BSQLF_FETCH_ALL_ATTRS (BSQLF_FETCH_ALL_USERATTRS|BSQLF_FETCH_ALL_OPATTRS) +#define BSQLF_CHECK_SCHEMA 0x0800 #define BACKSQL_ISF(si, f) \ (((si)->sql_flags & f) == f) @@ -538,6 +539,8 @@ typedef struct backsql_info { BACKSQL_ISF(si, BSQLF_FETCH_ALL_OPATTRS) #define BACKSQL_FETCH_ALL_ATTRS(si) \ BACKSQL_ISF(si, BSQLF_FETCH_ALL_ATTRS) +#define BACKSQL_CHECK_SCHEMA(si) \ + BACKSQL_ISF(si, BSQLF_CHECK_SCHEMA) Entry *sql_baseObject; #ifdef BACKSQL_ARBITRARY_KEY diff --git a/servers/slapd/back-sql/config.c b/servers/slapd/back-sql/config.c index 9e82f0b358..a333ae0419 100644 --- a/servers/slapd/back-sql/config.c +++ b/servers/slapd/back-sql/config.c @@ -561,6 +561,36 @@ backsql_db_config( return -1; } + } else if ( !strcasecmp( argv[ 0 ], "check_schema") ) { + if ( argc < 2 ) { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "missing { yes | no }" + "in \"check_schema\" directive\n", + fname, lineno, 0 ); + return 1; + } + + if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { + bi->sql_flags |= BSQLF_CHECK_SCHEMA; + + } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { + bi->sql_flags &= ~BSQLF_CHECK_SCHEMA; + + } else { + Debug( LDAP_DEBUG_TRACE, + "<==backsql_db_config (%s line %d): " + "\"check_schema\" directive arg " + "must be \"yes\" or \"no\"\n", + fname, lineno, 0 ); + return 1; + + } + Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): " + "check_schema=%s\n", + BACKSQL_CHECK_SCHEMA( bi ) ? "yes" : "no", + 0, 0 ); + } else { return SLAP_CONF_UNKNOWN; } @@ -580,13 +610,13 @@ read_baseObject( const char *fname ) { backsql_info *bi = (backsql_info *)be->be_private; - FILE *fp; + LDIFFP *fp; int rc = 0, lineno = 0, lmax = 0; char *buf = NULL; assert( fname ); - fp = fopen( fname, "r" ); + fp = ldif_open( fname, "r" ); if ( fp == NULL ) { Debug( LDAP_DEBUG_ANY, "could not open back-sql baseObject " @@ -600,7 +630,7 @@ read_baseObject( if ( bi->sql_baseObject == NULL ) { Debug( LDAP_DEBUG_ANY, "read_baseObject_file: SLAP_CALLOC failed", 0, 0, 0 ); - fclose( fp ); + ldif_close( fp ); return LDAP_NO_MEMORY; } bi->sql_baseObject->e_name = be->be_suffix[0]; @@ -658,7 +688,7 @@ read_baseObject( ch_free( buf ); - fclose( fp ); + ldif_close( fp ); Debug( LDAP_DEBUG_CONFIG, "back-sql baseObject file \"%s\" read.\n", fname, 0, 0 ); diff --git a/servers/slapd/back-sql/entry-id.c b/servers/slapd/back-sql/entry-id.c index 071be1e47a..49d3346c7e 100644 --- a/servers/slapd/back-sql/entry-id.c +++ b/servers/slapd/back-sql/entry-id.c @@ -934,39 +934,61 @@ next:; } } - if ( global_schemacheck ) { - const char *text = NULL; - char textbuf[ 1024 ]; - size_t textlen = sizeof( textbuf ); - struct berval bv[ 2 ]; - struct berval soc; - int rc; - - bv[ 0 ] = bsi->bsi_oc->bom_oc->soc_cname; - BER_BVZERO( &bv[ 1 ] ); - - rc = structural_class( bv, &soc, NULL, - &text, textbuf, textlen ); - if ( rc != LDAP_SUCCESS ) { - Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): " - "structural_class() failed %d (%s)\n", - bsi->bsi_e->e_name.bv_val, - rc, text ? text : "" ); - entry_clean( bsi->bsi_e ); - return rc; - } + if ( ( bsi->bsi_flags & BSQL_SF_ALL_OPER ) + || an_find( bsi->bsi_attrs, &AllOper ) + || an_find( bsi->bsi_attrs, &slap_schema.si_ad_structuralObjectClass->ad_cname ) ) + { + if ( BACKSQL_CHECK_SCHEMA( bi ) ) { + Attribute *a; + const char *text = NULL; + char textbuf[ 1024 ]; + size_t textlen = sizeof( textbuf ); + struct berval soc, + bv[ 2 ], + *nvals; + int rc = LDAP_SUCCESS; + + a = attr_find( bsi->bsi_e->e_attrs, + slap_schema.si_ad_objectClass ); + if ( a != NULL ) { + nvals = a->a_nvals; - if ( ( bsi->bsi_flags & BSQL_SF_ALL_OPER ) - || an_find( bsi->bsi_attrs, &AllOper ) - || an_find( bsi->bsi_attrs, &slap_schema.si_ad_structuralObjectClass->ad_cname ) ) - { - rc = attr_merge_normalize_one( bsi->bsi_e, - slap_schema.si_ad_structuralObjectClass, - &soc, bsi->bsi_op->o_tmpmemctx ); + } else { + bv[ 0 ] = bsi->bsi_oc->bom_oc->soc_cname; + BER_BVZERO( &bv[ 1 ] ); + nvals = bv; + } + + rc = structural_class( nvals, &soc, NULL, + &text, textbuf, textlen ); if ( rc != LDAP_SUCCESS ) { + Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): " + "structural_class() failed %d (%s)\n", + bsi->bsi_e->e_name.bv_val, + rc, text ? text : "" ); entry_clean( bsi->bsi_e ); return rc; } + + if ( !bvmatch( &soc, &bsi->bsi_oc->bom_oc->soc_cname ) ) { + Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): " + "computed structuralObjectClass %s " + "does not match objectClass %s associated " + "to entry\n", + bsi->bsi_e->e_name.bv_val, soc.bv_val, + bsi->bsi_oc->bom_oc->soc_cname.bv_val ); + entry_clean( bsi->bsi_e ); + return rc; + } + } + + rc = attr_merge_normalize_one( bsi->bsi_e, + slap_schema.si_ad_structuralObjectClass, + &bsi->bsi_oc->bom_oc->soc_cname, + bsi->bsi_op->o_tmpmemctx ); + if ( rc != LDAP_SUCCESS ) { + entry_clean( bsi->bsi_e ); + return rc; } } diff --git a/servers/slapd/back-sql/init.c b/servers/slapd/back-sql/init.c index 4a236a1718..f3e744fe4b 100644 --- a/servers/slapd/back-sql/init.c +++ b/servers/slapd/back-sql/init.c @@ -98,7 +98,7 @@ backsql_db_init( backsql_info *bi; Debug( LDAP_DEBUG_TRACE, "==>backsql_db_init()\n", 0, 0, 0 ); - bi = (backsql_info *)ch_calloc( 1, sizeof( backsql_info ) ); + bi = (backsql_info *)ch_malloc( sizeof( backsql_info ) ); memset( bi, '\0', sizeof( backsql_info ) ); ldap_pvt_thread_mutex_init( &bi->sql_dbconn_mutex ); ldap_pvt_thread_mutex_init( &bi->sql_schema_mutex ); @@ -474,6 +474,7 @@ backsql_db_open( /* enable if only one suffix is defined */ bi->sql_flags |= BSQLF_USE_SUBTREE_SHORTCUT; } + bi->sql_flags |= BSQLF_CHECK_SCHEMA; Debug( LDAP_DEBUG_TRACE, "<==backsql_db_open(): " "test succeeded, schema map loaded\n", 0, 0, 0 ); diff --git a/servers/slapd/back-sql/modify.c b/servers/slapd/back-sql/modify.c index 8f5be4fc39..b75697a2d8 100644 --- a/servers/slapd/back-sql/modify.c +++ b/servers/slapd/back-sql/modify.c @@ -155,7 +155,7 @@ backsql_modify( Operation *op, SlapReply *rs ) goto do_transact; } - if ( global_schemacheck ) { + if ( BACKSQL_CHECK_SCHEMA( bi ) ) { char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' }; entry_clean( &m ); diff --git a/servers/slapd/back-sql/modrdn.c b/servers/slapd/back-sql/modrdn.c index 55acd62d2d..7c6c36baea 100644 --- a/servers/slapd/back-sql/modrdn.c +++ b/servers/slapd/back-sql/modrdn.c @@ -446,7 +446,7 @@ backsql_modrdn( Operation *op, SlapReply *rs ) goto done; } - if ( global_schemacheck ) { + if ( BACKSQL_CHECK_SCHEMA( bi ) ) { char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' }; entry_clean( &r ); diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index a157ee49e8..3a1d41969b 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -147,7 +147,6 @@ enum { CFG_DIT, CFG_ATTR, CFG_ATOPT, - CFG_CHECK, CFG_REPLOG, CFG_ROOTDSE, CFG_LOGFILE, @@ -455,9 +454,6 @@ static ConfigTable config_back_cf_table[] = { "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL }, { "saslRegexp", NULL, 3, 3, 0, ARG_MAGIC|CFG_AZREGEXP, &config_generic, NULL, NULL, NULL }, - { "schemacheck", "on|off", 2, 2, 0, ARG_ON_OFF|ARG_MAGIC|CFG_CHECK, - &config_generic, "( OLcfgGlAt:57 NAME 'olcSchemaCheck' " - "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL }, { "schemadn", "dn", 2, 2, 0, ARG_MAY_DB|ARG_DN|ARG_MAGIC, &config_schema_dn, "( OLcfgGlAt:58 NAME 'olcSchemaDN' " "SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL }, @@ -604,7 +600,7 @@ static ConfigOCs cf_ocs[] = { "olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ " "olcRootDSE $ olcRootPW $ " "olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ " - "olcSchemaCheck $ olcSecurity $ olcSizeLimit $ " + "olcSecurity $ olcSizeLimit $ " "olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ olcSrvtab $ " "olcThreads $ olcTimeLimit $ olcTLSCACertificateFile $ " "olcTLSCACertificatePath $ olcTLSCertificateFile $ " @@ -765,9 +761,6 @@ config_generic(ConfigArgs *c) { } break; - case CFG_CHECK: - c->value_int = global_schemacheck; - break; case CFG_ACL: { AccessControl *a; char *src, *dst, ibuf[11]; @@ -885,7 +878,6 @@ config_generic(ConfigArgs *c) { case CFG_RO: case CFG_AZPOLICY: case CFG_DEPTH: - case CFG_CHECK: case CFG_LASTMOD: case CFG_SASLSECP: case CFG_SSTR_IF_MAX: @@ -1088,13 +1080,6 @@ config_generic(ConfigArgs *c) { return(1); break; - case CFG_CHECK: - global_schemacheck = c->value_int; - if(!global_schemacheck) Debug(LDAP_DEBUG_ANY, "%s: " - "schema checking disabled! your mileage may vary!\n", - c->log, 0, 0); - break; - case CFG_ACL: parse_acl(c->be, c->fname, c->lineno, c->argc, c->argv, c->valx); break; @@ -2557,7 +2542,10 @@ read_config(const char *fname, const char *dir) { cfdir = SLAPD_DEFAULT_CONFIGDIR; } /* if fname is defaulted, try reading .d */ - if ( config_setup_ldif( be, cfdir, !fname )) + rc = config_setup_ldif( be, cfdir, !fname ); + + /* It's OK if the base object doesn't exist yet */ + if ( rc && rc != LDAP_NO_SUCH_OBJECT ) return 1; /* If we read the config from back-ldif, nothing to do here */ @@ -3317,8 +3305,8 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs, if(rc == LDAP_SUCCESS) { /* check that the entry still obeys the schema */ - rc = entry_schema_check(op->o_bd, e, NULL, - &rs->sr_text, ca->msg, sizeof(ca->msg) ); + rc = entry_schema_check(op->o_bd, e, NULL, 0, + &rs->sr_text, ca->msg, sizeof(ca->msg) ); } if ( rc == LDAP_SUCCESS ) { /* Basic syntax checks are OK. Do the actual settings. */ diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 27fe43f1c6..252912b22f 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -139,8 +139,8 @@ static struct slap_control control_defs[] = { SLAP_CTRL_HIDE|SLAP_CTRL_DELETE, NULL, parseTreeDelete, LDAP_SLIST_ENTRY_INITIALIZER(next) }, #endif -#ifdef LDAP_CONTORL_X_SEARCH_OPTIONS - { LDAP_CONTORL_X_SEARCH_OPTIONS, +#ifdef LDAP_CONTROL_X_SEARCH_OPTIONS + { LDAP_CONTROL_X_SEARCH_OPTIONS, (int)offsetof(struct slap_control_ids, sc_searchOptions), SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL, parseSearchOptions, LDAP_SLIST_ENTRY_INITIALIZER(next) }, @@ -1236,7 +1236,7 @@ static int parseSubentries ( ? SLAP_CONTROL_CRITICAL : SLAP_CONTROL_NONCRITICAL; - if ( (void *)(ctrl->ldctl_value.bv_val[2] != 0x00)) { + if (ctrl->ldctl_value.bv_val[2]) { set_subentries_visibility( op ); } @@ -1316,7 +1316,7 @@ static int parseTreeDelete ( } #endif -#ifdef LDAP_CONTORL_X_SEARCH_OPTIONS +#ifdef LDAP_CONTROL_X_SEARCH_OPTIONS static int parseSearchOptions ( Operation *op, SlapReply *rs, @@ -1324,6 +1324,7 @@ static int parseSearchOptions ( { BerElement *ber; ber_int_t search_flags; + ber_tag_t tag; if ( ctrl->ldctl_value.bv_len == 0 ) { rs->sr_text = "searchOptions control value not empty"; diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index ffef157940..e83ed0000d 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -181,24 +181,23 @@ str2entry2( char *s, int checkvals ) int fv; for (i=0; ik; l-- ) { - type[l] = type[l-1]; - vals[l] = vals[l-1]; - freeval[l] = freeval[l-1]; + for ( k=j; k>i; k-- ) { + type[k] = type[k-1]; + vals[k] = vals[k-1]; + freeval[k] = freeval[k-1]; } - type[l] = type[i]; - vals[l] = bv; - freeval[l] = fv; + k++; + type[k] = type[i]; + vals[k] = bv; + freeval[k] = fv; } - i = k = j; + i++; } } } diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index f9c64d4c9f..f80cebdf66 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -842,7 +842,7 @@ int slap_mods_opattrs( if( op->o_tag == LDAP_REQ_ADD ) { struct berval tmpval; - if( global_schemacheck ) { + { int rc = mods_structural_class( mods, &tmpval, text, textbuf, textlen ); if( rc != LDAP_SUCCESS ) return rc; diff --git a/servers/slapd/overlays/Makefile.in b/servers/slapd/overlays/Makefile.in index a1f8a338ec..bf91420166 100644 --- a/servers/slapd/overlays/Makefile.in +++ b/servers/slapd/overlays/Makefile.in @@ -29,6 +29,7 @@ SRCS = overlays.c \ OBJS = overlays.o \ @SLAPD_STATIC_OVERLAYS@ +LTONLY_MOD = $(LTONLY_mod) LDAP_INCDIR= ../../../include LDAP_LIBDIR= ../../../libraries @@ -76,7 +77,8 @@ rwm_x.o: rwm.o rwmconf.o rwmdn.o rwmmap.o $(LD) -r -o $@ rwm.o rwmconf.o rwmdn.o rwmmap.o rwm.la : rwm.lo rwmconf.lo rwmdn.lo rwmmap.lo - $(LTLINK_MOD) -module -o $@ rwm.lo rwmconf.lo rwmdn.lo rwmmap.lo version.lo $(LINK_LIBS) + $(LTLINK_MOD) -module -o $@ rwm.lo rwmconf.lo rwmdn.lo rwmmap.lo \ + version.lo $(LINK_LIBS) $(LDAP_LIBLREWRITE_LA) syncprov.la : syncprov.lo $(LTLINK_MOD) -module -o $@ syncprov.lo version.lo $(LINK_LIBS) @@ -97,12 +99,9 @@ MKDEPFLAG = -l .SUFFIXES: .c .o .lo -.c.o: - $(LTCOMPILE_LIB) $< - .c.lo: $(LTCOMPILE_MOD) $< $(LIBRARY): version.lo - $(LTLINK_LIB) -o $@ $(OBJS) version.lo + $(AR) rs $@ $(OBJS) diff --git a/servers/slapd/overlays/rwm.c b/servers/slapd/overlays/rwm.c index 4ff18d6573..85d73d2ad0 100644 --- a/servers/slapd/overlays/rwm.c +++ b/servers/slapd/overlays/rwm.c @@ -868,7 +868,7 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first, int stripEntryDN ) /* just count */ ; if ( last == 0 ) { - /* empty? for now, we leave it in place */ + /* empty? leave it in place because of attrsonly and vlv */ goto next_attr; } last--; @@ -1045,6 +1045,18 @@ rwm_send_entry( Operation *op, SlapReply *rs ) return SLAP_CB_CONTINUE; fail:; + if ( e != NULL && e != rs->sr_entry ) { + if ( e->e_name.bv_val == dn.bv_val ) { + BER_BVZERO( &e->e_name ); + } + + if ( e->e_nname.bv_val == ndn.bv_val ) { + BER_BVZERO( &e->e_nname ); + } + + entry_free( e ); + } + if ( !BER_BVISNULL( &dn ) ) { ch_free( dn.bv_val ); } @@ -1053,10 +1065,6 @@ fail:; ch_free( ndn.bv_val ); } - if ( e != NULL && e != rs->sr_entry ) { - entry_free( e ); - } - return rc; } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index e2175c2279..1250297aa3 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -1495,7 +1495,6 @@ LDAP_SLAPD_V (const char) Versionstr[]; LDAP_SLAPD_V (int) global_gentlehup; LDAP_SLAPD_V (int) global_idletimeout; -LDAP_SLAPD_V (int) global_schemacheck; LDAP_SLAPD_V (char *) global_host; LDAP_SLAPD_V (char *) global_realm; LDAP_SLAPD_V (char **) default_passwd_hash; diff --git a/servers/slapd/root_dse.c b/servers/slapd/root_dse.c index f4ee3bb477..3b3cb12f0c 100644 --- a/servers/slapd/root_dse.c +++ b/servers/slapd/root_dse.c @@ -176,14 +176,13 @@ root_dse_info( } /* supportedLDAPVersion */ - for ( i=LDAP_VERSION_MIN; i<=LDAP_VERSION_MAX; i++ ) { + /* don't publish version 2 as we don't really support it + * (even when configured to accept version 2 Bind requests) + * and the value would never be used by true LDAPv2 (or LDAPv3) + * clients. + */ + for ( i=LDAP_VERSION3; i<=LDAP_VERSION_MAX; i++ ) { char buf[BUFSIZ]; - if (!( global_allows & SLAP_ALLOW_BIND_V2 ) && - ( i < LDAP_VERSION3 ) ) - { - /* version 2 and lower are disallowed */ - continue; - } snprintf(buf, sizeof buf, "%d", i); val.bv_val = buf; val.bv_len = strlen( val.bv_val ); @@ -235,11 +234,11 @@ root_dse_info( */ int read_root_dse_file( const char *fname ) { - FILE *fp; + struct LDIFFP *fp; int rc = 0, lineno = 0, lmax = 0; char *buf = NULL; - if ( (fp = fopen( fname, "r" )) == NULL ) { + if ( (fp = ldif_open( fname, "r" )) == NULL ) { Debug( LDAP_DEBUG_ANY, "could not open rootdse attr file \"%s\" - absolute path?\n", fname, 0, 0 ); @@ -251,7 +250,7 @@ int read_root_dse_file( const char *fname ) if( usr_attr == NULL ) { Debug( LDAP_DEBUG_ANY, "read_root_dse_file: SLAP_CALLOC failed", 0, 0, 0 ); - fclose( fp ); + ldif_close( fp ); return LDAP_OTHER; } usr_attr->e_attrs = NULL; @@ -303,7 +302,7 @@ int read_root_dse_file( const char *fname ) ch_free( buf ); - fclose( fp ); + ldif_close( fp ); Debug(LDAP_DEBUG_CONFIG, "rootDSE file %s read.\n", fname, 0, 0); return rc; diff --git a/servers/slapd/schema_check.c b/servers/slapd/schema_check.c index 253849d378..cdf21460ca 100644 --- a/servers/slapd/schema_check.c +++ b/servers/slapd/schema_check.c @@ -111,9 +111,6 @@ entry_schema_check( } } - /* it's a REALLY bad idea to disable schema checks */ - if( !global_schemacheck ) return LDAP_SUCCESS; - /* find the structural object class attribute */ asc = attr_find( e->e_attrs, ad_structuralObjectClass ); if ( asc == NULL ) { diff --git a/servers/slapd/schemaparse.c b/servers/slapd/schemaparse.c index d0b0d5b77a..0834dc0ae8 100644 --- a/servers/slapd/schemaparse.c +++ b/servers/slapd/schemaparse.c @@ -25,8 +25,6 @@ #include "slap.h" #include "ldap_schema.h" -int global_schemacheck = 1; /* schemacheck ON is default */ - static void oc_usage(void); static void at_usage(void); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index c8ffe0ba33..f7fd70d98d 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1181,6 +1181,9 @@ typedef enum slap_access_e { ACL_WRITE, ACL_MANAGE, + /* always leave at end of levels but not greater than ACL_LEVEL_MASK */ + ACL_LAST, + /* ACL level mask and modifiers */ ACL_LEVEL_MASK = 0x000f, ACL_QUALIFIER1 = 0x0100, @@ -2350,6 +2353,9 @@ typedef struct slap_op { char o_do_not_cache; /* don't cache groups from this op */ char o_is_auth_check; /* authorization in progress */ + char o_nocaching; + char o_delete_glue_parent; + #define SLAP_CONTROL_NONE 0 #define SLAP_CONTROL_IGNORED 1 #define SLAP_CONTROL_NONCRITICAL 2 @@ -2437,10 +2443,6 @@ typedef struct slap_op { void *o_private; /* anything the backend needs */ LDAP_STAILQ_ENTRY(slap_op) o_next; /* next operation in list */ - - int o_nocaching; - int o_delete_glue_parent; - } Operation; #define OPERATION_BUFFER_SIZE (sizeof(Operation)+sizeof(Opheader)+SLAP_MAX_CIDS*sizeof(void *)) diff --git a/servers/slapd/slapcat.c b/servers/slapd/slapcat.c index e8a4beda5a..3e4d7ae12b 100644 --- a/servers/slapd/slapcat.c +++ b/servers/slapd/slapcat.c @@ -30,6 +30,7 @@ #include #include "slapcommon.h" +#include "ldif.h" int slapcat( int argc, char **argv ) @@ -101,8 +102,8 @@ slapcat( int argc, char **argv ) break; } - fputs( data, ldiffp ); - fputs( "\n", ldiffp ); + fputs( data, ldiffp->fp ); + fputs( "\n", ldiffp->fp ); } be->be_entry_close( be ); diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c index 48122b53d1..1d72c5cf74 100644 --- a/servers/slapd/slapcommon.c +++ b/servers/slapd/slapcommon.c @@ -36,6 +36,7 @@ #include "slapcommon.h" #include "lutil.h" +#include "ldif.h" tool_vars tool_globals; @@ -44,6 +45,8 @@ static char *leakfilename; static FILE *leakfile; #endif +static LDIFFP dummy; + static void usage( int tool, const char *progname ) { @@ -376,9 +379,10 @@ slap_tool_init( ldap_syslog = 0; if ( ldiffile == NULL ) { - ldiffp = tool == SLAPCAT ? stdout : stdin; + dummy.fp = tool == SLAPCAT ? stdout : stdin; + ldiffp = &dummy; - } else if ((ldiffp = fopen( ldiffile, tool == SLAPCAT ? "w" : "r" )) + } else if ((ldiffp = ldif_open( ldiffile, tool == SLAPCAT ? "w" : "r" )) == NULL ) { perror( ldiffile ); diff --git a/servers/slapd/slapcommon.h b/servers/slapd/slapcommon.h index 4dcf7a8cbb..30ae1567c5 100644 --- a/servers/slapd/slapcommon.h +++ b/servers/slapd/slapcommon.h @@ -41,7 +41,7 @@ typedef struct tool_vars { int tv_dryrun; Filter *tv_filter; struct berval tv_sub_ndn; - FILE *tv_ldiffp; + struct LDIFFP *tv_ldiffp; struct berval tv_baseDN; struct berval tv_authcDN; struct berval tv_authzDN; -- 2.39.5