From 39b5870d6ce4f88773e2d44e13d45036fc7e6210 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Fri, 6 Sep 2002 03:43:57 +0000 Subject: [PATCH] New mods code (quick and dirty disabled) module build fixes --- servers/slapd/Makefile.in | 23 +-- servers/slapd/add.c | 44 ++--- servers/slapd/backend.c | 6 +- servers/slapd/mods.c | 298 ++++++++++++++++++++++++++++---- servers/slapd/proto-slap.h | 4 + servers/slapd/slap.h | 56 +++--- servers/slapd/tools/Makefile.in | 14 +- 7 files changed, 336 insertions(+), 109 deletions(-) diff --git a/servers/slapd/Makefile.in b/servers/slapd/Makefile.in index 0cea35b4dc..2176cdcc35 100644 --- a/servers/slapd/Makefile.in +++ b/servers/slapd/Makefile.in @@ -39,13 +39,14 @@ LDAP_INCDIR= ../../include LDAP_LIBDIR= ../../libraries SLAP_DIR= +SLAPD_STATIC_DEPENDS=@SLAPD_NO_STATIC@ libbackends.a SLAPD_STATIC_BACKENDS=@SLAPD_STATIC_BACKENDS@ SLAPD_DYNAMIC_BACKENDS=@SLAPD_DYNAMIC_BACKENDS@ XDEFS = $(MODULES_CPPFLAGS) XLDFLAGS = $(MODULES_LDFLAGS) -XLIBS = libbackends.a $(SLAPD_L) +XLIBS = $(SLAPD_STATIC_DEPENDS) $(SLAPD_L) XXLIBS = $(LDBM_LIBS) $(SLAPD_LIBS) $(SECURITY_LIBS) $(LDIF_LIBS) $(LUTIL_LIBS) XXXLIBS = $(LTHREAD_LIBS) $(MODULES_LIBS) @@ -57,7 +58,7 @@ all-local-srv: all-cffiles NT_SLAPD_DEPENDS = slapd.exp NT_SLAPD_OBJECTS = slapd.exp symdummy.o $(OBJS) version.o -UNIX_SLAPD_DEPENDS = libbackends.a version.o $(SLAPD_L) +UNIX_SLAPD_DEPENDS = $(SLAPD_STATIC_DEPENDS) version.o $(SLAPD_L) UNIX_SLAPD_OBJECTS = $(OBJS) version.o SLAPD_DEPENDS = $(@PLAT@_SLAPD_DEPENDS) @@ -225,22 +226,14 @@ slapd.exp: libslapd.a slapd: $(SLAPD_DEPENDS) $(LTLINK) -o $@ $(SLAPD_OBJECTS) $(LIBS) $(WRAP_LIBS) - @if test -n "$(SLAPD_DYNAMIC_BACKENDS)"; then \ - echo "building dynamic backends..."; \ - for i in XX $(SLAPD_DYNAMIC_BACKENDS); do \ - if test $$i != XX; then \ - echo " "; echo " cd $$i; $(MAKE) $(MFLAGS) all"; \ - ( cd $$i; $(MAKE) $(MFLAGS) all ); \ - if test $$? != 0; then exit 1; fi; \ - fi; \ - done; \ - echo " "; \ - fi - cd tools; $(MAKE) $(MFLAGS) all sslapd: version.o $(LTLINK) -static -o $@ $(OBJS) version.o $(LIBS) $(WRAP_LIBS) +tools $(SLAPD_DYNAMIC_BACKENDS): slapd + cd $@; $(MAKE) $(MFLAGS) all + @touch $@ + # # In Windows, dynamic backends have to be built after slapd. For this # reason, we only build static backends now and dynamic backends later. @@ -332,7 +325,7 @@ install-slapd: FORCE fi; \ done -all-cffiles: slapd +all-cffiles: slapd $(SLAPD_DYNAMIC_BACKENDS) tools @if test $(PLAT) = NT; then \ sysconfdir=`cygpath -w $(sysconfdir) | \ $(SED) -e 's/\\\\/\\\\\\\\\\\\\\\\/g'`; \ diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 6e7cb7e443..a907872273 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -398,10 +398,8 @@ static int slap_mods2entry( for ( i = 0; mods->sml_bvalues[i].bv_val != NULL; i++ ) { /* test asserted values against themselves */ for( j = 0; j < i; j++ ) { - int rc = ber_bvcmp( &mods->sml_bvalues[i], - &mods->sml_bvalues[j] ); - - if( rc == 0 ) { + if ( bvmatch( &mods->sml_bvalues[i], + &mods->sml_bvalues[j] ) ) { /* value exists already */ snprintf( textbuf, textlen, "%s: value #%d provided more than once", @@ -412,34 +410,16 @@ static int slap_mods2entry( } } else { - for ( i = 0; mods->sml_bvalues[i].bv_val != NULL; i++ ) { - int rc, match; - const char *text = NULL; - struct berval asserted; - - rc = value_normalize( mods->sml_desc, - SLAP_MR_EQUALITY, - &mods->sml_bvalues[i], - &asserted, - &text ); - - if( rc != LDAP_SUCCESS ) return rc; - - for ( j = 0; j < i; j++ ) { - int rc = value_match( &match, mods->sml_desc, mr, - SLAP_MR_VALUE_SYNTAX_MATCH, - &mods->sml_bvalues[j], &asserted, &text ); - - if( rc == LDAP_SUCCESS && match == 0 ) { - free( asserted.bv_val ); - snprintf( textbuf, textlen, - "%s: value #%d provided more than once", - mods->sml_desc->ad_cname.bv_val, j ); - return LDAP_TYPE_OR_VALUE_EXISTS; - } - } - - free( asserted.bv_val ); + int rc; + const char *text = NULL; + char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' }; + + rc = modify_check_duplicates( mods->sml_desc, mr, + NULL, mods->sml_bvalues, + &text, textbuf, sizeof( textbuf ) ); + + if ( rc != LDAP_SUCCESS ) { + return rc; } } } diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index b5f3fe0440..987eb8832c 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -585,7 +585,7 @@ be_issuffix( int i; for ( i = 0; be->be_nsuffix != NULL && be->be_nsuffix[i].bv_val != NULL; i++ ) { - if ( ber_bvcmp( &be->be_nsuffix[i], bvsuffix ) == 0 ) { + if ( bvmatch( &be->be_nsuffix[i], bvsuffix ) ) { return( 1 ); } } @@ -821,7 +821,7 @@ backend_check_restrictions( { struct berval bv = BER_BVC( LDAP_EXOP_START_TLS ); - if( ber_bvcmp( opdata, &bv ) == 0 ) { + if( bvmatch( opdata, &bv ) ) { session++; starttls++; break; @@ -830,7 +830,7 @@ backend_check_restrictions( { struct berval bv = BER_BVC( LDAP_EXOP_X_WHO_AM_I ); - if( ber_bvcmp( opdata, &bv ) == 0 ) { + if( bvmatch( opdata, &bv ) ) { break; } } diff --git a/servers/slapd/mods.c b/servers/slapd/mods.c index f57cf41dab..348e7d3179 100644 --- a/servers/slapd/mods.c +++ b/servers/slapd/mods.c @@ -18,6 +18,211 @@ #include "slap.h" +#undef QUICK_DIRTY_DUPLICATE_CHECK + +int +modify_check_duplicates( + AttributeDescription *ad, + MatchingRule *mr, + BerVarray vals, + BerVarray mods, + const char **text, + char *textbuf, size_t textlen ) +{ + int i, j, numvals = 0, nummods, + rc = LDAP_SUCCESS; + BerVarray nvals = NULL, nmods; + + /* + * FIXME: better do the following + * + * - count the existing values + * - count the new values + * + * - if the existing values are less than the new ones { + * - normalize all the existing values + * - for each new value { + * - normalize + * - check with existing + * - cross-check with already normalized new vals + * } + * } else { + * - for each new value { + * - normalize + * - cross-check with already normalized new vals + * } + * - for each existing value { + * - normalize + * - check with already normalized new values + * } + * } + * + * The first case is good when adding a lot of new values, + * and significantly at first import of values (e.g. adding + * a new group); the latter case seems to be quite important + * as well, because it is likely to be the most frequently + * used when administering the entry. The current + * implementation will always normalize all the existing + * values before checking. If there's no duplicate, the + * performances should not change; they will in case of error. + */ + + for ( nummods = 0; mods[ nummods ].bv_val != NULL; nummods++ ) + /* count new values */ ; + + if ( vals ) { + for ( numvals = 0; vals[ numvals ].bv_val != NULL; numvals++ ) + /* count existing values */ ; + } + + if ( numvals > 0 && numvals < nummods ) { + nvals = ch_calloc( numvals + 1, sizeof( struct berval ) ); + + /* normalize the existing values first */ + for ( j = 0; vals[ j ].bv_val != NULL; j++ ) { + rc = value_normalize( ad, SLAP_MR_EQUALITY, + &vals[ j ], &nvals[ j ], text ); + + /* existing attribute values must normalize */ + assert( rc == LDAP_SUCCESS ); + + if ( rc != LDAP_SUCCESS ) { + nvals[ j ].bv_val = NULL; + goto return_results; + } + } + nvals[ j ].bv_val = NULL; + } + + /* + * If the existing values are less than the new values, + * it is more convenient to normalize all the existing + * values and test each new value against them first, + * then to other already normalized values + */ + nmods = ch_calloc( nummods + 1, sizeof( struct berval ) ); + + for ( i = 0; mods[ i ].bv_val != NULL; i++ ) { + rc = value_normalize( ad, SLAP_MR_EQUALITY, + &mods[ i ], &nmods[ i ], text ); + + if ( rc != LDAP_SUCCESS ) { + nmods[ i ].bv_val = NULL; + goto return_results; + } + + if ( numvals > 0 && numvals < nummods ) { + for ( j = 0; nvals[ j ].bv_val; j++ ) { +#ifdef QUICK_DIRTY_DUPLICATE_CHECK + if ( bvmatch( &nmods[ i ], &nvals[ j ] ) ) { +#else /* !QUICK_DIRTY_DUPLICATE_CHECK */ + int match; + + rc = (mr->smr_match)( &match, + SLAP_MR_VALUE_SYNTAX_MATCH, + ad->ad_type->sat_syntax, + mr, &nmods[ i ], &nvals[ j ] ); + if ( rc != LDAP_SUCCESS ) { + nmods[ i + 1 ].bv_val = NULL; + goto return_results; + } + + if ( match == 0 ) { +#endif /* !QUICK_DIRTY_DUPLICATE_CHECK */ + snprintf( textbuf, textlen, + "%s: value #%d provided more than once", + ad->ad_cname.bv_val, i ); + rc = LDAP_TYPE_OR_VALUE_EXISTS; + nmods[ i + 1 ].bv_val = NULL; + goto return_results; + } + } + } + + for ( j = 0; j < i; j++ ) { +#ifdef QUICK_DIRTY_DUPLICATE_CHECK + if ( bvmatch( &nmods[ i ], &nmods[ j ] ) ) { +#else /* !QUICK_DIRTY_DUPLICATE_CHECK */ + int match; + + rc = (mr->smr_match)( &match, + SLAP_MR_VALUE_SYNTAX_MATCH, + ad->ad_type->sat_syntax, + mr, &nmods[ i ], &nmods[ j ] ); + if ( rc != LDAP_SUCCESS ) { + nmods[ i + 1 ].bv_val = NULL; + goto return_results; + } + + if ( match == 0 ) { +#endif /* !QUICK_DIRTY_DUPLICATE_CHECK */ + snprintf( textbuf, textlen, + "%s: value #%d provided more than once", + ad->ad_cname.bv_val, j ); + rc = LDAP_TYPE_OR_VALUE_EXISTS; + nmods[ i + 1 ].bv_val = NULL; + goto return_results; + } + } + } + nmods[ i ].bv_val = NULL; + + /* + * if new values are more than existing values, it is more + * convenient to normalize and check all new values first, + * then check each new value against existing values, which + * can be normalized in place + */ + + if ( numvals >= nummods ) { + for ( j = 0; vals[ j ].bv_val; j++ ) { + struct berval asserted; + + rc = value_normalize( ad, SLAP_MR_EQUALITY, + &vals[ j ], &asserted, text ); + + if ( rc != LDAP_SUCCESS ) { + goto return_results; + } + + for ( i = 0; nmods[ i ].bv_val; i++ ) { +#ifdef QUICK_DIRTY_DUPLICATE_CHECK + if ( bvmatch( &nmods[ i ], &asserted ) ) { +#else /* !QUICK_DIRTY_DUPLICATE_CHECK */ + int match; + + rc = (mr->smr_match)( &match, + SLAP_MR_VALUE_SYNTAX_MATCH, + ad->ad_type->sat_syntax, + mr, &nmods[ i ], &asserted ); + if ( rc != LDAP_SUCCESS ) { + goto return_results; + } + + if ( match == 0 ) { +#endif /* !QUICK_DIRTY_DUPLICATE_CHECK */ + snprintf( textbuf, textlen, + "%s: value #%d provided more than once", + ad->ad_cname.bv_val, j ); + rc = LDAP_TYPE_OR_VALUE_EXISTS; + goto return_results; + } + } + + } + } + +return_results:; + if ( nvals ) { + ber_bvarray_free( nvals ); + } + if ( nmods ) { + ber_bvarray_free( nmods ); + } + + return rc; +} + int modify_add_values( Entry *e, @@ -61,10 +266,9 @@ modify_add_values( /* test asserted values against existing values */ if( a ) { for( j = 0; a->a_vals[j].bv_val != NULL; j++ ) { - int rc = ber_bvcmp( &mod->sm_bvalues[i], - &a->a_vals[j] ); + if ( bvmatch( &mod->sm_bvalues[i], + &a->a_vals[j] ) ) { - if( rc == 0 ) { /* value exists already */ *text = textbuf; snprintf( textbuf, textlen, @@ -77,10 +281,9 @@ modify_add_values( /* test asserted values against themselves */ for( j = 0; j < i; j++ ) { - int rc = ber_bvcmp( &mod->sm_bvalues[i], - &mod->sm_bvalues[j] ); + if ( bvmatch( &mod->sm_bvalues[i], + &mod->sm_bvalues[j] ) ) { - if( rc == 0 ) { /* value exists already */ *text = textbuf; snprintf( textbuf, textlen, @@ -92,23 +295,56 @@ modify_add_values( } } else { - for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) { - int rc, match; - struct berval asserted; - rc = value_normalize( mod->sm_desc, - SLAP_MR_EQUALITY, - &mod->sm_bvalues[i], - &asserted, - text ); + /* + * The original code performs ( n ) normalizations + * and ( n * ( n - 1 ) / 2 ) matches, which hide + * the same number of normalizations. The new code + * performs the same number of normalizations ( n ) + * and ( n * ( n - 1 ) / 2 ) mem compares, far less + * expensive than an entire match, if a match is + * equivalent to a normalization and a mem compare ... + * + * This is far more memory expensive than the previous, + * but it can heavily improve performances when big + * chunks of data are added (typical example is a group + * with thousands of DN-syntax members; on my system: + * for members of 5-RDN DNs, + + members orig bvmatch (dirty) new + 1000 0m38.456s 0m0.553s 0m0.608s + 2000 2m33.341s 0m0.851s 0m1.003s + + * Moreover, 100 groups with 10000 members each were + * added in 37m27.933s (an analogous LDIF file was + * loaded into Active Directory in 38m28.682s, BTW). + * + * Maybe we could switch to the new algorithm when + * the number of values overcomes a given threshold? + */ + + int rc; + const char *text = NULL; + char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' }; + + if ( mod->sm_bvalues[ 1 ].bv_val == 0 ) { + if ( a != NULL ) { + struct berval asserted; + int i; + + rc = value_normalize( mod->sm_desc, SLAP_MR_EQUALITY, + &mod->sm_bvalues[ 0 ], &asserted, &text ); + + if ( rc != LDAP_SUCCESS ) { + return rc; + } - if( rc != LDAP_SUCCESS ) return rc; + for ( i = 0; a->a_vals[ i ].bv_val; i++ ) { + int match; - if( a ) { - for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) { - int rc = value_match( &match, mod->sm_desc, mr, + rc = value_match( &match, mod->sm_desc, mr, SLAP_MR_VALUE_SYNTAX_MATCH, - &a->a_vals[j], &asserted, text ); + &a->a_vals[ i ], &asserted, &text ); if( rc == LDAP_SUCCESS && match == 0 ) { free( asserted.bv_val ); @@ -117,18 +353,14 @@ modify_add_values( } } - for ( j = 0; j < i; j++ ) { - int rc = value_match( &match, mod->sm_desc, mr, - SLAP_MR_VALUE_SYNTAX_MATCH, - &mod->sm_bvalues[j], &asserted, text ); - - if( rc == LDAP_SUCCESS && match == 0 ) { - free( asserted.bv_val ); - return LDAP_TYPE_OR_VALUE_EXISTS; - } + } else { + rc = modify_check_duplicates( mod->sm_desc, mr, + a ? a->a_vals : NULL, mod->sm_bvalues, + &text, textbuf, sizeof( textbuf ) ); + + if ( rc != LDAP_SUCCESS ) { + return rc; } - - free( asserted.bv_val ); } } @@ -190,7 +422,11 @@ modify_delete_values( return LDAP_NO_SUCH_ATTRIBUTE; } - /* find each value to delete */ + /* find each value to delete + * + * FIXME: need to optimize this operation too, + * see modify_check_duplicates() + */ for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) { int rc; struct berval asserted; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index db7d7ba9fa..bde85b5368 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -570,6 +570,10 @@ LDAP_SLAPD_F( int ) slap_mods_opattrs( /* * mods.c */ +LDAP_SLAPD_F( int ) modify_check_duplicates( + AttributeDescription *ad, MatchingRule *mr, + BerVarray vals, BerVarray mods, + const char **text, char *textbuf, size_t textlen ); LDAP_SLAPD_F( int ) modify_add_values( Entry *e, Modification *mod, const char **text, char *textbuf, size_t textlen ); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index e0f796eaa9..798b40b9ba 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -224,19 +224,20 @@ typedef struct slap_ssf_set { #define SLAP_SCHERR_CLASS_BAD_SUP 4 #define SLAP_SCHERR_CLASS_DUP 5 #define SLAP_SCHERR_ATTR_NOT_FOUND 6 -#define SLAP_SCHERR_ATTR_BAD_USAGE 7 -#define SLAP_SCHERR_ATTR_BAD_SUP 8 -#define SLAP_SCHERR_ATTR_INCOMPLETE 9 -#define SLAP_SCHERR_ATTR_DUP 10 -#define SLAP_SCHERR_MR_NOT_FOUND 11 -#define SLAP_SCHERR_MR_INCOMPLETE 12 -#define SLAP_SCHERR_MR_DUP 13 -#define SLAP_SCHERR_SYN_NOT_FOUND 14 -#define SLAP_SCHERR_SYN_DUP 15 -#define SLAP_SCHERR_NO_NAME 16 -#define SLAP_SCHERR_NOT_SUPPORTED 17 -#define SLAP_SCHERR_BAD_DESCR 18 -#define SLAP_SCHERR_OIDM 19 +#define SLAP_SCHERR_ATTR_BAD_MR 7 +#define SLAP_SCHERR_ATTR_BAD_USAGE 8 +#define SLAP_SCHERR_ATTR_BAD_SUP 9 +#define SLAP_SCHERR_ATTR_INCOMPLETE 10 +#define SLAP_SCHERR_ATTR_DUP 11 +#define SLAP_SCHERR_MR_NOT_FOUND 12 +#define SLAP_SCHERR_MR_INCOMPLETE 13 +#define SLAP_SCHERR_MR_DUP 14 +#define SLAP_SCHERR_SYN_NOT_FOUND 15 +#define SLAP_SCHERR_SYN_DUP 16 +#define SLAP_SCHERR_NO_NAME 17 +#define SLAP_SCHERR_NOT_SUPPORTED 18 +#define SLAP_SCHERR_BAD_DESCR 19 +#define SLAP_SCHERR_OIDM 20 #define SLAP_SCHERR_LAST SLAP_SCHERR_OIDM typedef union slap_sockaddr { @@ -442,7 +443,7 @@ typedef struct slap_matching_rule { /* * null terminated list of syntaxes compatible with this syntax * note: when MS_EXT is set, this MUST NOT contain the assertion - * syntax of the rule. When MS_EXT is not set, it MAY. + * syntax of the rule. When MS_EXT is not set, it MAY. */ Syntax **smr_compat_syntaxes; @@ -1228,7 +1229,7 @@ struct slap_backend_db { #define SLAP_RESTRICT_OP_SEARCH 0x0080U #define SLAP_RESTRICT_OP_READS \ - ( SLAP_RESTRICT_OP_COMPARE \ + ( SLAP_RESTRICT_OP_COMPARE \ | SLAP_RESTRICT_OP_SEARCH ) #define SLAP_RESTRICT_OP_WRITES \ ( SLAP_RESTRICT_OP_ADD \ @@ -1270,7 +1271,7 @@ struct slap_backend_db { struct berval be_rootdn; /* the magic "root" name (DN) for this db */ struct berval be_rootndn; /* the magic "root" normalized name (DN) for this db */ struct berval be_rootpw; /* the magic "root" password for this db */ - unsigned int be_max_deref_depth; /* limit for depth of an alias deref */ + unsigned int be_max_deref_depth; /* limit for depth of an alias deref */ #define be_sizelimit be_def_limit.lms_s_soft #define be_timelimit be_def_limit.lms_t_soft struct slap_limits_set be_def_limit; /* default limits */ @@ -1343,13 +1344,13 @@ typedef int (BI_op_abandon) LDAP_P((BackendDB *bd, ber_int_t msgid)); typedef int (BI_op_extended) LDAP_P(( - BackendDB *be, - struct slap_conn *conn, - struct slap_op *op, + BackendDB *be, + struct slap_conn *conn, + struct slap_op *op, const char *reqoid, - struct berval * reqdata, + struct berval * reqdata, char **rspoid, - struct berval ** rspdata, + struct berval ** rspdata, LDAPControl *** rspctrls, const char ** text, BerVarray *refs )); @@ -1576,6 +1577,17 @@ typedef struct slap_op { ber_int_t o_pagedresults_size; PagedResultsState o_pagedresults_state; +#ifdef LDAP_CLIENT_UPDATE + char o_clientupdate; + char o_clientupdate_type; +#define SLAP_LCUP_NONE (0x0) +#define SLAP_LCUP_SYNC (0x1) +#define SLAP_LCUP_PERSIST (0x2) +#define SLAP_LCUP_SYNC_AND_PERSIST (0x3) + ber_int_t o_clientupdate_interval; + struct berval* o_clientupdate_state; +#endif + #ifdef LDAP_CONNECTIONLESS Sockaddr o_peeraddr; /* UDP peer address */ #endif @@ -1682,7 +1694,7 @@ typedef struct slap_conn { fprintf( stderr, (fmt), (connid), (opid), (arg1), (arg2), (arg3) );\ if ( ldap_syslog & (level) ) \ syslog( ldap_syslog_level, (fmt), (connid), (opid), (arg1), \ - (arg2), (arg3) ); \ + (arg2), (arg3) ); \ } while (0) #else #define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) diff --git a/servers/slapd/tools/Makefile.in b/servers/slapd/tools/Makefile.in index 98d17978e9..269b8d4908 100644 --- a/servers/slapd/tools/Makefile.in +++ b/servers/slapd/tools/Makefile.in @@ -29,6 +29,8 @@ XXLIBS = $(SLAPD_LIBS) \ $(LDIF_LIBS) $(LUTIL_LIBS) XXXLIBS = $(MODULES_LIBS) $(LTHREAD_LIBS) +STATIC_DEPENDS=@SLAPD_NO_STATIC@ ../libbackends.a + PROGRAMS=slapadd slapcat slapindex slappasswd SRCS = mimic.c slapcommon.c \ @@ -53,14 +55,14 @@ build-progs: $(PROGRAMS) # # SLAP Tools # -slapadd: slapadd.o ../libbackends.a $(SLAPOBJS) $(SLAPD_L) - $(LTLINK) -o $@ slapadd.o $(SLAPOBJS) ../libbackends.a $(LIBS) +slapadd: slapadd.o $(STATIC_DEPENDS) $(SLAPOBJS) $(SLAPD_L) + $(LTLINK) -o $@ slapadd.o $(SLAPOBJS) $(STATIC_DEPENDS) $(LIBS) -slapcat: slapcat.o ../libbackends.a $(SLAPOBJS) $(SLAPD_L) - $(LTLINK) -o $@ slapcat.o $(SLAPOBJS) ../libbackends.a $(LIBS) +slapcat: slapcat.o $(STATIC_DEPENDS) $(SLAPOBJS) $(SLAPD_L) + $(LTLINK) -o $@ slapcat.o $(SLAPOBJS) $(STATIC_DEPENDS) $(LIBS) -slapindex: slapindex.o ../libbackends.a $(SLAPOBJS) $(SLAPD_L) - $(LTLINK) -o $@ slapindex.o $(SLAPOBJS) ../libbackends.a $(LIBS) +slapindex: slapindex.o $(STATIC_DEPENDS) $(SLAPOBJS) $(SLAPD_L) + $(LTLINK) -o $@ slapindex.o $(SLAPOBJS) $(STATIC_DEPENDS) $(LIBS) slappasswd: slappasswd.o $(SLAPD_L) $(LTLINK) -o $@ slappasswd.o $(LIBS) -- 2.39.5