AC_PROG_LIBTOOL
LTSTATIC=""
-if test -z "$LTDYNAMIC" -a "${OPENLDAP_CVS}"; then
+if test -z "$LTDYNAMIC"; then
LTSTATIC="-static"
fi
AC_SUBST(LTSTATIC)dnl
exactly matches the
.BR domain
pattern.
+The
+.B domain
+of the contacting host is determined by performing a DNS reverse lookup.
+As this lookup can easily be spoofed, use of the
+.B domain
+statement is strongly discouraged. By default, reverse lookups are disabled.
.LP
The statement
.B set=<pattern>
set conditions within a particular database).
.TP
.B reverse-lookup on | off
-Enable/disable client name reverse lookup (default is
-.BR on
+Enable/disable client name unverified reverse lookup (default is
+.BR off
if compiled with --enable-rlookups).
.TP
.B rootDSE <file>
/* Define if you have the getpassphrase function. */
#undef HAVE_GETPASSPHRASE
+/* Define if you have the getpeereid function. */
+#undef HAVE_GETPEEREID
+
/* Define if you have the getpwnam function. */
#undef HAVE_GETPWNAM
/* Define if you have the send function. */
#undef HAVE_SEND
+/* Define if you have the sendmsg function. */
+#undef HAVE_SENDMSG
+
/* Define if you have the sendto function. */
#undef HAVE_SENDTO
/* Define if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define if you have the <sys/ucred.h> header file. */
+#undef HAVE_SYS_UCRED_H
+
/* Define if you have the <sys/un.h> header file. */
#undef HAVE_SYS_UN_H
/* define to support LAN Manager passwords */
#undef SLAPD_LMHASH
-/* set to the number of arguments ctime_r() expects */
-#undef CTIME_R_NARGS
-
-/* set to the number of arguments gethostbyname_r() expects */
-#undef GETHOSTBYNAME_R_NARGS
-
-/* set to the number of arguments gethostbyaddr_r() expects */
-#undef GETHOSTBYADDR_R_NARGS
-
/* if you have NT Threads */
#undef HAVE_NT_THREADS
/* define if you have (or want) no threads */
#undef NO_THREADS
+/* set to the number of arguments ctime_r() expects */
+#undef CTIME_R_NARGS
+
+/* set to the number of arguments gethostbyname_r() expects */
+#undef GETHOSTBYNAME_R_NARGS
+
+/* set to the number of arguments gethostbyaddr_r() expects */
+#undef GETHOSTBYADDR_R_NARGS
+
/* define if Berkeley DB has DB_THREAD support */
#undef HAVE_BERKELEY_DB_THREAD
/* define this to add syslog code */
#undef LDAP_SYSLOG
-/* define this to remove -lldap cache support */
-#undef LDAP_NOCACHE
-
/* define this for LDAP process title support */
#undef LDAP_PROCTITLE
schemaparse.c ad.c at.c mr.c syntax.c oc.c saslauthz.c \
oidm.c starttls.c index.c sets.c referral.c \
root_dse.c sasl.c module.c suffixalias.c mra.c mods.c \
- limits.c backglue.c operational.c matchedValues.c \
+ limits.c backglue.c operational.c matchedValues.c cancel.c \
$(@PLAT@_SRCS)
OBJS = main.o daemon.o connection.o search.o filter.o add.o cr.o \
schemaparse.o ad.o at.o mr.o syntax.o oc.o saslauthz.o \
oidm.o starttls.o index.o sets.o referral.o \
root_dse.o sasl.o module.o suffixalias.o mra.o mods.o \
- limits.o backglue.o operational.o matchedValues.o \
+ limits.o backglue.o operational.o matchedValues.o cancel.o \
$(@PLAT@_OBJS)
LDAP_INCDIR= ../../include
/* abandon.c - decode and handle an ldap abandon operation */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
done:
-#if LDAP_CLIENT_UPDATE
+#ifdef LDAP_CLIENT_UPDATE
for ( i = 0; i < nbackends; i++ ) {
if ( strncmp( backends[i].be_type, "bdb", 3 ) ) continue;
if ( bdb_abandon( &backends[i], conn, id ) == LDAP_SUCCESS ) {
/* acl.c - routines to parse and check acl's */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
slap_control_t control;
const char *attr;
regmatch_t matches[MAXREMATCHES];
+ int st_same_attr = 0;
+ int st_initialized = 0;
+ static AccessControlState state_init = ACL_STATE_INIT;
assert( e != NULL );
assert( desc != NULL );
assert( attr != NULL );
- if( state && state->as_recorded ) {
+ if( state && state->as_recorded && state->as_vd_ad==desc) {
if( state->as_recorded & ACL_STATE_RECORDED_NV &&
val == NULL )
{
{
return state->as_result;
}
+ st_same_attr = 1;
+ } if (state) {
+ state->as_vd_ad=desc;
}
#ifdef NEW_LOGGING
ret = 0;
control = ACL_BREAK;
- if( state && ( state->as_recorded & ACL_STATE_RECORDED_VD )) {
+ if( st_same_attr ) {
assert( state->as_vd_acl != NULL );
a = state->as_vd_acl;
#endif
}
+ if (state) {
+ if (state->as_vi_acl == a && (state->as_recorded & ACL_STATE_RECORDED_NV)) {
+ Debug( LDAP_DEBUG_ACL, "access_allowed: result from state (%s)\n", attr, 0, 0 );
+ return state->as_result;
+ } else if (!st_initialized) {
+ Debug( LDAP_DEBUG_ACL, "access_allowed: no res from state (%s)\n", attr, 0, 0);
+ *state = state_init;
+ state->as_vd_ad=desc;
+ st_initialized=1;
+ }
+ }
+
vd_access:
control = acl_mask( a, &mask, be, conn, op,
e, desc, val, matches, count, state );
done:
if( state != NULL ) {
+ /* If not value-dependent, save ACL in case of more attrs */
+ if ( !(state->as_recorded & ACL_STATE_RECORDED_VD) )
+ state->as_vi_acl = a;
state->as_recorded |= ACL_STATE_RECORDED;
state->as_result = ret;
}
}
if ( b->a_set_pat.bv_len != 0 ) {
- if (aci_match_set( &b->a_set_pat, be, e, conn, op, 0 ) == 0) {
+ struct berval bv;
+ char buf[ACL_BUF_SIZE];
+ if( b->a_set_style == ACL_STYLE_REGEX ){
+ bv.bv_len = sizeof(buf) - 1;
+ bv.bv_val = buf;
+ string_expand( &bv, &b->a_set_pat, e->e_ndn, matches );
+ }else{
+ bv = b->a_set_pat;
+ }
+ if (aci_match_set( &bv, be, e, conn, op, 0 ) == 0) {
continue;
}
}
)
{
struct berval *bv;
+ AccessControlState state = ACL_STATE_INIT;
assert( be != NULL );
}
for ( ; mlist != NULL; mlist = mlist->sml_next ) {
- static AccessControlState state_init = ACL_STATE_INIT;
- AccessControlState state;
-
/*
* no-user-modification operational attributes are ignored
* by ACL_WRITE checking as any found here are not provided
continue;
}
- state = state_init;
-
switch ( mlist->sml_op ) {
case LDAP_MOD_REPLACE:
/*
/* aclparse.c - routines to parse and check acl's */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
} else if ( strcasecmp( style, "one" ) == 0 ) {
a->acl_dn_style = ACL_STYLE_ONE;
ber_str2bv( right, 0, 1, &a->acl_dn_pat );
- } else if ( strcasecmp( style, "subtree" ) == 0 ) {
+ } else if ( strcasecmp( style, "subtree" ) == 0 || strcasecmp( style, "sub" ) == 0 ) {
a->acl_dn_style = ACL_STYLE_SUBTREE;
ber_str2bv( right, 0, 1, &a->acl_dn_pat );
} else if ( strcasecmp( style, "children" ) == 0 ) {
sty = ACL_STYLE_BASE;
} else if ( strcasecmp( style, "one" ) == 0 ) {
sty = ACL_STYLE_ONE;
- } else if ( strcasecmp( style, "subtree" ) == 0 ) {
+ } else if ( strcasecmp( style, "subtree" ) == 0 || strcasecmp( style, "sub" ) == 0 ) {
sty = ACL_STYLE_SUBTREE;
} else if ( strcasecmp( style, "children" ) == 0 ) {
sty = ACL_STYLE_CHILDREN;
"\t[aci=<attrname>]\n"
#endif
"\t[ssf=<n>] [transport_ssf=<n>] [tls_ssf=<n>] [sasl_ssf=<n>]\n"
- "<dnstyle> ::= regex | base | exact (alias of base) | one | sub | children\n"
+ "<dnstyle> ::= regex | base | exact (alias of base) | one | subtree | children\n"
"<style> ::= regex | base | exact (alias of base)\n"
"<groupflags> ::= R\n"
"<access> ::= [self]{<level>|<priv>}\n"
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* ad.c - routines for dealing with attribute descriptions */
#include "ldap_pvt.h"
#include "slap.h"
+typedef struct Attr_option {
+ struct berval name; /* option name or prefix */
+ int prefix; /* NAME is a tag and range prefix */
+} Attr_option;
+
+static Attr_option lang_option = { { sizeof("lang-")-1, "lang-" }, 1 };
+
+/* Options sorted by name, and number of options */
+static Attr_option *options = &lang_option;
+static int option_count = 1;
+
+static Attr_option *ad_find_option_definition( const char *opt, int optlen );
+
static int ad_keystring(
struct berval *bv )
{
}
}
-/* Is there an AttributeDescription for this type that uses this language? */
-AttributeDescription * ad_find_lang(
+/* Is there an AttributeDescription for this type that uses these tags? */
+AttributeDescription * ad_find_tags(
AttributeType *type,
- struct berval *lang )
+ struct berval *tags )
{
AttributeDescription *ad;
ldap_pvt_thread_mutex_lock( &type->sat_ad_mutex );
for (ad = type->sat_ad; ad; ad=ad->ad_next)
{
- if (ad->ad_lang.bv_len == lang->bv_len &&
- !strcasecmp(ad->ad_lang.bv_val, lang->bv_val))
+ if (ad->ad_tags.bv_len == tags->bv_len &&
+ !strcasecmp(ad->ad_tags.bv_val, tags->bv_val))
break;
}
ldap_pvt_thread_mutex_unlock( &type->sat_ad_mutex );
AttributeDescription desc, *d2;
char *name, *options;
char *opt, *next;
- int nlang;
- int langlen;
+ int ntags;
+ int tagslen;
/* hardcoded limits for speed */
-#define MAX_LANG_OPTIONS 128
- struct berval langs[MAX_LANG_OPTIONS+1];
-#define MAX_LANG_LEN 1024
- char langbuf[MAX_LANG_LEN];
+#define MAX_TAGGING_OPTIONS 128
+ struct berval tags[MAX_TAGGING_OPTIONS+1];
+#define MAX_TAGS_LEN 1024
+ char tagbuf[MAX_TAGS_LEN];
assert( ad != NULL );
assert( *ad == NULL ); /* temporary */
/*
* parse options in place
*/
- nlang = 0;
- memset( langs, 0, sizeof( langs ));
- langlen = 0;
+ ntags = 0;
+ memset( tags, 0, sizeof( tags ));
+ tagslen = 0;
for( opt=options; opt != NULL; opt=next ) {
int optlen;
desc.ad_flags |= SLAP_DESC_BINARY;
continue;
- } else if ( optlen >= sizeof("lang-")-1 &&
- strncasecmp( opt, "lang-", sizeof("lang-")-1 ) == 0 )
+ } else if ( ad_find_option_definition( opt, optlen ) )
{
int i;
if( opt[optlen-1] == '-' ) {
- desc.ad_flags |= SLAP_DESC_LANG_RANGE;
+ desc.ad_flags |= SLAP_DESC_TAG_RANGE;
}
- if( nlang >= MAX_LANG_OPTIONS ) {
- *text = "too many language options";
+ if( ntags >= MAX_TAGGING_OPTIONS ) {
+ *text = "too many tagging options";
return rtn;
}
* tags should be presented in sorted order,
* so run the array in reverse.
*/
- for( i=nlang-1; i>=0; i-- ) {
+ for( i=ntags-1; i>=0; i-- ) {
int rc;
- rc = strncasecmp( opt, langs[i].bv_val,
- (unsigned) optlen < langs[i].bv_len
- ? optlen : langs[i].bv_len );
+ rc = strncasecmp( opt, tags[i].bv_val,
+ (unsigned) optlen < tags[i].bv_len
+ ? optlen : tags[i].bv_len );
- if( rc == 0 && (unsigned)optlen == langs[i].bv_len ) {
+ if( rc == 0 && (unsigned)optlen == tags[i].bv_len ) {
/* duplicate (ignore) */
goto done;
} else if ( rc > 0 ||
- ( rc == 0 && (unsigned)optlen > langs[i].bv_len ))
+ ( rc == 0 && (unsigned)optlen > tags[i].bv_len ))
{
- AC_MEMCPY( &langs[i+1], &langs[i],
- (nlang-i)*sizeof(struct berval) );
- langs[i].bv_val = opt;
- langs[i].bv_len = optlen;
+ AC_MEMCPY( &tags[i+1], &tags[i],
+ (ntags-i)*sizeof(struct berval) );
+ tags[i].bv_val = opt;
+ tags[i].bv_len = optlen;
goto done;
}
}
- if( nlang ) {
- AC_MEMCPY( &langs[1], &langs[0],
- nlang*sizeof(struct berval) );
+ if( ntags ) {
+ AC_MEMCPY( &tags[1], &tags[0],
+ ntags*sizeof(struct berval) );
}
- langs[0].bv_val = opt;
- langs[0].bv_len = optlen;
+ tags[0].bv_val = opt;
+ tags[0].bv_len = optlen;
done:;
- langlen += optlen + 1;
- nlang++;
+ tagslen += optlen + 1;
+ ntags++;
} else {
*text = "unrecognized option";
}
}
- if( nlang > 0 ) {
+ if( ntags > 0 ) {
int i;
- if( langlen > MAX_LANG_LEN ) {
- *text = "language options too long";
+ if( tagslen > MAX_TAGS_LEN ) {
+ *text = "tagging options too long";
return rtn;
}
- desc.ad_lang.bv_val = langbuf;
- langlen = 0;
+ desc.ad_tags.bv_val = tagbuf;
+ tagslen = 0;
- for( i=0; i<nlang; i++ ) {
- AC_MEMCPY( &desc.ad_lang.bv_val[langlen],
- langs[i].bv_val, langs[i].bv_len );
+ for( i=0; i<ntags; i++ ) {
+ AC_MEMCPY( &desc.ad_tags.bv_val[tagslen],
+ tags[i].bv_val, tags[i].bv_len );
- langlen += langs[i].bv_len;
- desc.ad_lang.bv_val[langlen++] = ';';
+ tagslen += tags[i].bv_len;
+ desc.ad_tags.bv_val[tagslen++] = ';';
}
- desc.ad_lang.bv_val[--langlen] = '\0';
- desc.ad_lang.bv_len = langlen;
+ desc.ad_tags.bv_val[--tagslen] = '\0';
+ desc.ad_tags.bv_len = tagslen;
}
/* see if a matching description is already cached */
if( d2->ad_flags != desc.ad_flags ) {
continue;
}
- if( d2->ad_lang.bv_len != desc.ad_lang.bv_len ) {
+ if( d2->ad_tags.bv_len != desc.ad_tags.bv_len ) {
continue;
}
- if( d2->ad_lang.bv_len == 0 ) {
+ if( d2->ad_tags.bv_len == 0 ) {
break;
}
- if( strncasecmp( d2->ad_lang.bv_val, desc.ad_lang.bv_val,
- desc.ad_lang.bv_len ) == 0 )
+ if( strncasecmp( d2->ad_tags.bv_val, desc.ad_tags.bv_val,
+ desc.ad_tags.bv_len ) == 0 )
{
break;
}
for (d2 = desc.ad_type->sat_ad; d2; d2=d2->ad_next) {
if (d2->ad_flags != desc.ad_flags)
continue;
- if (d2->ad_lang.bv_len != desc.ad_lang.bv_len)
+ if (d2->ad_tags.bv_len != desc.ad_tags.bv_len)
continue;
- if (d2->ad_lang.bv_len == 0)
+ if (d2->ad_tags.bv_len == 0)
break;
- if (strncasecmp(d2->ad_lang.bv_val, desc.ad_lang.bv_val,
- desc.ad_lang.bv_len) == 0)
+ if (strncasecmp(d2->ad_tags.bv_val, desc.ad_tags.bv_val,
+ desc.ad_tags.bv_len) == 0)
break;
}
if (d2) {
/* Allocate a single contiguous block. If there are no
* options, we just need space for the AttrDesc structure.
* Otherwise, we need to tack on the full name length +
- * options length.
+ * options length, + maybe tagging options length again.
*/
- if (desc.ad_lang.bv_len || desc.ad_flags != SLAP_DESC_NONE) {
- dlen = desc.ad_type->sat_cname.bv_len;
- if (desc.ad_lang.bv_len) {
- dlen += 1+desc.ad_lang.bv_len;
+ if (desc.ad_tags.bv_len || desc.ad_flags != SLAP_DESC_NONE) {
+ dlen = desc.ad_type->sat_cname.bv_len + 1;
+ if (desc.ad_tags.bv_len) {
+ dlen += 1+desc.ad_tags.bv_len;
}
if( slap_ad_is_binary( &desc ) ) {
- dlen += sizeof(";binary")-1;
+ dlen += sizeof(";binary")+desc.ad_tags.bv_len;
}
}
- d2 = ch_malloc(sizeof(AttributeDescription) + dlen + 1);
+ d2 = ch_malloc(sizeof(AttributeDescription) + dlen);
d2->ad_type = desc.ad_type;
d2->ad_flags = desc.ad_flags;
d2->ad_cname.bv_len = desc.ad_type->sat_cname.bv_len;
- d2->ad_lang.bv_len = desc.ad_lang.bv_len;
+ d2->ad_tags.bv_len = desc.ad_tags.bv_len;
if (dlen == 0) {
d2->ad_cname.bv_val = d2->ad_type->sat_cname.bv_val;
- d2->ad_lang.bv_val = NULL;
+ d2->ad_tags.bv_val = NULL;
} else {
+ char *cp, *op, *lp;
+ int j;
d2->ad_cname.bv_val = (char *)(d2+1);
strcpy(d2->ad_cname.bv_val, d2->ad_type->sat_cname.bv_val);
+ cp = d2->ad_cname.bv_val + d2->ad_cname.bv_len;
if( slap_ad_is_binary( &desc ) ) {
- strcpy(d2->ad_cname.bv_val+d2->ad_cname.bv_len,
- ";binary");
- d2->ad_cname.bv_len += sizeof(";binary")-1;
+ op = cp;
+ lp = NULL;
+ if( desc.ad_tags.bv_len ) {
+ lp = desc.ad_tags.bv_val;
+ while( strncasecmp(lp, "binary", sizeof("binary")-1) < 0
+ && (lp = strchr( lp, ';' )) != NULL )
+ ++lp;
+ if( lp != desc.ad_tags.bv_val ) {
+ *cp++ = ';';
+ j = (lp
+ ? lp - desc.ad_tags.bv_val - 1
+ : strlen( desc.ad_tags.bv_val ));
+ strncpy(cp, desc.ad_tags.bv_val, j);
+ cp += j;
+ }
+ }
+ strcpy(cp, ";binary");
+ cp += sizeof(";binary")-1;
+ if( lp != NULL ) {
+ *cp++ = ';';
+ strcpy(cp, lp);
+ cp += strlen( cp );
+ }
+ d2->ad_cname.bv_len = cp - d2->ad_cname.bv_val;
+ if( desc.ad_tags.bv_len )
+ ldap_pvt_str2lower(op);
+ j = 1;
+ } else {
+ j = 0;
}
- if( d2->ad_lang.bv_len ) {
- d2->ad_cname.bv_val[d2->ad_cname.bv_len++]=';';
- d2->ad_lang.bv_val = d2->ad_cname.bv_val+
- d2->ad_cname.bv_len;
- strncpy(d2->ad_lang.bv_val,desc.ad_lang.bv_val,
- d2->ad_lang.bv_len);
- d2->ad_lang.bv_val[d2->ad_lang.bv_len] = '\0';
- ldap_pvt_str2lower(d2->ad_lang.bv_val);
- d2->ad_cname.bv_len += d2->ad_lang.bv_len;
+ if( desc.ad_tags.bv_len ) {
+ lp = d2->ad_cname.bv_val + d2->ad_cname.bv_len + j;
+ if ( j == 0 )
+ *lp++ = ';';
+ d2->ad_tags.bv_val = lp;
+ strcpy(lp, desc.ad_tags.bv_val);
+ ldap_pvt_str2lower(lp);
+ if( j == 0 )
+ d2->ad_cname.bv_len += 1 + desc.ad_tags.bv_len;
}
}
/* Add new desc to list. We always want the bare Desc with
return LDAP_SUCCESS;
}
-static int is_ad_sublang(
- struct berval *sublangbv,
- struct berval *suplangbv )
+static int is_ad_subtags(
+ struct berval *subtagsbv,
+ struct berval *suptagsbv )
{
- const char *suplang, *supp, *supdelimp;
- const char *sublang, *subp, *subdelimp;
+ const char *suptags, *supp, *supdelimp;
+ const char *subtags, *subp, *subdelimp;
int suplen, sublen;
- if( suplangbv->bv_len == 0 ) return 1;
- if( sublangbv->bv_len == 0 ) return 0;
+ if( suptagsbv->bv_len == 0 ) return 1;
+ if( subtagsbv->bv_len == 0 ) return 0;
- sublang =sublangbv->bv_val;
- suplang =suplangbv->bv_val;
+ subtags =subtagsbv->bv_val;
+ suptags =suptagsbv->bv_val;
- for( supp=suplang ; supp; supp=supdelimp ) {
+ for( supp=suptags ; supp; supp=supdelimp ) {
supdelimp = strchrlen( supp, ';', &suplen );
if( supdelimp ) supdelimp++;
- for( subp=sublang ; subp; subp=subdelimp ) {
+ for( subp=subtags ; subp; subp=subdelimp ) {
subdelimp = strchrlen( subp, ';', &sublen );
if( subdelimp ) subdelimp++;
}
/* ensure sub does support all flags of super */
- lr = sub->ad_lang.bv_len ? SLAP_DESC_LANG_RANGE : 0;
+ lr = sub->ad_tags.bv_len ? SLAP_DESC_TAG_RANGE : 0;
if(( super->ad_flags & ( sub->ad_flags | lr )) != super->ad_flags ) {
return 0;
}
- /* check for language tags */
- if ( !is_ad_sublang( &sub->ad_lang, &super->ad_lang )) {
+ /* check for tagging options */
+ if ( !is_ad_subtags( &sub->ad_tags, &super->ad_tags )) {
return 0;
}
bv->bv_len);
desc->ad_flags = SLAP_DESC_NONE;
- desc->ad_lang.bv_val = NULL;
- desc->ad_lang.bv_len = 0;
+ desc->ad_tags.bv_val = NULL;
+ desc->ad_tags.bv_len = 0;
desc->ad_cname.bv_len = bv->bv_len;
desc->ad_cname.bv_val = (char *)(desc+1);
return( an );
}
+
+/* Define an attribute option. */
+int
+ad_define_option( const char *name, const char *fname, int lineno )
+{
+ int i;
+ unsigned int optlen;
+
+ if ( options == &lang_option ) {
+ options = NULL;
+ option_count = 0;
+ }
+ if ( name == NULL )
+ return 0;
+
+ optlen = 0;
+ do {
+ if ( !DESC_CHAR( name[optlen] ) ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: illegal option name \"%s\"\n",
+ fname, lineno, name );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: illegal option name \"%s\"\n",
+ fname, lineno, name );
+#endif
+ return 1;
+ }
+ } while ( name[++optlen] );
+
+ options = ch_realloc( options,
+ (option_count+1) * sizeof(Attr_option) );
+
+ if ( strcasecmp( name, "binary" ) == 0
+ || ad_find_option_definition( name, optlen ) ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: option \"%s\" is already defined\n",
+ fname, lineno, name );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: option \"%s\" is already defined\n",
+ fname, lineno, name );
+#endif
+ return 1;
+ }
+
+ for ( i = option_count; i; --i ) {
+ if ( strcasecmp( name, options[i-1].name.bv_val ) >= 0 )
+ break;
+ options[i] = options[i-1];
+ }
+
+ options[i].name.bv_val = ch_strdup( name );
+ options[i].name.bv_len = optlen;
+ options[i].prefix = (name[optlen-1] == '-');
+
+ if ( i != option_count &&
+ options[i].prefix &&
+ optlen < options[i+1].name.bv_len &&
+ strncasecmp( name, options[i+1].name.bv_val, optlen ) == 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: option \"%s\" overrides previous option\n",
+ fname, lineno, name );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: option \"%s\" overrides previous option\n",
+ fname, lineno, name );
+#endif
+ return 1;
+ }
+
+ option_count++;
+ return 0;
+}
+
+/* Find the definition of the option name or prefix matching the arguments */
+static Attr_option *
+ad_find_option_definition( const char *opt, int optlen )
+{
+ int top = 0, bot = option_count;
+ while ( top < bot ) {
+ int mid = (top + bot) / 2;
+ int mlen = options[mid].name.bv_len;
+ char *mname = options[mid].name.bv_val;
+ int j;
+ if ( optlen < mlen ) {
+ j = strncasecmp( opt, mname, optlen ) - 1;
+ } else {
+ j = strncasecmp( opt, mname, mlen );
+ if ( j==0 && (optlen==mlen || options[mid].prefix) )
+ return &options[mid];
+ }
+ if ( j < 0 )
+ bot = mid;
+ else
+ top = mid + 1;
+ }
+ return NULL;
+}
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/*
#include "ldap_pvt.h"
#include "slap.h"
-static int slap_mods2entry(
- Modifications *mods,
- Entry **e,
- int repl_user,
- const char **text,
- char *textbuf, size_t textlen );
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+static Slapi_PBlock *initAddPlugin( Backend *be, Connection *conn, Operation *op,
+ struct berval *dn, Entry *e, int manageDSAit );
+static int doPreAddPluginFNs( Backend *be, Slapi_PBlock *pb );
+static void doPostAddPluginFNs( Backend *be, Slapi_PBlock *pb );
+#endif /* LDAP_SLAPI */
int
do_add( Connection *conn, Operation *op )
const char *text;
int rc = LDAP_SUCCESS;
int manageDSAit;
+#ifdef LDAP_SLAPI
+ Slapi_PBlock *pb = NULL;
+#endif /* LDAP_SLAPI */
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ENTRY, "do_add: conn %d enter\n", conn->c_connid,0,0 );
goto done;
}
+#ifdef LDAP_SLAPI
+ pb = initAddPlugin( be, conn, op, &dn, e, manageDSAit );
+#endif /* LDAP_SLAPI */
+
/*
* do the add if 1 && (2 || 3)
* 1) there is an add function implemented in this backend;
goto done;
}
+#ifdef LDAP_SLAPI
+ /*
+ * Call the preoperation plugin here, because the entry
+ * will actually contain something.
+ */
+ rc = doPreAddPluginFNs( be, pb );
+ if ( rc != LDAP_SUCCESS ) {
+ /* plugin will have sent result */
+ goto done;
+ }
+#endif /* LDAP_SLAPI */
+
if ( (*be->be_add)( be, conn, op, e ) == 0 ) {
#ifdef SLAPD_MULTIMASTER
if ( !repl_user )
#ifndef SLAPD_MULTIMASTER
} else {
- BerVarray defref = be->be_update_refs
+ BerVarray defref;
+ BerVarray ref;
+#ifdef LDAP_SLAPI
+ /*
+ * SLAPI_ADD_ENTRY will be empty, but this may be acceptable
+ * on replicas (for now, it involves the minimum code intrusion).
+ */
+ rc = doPreAddPluginFNs( be, pb );
+ if ( rc != LDAP_SUCCESS ) {
+ /* plugin will have sent result */
+ goto done;
+ }
+#endif /* LDAP_SLAPI */
+
+ defref = be->be_update_refs
? be->be_update_refs : default_referral;
- BerVarray ref = referral_rewrite( defref,
+ ref = referral_rewrite( defref,
NULL, &e->e_name, LDAP_SCOPE_DEFAULT );
send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL, NULL,
ref ? ref : defref, NULL );
if ( ref ) ber_bvarray_free( ref );
-#endif
+#endif /* SLAPD_MULTIMASTER */
}
} else {
+#ifdef LDAP_SLAPI
+ rc = doPreAddPluginFNs( be, pb );
+ if ( rc != LDAP_SUCCESS ) {
+ /* plugin will have sent result */
+ goto done;
+ }
+#endif
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO,
"do_add: conn %d no backend support\n", conn->c_connid, 0, 0 );
NULL, "operation not supported within namingContext", NULL, NULL );
}
+#ifdef LDAP_SLAPI
+ doPostAddPluginFNs( be, pb );
+#endif /* LDAP_SLAPI */
+
done:
if( modlist != NULL ) {
slap_mods_free( modlist );
return rc;
}
-static int slap_mods2entry(
+int
+slap_mods2entry(
Modifications *mods,
Entry **e,
int repl_user,
char textbuf[ SLAP_TEXT_BUFLEN ] = { '\0' };
rc = modify_check_duplicates( mods->sml_desc, mr,
- NULL, mods->sml_bvalues,
+ NULL, mods->sml_bvalues, 0,
&text, textbuf, sizeof( textbuf ) );
if ( rc != LDAP_SUCCESS ) {
return LDAP_SUCCESS;
}
+
+#ifdef LDAP_SLAPI
+static Slapi_PBlock *initAddPlugin( Backend *be, Connection *conn, Operation *op,
+ struct berval *dn, Entry *e, int manageDSAit )
+{
+ Slapi_PBlock *pb;
+
+ pb = op->o_pb;
+
+ slapi_x_backend_set_pb( pb, be );
+ slapi_x_connection_set_pb( pb, conn );
+ slapi_x_operation_set_pb( pb, op );
+
+ slapi_pblock_set( pb, SLAPI_ADD_TARGET, (void *)dn->bv_val );
+ slapi_pblock_set( pb, SLAPI_ADD_ENTRY, (void *)e );
+ slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
+
+ return pb;
+}
+
+static int doPreAddPluginFNs( Backend *be, Slapi_PBlock *pb )
+{
+ int rc;
+
+ rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_ADD_FN, pb );
+ if ( rc != 0 ) {
+ /*
+ * A preoperation plugin failure will abort the
+ * entire operation.
+ */
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_add: add preoperation plugin failed\n",
+ 0, 0, 0);
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_add: add preoperation plugin failed.\n",
+ 0, 0, 0);
+ if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0 )
+ rc = LDAP_OTHER;
+#endif
+ } else {
+ rc = LDAP_SUCCESS;
+ }
+
+ return rc;
+}
+
+static void doPostAddPluginFNs( Backend *be, Slapi_PBlock *pb )
+{
+ int rc;
+
+ rc = doPluginFNs( be, SLAPI_PLUGIN_POST_ADD_FN, pb );
+ if ( rc != 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_add: add postoperation plugin failed\n",
+ 0, 0, 0);
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_add: add preoperation plugin failed.\n",
+ 0, 0, 0);
+#endif
+ }
+}
+#endif /* LDAP_SLAPI */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* at.c - routines for dealing with attribute types */
};
static Avlnode *attr_index = NULL;
-static AttributeType *attr_list = NULL;
+static LDAP_SLIST_HEAD(ATList, slap_attribute_type) attr_list
+ = LDAP_SLIST_HEAD_INITIALIZER(&attr_list);
static int
attr_index_cmp(
- struct aindexrec *air1,
- struct aindexrec *air2
+ const void *v_air1,
+ const void *v_air2
)
{
+ const struct aindexrec *air1 = v_air1;
+ const struct aindexrec *air2 = v_air2;
int i = air1->air_name.bv_len - air2->air_name.bv_len;
if (i)
return i;
static int
attr_index_name_cmp(
- struct berval *type,
- struct aindexrec *air
+ const void *v_type,
+ const void *v_air
)
{
+ const struct berval *type = v_type;
+ const struct aindexrec *air = v_air;
int i = type->bv_len - air->air_name.bv_len;
if (i)
return i;
{
struct aindexrec *air;
- air = (struct aindexrec *) avl_find( attr_index, name,
- (AVL_CMP) attr_index_name_cmp );
+ air = avl_find( attr_index, name, attr_index_name_cmp );
return air != NULL ? air->air_at : NULL;
}
void
at_destroy( void )
{
- AttributeType *a, *n;
+ AttributeType *a;
avl_free(attr_index, ldap_memfree);
- for (a=attr_list; a; a=n) {
- n = a->sat_next;
+ while( !LDAP_SLIST_EMPTY(&attr_list) ) {
+ a = LDAP_SLIST_FIRST(&attr_list);
+ LDAP_SLIST_REMOVE_HEAD(&attr_list, sat_next);
+
if (a->sat_subtypes) ldap_memfree(a->sat_subtypes);
ad_destroy(a->sat_ad);
ldap_pvt_thread_mutex_destroy(&a->sat_ad_mutex);
ldap_attributetype_free((LDAPAttributeType *)a);
}
- if ( slap_schema.si_at_undefined )
+
+ if ( slap_schema.si_at_undefined ) {
ad_destroy(slap_schema.si_at_undefined->sat_ad);
+ }
}
int
{
assert( at );
- *at = attr_list;
+ *at = LDAP_SLIST_FIRST(&attr_list);
return (*at != NULL);
}
#if 1 /* pedantic check */
{
- AttributeType *tmp;
+ AttributeType *tmp = NULL;
- for ( tmp = attr_list; tmp; tmp = tmp->sat_next ) {
+ LDAP_SLIST_FOREACH(tmp,&attr_list,sat_next) {
if ( tmp == *at ) {
break;
}
}
#endif
- *at = (*at)->sat_next;
+ *at = LDAP_SLIST_NEXT(*at,sat_next);
return (*at != NULL);
}
const char **err
)
{
- AttributeType **atp;
struct aindexrec *air;
char **names;
- atp = &attr_list;
- while ( *atp != NULL ) {
- atp = &(*atp)->sat_next;
- }
- *atp = sat;
+ LDAP_SLIST_INSERT_HEAD( &attr_list, sat, sat_next );
if ( sat->sat_oid ) {
air = (struct aindexrec *)
air->air_name.bv_len = strlen(sat->sat_oid);
air->air_at = sat;
if ( avl_insert( &attr_index, (caddr_t) air,
- (AVL_CMP) attr_index_cmp,
- (AVL_DUP) avl_dup_error ) ) {
+ attr_index_cmp, avl_dup_error ) ) {
*err = sat->sat_oid;
ldap_memfree(air);
return SLAP_SCHERR_ATTR_DUP;
air->air_name.bv_len = strlen(*names);
air->air_at = sat;
if ( avl_insert( &attr_index, (caddr_t) air,
- (AVL_CMP) attr_index_cmp,
- (AVL_DUP) avl_dup_error ) ) {
+ attr_index_cmp, avl_dup_error ) ) {
*err = *names;
ldap_memfree(air);
return SLAP_SCHERR_ATTR_DUP;
/* collective attributes cannot be single-valued */
return SLAP_SCHERR_ATTR_BAD_USAGE;
}
-
- /* collective attributes not supported */
- return SLAP_SCHERR_NOT_SUPPORTED;
}
sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
#ifdef LDAP_DEBUG
static int
-at_index_printnode( struct aindexrec *air )
+at_index_printnode( void *v_air, void *ignore )
{
-
+ struct aindexrec *air = v_air;
printf("%s = %s\n",
air->air_name.bv_val,
ldap_attributetype2str(&air->air_at->sat_atype) );
at_index_print( void )
{
printf("Printing attribute type index:\n");
- (void) avl_apply( attr_index, (AVL_APPLY) at_index_printnode,
- 0, -1, AVL_INORDER );
+ (void) avl_apply( attr_index, at_index_printnode, 0, -1, AVL_INORDER );
}
#endif
vals[1].bv_val = NULL;
- for ( at = attr_list; at; at = at->sat_next ) {
+ LDAP_SLIST_FOREACH(at,&attr_list,sat_next) {
if( at->sat_flags & SLAP_AT_HIDE ) continue;
if ( ldap_attributetype2bv( &at->sat_atype, vals ) == NULL ) {
add.c bind.c compare.c delete.c modify.c modrdn.c search.c \
extended.c passwd.c referral.c attribute.c group.c operational.c \
attr.c index.c key.c dbcache.c filterindex.c \
- dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c lcup.c
+ dn2entry.c dn2id.c error.c id2entry.c idl.c nextid.c cache.c psearch.c
OBJS = init.lo tools.lo config.lo \
add.lo bind.lo compare.lo delete.lo modify.lo modrdn.lo search.lo \
extended.lo passwd.lo referral.lo attribute.lo group.lo operational.lo \
attr.lo index.lo key.lo dbcache.lo filterindex.lo \
- dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo lcup.lo
+ dn2entry.lo dn2id.lo error.lo id2entry.lo idl.lo nextid.lo cache.lo psearch.lo
LDAP_INCDIR= ../../../include
LDAP_LIBDIR= ../../../libraries
/* add.c - ldap BerkeleyDB back-end add routine */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#ifdef BDB_SUBENTRIES
int subentry;
#endif
- u_int32_t locker;
+ u_int32_t locker = 0;
DB_LOCK lock;
#if 0
u_int32_t lockid;
#endif
int noop = 0;
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
Operation* ps_list;
#endif
opinfo.boi_bdb = be;
opinfo.boi_txn = ltid;
+ opinfo.boi_locker = locker;
opinfo.boi_err = 0;
op->o_private = &opinfo;
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
if ( rc == LDAP_SUCCESS && !noop ) {
LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
- bdb_psearch( be, conn, op, ps_list, e, LCUP_PSEARCH_BY_ADD );
+ bdb_psearch( be, conn, op, ps_list, e, LDAP_PSEARCH_BY_ADD );
}
}
#endif /* LDAP_CLIENT_UPDATE */
/* attr.c - backend routines for dealing with attributes */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
static int
ainfo_type_cmp(
- AttributeDescription *desc,
- AttrInfo *a
+ const void *v_desc,
+ const void *v_a
)
{
+ const AttributeDescription *desc = v_desc;
+ const AttrInfo *a = v_a;
return desc - a->ai_desc;
}
static int
ainfo_cmp(
- AttrInfo *a,
- AttrInfo *b
+ const void *v_a,
+ const void *v_b
)
{
+ const AttrInfo *a = v_a, *b = v_b;
return a->ai_desc - b->ai_desc;
}
{
AttrInfo *a;
- a = (AttrInfo *) avl_find( bdb->bi_attrs, desc,
- (AVL_CMP) ainfo_type_cmp );
+ a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
*indexmask = a != NULL ? a->ai_indexmask : 0;
}
a->ai_indexmask = mask;
rc = avl_insert( &bdb->bi_attrs, (caddr_t) a,
- (AVL_CMP) ainfo_cmp, (AVL_DUP) avl_dup_error );
+ ainfo_cmp, avl_dup_error );
if( rc ) {
fprintf( stderr, "%s: line %d: duplicate index definition "
/* attribute.c - bdb backend acl attribute routine */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
const char *entry_at_name = entry_at->ad_cname.bv_val;
AccessControlState acl_state = ACL_STATE_INIT;
- u_int32_t locker;
+ u_int32_t locker = 0;
DB_LOCK lock;
+ int free_lock_id = 0;
#ifdef NEW_LOGGING
LDAP_LOG( BACK_BDB, ARGS,
- "bdb_attribute: gr dn: \"%s\"\n", entry_ndn->bv_val, 0, 0 );
+ "bdb_attribute: gr ndn: \"%s\"\n", entry_ndn->bv_val, 0, 0 );
LDAP_LOG( BACK_BDB, ARGS,
"bdb_attribute: at: \"%s\"\n", entry_at_name, 0, 0);
- LDAP_LOG( BACK_BDB, ARGS, "bdb_attribute: tr dn: \"%s\"\n",
+ LDAP_LOG( BACK_BDB, ARGS, "bdb_attribute: tr ndn: \"%s\"\n",
target ? target->e_ndn : "", 0, 0 );
#else
Debug( LDAP_DEBUG_ARGS,
- "=> bdb_attribute: gr dn: \"%s\"\n",
+ "=> bdb_attribute: gr ndn: \"%s\"\n",
entry_ndn->bv_val, 0, 0 );
Debug( LDAP_DEBUG_ARGS,
"=> bdb_attribute: at: \"%s\"\n",
entry_at_name, 0, 0 );
Debug( LDAP_DEBUG_ARGS,
- "=> bdb_attribute: tr dn: \"%s\"\n",
+ "=> bdb_attribute: tr ndn: \"%s\"\n",
target ? target->e_ndn : "", 0, 0 );
#endif
if( op ) boi = (struct bdb_op_info *) op->o_private;
if( boi != NULL && be == boi->boi_bdb ) {
txn = boi->boi_txn;
+ locker = boi->boi_locker;
}
if ( txn != NULL ) {
locker = TXN_ID ( txn );
- } else {
+ } else if ( !locker ) {
rc = LOCK_ID ( bdb->bi_dbenv, &locker );
+ free_lock_id = 1;
switch(rc) {
case 0:
break;
case DB_LOCK_NOTGRANTED:
goto dn2entry_retry;
default:
- if( txn != NULL ) {
- boi->boi_err = rc;
- }
- else {
+ boi->boi_err = rc;
+ if ( free_lock_id ) {
LOCK_ID_FREE( bdb->bi_dbenv, locker );
}
return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY;
"=> bdb_attribute: cannot find entry: \"%s\"\n",
entry_ndn->bv_val, 0, 0 );
#endif
- if ( txn == NULL ) {
+ if ( free_lock_id ) {
LOCK_ID_FREE( bdb->bi_dbenv, locker );
}
return LDAP_NO_SUCH_OBJECT;
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
}
- if ( txn == NULL ) {
+ if ( free_lock_id ) {
LOCK_ID_FREE( bdb->bi_dbenv, locker );
}
/* back-bdb.h - bdb back-end header file */
/* $OpenLDAP$ */
/*
- * Copyright 2000-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 2000-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* The default search IDL stack cache depth */
#define DEFAULT_SEARCH_STACK_DEPTH 16
-/* for the (expermental) IDL cache */
+/* for the IDL cache */
+#define SLAP_IDL_CACHE 1
+
#ifdef SLAP_IDL_CACHE
typedef struct bdb_idl_cache_entry_s {
struct berval kstr;
ID bi_lastid;
ldap_pvt_thread_mutex_t bi_lastid_mutex;
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
LDAP_LIST_HEAD(pl, slap_op) psearch_list;
#endif
#ifdef SLAP_IDL_CACHE
struct bdb_op_info {
BackendDB* boi_bdb;
DB_TXN* boi_txn;
- int boi_err;
+ u_int32_t boi_err;
+ u_int32_t boi_locker;
};
#define DB_OPEN(db, file, name, type, flags, mode) \
/* bind.c - bdb backend bind routine */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
LOCK_ID_FREE(bdb->bi_dbenv, locker);
- /* front end with send result on success (rc==0) */
+ /* front end will send result on success (rc==0) */
return rc;
}
/* cache.c - routines to maintain an in-core cache of entries */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
}
if ( avl_insert( &cache->c_dntree, (caddr_t) e,
- (AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
+ entry_dn_cmp, avl_dup_error ) != 0 )
{
/* free cache write lock */
ldap_pvt_thread_rdwr_wunlock( &cache->c_rwlock );
/* id tree */
if ( avl_insert( &cache->c_idtree, (caddr_t) e,
- (AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 )
+ entry_id_cmp, avl_dup_error ) != 0 )
{
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, DETAIL1,
/* delete from dn tree inserted above */
if ( avl_delete( &cache->c_dntree, (caddr_t) e,
- (AVL_CMP) entry_dn_cmp ) == NULL )
+ entry_dn_cmp ) == NULL )
{
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, INFO,
case DB_LOCK_NOTGRANTED :
/* undo avl changes immediately */
if ( avl_delete( &cache->c_idtree, (caddr_t) e,
- (AVL_CMP) entry_id_cmp ) == NULL ) {
+ entry_id_cmp ) == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, INFO,
"bdb_cache_add_entry: can't delete (%s) from cache.\n",
#endif
}
if ( avl_delete( &cache->c_dntree, (caddr_t) e,
- (AVL_CMP) entry_dn_cmp ) == NULL ) {
+ entry_dn_cmp ) == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, INFO,
"bdb_cache_add_entry: can't delete (%s) from cache.\n",
assert( e->e_private );
if ( avl_insert( &cache->c_dntree, (caddr_t) e,
- (AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
+ entry_dn_cmp, avl_dup_error ) != 0 )
{
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, DETAIL1,
/* id tree */
if ( avl_insert( &cache->c_idtree, (caddr_t) e,
- (AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 )
+ entry_id_cmp, avl_dup_error ) != 0 )
{
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, DETAIL1,
/* delete from dn tree inserted above */
if ( avl_delete( &cache->c_dntree, (caddr_t) e,
- (AVL_CMP) entry_dn_cmp ) == NULL )
+ entry_dn_cmp ) == NULL )
{
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, INFO,
ldap_pvt_thread_rdwr_rlock( &cache->c_rwlock );
if ( (ep = (Entry *) avl_find( cache->c_dntree, (caddr_t) &e,
- (AVL_CMP) entry_dn_cmp )) != NULL )
+ entry_dn_cmp )) != NULL )
{
int state;
count++;
ldap_pvt_thread_rdwr_rlock( &cache->c_rwlock );
if ( (ep = (Entry *) avl_find( cache->c_idtree, (caddr_t) &e,
- (AVL_CMP) entry_id_cmp )) != NULL )
+ entry_id_cmp )) != NULL )
{
int state;
ID ep_id;
int rc = 0; /* return code */
/* dn tree */
- if ( avl_delete( &cache->c_dntree, (caddr_t) e, (AVL_CMP) entry_dn_cmp )
- == NULL )
+ if ( avl_delete( &cache->c_dntree, (caddr_t) e, entry_dn_cmp ) == NULL )
{
rc = -1;
}
/* id tree */
- if ( avl_delete( &cache->c_idtree, (caddr_t) e, (AVL_CMP) entry_id_cmp )
- == NULL )
+ if ( avl_delete( &cache->c_idtree, (caddr_t) e, entry_id_cmp ) == NULL )
{
rc = -1;
}
/* delete.c - bdb backend delete routine */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
DB_TXN *ltid = NULL;
struct bdb_op_info opinfo;
- u_int32_t locker;
+ u_int32_t locker = 0;
DB_LOCK lock;
#if 0
u_int32_t lockid;
int noop = 0;
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
Operation* ps_list;
#endif
opinfo.boi_bdb = be;
opinfo.boi_txn = ltid;
+ opinfo.boi_locker = locker;
opinfo.boi_err = 0;
op->o_private = &opinfo;
return_results:
send_ldap_result( conn, op, rc, NULL, text, NULL, NULL );
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
if ( rc == LDAP_SUCCESS && !noop ) {
LDAP_LIST_FOREACH( ps_list, &bdb->psearch_list, link ) {
- bdb_psearch( be, conn, op, ps_list, e, LCUP_PSEARCH_BY_DELETE );
+ bdb_psearch( be, conn, op, ps_list, e, LDAP_PSEARCH_BY_DELETE );
}
}
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
if(rc == LDAP_SUCCESS && bdb->bi_txn_cp ) {
ldap_pvt_thread_yield();
/* dn2id.c - routines to deal with the dn2id index */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
goto done;
}
+#ifndef BDB_MULTIPLE_SUFFIXES
if( !be_issuffix( be, &ptr )) {
+#endif
buf[0] = DN_SUBTREE_PREFIX;
- rc = bdb_idl_insert_key( be, db, txn, &key, e->e_id );
+ rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE );
if( rc != 0 ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, ERR,
- "=> bdb_dn2id_add: subtree (%s) insert failed: %d\n",
+ "=> bdb_dn2id_add: subtree (%s) put failed: %d\n",
ptr.bv_val, rc, 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "=> bdb_dn2id_add: subtree (%s) insert failed: %d\n",
+ "=> bdb_dn2id_add: subtree (%s) put failed: %d\n",
ptr.bv_val, rc, 0 );
#endif
goto done;
}
+#ifdef BDB_MULTIPLE_SUFFIXES
+ if( !be_issuffix( be, &ptr )) {
+#endif
dnParent( &ptr, &pdn );
key.size = pdn.bv_len + 2;
#endif
goto done;
}
+#ifndef BDB_MULTIPLE_SUFFIXES
}
while( !be_issuffix( be, &ptr )) {
+#else
+ for (;;) {
+#endif
ptr.bv_val[-1] = DN_SUBTREE_PREFIX;
rc = bdb_idl_insert_key( be, db, txn, &key, e->e_id );
#endif
break;
}
+#ifdef BDB_MULTIPLE_SUFFIXES
+ if( be_issuffix( be, &ptr )) break;
+#endif
dnParent( &ptr, &pdn );
key.size = pdn.bv_len + 2;
key.data = pdn.bv_val - 1;
ptr = pdn;
}
+#ifdef BDB_MULTIPLE_SUFFIXES
+ }
+#endif
done:
ch_free( buf );
goto done;
}
+#ifndef BDB_MULTIPLE_SUFFIXES
if( !be_issuffix( be, &ptr )) {
+#endif
buf[0] = DN_SUBTREE_PREFIX;
rc = db->del( db, txn, &key, 0 );
if( rc != 0 ) {
goto done;
}
+#ifdef BDB_MULTIPLE_SUFFIXES
+ if( !be_issuffix( be, &ptr )) {
+#endif
dnParent( &ptr, &pdn );
key.size = pdn.bv_len + 2;
#endif
goto done;
}
+#ifndef BDB_MULTIPLE_SUFFIXES
}
while( !be_issuffix( be, &ptr )) {
+#else
+ for (;;) {
+#endif
ptr.bv_val[-1] = DN_SUBTREE_PREFIX;
rc = bdb_idl_delete_key( be, db, txn, &key, e->e_id );
#endif
goto done;
}
+#ifdef BDB_MULTIPLE_SUFFIXES
+ if( be_issuffix( be, &ptr )) break;
+#endif
dnParent( &ptr, &pdn );
key.size = pdn.bv_len + 2;
key.data = pdn.bv_val - 1;
ptr = pdn;
}
+#ifdef BDB_MULTIPLE_SUFFIXES
+ }
+#endif
done:
ch_free( buf );
Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2idl( \"%s\" )\n", dn->bv_val, 0, 0 );
#endif
+#ifndef BDB_MULTIPLE_SUFFIXES
if (prefix == DN_SUBTREE_PREFIX && be_issuffix(be, dn))
{
BDB_IDL_ALL(bdb, ids);
return 0;
}
+#endif
DBTzero( &key );
key.size = dn->bv_len + 2;
static int
node_frdn_cmp(
- struct berval *nrdn,
- idNode *n
+ const void *v_nrdn,
+ const void *v_n
)
{
+ const struct berval *nrdn = v_nrdn;
+ const idNode *n = v_n;
return ber_bvcmp(nrdn, &n->i_rdn->nrdn);
}
static int
node_add_cmp(
- idNode *a,
- idNode *b
+ const void *v_a,
+ const void *v_b
)
{
+ const idNode *a = v_a, *b = v_b;
return a->i_id - b->i_id;
}
static int
node_rdn_cmp(
- idNode *a,
- idNode *b
+ const void *v_a,
+ const void *v_b
)
{
+ const idNode *a = v_a, *b = v_b;
/* should be slightly better without ordering drawbacks */
return ber_bvcmp(&a->i_rdn->nrdn, &b->i_rdn->nrdn);
}
Avlnode *tree
)
{
- return avl_find(tree, (const void *)nrdn, (AVL_CMP)node_frdn_cmp);
+ return avl_find(tree, nrdn, node_frdn_cmp);
}
/* This function links a node into its parent's i_kids tree. */
-int bdb_insert_kid(
- idNode *a,
- Avlnode *tree
+static int bdb_insert_kid(
+ void *v_a,
+ void *v_tree
)
{
+ idNode *a = v_a;
+ Avlnode *tree = v_tree;
int rc;
if (a->i_rdn->parent == 0)
return -1;
ldap_pvt_thread_rdwr_wlock(&a->i_parent->i_kids_rdwr);
rc = avl_insert( &a->i_parent->i_kids, (caddr_t) a,
- (AVL_CMP)node_rdn_cmp, (AVL_DUP) avl_dup_error );
+ node_rdn_cmp, avl_dup_error );
ldap_pvt_thread_rdwr_wunlock(&a->i_parent->i_kids_rdwr);
return rc;
}
node->i_rdn->rdn.bv_val += (long)d;
node->i_rdn->nrdn.bv_val += (long)d;
ldap_pvt_thread_rdwr_init(&node->i_kids_rdwr);
- avl_insert( &bdb->bi_tree, (caddr_t) node,
- (AVL_CMP)node_add_cmp, (AVL_DUP) avl_dup_error );
+ avl_insert( &bdb->bi_tree, (caddr_t) node, node_add_cmp, avl_dup_error );
if (id == 1)
bdb->bi_troot = node;
return node;
}
cursor->c_close( cursor );
- rc = avl_apply(bdb->bi_tree, (AVL_APPLY)bdb_insert_kid, bdb->bi_tree,
+ rc = avl_apply(bdb->bi_tree, bdb_insert_kid, bdb->bi_tree,
-1, AVL_INORDER );
return rc;
if (n) {
if (n->i_parent) {
ldap_pvt_thread_rdwr_wlock(&n->i_parent->i_kids_rdwr);
- avl_delete(&n->i_parent->i_kids, &n->i_rdn->nrdn,
- (AVL_CMP)node_frdn_cmp);
+ avl_delete(&n->i_parent->i_kids, &n->i_rdn->nrdn, node_frdn_cmp);
ldap_pvt_thread_rdwr_wunlock(&n->i_parent->i_kids_rdwr);
}
free(n->i_rdn);
struct berval rdn;
char *p1, *p2;
idNode *n, *p;
+ int rc = 0;
if (!bdb->bi_troot)
return DB_NOTFOUND;
*id = n->i_id;
} else if (id2) {
*id2 = p->i_id;
+ } else {
+ rc = DB_NOTFOUND;
}
- return n ? 0 : DB_NOTFOUND;
+
+ return rc;
}
int
*/
static int
insert_one(
- idNode *n,
- ID *ids
+ void *v_n,
+ void *v_ids
)
{
+ idNode *n = v_n;
+ ID *ids = v_ids;
return bdb_idl_insert(ids, n->i_id);
}
static int
insert_sub(
- idNode *n,
- ID *ids
+ void *v_n,
+ void *v_ids
)
{
+ idNode *n = v_n;
+ ID *ids = v_ids;
int rc;
rc = bdb_idl_insert(ids, n->i_id);
if (rc == 0) {
ldap_pvt_thread_rdwr_rlock(&n->i_kids_rdwr);
- rc = avl_apply(n->i_kids, (AVL_APPLY)insert_sub, ids, -1,
- AVL_INORDER);
+ rc = avl_apply(n->i_kids, insert_sub, ids, -1, AVL_INORDER);
ldap_pvt_thread_rdwr_runlock(&n->i_kids_rdwr);
}
return rc;
ids[0] = 0;
ldap_pvt_thread_rdwr_rlock(&n->i_kids_rdwr);
if (prefix == DN_ONE_PREFIX) {
- rc = avl_apply(n->i_kids, (AVL_APPLY)insert_one, ids, -1,
- AVL_INORDER);
+ rc = avl_apply(n->i_kids, insert_one, ids, -1, AVL_INORDER);
} else {
- rc = avl_apply(n->i_kids, (AVL_APPLY)insert_sub, ids, -1,
- AVL_INORDER);
+ ids[0] = 1;
+ ids[1] = id;
+ if (n->i_kids)
+ rc = avl_apply(n->i_kids, insert_sub, ids, -1, AVL_INORDER);
}
ldap_pvt_thread_rdwr_runlock(&n->i_kids_rdwr);
return rc;
/* $OpenLDAP$ */
/*
- * Copyright 2000-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 2000-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
extern BI_operational bdb_operational;
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
extern BI_has_subordinates bdb_hasSubordinates;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
/* tools.c */
extern BI_tool_entry_open bdb_tool_entry_open;
/* filterindex.c - generate the list of candidate entries from a filter */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
DB *db;
int rc;
slap_mask_t mask;
- struct berval prefix = {0};
+ struct berval prefix = {0, NULL};
#ifdef NEW_LOGGING
- LDAP_LOG ( INDEX, ENTRY, "=> bdb_presence_candidates\n", 0, 0, 0 );
+ LDAP_LOG ( INDEX, ENTRY, "=> bdb_presence_candidates (%s)\n",
+ desc->ad_cname.bv_val, 0, 0 );
#else
- Debug( LDAP_DEBUG_TRACE, "=> bdb_presence_candidates\n", 0, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE, "=> bdb_presence_candidates (%s)\n",
+ desc->ad_cname.bv_val, 0, 0 );
#endif
if( desc == slap_schema.si_ad_objectClass ) {
if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_presence_candidates: index_param returned=%d\n", rc, 0, 0 );
+ "<= bdb_presence_candidates: (%s) index_param "
+ "returned=%d\n",
+ desc->ad_cname.bv_val, rc, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
- "<= bdb_presence_candidates: index_param returned=%d\n",
- rc, 0, 0 );
+ "<= bdb_presence_candidates: (%s) index_param "
+ "returned=%d\n",
+ desc->ad_cname.bv_val, rc, 0 );
#endif
return 0;
}
/* not indexed */
#ifdef NEW_LOGGING
LDAP_LOG(INDEX, RESULTS,
- "<= bdb_presence_candidates: not indexed\n", 0, 0, 0 );
+ "<= bdb_presence_candidates: (%s) not indexed\n",
+ desc->ad_cname.bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
- "<= bdb_presence_candidates: not indexed\n",
- 0, 0, 0 );
+ "<= bdb_presence_candidates: (%s) not indexed\n",
+ desc->ad_cname.bv_val, 0, 0 );
#endif
return 0;
}
if( prefix.bv_val == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG(INDEX, RESULTS,
- "<= bdb_presence_candidates: no prefix\n", 0, 0, 0 );
+ "<= bdb_presence_candidates: (%s) no prefix\n",
+ desc->ad_cname.bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
- "<= bdb_presence_candidates: no prefix\n",
- 0, 0, 0 );
+ "<= bdb_presence_candidates: (%s) no prefix\n",
+ desc->ad_cname.bv_val, 0, 0 );
#endif
return 0;
}
} else if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_presence_candidates: key read failed (%d)\n", rc, 0, 0 );
+ "<= bdb_presence_candidates: (%s) "
+ "key read failed (%d)\n",
+ desc->ad_cname.bv_val, rc, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
- "<= bdb_presense_candidates: key read failed (%d)\n",
- rc, 0, 0 );
+ "<= bdb_presense_candidates: (%s) "
+ "key read failed (%d)\n",
+ desc->ad_cname.bv_val, rc, 0 );
#endif
goto done;
}
int i;
int rc;
slap_mask_t mask;
- struct berval prefix = {0};
+ struct berval prefix = {0, NULL};
struct berval *keys = NULL;
MatchingRule *mr;
#ifdef NEW_LOGGING
- LDAP_LOG ( INDEX, ENTRY, "=> bdb_equality_candidates\n", 0, 0, 0 );
+ LDAP_LOG ( INDEX, ENTRY, "=> bdb_equality_candidates (%s)\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#else
- Debug( LDAP_DEBUG_TRACE, "=> bdb_equality_candidates\n", 0, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE, "=> bdb_equality_candidates (%s)\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#endif
rc = bdb_index_param( be, ava->aa_desc, LDAP_FILTER_EQUALITY,
if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_equality_candidates: index_param failed (%d)\n", rc, 0, 0);
+ "<= bdb_equality_candidates: (%s) "
+ "index_param failed (%d)\n",
+ ava->aa_desc->ad_cname.bv_val, rc, 0);
#else
Debug( LDAP_DEBUG_ANY,
- "<= bdb_equality_candidates: index_param failed (%d)\n",
- rc, 0, 0 );
+ "<= bdb_equality_candidates: (%s) "
+ "index_param failed (%d)\n",
+ ava->aa_desc->ad_cname.bv_val, rc, 0 );
#endif
return rc;
}
if ( db == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG(INDEX, RESULTS,
- "<= bdb_equality_candidates: not indexed\n", 0, 0, 0 );
+ "<= bdb_equality_candidates: (%s) not indexed\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "<= bdb_equality_candidates: not indexed\n", 0, 0, 0 );
+ "<= bdb_equality_candidates: (%s) not indexed\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#endif
return -1;
}
if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_equality_candidates: (%s) MR filter failed (%d)\n",
- prefix.bv_val, rc, 0 );
+ "<= bdb_equality_candidates: (%s, %s) "
+ "MR filter failed (%d)\n",
+ prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
#else
Debug( LDAP_DEBUG_TRACE,
- "<= bdb_equality_candidates: (%s) MR filter failed (%d)\n",
- prefix.bv_val, rc, 0 );
+ "<= bdb_equality_candidates: (%s, %s) "
+ "MR filter failed (%d)\n",
+ prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
#endif
return rc;
}
if( keys == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_equality_candidates: no keys\n", 0, 0, 0 );
+ "<= bdb_equality_candidates: (%s) no keys\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
- "<= bdb_equality_candidates: no keys\n",
- 0, 0, 0 );
+ "<= bdb_equality_candidates: (%s) no keys\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#endif
return 0;
}
} else if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_equality_candidates: key read failed (%d)\n", rc, 0, 0);
+ "<= bdb_equality_candidates: (%s) "
+ "key read failed (%d)\n",
+ ava->aa_desc->ad_cname.bv_val, rc, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
- "<= bdb_equality_candidates: key read failed (%d)\n",
- rc, 0, 0 );
+ "<= bdb_equality_candidates: (%s) "
+ "key read failed (%d)\n",
+ ava->aa_desc->ad_cname.bv_val, rc, 0 );
#endif
break;
}
if( BDB_IDL_IS_ZERO( tmp ) ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_equality_candidates: NULL\n", 0, 0, 0);
+ "<= bdb_equality_candidates: (%s) NULL\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0);
#else
Debug( LDAP_DEBUG_TRACE,
- "<= bdb_equality_candidates: NULL\n",
- 0, 0, 0 );
+ "<= bdb_equality_candidates: (%s) NULL\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#endif
BDB_IDL_ZERO( ids );
break;
int i;
int rc;
slap_mask_t mask;
- struct berval prefix = {0};
+ struct berval prefix = {0, NULL};
struct berval *keys = NULL;
MatchingRule *mr;
#ifdef NEW_LOGGING
- LDAP_LOG ( INDEX, ENTRY, "=> bdb_approx_candidates\n", 0, 0, 0 );
+ LDAP_LOG ( INDEX, ENTRY, "=> bdb_approx_candidates (%s)\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#else
- Debug( LDAP_DEBUG_TRACE, "=> bdb_approx_candidates\n", 0, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE, "=> bdb_approx_candidates (%s)\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#endif
rc = bdb_index_param( be, ava->aa_desc, LDAP_FILTER_APPROX,
if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_approx_candidates: index_param failed (%d)\n", rc, 0, 0 );
+ "<= bdb_approx_candidates: (%s) "
+ "index_param failed (%d)\n",
+ ava->aa_desc->ad_cname.bv_val, rc, 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "<= bdb_approx_candidates: index_param failed (%d)\n",
- rc, 0, 0 );
+ "<= bdb_approx_candidates: (%s) "
+ "index_param failed (%d)\n",
+ ava->aa_desc->ad_cname.bv_val, rc, 0 );
#endif
return rc;
}
if ( db == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG(INDEX, RESULTS,
- "<= bdb_approx_candidates: not indexed\n",0, 0, 0 );
+ "<= bdb_approx_candidates: (%s) not indexed\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "<= bdb_approx_candidates: not indexed\n", 0, 0, 0 );
+ "<= bdb_approx_candidates: (%s) not indexed\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#endif
return -1;
}
if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_approx_candidates: (%s) MR filter failed (%d)\n",
- prefix.bv_val, rc, 0 );
+ "<= bdb_approx_candidates: (%s, %s) "
+ "MR filter failed (%d)\n",
+ prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
#else
Debug( LDAP_DEBUG_TRACE,
- "<= bdb_approx_candidates: (%s) MR filter failed (%d)\n",
- prefix.bv_val, rc, 0 );
+ "<= bdb_approx_candidates: (%s, %s) "
+ "MR filter failed (%d)\n",
+ prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
#endif
return rc;
}
if( keys == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_approx_candidates: no keys (%s)\n", prefix.bv_val, 0, 0 );
+ "<= bdb_approx_candidates: (%s) no keys (%s)\n",
+ prefix.bv_val, ava->aa_desc->ad_cname.bv_val, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
- "<= bdb_approx_candidates: no keys (%s)\n",
- prefix.bv_val, 0, 0 );
+ "<= bdb_approx_candidates: (%s) no keys (%s)\n",
+ prefix.bv_val, ava->aa_desc->ad_cname.bv_val, 0 );
#endif
return 0;
}
break;
} else if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
- LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_approx_candidates: key read failed (%d)\n", rc, 0, 0);
+ LDAP_LOG ( INDEX, RESULTS,
+ "<= bdb_approx_candidates: (%s) "
+ "key read failed (%d)\n",
+ ava->aa_desc->ad_cname.bv_val, rc, 0);
#else
- Debug( LDAP_DEBUG_TRACE, "<= bdb_approx_candidates key read failed (%d)\n",
- rc, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE,
+ "<= bdb_approx_candidates: (%s) "
+ "key read failed (%d)\n",
+ ava->aa_desc->ad_cname.bv_val, rc, 0 );
#endif
break;
}
if( BDB_IDL_IS_ZERO( tmp ) ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_approx_candidates: NULL\n", 0, 0, 0 );
+ "<= bdb_approx_candidates: (%s) NULL\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#else
- Debug( LDAP_DEBUG_TRACE, "<= bdb_approx_candidates NULL\n",
- 0, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE,
+ "<= bdb_approx_candidates: (%s) NULL\n",
+ ava->aa_desc->ad_cname.bv_val, 0, 0 );
#endif
BDB_IDL_ZERO( ids );
break;
int i;
int rc;
slap_mask_t mask;
- struct berval prefix = {0};
+ struct berval prefix = {0, NULL};
struct berval *keys = NULL;
MatchingRule *mr;
#ifdef NEW_LOGGING
- LDAP_LOG ( INDEX, ENTRY, "=> bdb_substring_candidates\n", 0, 0, 0 );
+ LDAP_LOG ( INDEX, ENTRY, "=> bdb_substring_candidates (%s)\n",
+ sub->sa_desc->ad_cname.bv_val, 0, 0 );
#else
- Debug( LDAP_DEBUG_TRACE, "=> bdb_substring_candidates\n", 0, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE, "=> bdb_substring_candidates (%s)\n",
+ sub->sa_desc->ad_cname.bv_val, 0, 0 );
#endif
rc = bdb_index_param( be, sub->sa_desc, LDAP_FILTER_SUBSTRINGS,
if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_substring_candidates: index_param failed (%d)\n", rc, 0, 0);
+ "<= bdb_substring_candidates: (%s) "
+ "index_param failed (%d)\n",
+ sub->sa_desc->ad_cname.bv_val, rc, 0);
#else
Debug( LDAP_DEBUG_ANY,
- "<= bdb_substring_candidates: index_param failed (%d)\n",
- rc, 0, 0 );
+ "<= bdb_substring_candidates: (%s) "
+ "index_param failed (%d)\n",
+ sub->sa_desc->ad_cname.bv_val, rc, 0 );
#endif
return rc;
}
if ( db == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_substring_candidates: not indexed\n", 0, 0, 0 );
+ "<= bdb_substring_candidates: (%s) not indexed\n",
+ sub->sa_desc->ad_cname.bv_val, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "<= bdb_substring_candidates: not indexed\n",
- 0, 0, 0 );
+ "<= bdb_substring_candidates: (%s) not indexed\n",
+ sub->sa_desc->ad_cname.bv_val, 0, 0 );
#endif
return -1;
}
if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_substring_candidates: (%s) MR filter failed (%d)\n",
+ "<= bdb_substring_candidates: (%s) "
+ "MR filter failed (%d)\n",
sub->sa_desc->ad_cname.bv_val, rc, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
- "<= bdb_substring_candidates: (%s) MR filter failed (%d)\n",
+ "<= bdb_substring_candidates: (%s) "
+ "MR filter failed (%d)\n",
sub->sa_desc->ad_cname.bv_val, rc, 0 );
#endif
return rc;
} else if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_substring_candidates: key read failed (%d)\n", rc, 0,0);
+ "<= bdb_substring_candidates: (%s) "
+ "key read failed (%d)\n",
+ sub->sa_desc->ad_cname.bv_val, rc, 0 );
#else
- Debug( LDAP_DEBUG_TRACE, "<= bdb_substring_candidates: key read failed (%d)\n",
- rc, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE,
+ "<= bdb_substring_candidates: (%s) "
+ "key read failed (%d)\n",
+ sub->sa_desc->ad_cname.bv_val, rc, 0 );
#endif
break;
}
if( BDB_IDL_IS_ZERO( tmp ) ) {
#ifdef NEW_LOGGING
LDAP_LOG ( INDEX, RESULTS,
- "<= bdb_substring_candidates: NULL \n", 0, 0, 0 );
+ "<= bdb_substring_candidates: (%s) NULL\n",
+ sub->sa_desc->ad_cname.bv_val, 0, 0 );
#else
- Debug( LDAP_DEBUG_TRACE, "<= bdb_substring_candidates: NULL\n",
- 0, 0, 0 );
+ Debug( LDAP_DEBUG_TRACE,
+ "<= bdb_substring_candidates: (%s) NULL\n",
+ sub->sa_desc->ad_cname.bv_val, 0, 0 );
#endif
BDB_IDL_ZERO( ids );
break;
/* group.c - bdb backend acl group routine */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
const char *group_oc_name = NULL;
const char *group_at_name = group_at->ad_cname.bv_val;
- u_int32_t locker;
+ u_int32_t locker = 0;
DB_LOCK lock;
+ int free_lock_id = 0;
if( group_oc->soc_names && group_oc->soc_names[0] ) {
group_oc_name = group_oc->soc_names[0];
Debug( LDAP_DEBUG_ARGS,
"=> bdb_group: tr ndn: \"%s\"\n",
- target->e_ndn, 0, 0 );
+ target ? target->e_ndn : "", 0, 0 );
#endif
if( op ) boi = (struct bdb_op_info *) op->o_private;
if( boi != NULL && be == boi->boi_bdb ) {
txn = boi->boi_txn;
+ locker = boi->boi_locker;
}
if ( txn ) {
locker = TXN_ID( txn );
- } else {
+ } else if ( !locker ) {
rc = LOCK_ID ( bdb->bi_dbenv, &locker );
+ free_lock_id = 1;
switch(rc) {
case 0:
break;
}
}
- if (dn_match(&target->e_name, gr_ndn)) {
+ if ( target != NULL && dn_match( &target->e_nname, gr_ndn )) {
/* we already have a LOCKED copy of the entry */
e = target;
#ifdef NEW_LOGGING
if( rc ) {
if ( rc == DB_LOCK_DEADLOCK || rc == DB_LOCK_NOTGRANTED )
goto dn2entry_retry;
- if( txn ) {
- boi->boi_err = rc;
- }
- else {
+ boi->boi_err = rc;
+ if ( free_lock_id ) {
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
}
return( 1 );
"=> bdb_group: cannot find group: \"%s\"\n",
gr_ndn->bv_val, 0, 0 );
#endif
- if ( txn == NULL ) {
+ if ( free_lock_id ) {
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
}
return( 1 );
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
}
- if ( txn == NULL ) {
+ if ( free_lock_id ) {
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
}
/* id2entry.c - routines to deal with the id2entry database */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
free ( (*e)->e_private );
bdb_entry_return( *e );
*e = NULL;
- ch_free( data.data );
}
rc = ret;
}
/* idl.c - ldap id list handling routines */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#define IDL_CMP(x,y) ( x < y ? -1 : ( x > y ? 1 : 0 ) )
+#ifdef SLAP_IDL_CACHE
+#define IDL_LRU_DELETE( bdb, e ) do { \
+ if ( e->idl_lru_prev != NULL ) { \
+ e->idl_lru_prev->idl_lru_next = e->idl_lru_next; \
+ } else { \
+ bdb->bi_idl_lru_head = e->idl_lru_next; \
+ } \
+ if ( e->idl_lru_next != NULL ) { \
+ e->idl_lru_next->idl_lru_prev = e->idl_lru_prev; \
+ } else { \
+ bdb->bi_idl_lru_tail = e->idl_lru_prev; \
+ } \
+} while ( 0 )
+
+#define IDL_LRU_ADD( bdb, e ) do { \
+ e->idl_lru_next = bdb->bi_idl_lru_head; \
+ if ( e->idl_lru_next != NULL ) { \
+ e->idl_lru_next->idl_lru_prev = (e); \
+ } \
+ (bdb)->bi_idl_lru_head = (e); \
+ e->idl_lru_prev = NULL; \
+ if ( (bdb)->bi_idl_lru_tail == NULL ) { \
+ (bdb)->bi_idl_lru_tail = (e); \
+ } \
+} while ( 0 )
+
+static int
+bdb_idl_entry_cmp( const void *v_idl1, const void *v_idl2 )
+{
+ const bdb_idl_cache_entry_t *idl1 = v_idl1, *idl2 = v_idl2;
+ int rc;
+
+ if ((rc = idl1->db - idl2->db )) return rc;
+ if ((rc = idl1->kstr.bv_len - idl2->kstr.bv_len )) return rc;
+ return ( memcmp ( idl1->kstr.bv_val, idl2->kstr.bv_val , idl1->kstr.bv_len ) );
+}
+#endif
+
#if IDL_DEBUG > 0
static void idl_check( ID *ids )
{
size_t len;
int rc2;
int flags = bdb->bi_db_opflags | DB_MULTIPLE;
+#ifdef SLAP_IDL_CACHE
+ bdb_idl_cache_entry_t idl_tmp;
+#endif
- /* buf must be large enough to grab the entire IDL in one
- * get(), otherwise BDB 4 will leak resources on subsequent
- * get's. We can safely call get() twice - once for the data,
- * and once to get the DB_NOTFOUND result meaning there's
- * no more data. See ITS#2040 for details. This bug is fixed
- * in BDB 4.1 so a smaller buffer will work if stack space is
- * too limited.
+ /* If using BerkeleyDB 4.0, the buf must be large enough to
+ * grab the entire IDL in one get(), otherwise BDB will leak
+ * resources on subsequent get's. We can safely call get()
+ * twice - once for the data, and once to get the DB_NOTFOUND
+ * result meaning there's no more data. See ITS#2040 for details.
+ * This bug is fixed in BDB 4.1 so a smaller buffer will work if
+ * stack space is too limited.
+ *
+ * configure now requires Berkeley DB 4.1.
*/
- ID buf[BDB_IDL_DB_SIZE*5];
+#if (DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR == 0)
+# define BDB_ENOUGH 5
+#else
+# define BDB_ENOUGH 1
+#endif
+ ID buf[BDB_IDL_DB_SIZE*BDB_ENOUGH];
+
+ char keybuf[16];
- {
- char buf[16];
#ifdef NEW_LOGGING
- LDAP_LOG( INDEX, ARGS,
- "bdb_idl_fetch_key: %s\n",
- bdb_show_key( key, buf ), 0, 0 );
+ LDAP_LOG( INDEX, ARGS,
+ "bdb_idl_fetch_key: %s\n",
+ bdb_show_key( key, keybuf ), 0, 0 );
#else
- Debug( LDAP_DEBUG_ARGS,
- "bdb_idl_fetch_key: %s\n",
- bdb_show_key( key, buf ), 0, 0 );
+ Debug( LDAP_DEBUG_ARGS,
+ "bdb_idl_fetch_key: %s\n",
+ bdb_show_key( key, keybuf ), 0, 0 );
#endif
- }
+
assert( ids != NULL );
+#ifdef SLAP_IDL_CACHE
+ if ( bdb->bi_idl_cache_max_size ) {
+ bdb_idl_cache_entry_t *matched_idl_entry;
+ DBT2bv( key, &idl_tmp.kstr );
+ idl_tmp.db = db;
+ ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_mutex );
+ matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
+ bdb_idl_entry_cmp );
+ if ( matched_idl_entry != NULL ) {
+ BDB_IDL_CPY( ids, matched_idl_entry->idl );
+ IDL_LRU_DELETE( bdb, matched_idl_entry );
+ IDL_LRU_ADD( bdb, matched_idl_entry );
+ ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_mutex );
+ return LDAP_SUCCESS;
+ }
+ ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_mutex );
+ }
+#endif
+
DBTzero( &data );
data.data = buf;
data.ulen = sizeof(buf);
data.flags = DB_DBT_USERMEM;
- if ( tid )
- flags |= DB_RMW;
+ if ( tid ) flags |= DB_RMW;
rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
if( rc != 0 ) {
#endif
return rc;
}
+
rc = cursor->c_get( cursor, key, &data, flags | DB_SET );
if (rc == 0) {
i = ids;
}
data.size = BDB_IDL_SIZEOF(ids);
}
+
rc2 = cursor->c_close( cursor );
if (rc2) {
#ifdef NEW_LOGGING
#endif
return rc2;
}
+
if( rc == DB_NOTFOUND ) {
return rc;
return -1;
}
+#ifdef SLAP_IDL_CACHE
+ if ( bdb->bi_idl_cache_max_size ) {
+ bdb_idl_cache_entry_t *ee;
+ ee = (bdb_idl_cache_entry_t *) ch_malloc(
+ sizeof( bdb_idl_cache_entry_t ) );
+ ee->db = db;
+ ee->idl = (ID*) ch_malloc( BDB_IDL_SIZEOF ( ids ) );
+ ee->idl_lru_prev = NULL;
+ ee->idl_lru_next = NULL;
+ BDB_IDL_CPY( ee->idl, ids );
+ ber_dupbv( &ee->kstr, &idl_tmp.kstr );
+ ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_mutex );
+ if ( avl_insert( &bdb->bi_idl_tree, (caddr_t) ee,
+ bdb_idl_entry_cmp, avl_dup_error ))
+ {
+ ch_free( ee->kstr.bv_val );
+ ch_free( ee->idl );
+ ch_free( ee );
+ } else {
+ IDL_LRU_ADD( bdb, ee );
+ if ( ++bdb->bi_idl_cache_size > bdb->bi_idl_cache_max_size ) {
+ int i = 0;
+ while ( bdb->bi_idl_lru_tail != NULL && i < 10 ) {
+ ee = bdb->bi_idl_lru_tail;
+ avl_delete( &bdb->bi_idl_tree, (caddr_t) ee,
+ bdb_idl_entry_cmp );
+ IDL_LRU_DELETE( bdb, ee );
+ i++;
+ --bdb->bi_idl_cache_size;
+ ch_free( ee->kstr.bv_val );
+ ch_free( ee->idl );
+ ch_free( ee );
+ }
+ }
+ }
+ ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_mutex );
+ }
+#endif
+
return rc;
}
assert( id != NOID );
+#ifdef SLAP_IDL_CACHE
+ if ( bdb->bi_idl_cache_size ) {
+ bdb_idl_cache_entry_t *matched_idl_entry, idl_tmp;
+ DBT2bv( key, &idl_tmp.kstr );
+ idl_tmp.db = db;
+ ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_mutex );
+ matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
+ bdb_idl_entry_cmp );
+ if ( matched_idl_entry != NULL ) {
+ avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry,
+ bdb_idl_entry_cmp );
+ --bdb->bi_idl_cache_size;
+ IDL_LRU_DELETE( bdb, matched_idl_entry );
+ free( matched_idl_entry->kstr.bv_val );
+ free( matched_idl_entry->idl );
+ free( matched_idl_entry );
+ }
+ ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_mutex );
+ }
+#endif
+
DBTzero( &data );
data.size = sizeof( ID );
data.ulen = data.size;
}
assert( id != NOID );
+#ifdef SLAP_IDL_CACHE
+ if ( bdb->bi_idl_cache_max_size ) {
+ bdb_idl_cache_entry_t *matched_idl_entry, idl_tmp;
+ DBT2bv( key, &idl_tmp.kstr );
+ idl_tmp.db = db;
+ ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_mutex );
+ matched_idl_entry = avl_find( bdb->bi_idl_tree, &idl_tmp,
+ bdb_idl_entry_cmp );
+ if ( matched_idl_entry != NULL ) {
+ avl_delete( &bdb->bi_idl_tree, (caddr_t) matched_idl_entry,
+ bdb_idl_entry_cmp );
+ --bdb->bi_idl_cache_size;
+ IDL_LRU_DELETE( bdb, matched_idl_entry );
+ free( matched_idl_entry->kstr.bv_val );
+ free( matched_idl_entry->idl );
+ free( matched_idl_entry );
+ }
+ ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_mutex );
+ }
+#endif
+
DBTzero( &data );
data.data = &tmp;
data.size = sizeof( id );
return NOID;
}
+
/* index.c - routines for dealing with attribute indexes */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
return mask;
}
- /* If there is a language tag, did we ever index the base
+ /* If there is a tagging option, did we ever index the base
* type? If so, check for mask, otherwise it's not there.
*/
- if( slap_ad_is_lang( desc ) && desc != desc->ad_type->sat_ad ) {
- /* has language tag */
+ if( slap_ad_is_tagged( desc ) && desc != desc->ad_type->sat_ad ) {
+ /* has tagging option */
bdb_attr_mask( be->be_private, desc->ad_type->sat_ad, &mask );
- if ( mask && ( mask ^ SLAP_INDEX_NOLANG ) ) {
+ if ( mask && ( mask ^ SLAP_INDEX_NOTAGS ) ) {
*atname = desc->ad_type->sat_cname;
*dbname = desc->ad_type->sat_cname.bv_val;
return mask;
Backend *be,
DB_TXN *txn,
AttributeType *type,
- struct berval *lang,
+ struct berval *tags,
BerVarray vals,
ID id,
int op )
if( type->sat_sup ) {
/* recurse */
rc = index_at_values( be, txn,
- type->sat_sup, lang,
+ type->sat_sup, tags,
vals, id, op );
if( rc ) return rc;
if( rc ) return rc;
}
- if( lang->bv_len ) {
+ if( tags->bv_len ) {
AttributeDescription *desc;
mask = 0;
- desc = ad_find_lang( type, lang );
+ desc = ad_find_tags( type, tags );
if( desc ) {
bdb_attr_mask( be->be_private, desc, &mask );
}
int rc;
rc = index_at_values( be, txn,
- desc->ad_type, &desc->ad_lang,
+ desc->ad_type, &desc->ad_tags,
vals, id, op );
return rc;
/* init.c - initialize bdb backend */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
bdb->bi_search_stack_depth = DEFAULT_SEARCH_STACK_DEPTH;
bdb->bi_search_stack = NULL;
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
LDAP_LIST_INIT (&bdb->psearch_list);
#endif
c = curkey->data;
#ifdef WORDS_BIGENDIAN
- for( i = 0; i < sizeof(ID); i++)
+ for( i = 0; i < (int)sizeof(ID); i++)
#else
for( i = sizeof(ID)-1; i >= 0; i--)
#endif
be->be_suffix[0].bv_val, 0, 0 );
#endif
+#ifndef BDB_MULTIPLE_SUFFIXES
+ if ( be->be_suffix[1].bv_val ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, ARGS,
+ "bdb_db_open: only one suffix allowed\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ARGS,
+ "bdb_db_open: only one suffix allowed\n", 0, 0, 0 );
+#endif
+ return -1;
+ }
+#endif
/* we should check existance of dbenv_home and db_directory */
rc = db_env_create( &bdb->bi_dbenv, 0 );
{
static char *controls[] = {
LDAP_CONTROL_MANAGEDSAIT,
-#ifdef LDAP_CONTROL_SUBENTRIES
- LDAP_CONTROL_SUBENTRIES,
-#endif
-#ifdef LDAP_CONTROL_NOOP
LDAP_CONTROL_NOOP,
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+ LDAP_CONTROL_PAGEDRESULTS,
#endif
-#ifdef LDAP_CONTROL_VALUESRETURNFILTER
LDAP_CONTROL_VALUESRETURNFILTER,
+#ifdef LDAP_CONTROL_SUBENTRIES
+ LDAP_CONTROL_SUBENTRIES,
#endif
#ifdef LDAP_CLIENT_UPDATE
LDAP_CONTROL_CLIENT_UPDATE,
bi->bi_chk_referrals = bdb_referrals;
bi->bi_operational = bdb_operational;
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
bi->bi_has_subordinates = bdb_hasSubordinates;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
bi->bi_entry_release_rw = bdb_entry_release;
/*
+++ /dev/null
-/* lcup.c - lcup operations */
-/* $OpenLDAP$ */
-/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-
-#include "portable.h"
-
-#include <stdio.h>
-
-#include "back-bdb.h"
-#include "idl.h"
-#include "external.h"
-
-#ifdef LDAP_CLIENT_UPDATE
-
-static int psearch_base_candidate(
- BackendDB *be,
- Entry *e,
- ID *ids );
-static int psearch_candidates(
- BackendDB *be,
- Operation *op,
- Entry *e,
- Filter *filter,
- int scope,
- int deref,
- ID *ids );
-
-int
-bdb_abandon(
- BackendDB *be,
- Connection *conn,
- ber_int_t id )
-{
- Operation *ps_list;
- struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-
- LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
- if ( ps_list->o_connid == conn->c_connid ) {
- if ( ps_list->o_msgid == id ) {
- ps_list->o_abandon = 1;
- LDAP_LIST_REMOVE( ps_list, link );
- slap_op_free ( ps_list );
- return LDAP_SUCCESS;
- }
- }
- }
- return LDAP_UNAVAILABLE;
-}
-
-int
-bdb_add_psearch_spec(
- BackendDB *be,
- Connection *conn,
- Operation *op,
- struct berval *base,
- struct berval *nbase,
- int scope,
- int deref,
- int slimit,
- int tlimit,
- Filter *filter,
- struct berval *fstr,
- AttributeName *attrs,
- int attrsonly )
-{
- struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-
- LDAP_LIST_FIRST(&op->psearch_spec) = (struct lcup_search_spec *)
- calloc ( 1, sizeof ( struct lcup_search_spec ) );
-
- LDAP_LIST_FIRST(&op->psearch_spec)->op = op;
-
- LDAP_LIST_FIRST(&op->psearch_spec)->base = ber_dupbv(NULL, base);
- LDAP_LIST_FIRST(&op->psearch_spec)->nbase = ber_dupbv(NULL, nbase);
-
- LDAP_LIST_FIRST(&op->psearch_spec)->scope = scope;
- LDAP_LIST_FIRST(&op->psearch_spec)->deref = deref;
- LDAP_LIST_FIRST(&op->psearch_spec)->slimit = slimit;
- LDAP_LIST_FIRST(&op->psearch_spec)->tlimit = tlimit;
-
- LDAP_LIST_FIRST(&op->psearch_spec)->filter = filter;
- LDAP_LIST_FIRST(&op->psearch_spec)->filterstr = ber_dupbv(NULL, fstr);
- LDAP_LIST_FIRST(&op->psearch_spec)->attrs = attrs;
-
- LDAP_LIST_FIRST(&op->psearch_spec)->attrsonly = attrsonly;
-
- LDAP_LIST_FIRST(&op->psearch_spec)->entry_count = 0;
-
- LDAP_LIST_INSERT_HEAD( &bdb->psearch_list, op, link );
-}
-
-int
-bdb_psearch(
- BackendDB *be,
- Connection *conn,
- Operation *op,
- Operation *ps_op,
- Entry *entry,
- int psearch_type )
-{
- struct bdb_info *bdb = (struct bdb_info *) be->be_private;
- int rc;
- const char *text = NULL;
- time_t stoptime;
- unsigned cursor;
- ID id;
- ID candidates[BDB_IDL_UM_SIZE];
- Entry *e = NULL;
- BerVarray v2refs = NULL;
- Entry *matched = NULL;
- struct berval realbase = { 0, NULL };
- int nentries = 0;
- int manageDSAit;
-
- Filter lcupf, csnfnot, csnfeq, csnfand, csnfge;
- AttributeAssertion aa_ge, aa_eq;
- struct berval entrycsn_bv = { 0, NULL };
- struct berval latest_entrycsn_bv = { 0, NULL };
-
- struct slap_limits_set *limit = NULL;
- int isroot = 0;
- int scopeok = 0;
-
- u_int32_t locker;
- DB_LOCK lock;
-
- Connection *ps_conn = ps_op->o_conn;
- struct berval *base = LDAP_LIST_FIRST(&ps_op->psearch_spec)->base;
- struct berval *nbase = LDAP_LIST_FIRST(&ps_op->psearch_spec)->nbase;
- int scope = LDAP_LIST_FIRST(&ps_op->psearch_spec)->scope;
- int deref = LDAP_LIST_FIRST(&ps_op->psearch_spec)->deref;
- int slimit = LDAP_LIST_FIRST(&ps_op->psearch_spec)->slimit;
- int tlimit = LDAP_LIST_FIRST(&ps_op->psearch_spec)->tlimit;
- Filter *filter = LDAP_LIST_FIRST(&ps_op->psearch_spec)->filter;
- struct berval *filterstr = LDAP_LIST_FIRST(&ps_op->psearch_spec)->filterstr;
- int attrsonly = LDAP_LIST_FIRST(&ps_op->psearch_spec)->attrsonly;
- AttributeName uuid_attr[2];
- AttributeName *attrs = uuid_attr;
-
- if ( psearch_type != LCUP_PSEARCH_BY_DELETE &&
- psearch_type != LCUP_PSEARCH_BY_SCOPEOUT )
- {
- attrs = LDAP_LIST_FIRST(&ps_op->psearch_spec)->attrs;
- } else {
- attrs[0].an_desc = slap_schema.si_ad_entryUUID;
- attrs[0].an_oc = NULL;
- ber_dupbv( &attrs[0].an_name, &attrs[0].an_desc->ad_cname );
- attrs[1].an_desc = NULL;
- attrs[1].an_oc = NULL;
- attrs[1].an_name.bv_len = 0;
- attrs[1].an_name.bv_val = NULL;
- }
-
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, ENTRY, "bdb_back_search\n", 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE, "=> bdb_back_search\n",
- 0, 0, 0);
-#endif
-
- manageDSAit = get_manageDSAit( ps_op );
-
- rc = LOCK_ID (bdb->bi_dbenv, &locker );
- switch(rc) {
- case 0:
- break;
- default:
- send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
- NULL, "internal error", NULL, NULL );
- if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
- psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
- ch_free( attrs[0].an_name.bv_val );
- return rc;
- }
-
- if ( nbase->bv_len == 0 ) {
- /* DIT root special case */
- e = (Entry *) &slap_entry_root;
- rc = 0;
- } else
-#ifdef BDB_ALIASES
- /* get entry with reader lock */
- if ( deref & LDAP_DEREF_FINDING ) {
- e = deref_dn_r( be, nbase-, &err, &matched, &text );
-
- } else
-#endif
- {
-dn2entry_retry:
- rc = bdb_dn2entry_r( be, NULL, nbase, &e, &matched, 0, locker, &lock );
- }
-
- switch(rc) {
- case DB_NOTFOUND:
- case 0:
- break;
- case LDAP_BUSY:
- if (e != NULL) {
- bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
- e, &lock);
- }
- if (matched != NULL) {
- bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
- matched, &lock);
- }
- send_ldap_result( ps_conn, ps_op, LDAP_BUSY,
- NULL, "ldap server busy", NULL, NULL );
- LOCK_ID_FREE( bdb->bi_dbenv, locker );
- if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
- psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
- ch_free( attrs[0].an_name.bv_val );
- return LDAP_BUSY;
- case DB_LOCK_DEADLOCK:
- case DB_LOCK_NOTGRANTED:
- goto dn2entry_retry;
- default:
- if (e != NULL) {
- bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
- e, &lock);
- }
- if (matched != NULL) {
- bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
- matched, &lock);
- }
- send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
- NULL, "internal error", NULL, NULL );
- LOCK_ID_FREE( bdb->bi_dbenv, locker );
- if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
- psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
- ch_free( attrs[0].an_name.bv_val );
- return rc;
- }
-
- if ( e == NULL ) {
- struct berval matched_dn = { 0, NULL };
- BerVarray refs = NULL;
-
- if ( matched != NULL ) {
- BerVarray erefs;
- ber_dupbv( &matched_dn, &matched->e_name );
-
- erefs = is_entry_referral( matched )
- ? get_entry_referrals( be, ps_conn, ps_op, matched )
- : NULL;
-
- bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
- matched, &lock);
- matched = NULL;
-
- if( erefs ) {
- refs = referral_rewrite( erefs, &matched_dn,
- base, scope );
- ber_bvarray_free( erefs );
- }
-
- } else {
- refs = referral_rewrite( default_referral,
- NULL, base, scope );
- }
-
- send_ldap_result( ps_conn, ps_op, rc=LDAP_REFERRAL ,
- matched_dn.bv_val, text, refs, NULL );
-
- LOCK_ID_FREE( bdb->bi_dbenv, locker );
- if ( refs ) ber_bvarray_free( refs );
- if ( matched_dn.bv_val ) ber_memfree( matched_dn.bv_val );
- if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
- psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
- ch_free( attrs[0].an_name.bv_val );
- return rc;
- }
-
- if (!manageDSAit && e != &slap_entry_root && is_entry_referral( e ) ) {
- /* entry is a referral, don't allow add */
- struct berval matched_dn;
- BerVarray erefs, refs;
-
- ber_dupbv( &matched_dn, &e->e_name );
- erefs = get_entry_referrals( be, ps_conn, ps_op, e );
- refs = NULL;
-
- bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
- e = NULL;
-
- if( erefs ) {
- refs = referral_rewrite( erefs, &matched_dn,
- base, scope );
- ber_bvarray_free( erefs );
- }
-
-#ifdef NEW_LOGGING
- LDAP_LOG( OPERATION, RESULTS,
- "bdb_search: entry is referral\n", 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE, "bdb_search: entry is referral\n",
- 0, 0, 0 );
-#endif
-
- send_ldap_result( ps_conn, ps_op, LDAP_REFERRAL,
- matched_dn.bv_val,
- refs ? NULL : "bad referral object",
- refs, NULL );
-
- LOCK_ID_FREE( bdb->bi_dbenv, locker );
- ber_bvarray_free( refs );
- ber_memfree( matched_dn.bv_val );
- if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
- psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
- ch_free( attrs[0].an_name.bv_val );
- return 1;
- }
-
- /* if not root, get appropriate limits */
- if ( be_isroot( be, &ps_op->o_ndn ) ) {
- isroot = 1;
- } else {
- ( void ) get_limits( be, &ps_op->o_ndn, &limit );
- }
-
- /* The time/size limits come first because they require very little
- * effort, so there's no chance the candidates are selected and then
- * the request is not honored only because of time/size constraints */
-
- /* if no time limit requested, use soft limit (unless root!) */
- if ( isroot ) {
- if ( tlimit == 0 ) {
- tlimit = -1; /* allow root to set no limit */
- }
-
- if ( slimit == 0 ) {
- slimit = -1;
- }
-
- } else {
- /* if no limit is required, use soft limit */
- if ( tlimit <= 0 ) {
- tlimit = limit->lms_t_soft;
-
- /* if requested limit higher than hard limit, abort */
- } else if ( tlimit > limit->lms_t_hard ) {
- /* no hard limit means use soft instead */
- if ( limit->lms_t_hard == 0 && tlimit > limit->lms_t_soft ) {
- tlimit = limit->lms_t_soft;
-
- /* positive hard limit means abort */
- } else if ( limit->lms_t_hard > 0 ) {
- send_search_result( ps_conn, ps_op,
- LDAP_UNWILLING_TO_PERFORM,
- NULL, NULL, NULL, NULL, 0 );
- rc = 0;
- goto done;
- }
-
- /* negative hard limit means no limit */
- }
-
- /* if no limit is required, use soft limit */
- if ( slimit <= 0 ) {
- slimit = limit->lms_s_soft;
-
- /* if requested limit higher than hard limit, abort */
- } else if ( slimit > limit->lms_s_hard ) {
- /* no hard limit means use soft instead */
- if ( limit->lms_s_hard == 0 && slimit > limit->lms_s_soft ) {
- slimit = limit->lms_s_soft;
-
- /* positive hard limit means abort */
- } else if ( limit->lms_s_hard > 0 ) {
- send_search_result( ps_conn, ps_op,
- LDAP_UNWILLING_TO_PERFORM,
- NULL, NULL, NULL, NULL, 0 );
- rc = 0;
- goto done;
- }
-
- /* negative hard limit means no limit */
- }
- }
-
- /* compute it anyway; root does not use it */
- stoptime = ps_op->o_time + tlimit;
-
- /* select candidates */
- if ( scope == LDAP_SCOPE_BASE ) {
- rc = psearch_base_candidate( be, e, candidates );
- } else {
- BDB_IDL_ALL( bdb, candidates );
- rc = psearch_candidates( be, op, e, filter,
- scope, deref, candidates );
- }
-
- if ( !BDB_IDL_IS_RANGE( candidates ) ) {
- cursor = bdb_idl_search( candidates, entry->e_id );
- if ( candidates[cursor] != entry->e_id ) {
- goto test_done;
- }
- } else {
- if ( entry->e_id < BDB_IDL_RANGE_FIRST(candidates) &&
- entry->e_id > BDB_IDL_RANGE_LAST(candidates) )
- {
- goto test_done;
- }
- }
-
- /* candidates = { e } */
- candidates[0] = 1;
- candidates[1] = entry->e_id;
-
- /* need normalized dn below */
- ber_dupbv( &realbase, &e->e_nname );
-
- if ( e != &slap_entry_root ) {
- bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
- }
- e = NULL;
-
- if ( candidates[0] == 0 ) {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, RESULTS,
- "bdb_search: no candidates\n", 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE, "bdb_search: no candidates\n",
- 0, 0, 0 );
-#endif
-
- send_search_result( ps_conn, ps_op,
- LDAP_SUCCESS,
- NULL, NULL, NULL, NULL, 0 );
-
- rc = 1;
- goto done;
- }
-
- /* if not root and candidates exceed to-be-checked entries, abort */
- if ( !isroot && limit->lms_s_unchecked != -1 ) {
- if ( BDB_IDL_N(candidates) > (unsigned) limit->lms_s_unchecked ) {
- send_search_result( ps_conn, ps_op, LDAP_ADMINLIMIT_EXCEEDED,
- NULL, NULL, NULL, NULL, 0 );
- rc = 1;
- goto done;
- }
- }
-
- lcupf.f_choice = LDAP_FILTER_AND;
- lcupf.f_and = &csnfnot;
- lcupf.f_next = NULL;
-
- csnfnot.f_choice = LDAP_FILTER_NOT;
- csnfnot.f_not = &csnfeq;
- csnfnot.f_next = &csnfand;
-
- csnfeq.f_choice = LDAP_FILTER_EQUALITY;
- csnfeq.f_ava = &aa_eq;
- csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
- ber_dupbv( &csnfeq.f_av_value, &ps_op->o_clientupdate_state );
-
- csnfand.f_choice = LDAP_FILTER_AND;
- csnfand.f_and = &csnfge;
- csnfand.f_next = NULL;
-
- csnfge.f_choice = LDAP_FILTER_GE;
- csnfge.f_ava = &aa_ge;
- csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
- ber_dupbv( &csnfge.f_av_value, &ps_op->o_clientupdate_state );
- csnfge.f_next = filter;
-
- id = entry->e_id;
-
- /* check for abandon */
- if ( ps_op->o_abandon ) {
- rc = 0;
- goto done;
- }
-
- /* check time limit */
- if ( tlimit != -1 && slap_get_time() > stoptime ) {
- send_search_result( ps_conn, ps_op, rc = LDAP_TIMELIMIT_EXCEEDED,
- NULL, NULL, v2refs, NULL, nentries );
- goto done;
- }
-
- e = entry;
-
-#ifdef BDB_SUBENTRIES
- if ( is_entry_subentry( e ) ) {
- if( scope != LDAP_SCOPE_BASE ) {
- if(!get_subentries_visibility( ps_op )) {
- /* only subentries are visible */
- goto test_done;
- }
-
- } else if ( get_subentries( ps_op ) &&
- !get_subentries_visibility( ps_op ))
- {
- /* only subentries are visible */
- goto test_done;
- }
-
- } else if ( get_subentries_visibility( ps_op )) {
- /* only subentries are visible */
- goto test_done;
- }
-#endif
-
-#ifdef BDB_ALIASES
- if ( deref & LDAP_DEREF_SEARCHING && is_entry_alias( e ) ) {
- Entry *matched;
- int err;
- const char *text;
-
- e = deref_entry_r( be, e, &err, &matched, &text );
-
- if( e == NULL ) {
- e = matched;
- goto test_done;
- }
-
- if( e->e_id == id ) {
- /* circular loop */
- goto test_done;
- }
-
- /* need to skip alias which deref into scope */
- if( scope & LDAP_SCOPE_ONELEVEL ) {
- struct berval pdn;
-
- dnParent( &e->e_nname, &pdn ):
- if ( ber_bvcmp( pdn, &realbase ) ) {
- goto test_done;
- }
-
- } else if ( dnIsSuffix( &e->e_nname, &realbase ) ) {
- /* alias is within scope */
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, RESULTS,
- "bdb_search: \"%s\" in subtree\n", e->edn, 0, 0);
-#else
- Debug( LDAP_DEBUG_TRACE,
- "bdb_search: \"%s\" in subtree\n",
- e->e_dn, 0, 0 );
-#endif
- goto test_done;
- }
-
- scopeok = 1;
- }
-#endif
-
- /*
- * if it's a referral, add it to the list of referrals. only do
- * this for non-base searches, and don't check the filter
- * explicitly here since it's only a candidate anyway.
- */
- if ( !manageDSAit && scope != LDAP_SCOPE_BASE &&
- is_entry_referral( e ) )
- {
- struct berval dn;
-
- /* check scope */
- if ( !scopeok && scope == LDAP_SCOPE_ONELEVEL ) {
- if ( !be_issuffix( be, &e->e_nname ) ) {
- dnParent( &e->e_nname, &dn );
- scopeok = dn_match( &dn, &realbase );
- } else {
- scopeok = (realbase.bv_len == 0);
- }
-
- } else if ( !scopeok && scope == LDAP_SCOPE_SUBTREE ) {
- scopeok = dnIsSuffix( &e->e_nname, &realbase );
-
- } else {
- scopeok = 1;
- }
-
- if( scopeok ) {
- BerVarray erefs = get_entry_referrals(
- be, ps_conn, ps_op, e );
- BerVarray refs = referral_rewrite( erefs,
- &e->e_name, NULL,
- scope == LDAP_SCOPE_SUBTREE
- ? LDAP_SCOPE_SUBTREE
- : LDAP_SCOPE_BASE );
-
- send_search_reference( be, ps_conn, ps_op,
- e, refs, NULL, &v2refs );
-
- ber_bvarray_free( refs );
-
- } else {
-#ifdef NEW_LOGGING
- LDAP_LOG(OPERATION, DETAIL2,
- "bdb_search: candidate referral %ld scope not okay\n",
- id, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE,
- "bdb_search: candidate referral %ld scope not okay\n",
- id, 0, 0 );
-#endif
- }
-
- goto test_done;
- }
-
- if ( psearch_type != LCUP_PSEARCH_BY_SCOPEOUT ) {
- rc = test_filter( be, ps_conn, ps_op, e, &lcupf );
- } else {
- rc = LDAP_COMPARE_TRUE;
- }
-
- if ( rc == LDAP_COMPARE_TRUE ) {
- struct berval dn;
-
- /* check scope */
- if ( !scopeok && scope == LDAP_SCOPE_ONELEVEL ) {
- if ( be_issuffix( be, &e->e_nname ) ) {
- scopeok = (realbase.bv_len == 0);
- } else {
- dnParent( &e->e_nname, &dn );
- scopeok = dn_match( &dn, &realbase );
- }
-
- } else if ( !scopeok && scope == LDAP_SCOPE_SUBTREE ) {
- scopeok = dnIsSuffix( &e->e_nname, &realbase );
-
- } else {
- scopeok = 1;
- }
-
- if ( scopeok ) {
- /* check size limit */
- if ( --slimit == -1 ) {
- send_search_result( ps_conn, ps_op,
- rc = LDAP_SIZELIMIT_EXCEEDED, NULL, NULL,
- v2refs, NULL, nentries );
- goto done;
- }
-
- if (e) {
- int result;
-
-#if 0 /* noop is masked SLAP_CTRL_UPDATE */
- if( ps_op->o_noop ) {
- result = 0;
- } else
-#endif
- {
- if ( psearch_type == LCUP_PSEARCH_BY_ADD ||
- psearch_type == LCUP_PSEARCH_BY_DELETE ||
- psearch_type == LCUP_PSEARCH_BY_MODIFY ||
- psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
- {
- Attribute* a;
- int ret;
- int res;
- const char *text = NULL;
- LDAPControl *ctrls[2];
- struct berval *bv;
-
- BerElement *ber = ber_alloc_t( LBER_USE_DER );
-
- if ( ber == NULL ) {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, RESULTS,
- "bdb_search: ber_alloc_t failed\n",
- 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE,
- "bdb_search: ber_alloc_t failed\n",
- 0, 0, 0 );
-#endif
- send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
- NULL, "internal error", NULL, NULL );
- goto done;
- }
-
- LDAP_LIST_FIRST(&ps_op->psearch_spec)->entry_count++;
-
- ctrls[0] = ch_malloc ( sizeof ( LDAPControl ) );
- ctrls[1] = NULL;
-
- if ( LDAP_LIST_FIRST(
- &ps_op->psearch_spec)->entry_count %
- ps_op->o_clientupdate_interval == 0 )
- {
- /* Send cookie */
- for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
- AttributeDescription *desc = a->a_desc;
- if ( desc == slap_schema.si_ad_entryCSN ) {
- ber_dupbv( &entrycsn_bv, &a->a_vals[0] );
- if ( latest_entrycsn_bv.bv_val == NULL ) {
- ber_dupbv( &latest_entrycsn_bv,
- &entrycsn_bv );
- } else {
- res = value_match( &ret, desc,
- desc->ad_type->sat_ordering,
- SLAP_MR_ASSERTION_SYNTAX_MATCH,
- &entrycsn_bv, &latest_entrycsn_bv,
- &text );
- if ( res != LDAP_SUCCESS ) {
- ret = 0;
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, RESULTS,
- "bdb_search: "
- "value_match failed\n",
- 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE,
- "bdb_search: "
- "value_match failed\n",
- 0, 0, 0 );
-#endif
- }
-
- if ( ret > 0 ) {
- ch_free(latest_entrycsn_bv.bv_val);
- latest_entrycsn_bv.bv_val = NULL;
- ber_dupbv( &latest_entrycsn_bv,
- &entrycsn_bv );
- }
- }
- }
- }
-
- if ( psearch_type != LCUP_PSEARCH_BY_DELETE ||
- psearch_type != LCUP_PSEARCH_BY_SCOPEOUT )
- {
- ber_printf( ber, "{bb{sON}N}",
- SLAP_LCUP_STATE_UPDATE_FALSE,
- SLAP_LCUP_ENTRY_DELETED_FALSE,
- LCUP_COOKIE_OID, &entrycsn_bv );
- } else {
- ber_printf( ber, "{bb{sON}N}",
- SLAP_LCUP_STATE_UPDATE_FALSE,
- SLAP_LCUP_ENTRY_DELETED_TRUE,
- LCUP_COOKIE_OID, &entrycsn_bv );
- }
-
- ch_free( entrycsn_bv.bv_val );
- entrycsn_bv.bv_val = NULL;
-
- } else {
- /* Do not send cookie */
- if ( psearch_type != LCUP_PSEARCH_BY_DELETE ||
- psearch_type != LCUP_PSEARCH_BY_SCOPEOUT )
- {
- ber_printf( ber, "{bbN}",
- SLAP_LCUP_STATE_UPDATE_FALSE,
- SLAP_LCUP_ENTRY_DELETED_FALSE );
- } else {
- ber_printf( ber, "{bbN}",
- SLAP_LCUP_STATE_UPDATE_FALSE,
- SLAP_LCUP_ENTRY_DELETED_TRUE );
- }
- }
-
- ctrls[0]->ldctl_oid = LDAP_CONTROL_ENTRY_UPDATE;
- ctrls[0]->ldctl_iscritical = ps_op->o_clientupdate;
- ret = ber_flatten( ber, &bv );
-
- if ( ret < 0 ) {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, RESULTS,
- "bdb_search: ber_flatten failed\n",
- 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE,
- "bdb_search: ber_flatten failed\n",
- 0, 0, 0 );
-#endif
- send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
- NULL, "internal error", NULL, NULL );
- goto done;
- }
-
- ber_dupbv( &ctrls[0]->ldctl_value, bv );
-
- result = send_search_entry( be, ps_conn, ps_op,
- e, attrs, attrsonly, ctrls);
-
- ch_free( ctrls[0]->ldctl_value.bv_val );
- ch_free( ctrls[0] );
- ber_free( ber, 1 );
- ber_bvfree( bv );
-
- if ( psearch_type == LCUP_PSEARCH_BY_MODIFY ) {
- struct psid_entry* psid_e;
- LDAP_LIST_FOREACH( psid_e, &op->premodify_list,
- link)
- {
- if( psid_e->ps ==
- LDAP_LIST_FIRST(&ps_op->psearch_spec))
- {
- LDAP_LIST_REMOVE(psid_e, link);
- break;
- }
- }
- if (psid_e != NULL) free (psid_e);
- }
-
- } else if ( psearch_type == LCUP_PSEARCH_BY_PREMODIFY ) {
- struct psid_entry* psid_e;
- psid_e = (struct psid_entry *) calloc (1,
- sizeof(struct psid_entry));
- psid_e->ps = LDAP_LIST_FIRST(&ps_op->psearch_spec);
- LDAP_LIST_INSERT_HEAD( &op->premodify_list,
- psid_e, link );
-
- } else {
- printf("Error !\n");
- }
- }
-
- switch (result) {
- case 0: /* entry sent ok */
- nentries++;
- break;
- case 1: /* entry not sent */
- break;
- case -1: /* connection closed */
- rc = LDAP_OTHER;
- goto done;
- }
- }
- } else {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, RESULTS,
- "bdb_search: %ld scope not okay\n", (long) id, 0, 0);
-#else
- Debug( LDAP_DEBUG_TRACE,
- "bdb_search: %ld scope not okay\n", (long) id, 0, 0 );
-#endif
- }
- } else {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, RESULTS,
- "bdb_search: %ld does match filter\n", (long) id, 0, 0);
-#else
- Debug( LDAP_DEBUG_TRACE,
- "bdb_search: %ld does match filter\n",
- (long) id, 0, 0 );
-#endif
- }
-
-test_done:
- rc = LDAP_SUCCESS;
-
-done:
- if ( csnfeq.f_ava != NULL && csnfeq.f_av_value.bv_val != NULL ) {
- ch_free( csnfeq.f_av_value.bv_val );
- }
-
- if ( csnfge.f_ava != NULL && csnfge.f_av_value.bv_val != NULL ) {
- ch_free( csnfge.f_av_value.bv_val );
- }
-
- LOCK_ID_FREE( bdb->bi_dbenv, locker );
-
- if( v2refs ) ber_bvarray_free( v2refs );
- if( realbase.bv_val ) ch_free( realbase.bv_val );
- if ( psearch_type == LCUP_PSEARCH_BY_DELETE ||
- psearch_type == LCUP_PSEARCH_BY_SCOPEOUT )
- ch_free( attrs[0].an_name.bv_val );
-
- return rc;
-}
-
-static int psearch_base_candidate(
- BackendDB *be,
- Entry *e,
- ID *ids )
-{
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, ENTRY,
- "psearch_base_candidate: base: \"%s\" (0x%08lx)\n", e->e_dn, (long) e->e_id, 0);
-#else
- Debug(LDAP_DEBUG_ARGS, "psearch_base_candidates: base: \"%s\" (0x%08lx)\n",
- e->e_dn, (long) e->e_id, 0);
-#endif
-
- ids[0] = 1;
- ids[1] = e->e_id;
- return 0;
-}
-
-/* Look for "objectClass Present" in this filter.
- * Also count depth of filter tree while we're at it.
- */
-static int psearch_oc_filter(
- Filter *f,
- int cur,
- int *max
-)
-{
- int rc = 0;
-
- if( cur > *max ) *max = cur;
-
- switch(f->f_choice) {
- case LDAP_FILTER_PRESENT:
- if (f->f_desc == slap_schema.si_ad_objectClass) {
- rc = 1;
- }
- break;
-
- case LDAP_FILTER_AND:
- case LDAP_FILTER_OR:
- cur++;
- for (f=f->f_and; f; f=f->f_next) {
- (void) psearch_oc_filter(f, cur, max);
- }
- break;
-
- default:
- break;
- }
- return rc;
-}
-
-static int psearch_candidates(
- BackendDB *be,
- Operation *op,
- Entry *e,
- Filter *filter,
- int scope,
- int deref,
- ID *ids )
-{
- int rc, depth = 1;
- Filter f, scopef, rf, xf;
- ID *stack;
- AttributeAssertion aa_ref;
-#ifdef BDB_SUBENTRIES
- Filter sf;
- AttributeAssertion aa_subentry;
-#endif
-#ifdef BDB_ALIASES
- Filter af;
- AttributeAssertion aa_alias;
-#endif
-
- /*
- * This routine takes as input a filter (user-filter)
- * and rewrites it as follows:
- * (&(scope=DN)[(objectClass=subentry)]
- * (|[(objectClass=referral)(objectClass=alias)](user-filter))
- */
-
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, ENTRY,
- "psearch_candidates: base=\"%s\" (0x%08lx) scope=%d\n",
- e->e_dn, (long) e->e_id, scope);
-#else
- Debug(LDAP_DEBUG_TRACE,
- "psearch_candidates: base=\"%s\" (0x%08lx) scope=%d\n",
- e->e_dn, (long) e->e_id, scope );
-#endif
-
- xf.f_or = filter;
- xf.f_choice = LDAP_FILTER_OR;
- xf.f_next = NULL;
-
- /* If the user's filter uses objectClass=*,
- * these clauses are redundant.
- */
- if (!psearch_oc_filter(filter, 1, &depth) && !get_subentries_visibility(op) ) {
- if( !get_manageDSAit(op) ) { /* match referrals */
- struct berval bv_ref = { sizeof("REFERRAL")-1, "REFERRAL" };
- rf.f_choice = LDAP_FILTER_EQUALITY;
- rf.f_ava = &aa_ref;
- rf.f_av_desc = slap_schema.si_ad_objectClass;
- rf.f_av_value = bv_ref;
- rf.f_next = xf.f_or;
- xf.f_or = &rf;
- }
-
-#ifdef BDB_ALIASES
- if( deref & LDAP_DEREF_SEARCHING ) { /* match aliases */
- struct berval bv_alias = { sizeof("ALIAS")-1, "ALIAS" };
- af.f_choice = LDAP_FILTER_EQUALITY;
- af.f_ava = &aa_alias;
- af.f_av_desc = slap_schema.si_ad_objectClass;
- af.f_av_value = bv_alias;
- af.f_next = xf.f_or;
- xf.f_or = ⁡
- }
-#endif
- /* We added one of these clauses, filter depth increased */
- if( xf.f_or != filter ) depth++;
- }
-
- f.f_next = NULL;
- f.f_choice = LDAP_FILTER_AND;
- f.f_and = &scopef;
- scopef.f_choice = scope == LDAP_SCOPE_SUBTREE
- ? SLAPD_FILTER_DN_SUBTREE
- : SLAPD_FILTER_DN_ONE;
- scopef.f_dn = &e->e_nname;
- scopef.f_next = xf.f_or == filter ? filter : &xf ;
- /* Filter depth increased again, adding scope clause */
- depth++;
-
-#ifdef BDB_SUBENTRIES
- if( get_subentries_visibility( op ) ) {
- struct berval bv_subentry = { sizeof("SUBENTRY")-1, "SUBENTRY" };
- sf.f_choice = LDAP_FILTER_EQUALITY;
- sf.f_ava = &aa_subentry;
- sf.f_av_desc = slap_schema.si_ad_objectClass;
- sf.f_av_value = bv_subentry;
- sf.f_next = scopef.f_next;
- scopef.f_next = &sf;
- }
-#endif
-
- /* Allocate IDL stack, plus 1 more for former tmp */
- stack = ch_malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );
-
- rc = bdb_filter_candidates( be, &f, ids, stack, stack+BDB_IDL_UM_SIZE );
-
- ch_free( stack );
-
- if( rc ) {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, DETAIL1,
- "bdb_psearch_candidates: failed (rc=%d)\n", rc, 0, 0 );
-#else
- Debug(LDAP_DEBUG_TRACE,
- "bdb_psearch_candidates: failed (rc=%d)\n",
- rc, NULL, NULL );
-#endif
-
- } else {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, DETAIL1,
- "bdb_psearch_candidates: id=%ld first=%ld last=%ld\n",
- (long) ids[0], (long) BDB_IDL_FIRST(ids),
- (long) BDB_IDL_LAST(ids));
-#else
- Debug(LDAP_DEBUG_TRACE,
- "bdb_psearch_candidates: id=%ld first=%ld last=%ld\n",
- (long) ids[0],
- (long) BDB_IDL_FIRST(ids),
- (long) BDB_IDL_LAST(ids) );
-#endif
- }
-
- return rc;
-}
-
-
-#endif /* LDAP_CLIENT_UPDATE */
/* modify.c - bdb backend modify routine */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#else
Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: add\n", 0, 0, 0);
#endif
- err = modify_add_values( e, mod, text, textbuf, textlen );
+ err = modify_add_values( e, mod, get_permitmodify(op),
+ text, textbuf, textlen );
if( err != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ERR,
#else
Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: delete\n", 0, 0, 0);
#endif
- err = modify_delete_values( e, mod, text, textbuf, textlen );
+ err = modify_delete_values( e, mod, get_permitmodify(op),
+ text, textbuf, textlen );
assert( err != LDAP_TYPE_OR_VALUE_EXISTS );
if( err != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
#else
Debug(LDAP_DEBUG_ARGS, "bdb_modify_internal: replace\n", 0, 0, 0);
#endif
- err = modify_replace_values( e, mod, text, textbuf, textlen );
+ err = modify_replace_values( e, mod, get_permitmodify(op),
+ text, textbuf, textlen );
if( err != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ERR,
*/
mod->sm_op = LDAP_MOD_ADD;
- err = modify_add_values( e, mod, text, textbuf, textlen );
+ err = modify_add_values( e, mod, get_permitmodify(op),
+ text, textbuf, textlen );
if ( err == LDAP_TYPE_OR_VALUE_EXISTS ) {
err = LDAP_SUCCESS;
}
DB_TXN *ltid = NULL;
struct bdb_op_info opinfo;
- u_int32_t locker;
+ u_int32_t locker = 0;
DB_LOCK lock;
int noop = 0;
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
Operation* ps_list;
struct psid_entry* pm_list;
struct psid_entry* pm_prev;
"bdb_modify: retrying...\n", 0, 0, 0);
#endif
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
pm_list = LDAP_LIST_FIRST(&op->premodify_list);
while ( pm_list != NULL ) {
LDAP_LIST_REMOVE ( pm_list, link );
opinfo.boi_bdb = be;
opinfo.boi_txn = ltid;
+ opinfo.boi_locker = locker;
opinfo.boi_err = 0;
op->o_private = &opinfo;
goto done;
}
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
if ( rc == LDAP_SUCCESS && !op->o_noop ) {
LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
- bdb_psearch(be, conn, op, ps_list, e, LCUP_PSEARCH_BY_PREMODIFY );
+ bdb_psearch(be, conn, op, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
}
}
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
/* Modify the entry */
rc = bdb_modify_internal( be, conn, op, ltid, modlist, e,
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
if ( rc == LDAP_SUCCESS && !op->o_noop ) {
/* Loop through in-scope entries for each psearch spec */
LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
- bdb_psearch( be, conn, op, ps_list, e, LCUP_PSEARCH_BY_MODIFY );
+ bdb_psearch( be, conn, op, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
}
pm_list = LDAP_LIST_FIRST(&op->premodify_list);
while ( pm_list != NULL ) {
bdb_psearch(be, conn, op, pm_list->ps->op,
- e, LCUP_PSEARCH_BY_SCOPEOUT);
+ e, LDAP_PSEARCH_BY_SCOPEOUT);
LDAP_LIST_REMOVE ( pm_list, link );
pm_prev = pm_list;
pm_list = LDAP_LIST_NEXT ( pm_list, link );
free (pm_prev);
}
}
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
if( rc == LDAP_SUCCESS && bdb->bi_txn_cp ) {
ldap_pvt_thread_yield();
done:
if( ltid != NULL ) {
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
pm_list = LDAP_LIST_FIRST(&op->premodify_list);
while ( pm_list != NULL ) {
LDAP_LIST_REMOVE ( pm_list, link );
/* modrdn.c - bdb backend modrdn routine */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
int manageDSAit = get_manageDSAit( op );
- u_int32_t locker;
+ u_int32_t locker = 0;
DB_LOCK lock;
int noop = 0;
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
Operation* ps_list;
struct psid_entry* pm_list;
struct psid_entry* pm_prev;
Debug( LDAP_DEBUG_TRACE, "==>bdb_modrdn: retrying...\n", 0, 0, 0 );
#endif
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
pm_list = LDAP_LIST_FIRST(&op->premodify_list);
while ( pm_list != NULL ) {
LDAP_LIST_REMOVE ( pm_list, link );
opinfo.boi_bdb = be;
opinfo.boi_txn = ltid;
+ opinfo.boi_locker = locker;
opinfo.boi_err = 0;
op->o_private = &opinfo;
goto return_results;
}
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
if ( rc == LDAP_SUCCESS && !op->o_noop ) {
LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
- bdb_psearch(be, conn, op, ps_list, e, LCUP_PSEARCH_BY_PREMODIFY );
+ bdb_psearch(be, conn, op, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
}
}
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
/* modify entry */
rc = bdb_modify_internal( be, conn, op, ltid, &mod[0], e,
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
if ( rc == LDAP_SUCCESS && !op->o_noop ) {
/* Loop through in-scope entries for each psearch spec */
LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
- bdb_psearch( be, conn, op, ps_list, e, LCUP_PSEARCH_BY_MODIFY );
+ bdb_psearch( be, conn, op, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
}
pm_list = LDAP_LIST_FIRST(&op->premodify_list);
while ( pm_list != NULL ) {
bdb_psearch(be, conn, op, pm_list->ps->op,
- e, LCUP_PSEARCH_BY_SCOPEOUT);
+ e, LDAP_PSEARCH_BY_SCOPEOUT);
LDAP_LIST_REMOVE ( pm_list, link );
pm_prev = pm_list;
pm_list = LDAP_LIST_NEXT ( pm_list, link );
free (pm_prev);
}
}
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
if( rc == LDAP_SUCCESS && bdb->bi_txn_cp ) {
ldap_pvt_thread_yield();
}
if( ltid != NULL ) {
-#ifdef LDAP_CLIENT_UPDATE
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
pm_list = LDAP_LIST_FIRST(&op->premodify_list);
while ( pm_list != NULL ) {
LDAP_LIST_REMOVE ( pm_list, link );
/* operational.c - bdb backend operational attributes function */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
opinfo.boi_bdb = be;
opinfo.boi_txn = ltid;
+ opinfo.boi_locker = TXN_ID ( ltid );
opinfo.boi_err = 0;
op->o_private = &opinfo;
/* passwd.c - bdb backend password routines */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
struct berval dn;
struct berval ndn;
- u_int32_t locker;
+ u_int32_t locker = 0;
DB_LOCK lock;
assert( reqoid != NULL );
opinfo.boi_bdb = be;
opinfo.boi_txn = ltid;
+ opinfo.boi_locker = locker;
opinfo.boi_err = 0;
op->o_private = &opinfo;
/* $OpenLDAP$ */
/*
- * Copyright 2000-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 2000-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
);
void bdb_cache_release_all( Cache *cache );
+/*
+ * lcup.c
+ */
+
#ifdef LDAP_CLIENT_UPDATE
int bdb_abandon(
BackendDB *be,
Connection *conn,
ber_int_t id
);
+#endif
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
int bdb_add_psearch_spec(
BackendDB *be,
Connection *conn,
Filter *filter,
struct berval *fstr,
AttributeName *attrs,
- int attrsonly
+ int attrsonly,
+ int protocol
);
int bdb_psearch(
Entry *entry,
int psearch_type
);
+#endif
+
+/*
+ * search.c
+ */
+#ifdef LDAP_CLIENT_UPDATE
+int
+bdb_build_lcup_update_ctrl(
+ Connection *conn,
+ Operation *op,
+ Entry *e,
+ int entry_count,
+ LDAPControl **ctrls,
+ int num_ctrls,
+ struct berval *latest_entrycsn_bv,
+ int isdeleted );
+
+int
+bdb_build_lcup_done_ctrl(
+ Connection *conn,
+ Operation *op,
+ LDAPControl **ctrls,
+ int num_ctrls,
+ struct berval *latest_entrycsn_bv );
+#endif
+
+#ifdef LDAP_SYNC
+int
+bdb_build_sync_state_ctrl(
+ Connection *conn,
+ Operation *op,
+ Entry *e,
+ int entry_sync_state,
+ LDAPControl **ctrls,
+ int num_ctrls,
+ int send_cookie,
+ struct berval *latest_entrycsn_bv );
+
+int
+bdb_build_sync_done_ctrl(
+ Connection *conn,
+ Operation *op,
+ LDAPControl **ctrls,
+ int num_ctrls,
+ int send_cookie,
+ struct berval *latest_entrycsn_bv );
+
+int
+bdb_send_ldap_intermediate(
+ Connection *conn,
+ Operation *op,
+ ber_int_t err,
+ const char *matched,
+ const char *text,
+ BerVarray refs,
+ const char *rspoid,
+ int state,
+ struct berval *cookie,
+ LDAPControl **ctrls );
#endif
#ifdef BDB_REUSE_LOCKERS
--- /dev/null
+/* psearch.c - psearch operations */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include "back-bdb.h"
+#include "idl.h"
+#include "external.h"
+
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+
+#define IS_BDB_REPLACE (( psearch_type == LDAP_PSEARCH_BY_DELETE ) || \
+ ( psearch_type == LDAP_PSEARCH_BY_SCOPEOUT ))
+#define IS_BDB_LCUP_REPLACE (( protocol == LDAP_CLIENT_UPDATE ) && IS_BDB_REPLACE )
+
+static int psearch_base_candidate(
+ BackendDB *be,
+ Entry *e,
+ ID *ids );
+
+static int psearch_candidates(
+ BackendDB *be,
+ Operation *op,
+ Entry *e,
+ Filter *filter,
+ int scope,
+ int deref,
+ ID *ids );
+
+int
+bdb_abandon(
+ BackendDB *be,
+ Connection *conn,
+ ber_int_t id )
+{
+ Operation *ps_list;
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+
+ LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
+ if ( ps_list->o_connid == conn->c_connid ) {
+ if ( ps_list->o_msgid == id ) {
+ ps_list->o_abandon = 1;
+ LDAP_LIST_REMOVE( ps_list, link );
+ slap_op_free ( ps_list );
+ return LDAP_SUCCESS;
+ }
+ }
+ }
+ return LDAP_UNAVAILABLE;
+}
+
+int
+bdb_cancel(
+ BackendDB *be,
+ Connection *conn,
+ ber_int_t id )
+{
+ Operation *ps_list;
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+
+ LDAP_LIST_FOREACH ( ps_list, &bdb->psearch_list, link ) {
+ if ( ps_list->o_connid == conn->c_connid ) {
+ if ( ps_list->o_msgid == id ) {
+ ps_list->o_cancel = LDAP_CANCEL_DONE;
+ LDAP_LIST_REMOVE( ps_list, link );
+
+#if 0
+ bdb_build_sync_done_ctrl( conn, ps_list, ps_list->ctrls, 1, &latest_entrycsn_bv );
+ send_search_result( conn, ps_list, LDAP_CANCELLED,
+ NULL, NULL, NULL, ps_list->ctrls, ps_list->nentries);
+#endif
+ send_search_result( conn, ps_list, LDAP_CANCELLED,
+ NULL, NULL, NULL, NULL, 0);
+
+
+
+ slap_op_free ( ps_list );
+ return LDAP_SUCCESS;
+ }
+ }
+ }
+ return LDAP_UNAVAILABLE;
+}
+
+int
+bdb_add_psearch_spec(
+ BackendDB *be,
+ Connection *conn,
+ Operation *op,
+ struct berval *base,
+ struct berval *nbase,
+ int scope,
+ int deref,
+ int slimit,
+ int tlimit,
+ Filter *filter,
+ struct berval *fstr,
+ AttributeName *attrs,
+ int attrsonly,
+ int protocol )
+{
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+
+ LDAP_LIST_FIRST( &op->psearch_spec ) = (struct ldap_psearch_spec *)
+ calloc ( 1, sizeof ( struct ldap_psearch_spec ) );
+
+ LDAP_LIST_FIRST( &op->psearch_spec )->op = op;
+
+ LDAP_LIST_FIRST( &op->psearch_spec )->base = ber_dupbv(NULL, base);
+ LDAP_LIST_FIRST( &op->psearch_spec )->nbase = ber_dupbv(NULL, nbase);
+
+ LDAP_LIST_FIRST( &op->psearch_spec )->scope = scope;
+ LDAP_LIST_FIRST( &op->psearch_spec )->deref = deref;
+ LDAP_LIST_FIRST( &op->psearch_spec )->slimit = slimit;
+ LDAP_LIST_FIRST( &op->psearch_spec )->tlimit = tlimit;
+
+ LDAP_LIST_FIRST( &op->psearch_spec )->filter = filter;
+ LDAP_LIST_FIRST( &op->psearch_spec )->filterstr = ber_dupbv(NULL, fstr);
+ LDAP_LIST_FIRST( &op->psearch_spec )->attrs = attrs;
+
+ LDAP_LIST_FIRST( &op->psearch_spec )->attrsonly = attrsonly;
+
+ LDAP_LIST_FIRST( &op->psearch_spec )->entry_count = 0;
+
+ LDAP_LIST_FIRST( &op->psearch_spec )->protocol = protocol;
+
+ LDAP_LIST_INSERT_HEAD( &bdb->psearch_list, op, link );
+}
+
+int
+bdb_psearch(
+ BackendDB *be,
+ Connection *conn,
+ Operation *op,
+ Operation *ps_op,
+ Entry *entry,
+ int psearch_type )
+{
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+ int rc;
+ const char *text = NULL;
+ time_t stoptime;
+ unsigned cursor;
+ ID id;
+ ID candidates[BDB_IDL_UM_SIZE];
+ Entry *e = NULL;
+ BerVarray v2refs = NULL;
+ Entry *matched = NULL;
+ struct berval realbase = { 0, NULL };
+ int nentries = 0;
+ int manageDSAit;
+
+ Filter cookief, csnfnot, csnfeq, csnfand, csnfge;
+ AttributeAssertion aa_ge, aa_eq;
+ struct berval entrycsn_bv = { 0, NULL };
+ struct berval latest_entrycsn_bv = { 0, NULL };
+
+ LDAPControl *ctrls[SLAP_SEARCH_MAX_CTRLS];
+ int num_ctrls = 0;
+
+ struct slap_limits_set *limit = NULL;
+ int isroot = 0;
+ int scopeok = 0;
+
+ u_int32_t locker;
+ DB_LOCK lock;
+
+ Connection *ps_conn = ps_op->o_conn;
+ struct berval *base = LDAP_LIST_FIRST( &ps_op->psearch_spec )->base;
+ struct berval *nbase = LDAP_LIST_FIRST( &ps_op->psearch_spec )->nbase;
+ int scope = LDAP_LIST_FIRST( &ps_op->psearch_spec )->scope;
+ int deref = LDAP_LIST_FIRST( &ps_op->psearch_spec )->deref;
+ int slimit = LDAP_LIST_FIRST( &ps_op->psearch_spec )->slimit;
+ int tlimit = LDAP_LIST_FIRST( &ps_op->psearch_spec )->tlimit;
+ Filter *filter = LDAP_LIST_FIRST( &ps_op->psearch_spec )->filter;
+ struct berval *filterstr = LDAP_LIST_FIRST( &ps_op->psearch_spec )->filterstr;
+ int attrsonly = LDAP_LIST_FIRST( &ps_op->psearch_spec )->attrsonly;
+ int protocol = LDAP_LIST_FIRST( &ps_op->psearch_spec )->protocol;
+ AttributeName uuid_attr[2];
+ AttributeName *attrs;
+
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ENTRY, "bdb_back_search\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "=> bdb_back_search\n",
+ 0, 0, 0);
+#endif
+
+ manageDSAit = get_manageDSAit( ps_op );
+
+ rc = LOCK_ID (bdb->bi_dbenv, &locker );
+ switch(rc) {
+ case 0:
+ break;
+ default:
+ send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
+ NULL, "internal error", NULL, NULL );
+ return rc;
+ }
+
+ for ( num_ctrls = 0; num_ctrls < SLAP_SEARCH_MAX_CTRLS; num_ctrls++ )
+ ctrls[num_ctrls] = NULL;
+ num_ctrls = 0;
+
+ if ( !IS_BDB_REPLACE ) {
+ attrs = LDAP_LIST_FIRST(&ps_op->psearch_spec)->attrs;
+ } else {
+#ifdef LDAP_CLIENT_UPDATE
+ if ( protocol == LDAP_CLIENT_UPDATE ) {
+ attrs = uuid_attr;
+ attrs[0].an_desc = slap_schema.si_ad_entryUUID;
+ attrs[0].an_oc = NULL;
+ ber_dupbv( &attrs[0].an_name, &attrs[0].an_desc->ad_cname );
+ attrs[1].an_desc = NULL;
+ attrs[1].an_oc = NULL;
+ attrs[1].an_name.bv_len = 0;
+ attrs[1].an_name.bv_val = NULL;
+ } else
+#endif
+#ifdef LDAP_SYNC
+ if (protocol == LDAP_SYNC ) {
+ attrs = uuid_attr;
+ attrs[0].an_desc = NULL;
+ attrs[0].an_oc = NULL;
+ attrs[0].an_name.bv_len = 0;
+ attrs[0].an_name.bv_val = NULL;
+ } else
+#endif
+ {
+ rc = 1;
+ goto done;
+ }
+ }
+
+ if ( nbase->bv_len == 0 ) {
+ /* DIT root special case */
+ e = (Entry *) &slap_entry_root;
+ rc = 0;
+ } else
+#ifdef BDB_ALIASES
+ /* get entry with reader lock */
+ if ( deref & LDAP_DEREF_FINDING ) {
+ e = deref_dn_r( be, nbase-, &err, &matched, &text );
+
+ } else
+#endif
+ {
+dn2entry_retry:
+ rc = bdb_dn2entry_r( be, NULL, nbase, &e, &matched, 0, locker, &lock );
+ }
+
+ switch(rc) {
+ case DB_NOTFOUND:
+ case 0:
+ break;
+ case LDAP_BUSY:
+ if (e != NULL) {
+ bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
+ e, &lock);
+ }
+ if (matched != NULL) {
+ bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
+ matched, &lock);
+ }
+ send_ldap_result( ps_conn, ps_op, LDAP_BUSY,
+ NULL, "ldap server busy", NULL, NULL );
+ LOCK_ID_FREE( bdb->bi_dbenv, locker );
+#ifdef LDAP_CLIENT_UPDATE
+ if ( IS_BDB_LCUP_REPLACE )
+ ch_free( attrs[0].an_name.bv_val );
+#endif
+ return LDAP_BUSY;
+ case DB_LOCK_DEADLOCK:
+ case DB_LOCK_NOTGRANTED:
+ goto dn2entry_retry;
+ default:
+ if (e != NULL) {
+ bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
+ e, &lock);
+ }
+ if (matched != NULL) {
+ bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
+ matched, &lock);
+ }
+ send_ldap_result( ps_conn, ps_op, rc=LDAP_OTHER,
+ NULL, "internal error", NULL, NULL );
+ LOCK_ID_FREE( bdb->bi_dbenv, locker );
+#ifdef LDAP_CLIENT_UPDATE
+ if ( IS_BDB_LCUP_REPLACE )
+ ch_free( attrs[0].an_name.bv_val );
+#endif
+ return rc;
+ }
+
+ if ( e == NULL ) {
+ struct berval matched_dn = { 0, NULL };
+ BerVarray refs = NULL;
+
+ if ( matched != NULL ) {
+ BerVarray erefs;
+ ber_dupbv( &matched_dn, &matched->e_name );
+
+ erefs = is_entry_referral( matched )
+ ? get_entry_referrals( be, ps_conn, ps_op, matched )
+ : NULL;
+
+ bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
+ matched, &lock);
+ matched = NULL;
+
+ if( erefs ) {
+ refs = referral_rewrite( erefs, &matched_dn,
+ base, scope );
+ ber_bvarray_free( erefs );
+ }
+
+ } else {
+ refs = referral_rewrite( default_referral,
+ NULL, base, scope );
+ }
+
+ send_ldap_result( ps_conn, ps_op, rc=LDAP_REFERRAL ,
+ matched_dn.bv_val, text, refs, NULL );
+
+ LOCK_ID_FREE( bdb->bi_dbenv, locker );
+ if ( refs ) ber_bvarray_free( refs );
+ if ( matched_dn.bv_val ) ber_memfree( matched_dn.bv_val );
+#ifdef LDAP_CLIENT_UPDATE
+ if ( IS_BDB_LCUP_REPLACE )
+ ch_free( attrs[0].an_name.bv_val );
+#endif
+ return rc;
+ }
+
+ if (!manageDSAit && e != &slap_entry_root && is_entry_referral( e ) ) {
+ /* entry is a referral, don't allow add */
+ struct berval matched_dn;
+ BerVarray erefs, refs;
+
+ ber_dupbv( &matched_dn, &e->e_name );
+ erefs = get_entry_referrals( be, ps_conn, ps_op, e );
+ refs = NULL;
+
+ bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
+ e = NULL;
+
+ if( erefs ) {
+ refs = referral_rewrite( erefs, &matched_dn,
+ base, scope );
+ ber_bvarray_free( erefs );
+ }
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, RESULTS,
+ "bdb_search: entry is referral\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "bdb_search: entry is referral\n",
+ 0, 0, 0 );
+#endif
+
+ send_ldap_result( ps_conn, ps_op, LDAP_REFERRAL,
+ matched_dn.bv_val,
+ refs ? NULL : "bad referral object",
+ refs, NULL );
+
+ LOCK_ID_FREE( bdb->bi_dbenv, locker );
+ ber_bvarray_free( refs );
+ ber_memfree( matched_dn.bv_val );
+#ifdef LDAP_CLIENT_UPDATE
+ if ( IS_BDB_LCUP_REPLACE )
+ ch_free( attrs[0].an_name.bv_val );
+#endif
+ return 1;
+ }
+
+ /* if not root, get appropriate limits */
+ if ( be_isroot( be, &ps_op->o_ndn ) ) {
+ isroot = 1;
+ } else {
+ ( void ) get_limits( be, &ps_op->o_ndn, &limit );
+ }
+
+ /* The time/size limits come first because they require very little
+ * effort, so there's no chance the candidates are selected and then
+ * the request is not honored only because of time/size constraints */
+
+ /* if no time limit requested, use soft limit (unless root!) */
+ if ( isroot ) {
+ if ( tlimit == 0 ) {
+ tlimit = -1; /* allow root to set no limit */
+ }
+
+ if ( slimit == 0 ) {
+ slimit = -1;
+ }
+
+ } else {
+ /* if no limit is required, use soft limit */
+ if ( tlimit <= 0 ) {
+ tlimit = limit->lms_t_soft;
+
+ /* if requested limit higher than hard limit, abort */
+ } else if ( tlimit > limit->lms_t_hard ) {
+ /* no hard limit means use soft instead */
+ if ( limit->lms_t_hard == 0 && tlimit > limit->lms_t_soft ) {
+ tlimit = limit->lms_t_soft;
+
+ /* positive hard limit means abort */
+ } else if ( limit->lms_t_hard > 0 ) {
+ send_search_result( ps_conn, ps_op,
+ LDAP_UNWILLING_TO_PERFORM,
+ NULL, NULL, NULL, NULL, 0 );
+ rc = 0;
+ goto done;
+ }
+
+ /* negative hard limit means no limit */
+ }
+
+ /* if no limit is required, use soft limit */
+ if ( slimit <= 0 ) {
+ slimit = limit->lms_s_soft;
+
+ /* if requested limit higher than hard limit, abort */
+ } else if ( slimit > limit->lms_s_hard ) {
+ /* no hard limit means use soft instead */
+ if ( limit->lms_s_hard == 0 && slimit > limit->lms_s_soft ) {
+ slimit = limit->lms_s_soft;
+
+ /* positive hard limit means abort */
+ } else if ( limit->lms_s_hard > 0 ) {
+ send_search_result( ps_conn, ps_op,
+ LDAP_UNWILLING_TO_PERFORM,
+ NULL, NULL, NULL, NULL, 0 );
+ rc = 0;
+ goto done;
+ }
+
+ /* negative hard limit means no limit */
+ }
+ }
+
+ /* compute it anyway; root does not use it */
+ stoptime = ps_op->o_time + tlimit;
+
+ /* select candidates */
+ if ( scope == LDAP_SCOPE_BASE ) {
+ rc = psearch_base_candidate( be, e, candidates );
+ } else {
+ BDB_IDL_ALL( bdb, candidates );
+ rc = psearch_candidates( be, op, e, filter,
+ scope, deref, candidates );
+ }
+
+ if ( !BDB_IDL_IS_RANGE( candidates ) ) {
+ cursor = bdb_idl_search( candidates, entry->e_id );
+ if ( candidates[cursor] != entry->e_id ) {
+ goto test_done;
+ }
+ } else {
+ if ( entry->e_id < BDB_IDL_RANGE_FIRST(candidates) &&
+ entry->e_id > BDB_IDL_RANGE_LAST(candidates) )
+ {
+ goto test_done;
+ }
+ }
+
+ /* candidates = { e } */
+ candidates[0] = 1;
+ candidates[1] = entry->e_id;
+
+ /* need normalized dn below */
+ ber_dupbv( &realbase, &e->e_nname );
+
+ if ( e != &slap_entry_root ) {
+ bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
+ }
+ e = NULL;
+
+ if ( candidates[0] == 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, RESULTS,
+ "bdb_search: no candidates\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "bdb_search: no candidates\n",
+ 0, 0, 0 );
+#endif
+
+ send_search_result( ps_conn, ps_op,
+ LDAP_SUCCESS,
+ NULL, NULL, NULL, NULL, 0 );
+
+ rc = 1;
+ goto done;
+ }
+
+ /* if not root and candidates exceed to-be-checked entries, abort */
+ if ( !isroot && limit->lms_s_unchecked != -1 ) {
+ if ( BDB_IDL_N(candidates) > (unsigned) limit->lms_s_unchecked ) {
+ send_search_result( ps_conn, ps_op, LDAP_ADMINLIMIT_EXCEEDED,
+ NULL, NULL, NULL, NULL, 0 );
+ rc = 1;
+ goto done;
+ }
+ }
+
+#ifdef LDAP_CLIENT_UPDATE
+ if ( protocol == LDAP_CLIENT_UPDATE ) {
+ cookief.f_choice = LDAP_FILTER_AND;
+ cookief.f_and = &csnfnot;
+ cookief.f_next = NULL;
+
+ csnfnot.f_choice = LDAP_FILTER_NOT;
+ csnfnot.f_not = &csnfeq;
+ csnfnot.f_next = &csnfand;
+
+ csnfeq.f_choice = LDAP_FILTER_EQUALITY;
+ csnfeq.f_ava = &aa_eq;
+ csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
+ ber_dupbv( &csnfeq.f_av_value, &ps_op->o_clientupdate_state );
+
+ csnfand.f_choice = LDAP_FILTER_AND;
+ csnfand.f_and = &csnfge;
+ csnfand.f_next = NULL;
+
+ csnfge.f_choice = LDAP_FILTER_GE;
+ csnfge.f_ava = &aa_ge;
+ csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
+ ber_dupbv( &csnfge.f_av_value, &ps_op->o_clientupdate_state );
+ csnfge.f_next = filter;
+ }
+#endif
+#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
+ else
+#endif
+#ifdef LDAP_SYNC
+ if ( protocol == LDAP_SYNC ) {
+ cookief.f_choice = LDAP_FILTER_AND;
+ cookief.f_and = &csnfnot;
+ cookief.f_next = NULL;
+
+ csnfnot.f_choice = LDAP_FILTER_NOT;
+ csnfnot.f_not = &csnfeq;
+ csnfnot.f_next = &csnfand;
+
+ csnfeq.f_choice = LDAP_FILTER_EQUALITY;
+ csnfeq.f_ava = &aa_eq;
+ csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
+ ber_dupbv( &csnfeq.f_av_value, &ps_op->o_sync_state );
+
+ csnfand.f_choice = LDAP_FILTER_AND;
+ csnfand.f_and = &csnfge;
+ csnfand.f_next = NULL;
+
+ csnfge.f_choice = LDAP_FILTER_GE;
+ csnfge.f_ava = &aa_ge;
+ csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
+ ber_dupbv( &csnfge.f_av_value, &ps_op->o_sync_state );
+ csnfge.f_next = filter;
+ }
+#endif
+
+ id = entry->e_id;
+
+ /* check for abandon */
+ if ( ps_op->o_abandon ) {
+ rc = 0;
+ goto done;
+ }
+
+ /* check time limit */
+ if ( tlimit != -1 && slap_get_time() > stoptime ) {
+ send_search_result( ps_conn, ps_op, rc = LDAP_TIMELIMIT_EXCEEDED,
+ NULL, NULL, v2refs, NULL, nentries );
+ goto done;
+ }
+
+ e = entry;
+
+#ifdef BDB_SUBENTRIES
+ if ( is_entry_subentry( e ) ) {
+ if( scope != LDAP_SCOPE_BASE ) {
+ if(!get_subentries_visibility( ps_op )) {
+ /* only subentries are visible */
+ goto test_done;
+ }
+
+ } else if ( get_subentries( ps_op ) &&
+ !get_subentries_visibility( ps_op ))
+ {
+ /* only subentries are visible */
+ goto test_done;
+ }
+
+ } else if ( get_subentries_visibility( ps_op )) {
+ /* only subentries are visible */
+ goto test_done;
+ }
+#endif
+
+#ifdef BDB_ALIASES
+ if ( deref & LDAP_DEREF_SEARCHING && is_entry_alias( e ) ) {
+ Entry *matched;
+ int err;
+ const char *text;
+
+ e = deref_entry_r( be, e, &err, &matched, &text );
+
+ if( e == NULL ) {
+ e = matched;
+ goto test_done;
+ }
+
+ if( e->e_id == id ) {
+ /* circular loop */
+ goto test_done;
+ }
+
+ /* need to skip alias which deref into scope */
+ if( scope & LDAP_SCOPE_ONELEVEL ) {
+ struct berval pdn;
+
+ dnParent( &e->e_nname, &pdn ):
+ if ( ber_bvcmp( pdn, &realbase ) ) {
+ goto test_done;
+ }
+
+ } else if ( dnIsSuffix( &e->e_nname, &realbase ) ) {
+ /* alias is within scope */
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, RESULTS,
+ "bdb_search: \"%s\" in subtree\n", e->edn, 0, 0);
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_search: \"%s\" in subtree\n",
+ e->e_dn, 0, 0 );
+#endif
+ goto test_done;
+ }
+
+ scopeok = 1;
+ }
+#endif
+
+ /*
+ * if it's a referral, add it to the list of referrals. only do
+ * this for non-base searches, and don't check the filter
+ * explicitly here since it's only a candidate anyway.
+ */
+ if ( !manageDSAit && scope != LDAP_SCOPE_BASE &&
+ is_entry_referral( e ) )
+ {
+ struct berval dn;
+
+ /* check scope */
+ if ( !scopeok && scope == LDAP_SCOPE_ONELEVEL ) {
+ if ( !be_issuffix( be, &e->e_nname ) ) {
+ dnParent( &e->e_nname, &dn );
+ scopeok = dn_match( &dn, &realbase );
+ } else {
+ scopeok = (realbase.bv_len == 0);
+ }
+
+ } else if ( !scopeok && scope == LDAP_SCOPE_SUBTREE ) {
+ scopeok = dnIsSuffix( &e->e_nname, &realbase );
+
+ } else {
+ scopeok = 1;
+ }
+
+ if( scopeok ) {
+ BerVarray erefs = get_entry_referrals(
+ be, ps_conn, ps_op, e );
+ BerVarray refs = referral_rewrite( erefs,
+ &e->e_name, NULL,
+ scope == LDAP_SCOPE_SUBTREE
+ ? LDAP_SCOPE_SUBTREE
+ : LDAP_SCOPE_BASE );
+
+ send_search_reference( be, ps_conn, ps_op,
+ e, refs, NULL, &v2refs );
+
+ ber_bvarray_free( refs );
+
+ } else {
+#ifdef NEW_LOGGING
+ LDAP_LOG(OPERATION, DETAIL2,
+ "bdb_search: candidate referral %ld scope not okay\n",
+ id, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_search: candidate referral %ld scope not okay\n",
+ id, 0, 0 );
+#endif
+ }
+
+ goto test_done;
+ }
+
+ if ( psearch_type != LDAP_PSEARCH_BY_SCOPEOUT ) {
+ rc = test_filter( be, ps_conn, ps_op, e, &cookief );
+ } else {
+ rc = LDAP_COMPARE_TRUE;
+ }
+
+ if ( rc == LDAP_COMPARE_TRUE ) {
+ struct berval dn;
+
+ /* check scope */
+ if ( !scopeok && scope == LDAP_SCOPE_ONELEVEL ) {
+ if ( be_issuffix( be, &e->e_nname ) ) {
+ scopeok = (realbase.bv_len == 0);
+ } else {
+ dnParent( &e->e_nname, &dn );
+ scopeok = dn_match( &dn, &realbase );
+ }
+
+ } else if ( !scopeok && scope == LDAP_SCOPE_SUBTREE ) {
+ scopeok = dnIsSuffix( &e->e_nname, &realbase );
+
+ } else {
+ scopeok = 1;
+ }
+
+ if ( scopeok ) {
+ /* check size limit */
+ if ( --slimit == -1 ) {
+ send_search_result( ps_conn, ps_op,
+ rc = LDAP_SIZELIMIT_EXCEEDED, NULL, NULL,
+ v2refs, NULL, nentries );
+ goto done;
+ }
+
+ if (e) {
+ int result;
+
+#if 0 /* noop is masked SLAP_CTRL_UPDATE */
+ if( ps_op->o_noop ) {
+ result = 0;
+ } else
+#endif
+ {
+#ifdef LDAP_SYNC
+ int premodify_found = 0;
+ int entry_sync_state;
+#endif
+
+ if ( psearch_type == LDAP_PSEARCH_BY_ADD ||
+ psearch_type == LDAP_PSEARCH_BY_DELETE ||
+ psearch_type == LDAP_PSEARCH_BY_MODIFY ||
+ psearch_type == LDAP_PSEARCH_BY_SCOPEOUT )
+ {
+ if ( psearch_type == LDAP_PSEARCH_BY_MODIFY ) {
+ struct psid_entry* psid_e;
+ LDAP_LIST_FOREACH( psid_e, &op->premodify_list, link)
+ {
+ if( psid_e->ps == LDAP_LIST_FIRST(&ps_op->psearch_spec))
+ {
+#ifdef LDAP_SYNC
+ premodify_found = 1;
+#endif
+ LDAP_LIST_REMOVE(psid_e, link);
+ break;
+ }
+ }
+ if (psid_e != NULL) free (psid_e);
+ }
+#ifdef LDAP_SYNC
+ if ( psearch_type == LDAP_PSEARCH_BY_ADD )
+ entry_sync_state = LDAP_SYNC_ADD;
+ else if ( psearch_type == LDAP_PSEARCH_BY_DELETE )
+ entry_sync_state = LDAP_SYNC_DELETE;
+ else if ( psearch_type == LDAP_PSEARCH_BY_MODIFY ) {
+ if ( premodify_found )
+ entry_sync_state = LDAP_SYNC_MODIFY;
+ else
+ entry_sync_state = LDAP_SYNC_ADD;
+ } else if ( psearch_type == LDAP_PSEARCH_BY_SCOPEOUT )
+ entry_sync_state = LDAP_SYNC_DELETE;
+ else {
+ rc = 1;
+ goto done;
+ }
+#endif
+
+#ifdef LDAP_CLIENT_UPDATE
+ if ( protocol == LDAP_CLIENT_UPDATE ) {
+ int entry_count = ++(LDAP_LIST_FIRST(&ps_op->psearch_spec)->entry_count);
+ if ( IS_BDB_REPLACE ) {
+ rc = bdb_build_lcup_update_ctrl( ps_conn, ps_op, e, entry_count, ctrls,
+ num_ctrls++, &latest_entrycsn_bv, SLAP_LCUP_ENTRY_DELETED_TRUE );
+ } else {
+ rc = bdb_build_lcup_update_ctrl( ps_conn, ps_op, e, entry_count, ctrls,
+ num_ctrls++, &latest_entrycsn_bv, SLAP_LCUP_ENTRY_DELETED_FALSE );
+ }
+ if ( rc != LDAP_SUCCESS )
+ goto done;
+ result = send_search_entry( be, ps_conn, ps_op, e, attrs, attrsonly, ctrls );
+ if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
+ ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+ ch_free( ctrls[--num_ctrls] );
+ ctrls[num_ctrls] = NULL;
+ } else
+#endif
+#ifdef LDAP_SYNC
+ if ( protocol == LDAP_SYNC ) {
+ rc = bdb_build_sync_state_ctrl( ps_conn, ps_op, e, entry_sync_state, ctrls,
+ num_ctrls++, 1, &latest_entrycsn_bv );
+ if ( rc != LDAP_SUCCESS )
+ goto done;
+ result = send_search_entry( be, ps_conn, ps_op, e, attrs, attrsonly, ctrls );
+ if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
+ ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+ ch_free( ctrls[--num_ctrls] );
+ ctrls[num_ctrls] = NULL;
+ } else
+#endif
+ {
+ rc = 1;
+ goto done;
+ }
+
+ } else if ( psearch_type == LDAP_PSEARCH_BY_PREMODIFY ) {
+ struct psid_entry* psid_e;
+ psid_e = (struct psid_entry *) calloc (1,
+ sizeof(struct psid_entry));
+ psid_e->ps = LDAP_LIST_FIRST(&ps_op->psearch_spec);
+ LDAP_LIST_INSERT_HEAD( &op->premodify_list,
+ psid_e, link );
+
+ } else {
+ printf("Error !\n");
+ }
+ }
+
+ switch (result) {
+ case 0: /* entry sent ok */
+ nentries++;
+ break;
+ case 1: /* entry not sent */
+ break;
+ case -1: /* connection closed */
+ rc = LDAP_OTHER;
+ goto done;
+ }
+ }
+ } else {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, RESULTS,
+ "bdb_search: %ld scope not okay\n", (long) id, 0, 0);
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_search: %ld scope not okay\n", (long) id, 0, 0 );
+#endif
+ }
+ } else {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, RESULTS,
+ "bdb_search: %ld does match filter\n", (long) id, 0, 0);
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_search: %ld does match filter\n",
+ (long) id, 0, 0 );
+#endif
+ }
+
+test_done:
+ rc = LDAP_SUCCESS;
+
+done:
+ if ( csnfeq.f_ava != NULL && csnfeq.f_av_value.bv_val != NULL ) {
+ ch_free( csnfeq.f_av_value.bv_val );
+ }
+
+ if ( csnfge.f_ava != NULL && csnfge.f_av_value.bv_val != NULL ) {
+ ch_free( csnfge.f_av_value.bv_val );
+ }
+
+ LOCK_ID_FREE( bdb->bi_dbenv, locker );
+
+ if( v2refs ) ber_bvarray_free( v2refs );
+ if( realbase.bv_val ) ch_free( realbase.bv_val );
+#ifdef LDAP_CLIENT_UPDATE
+ if ( IS_BDB_LCUP_REPLACE )
+ ch_free( attrs[0].an_name.bv_val );
+#endif
+
+ return rc;
+}
+
+static int psearch_base_candidate(
+ BackendDB *be,
+ Entry *e,
+ ID *ids )
+{
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ENTRY,
+ "psearch_base_candidate: base: \"%s\" (0x%08lx)\n", e->e_dn, (long) e->e_id, 0);
+#else
+ Debug(LDAP_DEBUG_ARGS, "psearch_base_candidates: base: \"%s\" (0x%08lx)\n",
+ e->e_dn, (long) e->e_id, 0);
+#endif
+
+ ids[0] = 1;
+ ids[1] = e->e_id;
+ return 0;
+}
+
+/* Look for "objectClass Present" in this filter.
+ * Also count depth of filter tree while we're at it.
+ */
+static int psearch_oc_filter(
+ Filter *f,
+ int cur,
+ int *max
+)
+{
+ int rc = 0;
+
+ if( cur > *max ) *max = cur;
+
+ switch(f->f_choice) {
+ case LDAP_FILTER_PRESENT:
+ if (f->f_desc == slap_schema.si_ad_objectClass) {
+ rc = 1;
+ }
+ break;
+
+ case LDAP_FILTER_AND:
+ case LDAP_FILTER_OR:
+ cur++;
+ for (f=f->f_and; f; f=f->f_next) {
+ (void) psearch_oc_filter(f, cur, max);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return rc;
+}
+
+static int psearch_candidates(
+ BackendDB *be,
+ Operation *op,
+ Entry *e,
+ Filter *filter,
+ int scope,
+ int deref,
+ ID *ids )
+{
+ int rc, depth = 1;
+ Filter f, scopef, rf, xf;
+ ID *stack;
+ AttributeAssertion aa_ref;
+#ifdef BDB_SUBENTRIES
+ Filter sf;
+ AttributeAssertion aa_subentry;
+#endif
+#ifdef BDB_ALIASES
+ Filter af;
+ AttributeAssertion aa_alias;
+#endif
+
+ /*
+ * This routine takes as input a filter (user-filter)
+ * and rewrites it as follows:
+ * (&(scope=DN)[(objectClass=subentry)]
+ * (|[(objectClass=referral)(objectClass=alias)](user-filter))
+ */
+
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ENTRY,
+ "psearch_candidates: base=\"%s\" (0x%08lx) scope=%d\n",
+ e->e_dn, (long) e->e_id, scope);
+#else
+ Debug(LDAP_DEBUG_TRACE,
+ "psearch_candidates: base=\"%s\" (0x%08lx) scope=%d\n",
+ e->e_dn, (long) e->e_id, scope );
+#endif
+
+ xf.f_or = filter;
+ xf.f_choice = LDAP_FILTER_OR;
+ xf.f_next = NULL;
+
+ /* If the user's filter uses objectClass=*,
+ * these clauses are redundant.
+ */
+ if (!psearch_oc_filter(filter, 1, &depth) && !get_subentries_visibility(op) ) {
+ if( !get_manageDSAit(op) ) { /* match referrals */
+ struct berval bv_ref = { sizeof("REFERRAL")-1, "REFERRAL" };
+ rf.f_choice = LDAP_FILTER_EQUALITY;
+ rf.f_ava = &aa_ref;
+ rf.f_av_desc = slap_schema.si_ad_objectClass;
+ rf.f_av_value = bv_ref;
+ rf.f_next = xf.f_or;
+ xf.f_or = &rf;
+ }
+
+#ifdef BDB_ALIASES
+ if( deref & LDAP_DEREF_SEARCHING ) { /* match aliases */
+ struct berval bv_alias = { sizeof("ALIAS")-1, "ALIAS" };
+ af.f_choice = LDAP_FILTER_EQUALITY;
+ af.f_ava = &aa_alias;
+ af.f_av_desc = slap_schema.si_ad_objectClass;
+ af.f_av_value = bv_alias;
+ af.f_next = xf.f_or;
+ xf.f_or = ⁡
+ }
+#endif
+ /* We added one of these clauses, filter depth increased */
+ if( xf.f_or != filter ) depth++;
+ }
+
+ f.f_next = NULL;
+ f.f_choice = LDAP_FILTER_AND;
+ f.f_and = &scopef;
+ scopef.f_choice = scope == LDAP_SCOPE_SUBTREE
+ ? SLAPD_FILTER_DN_SUBTREE
+ : SLAPD_FILTER_DN_ONE;
+ scopef.f_dn = &e->e_nname;
+ scopef.f_next = xf.f_or == filter ? filter : &xf ;
+ /* Filter depth increased again, adding scope clause */
+ depth++;
+
+#ifdef BDB_SUBENTRIES
+ if( get_subentries_visibility( op ) ) {
+ struct berval bv_subentry = { sizeof("SUBENTRY")-1, "SUBENTRY" };
+ sf.f_choice = LDAP_FILTER_EQUALITY;
+ sf.f_ava = &aa_subentry;
+ sf.f_av_desc = slap_schema.si_ad_objectClass;
+ sf.f_av_value = bv_subentry;
+ sf.f_next = scopef.f_next;
+ scopef.f_next = &sf;
+ }
+#endif
+
+ /* Allocate IDL stack, plus 1 more for former tmp */
+ stack = ch_malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );
+
+ rc = bdb_filter_candidates( be, &f, ids, stack, stack+BDB_IDL_UM_SIZE );
+
+ ch_free( stack );
+
+ if( rc ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, DETAIL1,
+ "bdb_psearch_candidates: failed (rc=%d)\n", rc, 0, 0 );
+#else
+ Debug(LDAP_DEBUG_TRACE,
+ "bdb_psearch_candidates: failed (rc=%d)\n",
+ rc, NULL, NULL );
+#endif
+
+ } else {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, DETAIL1,
+ "bdb_psearch_candidates: id=%ld first=%ld last=%ld\n",
+ (long) ids[0], (long) BDB_IDL_FIRST(ids),
+ (long) BDB_IDL_LAST(ids));
+#else
+ Debug(LDAP_DEBUG_TRACE,
+ "bdb_psearch_candidates: id=%ld first=%ld last=%ld\n",
+ (long) ids[0],
+ (long) BDB_IDL_FIRST(ids),
+ (long) BDB_IDL_LAST(ids) );
+#endif
+ }
+
+ return rc;
+}
+
+
+#endif
/* search.c - search operation */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
int scope,
int deref,
ID *ids );
+static void send_pagerequest_response(
+ Connection *conn,
+ Operation *op,
+ ID lastid,
+ int nentries,
+ int tentries );
int
bdb_search(
struct berval realbase = { 0, NULL };
int nentries = 0;
int manageDSAit;
+ int tentries = 0;
+ ID lastid = NOID;
-#ifdef LDAP_CLIENT_UPDATE
- Filter lcupf, csnfnot, csnfeq, csnfand, csnfge;
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+ Filter cookief, csnfnot, csnfeq, csnfand, csnfge;
AttributeAssertion aa_ge, aa_eq;
int entry_count = 0;
- struct berval entrycsn_bv = { 0, NULL };
- struct berval latest_entrycsn_bv = { 0, NULL };
-#endif /* LDAP_CLIENT_UPDATE */
+ struct berval latest_entrycsn_bv = { 0, NULL };
+ LDAPControl *ctrls[SLAP_SEARCH_MAX_CTRLS];
+ int num_ctrls = 0;
+#endif
+
+#ifdef LDAP_SYNC
+ int rc_sync = 0;
+ int entry_sync_state;
+ AttributeName null_attr;
+#endif
struct slap_limits_set *limit = NULL;
int isroot = 0;
- u_int32_t locker;
+ u_int32_t locker = 0;
DB_LOCK lock;
+ struct bdb_op_info opinfo;
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY, "bdb_back_search\n", 0, 0, 0 );
#ifdef LDAP_CLIENT_UPDATE
if ( op->o_clientupdate_type & SLAP_LCUP_PERSIST ) {
- bdb_add_psearch_spec( be, conn, op, base, base, scope,
- deref, slimit, tlimit, filter, filterstr, attrs, attrsonly );
+ bdb_add_psearch_spec( be, conn, op, base, base, scope, deref, slimit,
+ tlimit, filter, filterstr, attrs, attrsonly, LDAP_CLIENT_UPDATE );
return LDAP_SUCCESS;
}
#endif
+#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
+ else
+#endif
+#ifdef LDAP_SYNC
+ /* psearch needs to be registered before refresh begins */
+ /* psearch and refresh transmission is serialized in send_ldap_ber() */
+ if ( op->o_sync_mode & SLAP_SYNC_PERSIST ) {
+ bdb_add_psearch_spec( be, conn, op, base, base, scope, deref, slimit,
+ tlimit, filter, filterstr, attrs, attrsonly, LDAP_SYNC );
+ }
+ null_attr.an_desc = NULL;
+ null_attr.an_oc = NULL;
+ null_attr.an_name.bv_len = 0;
+ null_attr.an_name.bv_val = NULL;
+#endif
+
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+ for ( num_ctrls = 0; num_ctrls < SLAP_SEARCH_MAX_CTRLS; num_ctrls++ )
+ ctrls[num_ctrls] = NULL;
+ num_ctrls = 0;
+#endif
manageDSAit = get_manageDSAit( op );
rc = LOCK_ID (bdb->bi_dbenv, &locker );
+
switch(rc) {
case 0:
break;
return rc;
}
+ opinfo.boi_bdb = be;
+ opinfo.boi_txn = NULL;
+ opinfo.boi_locker = locker;
+ opinfo.boi_err = 0;
+ op->o_private = &opinfo;
+
if ( nbase->bv_len == 0 ) {
/* DIT root special case */
e = (Entry *) &slap_entry_root;
/* if no limit is required, use soft limit */
if ( slimit <= 0 ) {
- slimit = limit->lms_s_soft;
+ if ( get_pagedresults(op) && limit->lms_s_pr != 0 ) {
+ slimit = limit->lms_s_pr;
+ } else {
+ slimit = limit->lms_s_soft;
+ }
/* if requested limit higher than hard limit, abort */
} else if ( slimit > limit->lms_s_hard ) {
}
}
+ if ( isroot || !limit->lms_s_pr_hide ) {
+ tentries = BDB_IDL_N(candidates);
+ }
+
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+ if ( get_pagedresults(op) ) {
+ if ( op->o_pagedresults_state.ps_cookie == 0 ) {
+ id = 0;
+ } else {
+ if ( op->o_pagedresults_size == 0 ) {
+ send_search_result( conn, op, LDAP_SUCCESS,
+ NULL, "search abandoned by pagedResult size=0",
+ NULL, NULL, 0);
+ goto done;
+ }
+ for ( id = bdb_idl_first( candidates, &cursor );
+ id != NOID && id <= (ID)( op->o_pagedresults_state.ps_cookie );
+ id = bdb_idl_next( candidates, &cursor ) );
+ }
+ if ( cursor == NOID ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, RESULTS,
+ "bdb_search: no paged results candidates\n",
+ 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_search: no paged results candidates\n",
+ 0, 0, 0 );
+#endif
+ send_pagerequest_response( conn, op, lastid, 0, 0 );
+
+ rc = 1;
+ goto done;
+ }
+ goto loop_begin;
+ }
+#endif
+
#ifdef LDAP_CLIENT_UPDATE
if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
- lcupf.f_choice = LDAP_FILTER_AND;
- lcupf.f_and = &csnfnot;
- lcupf.f_next = NULL;
+ cookief.f_choice = LDAP_FILTER_AND;
+ cookief.f_and = &csnfnot;
+ cookief.f_next = NULL;
csnfnot.f_choice = LDAP_FILTER_NOT;
csnfnot.f_not = &csnfeq;
ber_dupbv( &csnfge.f_av_value, &op->o_clientupdate_state );
csnfge.f_next = filter;
}
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
+#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
+ else
+#endif
+#ifdef LDAP_SYNC
+ if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
+ cookief.f_choice = LDAP_FILTER_AND;
+ cookief.f_and = &csnfnot;
+ cookief.f_next = NULL;
+
+ csnfnot.f_choice = LDAP_FILTER_NOT;
+ csnfnot.f_not = &csnfeq;
+ csnfnot.f_next = &csnfand;
+
+ csnfeq.f_choice = LDAP_FILTER_EQUALITY;
+ csnfeq.f_ava = &aa_eq;
+ csnfeq.f_av_desc = slap_schema.si_ad_entryCSN;
+ ber_dupbv( &csnfeq.f_av_value, &op->o_sync_state );
+
+ csnfand.f_choice = LDAP_FILTER_AND;
+ csnfand.f_and = &csnfge;
+ csnfand.f_next = NULL;
+
+ csnfge.f_choice = LDAP_FILTER_GE;
+ csnfge.f_ava = &aa_ge;
+ csnfge.f_av_desc = slap_schema.si_ad_entryCSN;
+ ber_dupbv( &csnfge.f_av_value, &op->o_sync_state );
+ csnfge.f_next = filter;
+ }
+#endif
for ( id = bdb_idl_first( candidates, &cursor );
id != NOID;
id = bdb_idl_next( candidates, &cursor ) )
{
+
int scopeok = 0;
+loop_begin:
/* check for abandon */
if ( op->o_abandon ) {
rc = 0;
goto done;
}
+#ifdef LDAP_EXOP_X_CANCEL
+ if ( op->o_cancel ) {
+ assert( op->o_cancel == LDAP_CANCEL_REQ );
+ rc = 0;
+ send_search_result( conn, op, LDAP_CANCELLED,
+ NULL, NULL, NULL, NULL, 0 );
+ op->o_cancel = LDAP_CANCEL_ACK;
+ goto done;
+ }
+#endif
+
/* check time limit */
if ( tlimit != -1 && slap_get_time() > stoptime ) {
send_search_result( conn, op, rc = LDAP_TIMELIMIT_EXCEEDED,
/* if it matches the filter and scope, send it */
#ifdef LDAP_CLIENT_UPDATE
if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
- rc = test_filter( be, conn, op, e, &lcupf );
+ rc = test_filter( be, conn, op, e, &cookief );
} else
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
+#ifdef LDAP_SYNC
+ if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
+ rc_sync = test_filter( be, conn, op, e, &cookief );
+ rc = test_filter( be, conn, op, e, filter );
+ if ( rc == LDAP_COMPARE_TRUE ) {
+ if ( rc_sync == LDAP_COMPARE_TRUE ) {
+ entry_sync_state = LDAP_SYNC_ADD;
+ } else {
+ entry_sync_state = LDAP_SYNC_PRESENT;
+ }
+ }
+ } else
+#endif
{
rc = test_filter( be, conn, op, e, filter );
}
goto done;
}
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+ if ( get_pagedresults(op) ) {
+ if ( nentries >= op->o_pagedresults_size ) {
+ send_pagerequest_response( conn, op,
+ lastid, nentries, tentries );
+ goto done;
+ }
+ lastid = id;
+ }
+#endif
+
if (e) {
int result;
{
#ifdef LDAP_CLIENT_UPDATE
if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
- Attribute* a;
- int ret;
- int res;
- const char *text = NULL;
- LDAPControl *ctrls[2];
- struct berval *bv;
-
- BerElement *ber = ber_alloc_t( LBER_USE_DER );
+ rc = bdb_build_lcup_update_ctrl( conn, op, e, ++entry_count, ctrls,
+ num_ctrls++, &latest_entrycsn_bv, SLAP_LCUP_ENTRY_DELETED_FALSE );
+ if ( rc != LDAP_SUCCESS )
+ goto done;
+ result = send_search_entry( be, conn, op,
+ e, attrs, attrsonly, ctrls);
- if ( ber == NULL ) {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, RESULTS,
- "bdb_search: ber_alloc_t failed\n",
- 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE,
- "bdb_search: ber_alloc_t failed\n",
- 0, 0, 0 );
+ if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
+ ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+ ch_free( ctrls[--num_ctrls] );
+ ctrls[num_ctrls] = NULL;
+ } else
#endif
- send_ldap_result( conn, op, rc=LDAP_OTHER,
- NULL, "internal error", NULL, NULL );
+#ifdef LDAP_SYNC
+ if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
+ rc = bdb_build_sync_state_ctrl( conn, op, e, entry_sync_state, ctrls,
+ num_ctrls++, 0, &latest_entrycsn_bv );
+ if ( rc != LDAP_SUCCESS )
goto done;
- }
- entry_count++;
-
- ctrls[0] = ch_malloc ( sizeof ( LDAPControl ) );
- ctrls[1] = NULL;
-
- if ( entry_count % op->o_clientupdate_interval == 0 ) {
- /* Send cookie */
- for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
- AttributeDescription *desc = a->a_desc;
- if ( desc == slap_schema.si_ad_entryCSN ) {
- ber_dupbv( &entrycsn_bv, &a->a_vals[0] );
- if ( latest_entrycsn_bv.bv_val == NULL ) {
- ber_dupbv( &latest_entrycsn_bv, &entrycsn_bv );
- } else {
- res = value_match( &ret, desc,
- desc->ad_type->sat_ordering,
- SLAP_MR_ASSERTION_SYNTAX_MATCH,
- &entrycsn_bv, &latest_entrycsn_bv, &text );
- if ( res != LDAP_SUCCESS ) {
- ret = 0;
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, RESULTS,
- "bdb_search: value_match failed\n",
- 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE,
- "bdb_search: value_match failed\n",
- 0, 0, 0 );
-#endif
- }
-
- if ( ret > 0 ) {
- ch_free( latest_entrycsn_bv.bv_val );
- latest_entrycsn_bv.bv_val = NULL;
- ber_dupbv( &latest_entrycsn_bv,
- &entrycsn_bv );
- }
- }
- }
- }
-
- ber_printf( ber,
- "{bb{sON}N}",
- SLAP_LCUP_STATE_UPDATE_FALSE,
- SLAP_LCUP_ENTRY_DELETED_FALSE,
- LCUP_COOKIE_OID, &entrycsn_bv );
-
- ch_free( entrycsn_bv.bv_val );
- entrycsn_bv.bv_val = NULL;
-
- } else {
- /* Do not send cookie */
- ber_printf( ber,
- "{bbN}",
- SLAP_LCUP_STATE_UPDATE_FALSE,
- SLAP_LCUP_ENTRY_DELETED_FALSE );
+ if ( rc_sync == LDAP_COMPARE_TRUE ) { /* ADD */
+ result = send_search_entry( be, conn, op,
+ e, attrs, attrsonly, ctrls);
+ } else { /* PRESENT */
+ result = send_search_entry( be, conn, op,
+ e, &null_attr, attrsonly, ctrls);
}
- ctrls[0]->ldctl_oid = LDAP_CONTROL_ENTRY_UPDATE;
- ctrls[0]->ldctl_iscritical = op->o_clientupdate;
- ret = ber_flatten( ber, &bv );
-
- if ( ret < 0 ) {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, RESULTS,
- "bdb_search: ber_flatten failed\n",
- 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE,
- "bdb_search: ber_flatten failed\n",
- 0, 0, 0 );
+ if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
+ ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+ ch_free( ctrls[--num_ctrls] );
+ ctrls[num_ctrls] = NULL;
+ } else
#endif
- send_ldap_result( conn, op, rc=LDAP_OTHER,
- NULL, "internal error", NULL, NULL );
- goto done;
- }
- ber_dupbv( &ctrls[0]->ldctl_value, bv );
-
- result = send_search_entry( be, conn, op,
- e, attrs, attrsonly, ctrls);
-
- ch_free( ctrls[0]->ldctl_value.bv_val );
- ch_free( ctrls[0] );
- ber_free( ber, 1 );
- ber_bvfree( bv );
- } else
-#endif /* LDAP_CLIENT_UPDATE */
{
result = send_search_entry( be, conn, op,
e, attrs, attrsonly, NULL);
#ifdef LDAP_CLIENT_UPDATE
if ( op->o_clientupdate_type & SLAP_LCUP_SYNC ) {
- int ret;
- LDAPControl *ctrls[2];
- BerElement *ber = ber_alloc_t( LBER_USE_DER );
- struct berval *bv;
-
- if ( ber == NULL ) {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, RESULTS,
- "bdb_search: ber_alloc_t failed\n", 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE, "bdb_search: ber_alloc_t failed\n",
- 0, 0, 0 );
-#endif
- send_ldap_result( conn, op, rc=LDAP_OTHER,
- NULL, "internal error", NULL, NULL );
- goto done;
- }
-
- ctrls[0] = ch_malloc ( sizeof ( LDAPControl ) );
- ctrls[1] = NULL;
+ bdb_build_lcup_done_ctrl( conn, op, ctrls, num_ctrls++, &latest_entrycsn_bv );
- ber_printf( ber, "{sO", LCUP_COOKIE_OID, &latest_entrycsn_bv );
- ber_printf( ber, "N}" );
+ send_search_result( conn, op,
+ v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
+ NULL, NULL, v2refs, ctrls, nentries );
- ctrls[0]->ldctl_oid = LDAP_CONTROL_CLIENT_UPDATE_DONE;
- ctrls[0]->ldctl_iscritical = op->o_clientupdate;
- ret = ber_flatten( ber, &bv );
+ ch_free( latest_entrycsn_bv.bv_val );
+ latest_entrycsn_bv.bv_val = NULL;
- if ( ret < 0 ) {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, RESULTS,
- "bdb_search: ber_flatten failed\n", 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE, "bdb_search: ber_flatten failed\n",
- 0, 0, 0 );
+ if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
+ ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+ ch_free( ctrls[--num_ctrls] );
+ ctrls[num_ctrls] = NULL;
+ } else
#endif
- send_ldap_result( conn, op, rc=LDAP_OTHER,
- NULL, "internal error", NULL, NULL );
- goto done;
+#ifdef LDAP_SYNC
+ if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
+ if ( op->o_sync_mode & SLAP_SYNC_PERSIST ) {
+ /* refreshAndPersist mode */
+ bdb_send_ldap_intermediate( conn, op,
+ LDAP_SUCCESS, NULL, NULL, NULL, LDAP_SYNC_INFO,
+ LDAP_SYNC_REFRESH_DONE, &latest_entrycsn_bv, NULL );
+ } else {
+ /* refreshOnly mode */
+ bdb_build_sync_done_ctrl( conn, op, ctrls, num_ctrls++, 1, &latest_entrycsn_bv );
+ send_search_result( conn, op,
+ v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
+ NULL, NULL, v2refs, ctrls, nentries );
+ if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL )
+ ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val );
+ ch_free( ctrls[--num_ctrls] );
+ ctrls[num_ctrls] = NULL;
}
- ber_dupbv( &ctrls[0]->ldctl_value, bv );
-
- send_search_result( conn, op,
- v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
- NULL, NULL, v2refs, ctrls, nentries );
-
ch_free( latest_entrycsn_bv.bv_val );
latest_entrycsn_bv.bv_val = NULL;
- ch_free( ctrls[0]->ldctl_value.bv_val );
- ch_free( ctrls[0] );
- ber_free( ber, 1 );
- ber_bvfree( bv );
} else
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
{
send_search_result( conn, op,
v2refs == NULL ? LDAP_SUCCESS : LDAP_REFERRAL,
ch_free( csnfge.f_av_value.bv_val );
}
}
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+ else
+#endif
+#ifdef LDAP_SYNC
+ if ( op->o_sync_mode & SLAP_SYNC_REFRESH ) {
+ if ( csnfeq.f_ava != NULL && csnfeq.f_av_value.bv_val != NULL ) {
+ ch_free( csnfeq.f_av_value.bv_val );
+ }
+
+ if ( csnfge.f_ava != NULL && csnfge.f_av_value.bv_val != NULL ) {
+ ch_free( csnfge.f_av_value.bv_val );
+ }
+ }
+#endif
LOCK_ID_FREE (bdb->bi_dbenv, locker );
return rc;
}
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+static void
+send_pagerequest_response(
+ Connection *conn,
+ Operation *op,
+ ID lastid,
+ int nentries,
+ int tentries )
+{
+ LDAPControl ctrl, *ctrls[2];
+ char berbuf[LBER_ELEMENT_SIZEOF];
+ BerElement *ber = (BerElement *)berbuf;
+ struct berval cookie = { 0, NULL };
+ PagedResultsCookie respcookie;
+
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ENTRY,
+ "send_pagerequest_response: lastid: (0x%08lx) "
+ "nentries: (0x%081x)\n",
+ lastid, nentries, NULL );
+#else
+ Debug(LDAP_DEBUG_ARGS, "send_pagerequest_response: lastid: (0x%08lx) "
+ "nentries: (0x%081x)\n", lastid, nentries, NULL );
+#endif
+
+ ctrl.ldctl_value.bv_val = NULL;
+ ctrls[0] = &ctrl;
+ ctrls[1] = NULL;
+
+ ber_init2( ber, NULL, LBER_USE_DER );
+
+ respcookie = ( PagedResultsCookie )lastid;
+ conn->c_pagedresults_state.ps_cookie = respcookie;
+ cookie.bv_len = sizeof( respcookie );
+ cookie.bv_val = (char *)&respcookie;
+
+ /*
+ * FIXME: we should consider sending an estimate of the entries
+ * left, after appropriate security check is done
+ */
+ ber_printf( ber, "{iO}", tentries, &cookie );
+
+ if ( ber_flatten2( ber, &ctrls[0]->ldctl_value, 0 ) == -1 ) {
+ goto done;
+ }
+
+ ctrls[0]->ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
+ ctrls[0]->ldctl_iscritical = 0;
+
+ send_search_result( conn, op,
+ LDAP_SUCCESS,
+ NULL, NULL, NULL, ctrls, nentries );
+
+done:
+ (void) ber_free_buf( ber );
+}
+#endif
+
+#ifdef LDAP_CLIENT_UPDATE
+int
+bdb_build_lcup_update_ctrl(
+ Connection *conn,
+ Operation *op,
+ Entry *e,
+ int entry_count,
+ LDAPControl **ctrls,
+ int num_ctrls,
+ struct berval *latest_entrycsn_bv,
+ int isdeleted )
+{
+ Attribute* a;
+ int ret;
+ int res;
+ int rc;
+ const char *text = NULL;
+
+ char berbuf[LBER_ELEMENT_SIZEOF];
+ BerElement *ber = (BerElement *)berbuf;
+
+ struct berval entrycsn_bv = { 0, NULL };
+
+ ber_init2( ber, 0, LBER_USE_DER );
+
+ ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+ for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+ AttributeDescription *desc = a->a_desc;
+ if ( desc == slap_schema.si_ad_entryCSN ) {
+ ber_dupbv( &entrycsn_bv, &a->a_vals[0] );
+ if ( latest_entrycsn_bv->bv_val == NULL ) {
+ ber_dupbv( latest_entrycsn_bv, &entrycsn_bv );
+ } else {
+ res = value_match( &ret, desc,
+ desc->ad_type->sat_ordering,
+ SLAP_MR_ASSERTION_SYNTAX_MATCH,
+ &entrycsn_bv, latest_entrycsn_bv, &text );
+ if ( res != LDAP_SUCCESS ) {
+ ret = 0;
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, RESULTS,
+ "bdb_search: value_match failed\n",
+ 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_search: value_match failed\n",
+ 0, 0, 0 );
+#endif
+ }
+
+ if ( ret > 0 ) {
+ ch_free( latest_entrycsn_bv->bv_val );
+ latest_entrycsn_bv->bv_val = NULL;
+ ber_dupbv( latest_entrycsn_bv, &entrycsn_bv );
+ }
+ }
+ }
+ }
+
+ if ( entry_count % op->o_clientupdate_interval == 0 )
+ ber_printf( ber,
+ "{bb{sON}N}",
+ SLAP_LCUP_STATE_UPDATE_FALSE,
+ isdeleted,
+ LDAP_LCUP_COOKIE_OID, &entrycsn_bv );
+ else /* Do not send cookie */
+ ber_printf( ber,
+ "{bbN}",
+ SLAP_LCUP_STATE_UPDATE_FALSE,
+ isdeleted );
+
+ ch_free( entrycsn_bv.bv_val );
+ entrycsn_bv.bv_val = NULL;
+
+ ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_ENTRY_UPDATE;
+ ctrls[num_ctrls]->ldctl_iscritical = op->o_clientupdate;
+ ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+ ber_free_buf( ber );
+
+ if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, RESULTS,
+ "bdb_build_lcup_ctrl: ber_flatten2 failed\n",
+ 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_build_lcup_ctrl: ber_flatten2 failed\n",
+ 0, 0, 0 );
+#endif
+ send_ldap_result( conn, op, rc=LDAP_OTHER,
+ NULL, "internal error", NULL, NULL );
+ return ret;
+ }
+
+ return LDAP_SUCCESS;
+}
+
+int
+bdb_build_lcup_done_ctrl(
+ Connection *conn,
+ Operation *op,
+ LDAPControl **ctrls,
+ int num_ctrls,
+ struct berval *latest_entrycsn_bv )
+{
+ int ret, rc;
+ char berbuf[LBER_ELEMENT_SIZEOF];
+ BerElement *ber = (BerElement *)berbuf;
+
+ ber_init2( ber, NULL, LBER_USE_DER );
+
+ ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+ ber_printf( ber, "{sO", LDAP_LCUP_COOKIE_OID, latest_entrycsn_bv );
+ ber_printf( ber, "N}" );
+
+ ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_CLIENT_UPDATE_DONE;
+ ctrls[num_ctrls]->ldctl_iscritical = op->o_clientupdate;
+ ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+ ber_free_buf( ber );
+
+ if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, RESULTS,
+ "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n",
+ 0, 0, 0 );
+#endif
+ send_ldap_result( conn, op, rc=LDAP_OTHER,
+ NULL, "internal error", NULL, NULL );
+ return ret;
+ }
+
+ return LDAP_SUCCESS;
+}
+#endif
+
+#ifdef LDAP_SYNC
+int
+bdb_build_sync_state_ctrl(
+ Connection *conn,
+ Operation *op,
+ Entry *e,
+ int entry_sync_state,
+ LDAPControl **ctrls,
+ int num_ctrls,
+ int send_cookie,
+ struct berval *latest_entrycsn_bv )
+{
+ Attribute* a;
+ int ret;
+ int res;
+ int rc;
+ const char *text = NULL;
+
+ char berbuf[LBER_ELEMENT_SIZEOF];
+ BerElement *ber = (BerElement *)berbuf;
+
+ struct berval entryuuid_bv = { 0, NULL };
+ struct berval entrycsn_bv = { 0, NULL };
+
+ ber_init2( ber, 0, LBER_USE_DER );
+
+ ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+ for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+ AttributeDescription *desc = a->a_desc;
+ if ( desc == slap_schema.si_ad_entryCSN ) {
+ ber_dupbv( &entrycsn_bv, &a->a_vals[0] );
+ if ( latest_entrycsn_bv->bv_val == NULL ) {
+ ber_dupbv( latest_entrycsn_bv, &entrycsn_bv );
+ } else {
+ res = value_match( &ret, desc,
+ desc->ad_type->sat_ordering,
+ SLAP_MR_ASSERTION_SYNTAX_MATCH,
+ &entrycsn_bv, latest_entrycsn_bv, &text );
+ if ( res != LDAP_SUCCESS ) {
+ ret = 0;
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, RESULTS,
+ "bdb_search: value_match failed\n",
+ 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_search: value_match failed\n",
+ 0, 0, 0 );
+#endif
+ }
+ if ( ret > 0 ) {
+ ch_free( latest_entrycsn_bv->bv_val );
+ latest_entrycsn_bv->bv_val = NULL;
+ ber_dupbv( latest_entrycsn_bv, &entrycsn_bv );
+ }
+ }
+ } else if ( desc == slap_schema.si_ad_entryUUID ) {
+ ber_dupbv( &entryuuid_bv, &a->a_vals[0] );
+ }
+ }
+
+ if ( send_cookie )
+ ber_printf( ber, "{eOON}", entry_sync_state, &entryuuid_bv, &entrycsn_bv );
+ else
+ ber_printf( ber, "{eON}", entry_sync_state, &entryuuid_bv );
+
+ ch_free( entrycsn_bv.bv_val );
+ entrycsn_bv.bv_val = NULL;
+ ch_free( entryuuid_bv.bv_val );
+ entryuuid_bv.bv_val = NULL;
+
+ ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE;
+ ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
+ ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+ ber_free_buf( ber );
+
+ if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, RESULTS,
+ "bdb_build_sync_ctrl: ber_flatten2 failed\n",
+ 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_build_sync_ctrl: ber_flatten2 failed\n",
+ 0, 0, 0 );
+#endif
+ send_ldap_result( conn, op, rc=LDAP_OTHER,
+ NULL, "internal error", NULL, NULL );
+ return ret;
+ }
+
+ return LDAP_SUCCESS;
+}
+
+int
+bdb_build_sync_done_ctrl(
+ Connection *conn,
+ Operation *op,
+ LDAPControl **ctrls,
+ int num_ctrls,
+ int send_cookie,
+ struct berval *latest_entrycsn_bv )
+{
+ int ret,rc;
+ char berbuf[LBER_ELEMENT_SIZEOF];
+ BerElement *ber = (BerElement *)berbuf;
+
+ ber_init2( ber, NULL, LBER_USE_DER );
+
+ ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) );
+
+ if ( send_cookie ) {
+ ber_printf( ber, "{ON}", latest_entrycsn_bv );
+ } else {
+ ber_printf( ber, "{N}" );
+ }
+
+ ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_DONE;
+ ctrls[num_ctrls]->ldctl_iscritical = op->o_sync;
+ ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 );
+
+ ber_free_buf( ber );
+
+ if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, RESULTS,
+ "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n",
+ 0, 0, 0 );
+#endif
+ send_ldap_result( conn, op, rc=LDAP_OTHER,
+ NULL, "internal error", NULL, NULL );
+ return ret;
+ }
+
+ return LDAP_SUCCESS;
+}
+
+int
+bdb_send_ldap_intermediate(
+ Connection *conn,
+ Operation *op,
+ ber_int_t err,
+ const char *matched,
+ const char *text,
+ BerVarray refs,
+ const char *rspoid,
+ int state,
+ struct berval *cookie,
+ LDAPControl **ctrls )
+{
+ char berbuf[LBER_ELEMENT_SIZEOF];
+ BerElement *ber = (BerElement *)berbuf;
+ struct berval rspdata;
+
+ int ret, rc;
+
+ ber_init2( ber, NULL, LBER_USE_DER );
+
+ if ( cookie == NULL )
+ ber_printf( ber, "{eN}", state );
+ else
+ ber_printf( ber, "{eON}", state, cookie );
+
+ ret = ber_flatten2( ber, &rspdata, 0 );
+
+ if ( ret < 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, RESULTS,
+ "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "bdb_build_lcup_done_ctrl: ber_flatten2 failed\n",
+ 0, 0, 0 );
+#endif
+ send_ldap_result( conn, op, rc=LDAP_OTHER,
+ NULL, "internal error", NULL, NULL );
+ return ret;
+ }
+
+ send_ldap_intermediate_resp( conn, op, err, matched, text, refs, rspoid, &rspdata, ctrls );
+
+ ber_free_buf( ber );
+
+ return LDAP_SUCCESS;
+}
+#endif
/* add.c - ldap backend add function */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* This is an altered version */
continue;
}
- ldap_back_map(&li->at_map, &a->a_desc->ad_cname, &mapped, 0);
- if (mapped.bv_val == NULL) {
+ ldap_back_map(&li->at_map, &a->a_desc->ad_cname, &mapped,
+ BACKLDAP_MAP);
+ if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
continue;
}
--- /dev/null
+/* group.c - ldap backend acl group routine */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "back-ldap.h"
+
+
+/* return 0 IFF we can retrieve the attributes
+ * of entry with ndn
+ */
+int
+ldap_back_attribute(
+ Backend *be,
+ Connection *conn,
+ Operation *op,
+ Entry *target,
+ struct berval *ndn,
+ AttributeDescription *entry_at,
+ BerVarray *vals
+)
+{
+ struct ldapinfo *li = (struct ldapinfo *) be->be_private;
+ int rc = 1, i, j, count, is_oc;
+ Attribute *attr = NULL;
+ BerVarray abv, v;
+ struct berval mapped = { 0, NULL };
+ char **vs = NULL;
+ LDAPMessage *result = NULL, *e = NULL;
+ char *gattr[2];
+ LDAP *ld = NULL;
+
+ *vals = NULL;
+ if (target != NULL && dn_match( &target->e_nname, ndn )) {
+ /* we already have a copy of the entry */
+ /* attribute and objectclass mapping has already been done */
+ if ((attr = attr_find(target->e_attrs, entry_at)) == NULL)
+ return(1);
+
+ for ( count = 0; attr->a_vals[count].bv_val != NULL; count++ ) { }
+ v = (BerVarray) ch_calloc( (count + 1), sizeof(struct berval) );
+ if (v != NULL) {
+ for ( j = 0, abv = attr->a_vals; --count >= 0; abv++ ) {
+ if ( abv->bv_len > 0 ) {
+ ber_dupbv( &v[j], abv );
+ if( v[j].bv_val == NULL )
+ break;
+ }
+ }
+ v[j].bv_val = NULL;
+ *vals = v;
+ return 0;
+ }
+
+ }
+ ldap_back_map(&li->at_map, &entry_at->ad_cname, &mapped, BACKLDAP_MAP);
+ if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
+ return 1;
+ }
+
+ if (ldap_initialize(&ld, li->url) != LDAP_SUCCESS) {
+ return 1;
+ }
+
+ if (ldap_bind_s(ld, li->binddn, li->bindpw, LDAP_AUTH_SIMPLE) != LDAP_SUCCESS) {
+ goto cleanup;
+ }
+
+ gattr[0] = mapped.bv_val;
+ gattr[1] = NULL;
+ if (ldap_search_ext_s(ld, ndn->bv_val, LDAP_SCOPE_BASE, "(objectclass=*)",
+ gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
+ LDAP_NO_LIMIT, &result) != LDAP_SUCCESS)
+ {
+ goto cleanup;
+ }
+
+ if ((e = ldap_first_entry(ld, result)) == NULL) {
+ goto cleanup;
+ }
+
+ vs = ldap_get_values(ld, e, mapped.bv_val);
+ if (vs == NULL) {
+ goto cleanup;
+ }
+
+ for ( count = 0; vs[count] != NULL; count++ ) { }
+ v = (BerVarray) ch_calloc( (count + 1), sizeof(struct berval) );
+ if (v == NULL) {
+ goto cleanup;
+ }
+
+ is_oc = (strcasecmp("objectclass", mapped.bv_val) == 0);
+ for ( i = 0, j = 0; i < count; i++) {
+ ber_str2bv(vs[i], 0, 0, &v[j] );
+ if (!is_oc) {
+ if( v[j].bv_val == NULL )
+ ch_free(vs[i]);
+ else
+ j++;
+ } else {
+ ldap_back_map(&li->oc_map, &v[j], &mapped,
+ BACKLDAP_REMAP);
+ if (mapped.bv_val && mapped.bv_val[0] != '\0') {
+ ber_dupbv( &v[j], &mapped );
+ if (v[j].bv_val)
+ j++;
+ }
+ ch_free(vs[i]);
+ }
+ }
+ v[j].bv_val = NULL;
+ *vals = v;
+ rc = 0;
+ ch_free(vs);
+ vs = NULL;
+
+cleanup:
+ if (vs) {
+ ldap_value_free(vs);
+ }
+ if (result) {
+ ldap_msgfree(result);
+ }
+ ldap_unbind(ld);
+
+ return(rc);
+}
+
/* back-ldap.h - ldap backend header file */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* This is an altered version */
void ldap_back_map_init ( struct ldapmap *lm, struct ldapmapping ** );
void ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *m,
int remap );
+#define BACKLDAP_MAP 0
+#define BACKLDAP_REMAP 1
char *
ldap_back_map_filter(
struct ldapmap *at_map,
int remap
);
-extern void mapping_free ( struct ldapmapping *mapping );
+extern void mapping_free ( void *mapping );
#ifdef ENABLE_REWRITE
extern int suffix_massage_config( struct rewrite_info *info,
LDAP_END_DECL
-#endif
+#endif /* SLAPD_LDAP_H */
/* compare.c - ldap backend compare function */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* This is an altered version */
}
#endif /* !ENABLE_REWRITE */
- ldap_back_map(&li->oc_map, &ava->aa_desc->ad_cname, &mapped_oc, 0);
- if (mapped_oc.bv_val == NULL)
- return( -1 );
-
- ldap_back_map(&li->at_map, &ava->aa_value, &mapped_at, 0);
- if (mapped_at.bv_val == NULL)
- return( -1 );
+ if ( ava->aa_desc == slap_schema.si_ad_objectClass ) {
+ ldap_back_map(&li->oc_map, &ava->aa_desc->ad_cname, &mapped_oc,
+ BACKLDAP_MAP);
+ if (mapped_oc.bv_val == NULL || mapped_oc.bv_val[0] == '\0') {
+ return( -1 );
+ }
+
+ } else {
+ ldap_back_map(&li->at_map, &ava->aa_value, &mapped_at,
+ BACKLDAP_MAP);
+ if (mapped_at.bv_val == NULL || mapped_at.bv_val[0] == '\0') {
+ return( -1 );
+ }
+ }
ldap_compare_s( lc->ld, mdn.bv_val, mapped_oc.bv_val, mapped_at.bv_val );
/* config.c - ldap backend configuration file routine */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* This is an altered version */
*/
return -1;
- } else if ( len >= sizeof( vbuf_ ) ) {
+ } else if ( len >= (int)sizeof( vbuf_ ) ) {
/*
* C99: snprintf returns the required size
*/
if ( len == -1 ) {
return -1;
- } else if ( len >= sizeof( rbuf_ ) ) {
+ } else if ( len >= (int)sizeof( rbuf_ ) ) {
rbuf = ch_malloc( len + 1 );
len = snprintf( rbuf, sizeof( rbuf_ ), "%%1%s)%%2",
nrnc->bv_val );
/* group.c - ldap backend acl group routine */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
}
#endif /* !ENABLE_REWRITE */
- ldap_back_map(&li->oc_map, &group_oc_name, &group_oc_name, 0);
- if (group_oc_name.bv_val == NULL)
+ ldap_back_map(&li->oc_map, &group_oc_name, &group_oc_name,
+ BACKLDAP_MAP);
+ if (group_oc_name.bv_val == NULL || group_oc_name.bv_val[0] == '\0')
goto cleanup;
- ldap_back_map(&li->at_map, &group_at_name, &group_at_name, 0);
- if (group_at_name.bv_val == NULL)
+ ldap_back_map(&li->at_map, &group_at_name, &group_at_name,
+ BACKLDAP_MAP);
+ if (group_at_name.bv_val == NULL || group_at_name.bv_val[0] == '\0')
goto cleanup;
filter = ch_malloc(sizeof("(&(objectclass=)(=))")
/* init.c - initialize ldap backend */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* This is an altered version */
static void
conn_free(
- struct ldapconn *lc
+ void *v_lc
)
{
+ struct ldapconn *lc = v_lc;
ldap_unbind( lc->ld );
if ( lc->bound_dn.bv_val ) {
ch_free( lc->bound_dn.bv_val );
}
void
-mapping_free ( struct ldapmapping *mapping )
+mapping_free( void *v_mapping )
{
+ struct ldapmapping *mapping = v_mapping;
ch_free( mapping->src.bv_val );
ch_free( mapping->dst.bv_val );
ch_free( mapping );
li->bindpw = NULL;
}
if (li->conntree) {
- avl_free( li->conntree, (AVL_FREE) conn_free );
+ avl_free( li->conntree, conn_free );
}
#ifdef ENABLE_REWRITE
if (li->rwinfo) {
#endif /* !ENABLE_REWRITE */
avl_free( li->oc_map.remap, NULL );
- avl_free( li->oc_map.map, (AVL_FREE) mapping_free );
+ avl_free( li->oc_map.map, mapping_free );
avl_free( li->at_map.remap, NULL );
- avl_free( li->at_map.map, (AVL_FREE) mapping_free );
+ avl_free( li->at_map.map, mapping_free );
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
ldap_pvt_thread_mutex_destroy( &li->conn_mutex );
/* map.c - ldap backend mapping routines */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* This is an altered version */
Avlnode *tree;
struct ldapmapping *mapping, fmapping;
- if (remap)
+ if (remap == BACKLDAP_REMAP)
tree = map->remap;
else
tree = map->map;
tmp.bv_len = p - q;
tmp.bv_val = q;
ldap_back_map(at_map, &tmp, &m, remap);
- if (m.bv_val == NULL)
+ if (m.bv_val == NULL || m.bv_val[0] == '\0') {
ldap_back_map(oc_map, &tmp, &m, remap);
- if (m.bv_val == NULL) {
- m = tmp;
+ if (m.bv_val == NULL || m.bv_val[0] == '\0') {
+ m = tmp;
+ }
}
extra += p - q;
plen = m.bv_len;
for (i = j = 0; an[i].an_name.bv_val; i++) {
ldap_back_map(at_map, &an[i].an_name, &mapped, remap);
- if (mapped.bv_val != NULL)
+ if (mapped.bv_val != NULL && mapped.bv_val != '\0')
na[j++] = mapped.bv_val;
}
if (j == 0 && i != 0)
/* modify.c - ldap backend modify function */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* This is an altered version */
continue;
}
- ldap_back_map(&li->at_map, &ml->sml_desc->ad_cname, &mapped, 0);
- if (mapped.bv_val == NULL) {
+ ldap_back_map(&li->at_map, &ml->sml_desc->ad_cname, &mapped,
+ BACKLDAP_MAP);
+ if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
continue;
}
/* search.c - ldap backend search function */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* This is an altered version */
#else /* !ENABLE_REWRITE */
filterstr,
#endif /* !ENABLE_REWRITE */
- 0);
+ BACKLDAP_MAP);
if ( mapped_filter == NULL ) {
#ifdef ENABLE_REWRITE
mapped_filter = mfilter.bv_val;
}
#endif /* ENABLE_REWRITE */
- mapped_attrs = ldap_back_map_attrs(&li->at_map, attrs, 0);
+ mapped_attrs = ldap_back_map_attrs(&li->at_map, attrs, BACKLDAP_MAP);
if ( mapped_attrs == NULL && attrs) {
for (count=0; attrs[count].an_name.bv_val; count++);
mapped_attrs = ch_malloc( (count+1) * sizeof(char *));
attrp = &ent.e_attrs;
while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
- ldap_back_map(&li->at_map, &a, &mapped, 1);
- if (mapped.bv_val == NULL)
+ ldap_back_map(&li->at_map, &a, &mapped, BACKLDAP_REMAP);
+ if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0')
continue;
attr = (Attribute *)ch_malloc( sizeof(Attribute) );
if (attr == NULL)
for ( last = 0; attr->a_vals[last].bv_val; last++ ) ;
for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
- ldap_back_map(&li->oc_map, bv, &mapped, 1);
- if (mapped.bv_val == NULL) {
+ ldap_back_map(&li->oc_map, bv, &mapped,
+ BACKLDAP_REMAP);
+ if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
LBER_FREE(bv->bv_val);
bv->bv_val = NULL;
if (--last < 0)
/* unbind.c - ldap backend unbind function */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* This is an altered version */
/* attr.c - backend routines for dealing with attributes */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
static int
ainfo_type_cmp(
- AttributeDescription *desc,
- AttrInfo *a
+ const void *v_desc,
+ const void *v_a
)
{
+ const AttributeDescription *desc = v_desc;
+ const AttrInfo *a = v_a;
return desc - a->ai_desc;
}
static int
ainfo_cmp(
- AttrInfo *a,
- AttrInfo *b
+ const void *v_a,
+ const void *v_b
)
{
+ const AttrInfo *a = v_a, *b = v_b;
return a->ai_desc - b->ai_desc;
}
{
AttrInfo *a;
- a = (AttrInfo *) avl_find( li->li_attrs, desc,
- (AVL_CMP) ainfo_type_cmp );
+ a = avl_find( li->li_attrs, desc, ainfo_type_cmp );
*indexmask = a != NULL ? a->ai_indexmask : 0;
}
a->ai_indexmask = mask;
rc = avl_insert( &li->li_attrs, (caddr_t) a,
- (AVL_CMP) ainfo_cmp, (AVL_DUP) avl_dup_error );
+ ainfo_cmp, avl_dup_error );
if( rc ) {
fprintf( stderr, "%s: line %d: duplicate index definition "
/* bind.c - ldbm backend bind and unbind routines */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
cache_return_entry_r( &li->li_cache, e );
ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
- /* front end with send result on success (rc==0) */
+ /* front end will send result on success (rc==0) */
return( rc );
}
/* cache.c - routines to maintain an in-core cache of entries */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
}
if ( avl_insert( &cache->c_dntree, (caddr_t) e,
- (AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
+ entry_dn_cmp, avl_dup_error ) != 0 )
{
/* free cache mutex */
ldap_pvt_thread_mutex_unlock( &cache->c_mutex );
/* id tree */
if ( avl_insert( &cache->c_idtree, (caddr_t) e,
- (AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 )
+ entry_id_cmp, avl_dup_error ) != 0 )
{
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, DETAIL1,
/* delete from dn tree inserted above */
if ( avl_delete( &cache->c_dntree, (caddr_t) e,
- (AVL_CMP) entry_dn_cmp ) == NULL )
+ entry_dn_cmp ) == NULL )
{
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, INFO,
assert( e->e_private );
if ( avl_insert( &cache->c_dntree, (caddr_t) e,
- (AVL_CMP) entry_dn_cmp, avl_dup_error ) != 0 )
+ entry_dn_cmp, avl_dup_error ) != 0 )
{
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, DETAIL1,
/* id tree */
if ( avl_insert( &cache->c_idtree, (caddr_t) e,
- (AVL_CMP) entry_id_cmp, avl_dup_error ) != 0 )
+ entry_id_cmp, avl_dup_error ) != 0 )
{
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, DETAIL1,
/* delete from dn tree inserted above */
if ( avl_delete( &cache->c_dntree, (caddr_t) e,
- (AVL_CMP) entry_dn_cmp ) == NULL )
+ entry_dn_cmp ) == NULL )
{
#ifdef NEW_LOGGING
LDAP_LOG( CACHE, INFO,
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
if ( (ep = (Entry *) avl_find( cache->c_dntree, (caddr_t) &e,
- (AVL_CMP) entry_dn_cmp )) != NULL )
+ entry_dn_cmp )) != NULL )
{
int state;
count++;
ldap_pvt_thread_mutex_lock( &cache->c_mutex );
if ( (ep = (Entry *) avl_find( cache->c_idtree, (caddr_t) &e,
- (AVL_CMP) entry_id_cmp )) != NULL )
+ entry_id_cmp )) != NULL )
{
int state;
ID ep_id;
int rc = 0; /* return code */
/* dn tree */
- if ( avl_delete( &cache->c_dntree, (caddr_t) e, (AVL_CMP) entry_dn_cmp )
- == NULL )
+ if ( avl_delete( &cache->c_dntree, (caddr_t) e, entry_dn_cmp ) == NULL )
{
rc = -1;
}
/* id tree */
- if ( avl_delete( &cache->c_idtree, (caddr_t) e, (AVL_CMP) entry_id_cmp )
- == NULL )
+ if ( avl_delete( &cache->c_idtree, (caddr_t) e, entry_id_cmp ) == NULL )
{
rc = -1;
}
/* ldbmcache.c - maintain a cache of open ldbm files */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
ldap_pvt_thread_mutex_unlock( &li->li_dbcache_mutex );
}
+#if 0 /* macro in proto-back-ldbm.h */
Datum
ldbm_cache_fetch(
DBCache *db,
{
return ldbm_fetch( db->dbc_db, key );
}
+#endif /* 0 */
int
ldbm_cache_store(
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
extern BI_operational ldbm_back_operational;
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
extern BI_has_subordinates ldbm_back_hasSubordinates;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
/* hooks for slap tools */
extern BI_tool_entry_open ldbm_tool_entry_open;
/* filterindex.c - generate the list of candidate entries from a filter */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
int rc;
char *dbname;
slap_mask_t mask;
- struct berval prefix = {0};
+ struct berval prefix = {0, NULL};
#ifdef NEW_LOGGING
LDAP_LOG( FILTER, ENTRY, "presence_candidates: enter\n", 0, 0, 0 );
int rc;
char *dbname;
slap_mask_t mask;
- struct berval prefix = {0};
+ struct berval prefix = {0, NULL};
struct berval *keys = NULL;
MatchingRule *mr;
int rc;
char *dbname;
slap_mask_t mask;
- struct berval prefix = {0};
+ struct berval prefix = {0, NULL};
struct berval *keys = NULL;
MatchingRule *mr;
int rc;
char *dbname;
slap_mask_t mask;
- struct berval prefix = {0};
+ struct berval prefix = {0, NULL};
struct berval *keys = NULL;
MatchingRule *mr;
/* idl.c - ldap id list handling routines */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
}
free( (char *) tmp );
+ assert( ID_BLOCK_NIDS(idl) == nids );
+
#ifdef LDBM_DEBUG_IDL
idl_check(idl);
#endif
/* index.c - routines for dealing with attribute indexes */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
return mask;
}
- /* If there is a language tag, did we ever index the base
+ /* If there is a tagging option, did we ever index the base
* type? If so, check for mask, otherwise it's not there.
*/
- if( slap_ad_is_lang( desc ) && desc != desc->ad_type->sat_ad ) {
- /* has language tag */
+ if( slap_ad_is_tagged( desc ) && desc != desc->ad_type->sat_ad ) {
+ /* has tagging option */
attr_mask( be->be_private, desc->ad_type->sat_ad, &mask );
- if( mask && ( mask ^ SLAP_INDEX_NOLANG ) ) {
+ if( mask && ( mask ^ SLAP_INDEX_NOTAGS ) ) {
*atname = desc->ad_type->sat_cname;
*dbname = desc->ad_type->sat_cname.bv_val;
return mask;
static int index_at_values(
Backend *be,
AttributeType *type,
- struct berval *lang,
+ struct berval *tags,
BerVarray vals,
ID id,
int op )
if( type->sat_sup ) {
/* recurse */
(void) index_at_values( be,
- type->sat_sup, lang,
+ type->sat_sup, tags,
vals, id, op );
}
mask );
}
- if( lang->bv_len ) {
+ if( tags->bv_len ) {
AttributeDescription *desc;
mask = 0;
- desc = ad_find_lang(type, lang);
+ desc = ad_find_tags(type, tags);
if( desc ) {
attr_mask( be->be_private, desc, &mask );
}
int op )
{
(void) index_at_values( be,
- desc->ad_type, &desc->ad_lang,
+ desc->ad_type, &desc->ad_tags,
vals, id, op );
return LDAP_SUCCESS;
/* init.c - initialize ldbm backend */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
bi->bi_acl_attribute = ldbm_back_attribute;
bi->bi_chk_referrals = ldbm_back_referrals;
bi->bi_operational = ldbm_back_operational;
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
bi->bi_has_subordinates = ldbm_back_hasSubordinates;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
/*
* hooks for slap tools
/* modify.c - ldbm backend modify routine */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: add\n", 0, 0, 0);
#endif
- rc = modify_add_values( e, mod, text, textbuf, textlen );
+ rc = modify_add_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG( BACK_LDBM, INFO,
Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: delete\n", 0, 0, 0);
#endif
- rc = modify_delete_values( e, mod, text, textbuf, textlen );
+ rc = modify_delete_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
assert( rc != LDAP_TYPE_OR_VALUE_EXISTS );
if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
Debug(LDAP_DEBUG_ARGS, "ldbm_modify_internal: replace\n", 0, 0, 0);
#endif
- rc = modify_replace_values( e, mod, text, textbuf, textlen );
+ rc = modify_replace_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
LDAP_LOG( BACK_LDBM, INFO,
*/
mod->sm_op = LDAP_MOD_ADD;
- rc = modify_add_values( e, mod, text, textbuf, textlen );
+ rc = modify_add_values( e, mod, op->o_permitmodify, text, textbuf, textlen );
if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
rc = LDAP_SUCCESS;
}
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
#ifndef _PROTO_BACK_LDBM
#define _PROTO_BACK_LDBM
+#include <ldap_cdefs.h>
+
+#include "external.h"
+
+LDAP_BEGIN_DECL
+
+/*
+ * alias.c
+ */
+Entry *deref_internal_r LDAP_P((
+ Backend *be,
+ Entry *e,
+ struct berval *dn,
+ int *err,
+ Entry **matched,
+ const char **text ));
+
+#define deref_entry_r( be, e, err, matched, text ) \
+ deref_internal_r( be, e, NULL, err, matched, text )
+#define deref_dn_r( be, dn, err, matched, text ) \
+ deref_internal_r( be, NULL, dn, err, matched, text)
+
/*
* 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_mask LDAP_P(( struct ldbminfo *li,
+ AttributeDescription *desc,
+ slap_mask_t *indexmask ));
+
+int attr_index_config LDAP_P(( struct ldbminfo *li,
+ const char *fname, int lineno,
+ int argc, char **argv ));
+void attr_index_destroy LDAP_P(( Avlnode *tree ));
/*
* 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(( Cache *cache, Entry *e, int rw ));
+int cache_update_entry LDAP_P(( Cache *cache, Entry *e ));
+void cache_return_entry_rw LDAP_P(( 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)
+void cache_entry_commit LDAP_P(( Entry *e ));
+
+ID cache_find_entry_ndn2id LDAP_P(( Backend *be, Cache *cache, struct berval *ndn ));
+Entry * cache_find_entry_id LDAP_P(( Cache *cache, ID id, int rw ));
+int cache_delete_entry LDAP_P(( Cache *cache, Entry *e ));
+void cache_release_all LDAP_P(( Cache *cache ));
/*
* 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 );
+DBCache * ldbm_cache_open LDAP_P(( Backend *be,
+ const char *name, const char *suffix, int flags ));
+void ldbm_cache_close LDAP_P(( Backend *be, DBCache *db ));
+void ldbm_cache_really_close LDAP_P(( Backend *be, DBCache *db ));
+void ldbm_cache_flush_all LDAP_P(( Backend *be ));
+void ldbm_cache_sync LDAP_P(( Backend *be ));
+#if 0 /* replaced by macro */
+Datum ldbm_cache_fetch LDAP_P(( DBCache *db, Datum key ));
+#else /* 1 */
+#define ldbm_cache_fetch( db, key ) ldbm_fetch( (db)->dbc_db, (key) )
+#endif /* 1 */
+int ldbm_cache_store LDAP_P(( DBCache *db, Datum key, Datum data, int flags ));
+int ldbm_cache_delete LDAP_P(( DBCache *db, Datum key ));
+void *ldbm_cache_sync_daemon LDAP_P(( void *));
/*
* 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, struct berval *dn, ID id ));
+int dn2id LDAP_P(( Backend *be, struct berval *dn, ID *idp ));
+int dn2idl LDAP_P(( Backend *be, struct berval *dn, int prefix, ID_BLOCK **idlp ));
+int dn2id_delete LDAP_P(( Backend *be, struct berval *dn, ID id ));
+
+Entry * dn2entry_rw LDAP_P(( Backend *be, struct berval *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,
+ Connection *conn, Operation *op,
+ 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, DBCache *db, Datum key ));
+int idl_insert_key LDAP_P(( Backend *be, 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, 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 *cursor ));
+ID idl_nextid LDAP_P(( ID_BLOCK *idl, ID *cursor ));
/*
* index.c
*/
+extern int
+index_is_indexed LDAP_P((
+ Backend *be,
+ AttributeDescription *desc ));
+
+extern int
+index_param LDAP_P((
+ Backend *be,
+ AttributeDescription *desc,
+ int ftype,
+ char **dbname,
+ slap_mask_t *mask,
+ struct berval *prefix ));
+
+extern int
+index_values LDAP_P((
+ Backend *be,
+ AttributeDescription *desc,
+ BerVarray vals,
+ ID id,
+ int op ));
+
+int index_entry LDAP_P(( Backend *be, int r, Entry *e, Attribute *ap ));
+#define index_entry_add(be,e,ap) index_entry((be),SLAP_INDEX_ADD_OP,(e),(ap))
+#define index_entry_del(be,e,ap) index_entry((be),SLAP_INDEX_DELETE_OP,(e),(ap))
-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 );
/*
- * kerberos.c
+ * key.c
*/
+extern int
+key_change LDAP_P((
+ Backend *be,
+ DBCache *db,
+ struct berval *k,
+ ID id,
+ int op ));
+extern int
+key_read LDAP_P((
+ Backend *be,
+ DBCache *db,
+ struct berval *k,
+ ID_BLOCK **idout ));
-#ifdef KERBEROS
-/* krbv4_ldap_auth( Backend *be, struct berval *cred, AUTH_DAT *ad ); */
-#endif
+/*
+ * passwd.c
+ */
+extern BI_op_extended ldbm_back_exop_passwd;
+
+/*
+ * 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
+ *
+ */
+
+/* returns LDAP error code indicating error OR SLAPD_ABANDON */
+int ldbm_modify_internal LDAP_P((Backend *be,
+ Connection *conn, Operation *op,
+ const char *dn, Modifications *mods, Entry *e,
+ const char **text, char *textbuf, size_t textlen ));
/*
* nextid.c
*/
-ID next_id( Backend *be );
-void next_id_return( Backend *be, ID id );
-ID next_id_get( Backend *be );
+int next_id LDAP_P(( Backend *be, ID *idp ));
+int next_id_get LDAP_P(( Backend *be, ID *idp ));
+int next_id_write LDAP_P(( Backend *be, ID id ));
+LDAP_END_DECL
#endif
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*
* Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
}
ldap_back_map( &li->targets[ candidate ]->at_map,
- &a->a_desc->ad_cname, &mapped, 0);
- if ( mapped.bv_val == NULL ) {
+ &a->a_desc->ad_cname, &mapped, BACKLDAP_MAP );
+ if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {
continue;
}
--- /dev/null
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ *
+ * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
+ *
+ * This work has been developed to fulfill the requirements
+ * of SysNet s.n.c. <http:www.sys-net.it> and it has been donated
+ * to the OpenLDAP Foundation in the hope that it may be useful
+ * to the Open Source community, but WITHOUT ANY WARRANTY.
+ *
+ * Permission is granted to anyone to use this software for any purpose
+ * on any computer system, and to alter it and redistribute it, subject
+ * to the following restrictions:
+ *
+ * 1. The author and SysNet s.n.c. are not responsible for the consequences
+ * of use of this software, no matter how awful, even if they arise from
+ * flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits should appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits should appear in the documentation.
+ * SysNet s.n.c. cannot be responsible for the consequences of the
+ * alterations.
+ *
+ * 4. This notice may not be removed or altered.
+ *
+ *
+ * This software is based on the backend back-ldap, implemented
+ * by Howard Chu <hyc@highlandsun.com>, and modified by Mark Valence
+ * <kurash@sassafras.com>, Pierangelo Masarati <ando@sys-net.it> and other
+ * contributors. The contribution of the original software to the present
+ * implementation is acknowledged in this copyright statement.
+ *
+ * A special acknowledgement goes to Howard for the overall architecture
+ * (and for borrowing large pieces of code), and to Mark, who implemented
+ * from scratch the attribute/objectclass mapping.
+ *
+ * The original copyright statement follows.
+ *
+ * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
+ *
+ * Permission is granted to anyone to use this software for any purpose
+ * on any computer system, and to alter it and redistribute it, subject
+ * to the following restrictions:
+ *
+ * 1. The author is not responsible for the consequences of use of this
+ * software, no matter how awful, even if they arise from flaws in it.
+ *
+ * 2. The origin of this software must not be misrepresented, either by
+ * explicit claim or by omission. Since few users ever read sources,
+ * credits should appear in the documentation.
+ *
+ * 3. Altered versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software. Since few users
+ * ever read sources, credits should appear in the
+ * documentation.
+ *
+ * 4. This notice may not be removed or altered.
+ *
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/socket.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "../back-ldap/back-ldap.h"
+#include "back-meta.h"
+
+
+/* return 0 IFF we can retrieve the attributes
+ * of entry with e_ndn
+ */
+
+/*
+ * FIXME: I never testd this function; I know it compiles ... :)
+ */
+int
+meta_back_attribute(
+ Backend *be,
+ Connection *conn,
+ Operation *op,
+ Entry *target,
+ struct berval *ndn,
+ AttributeDescription *entry_at,
+ BerVarray *vals
+)
+{
+ struct metainfo *li = ( struct metainfo * )be->be_private;
+ int rc = 1, i, j, count, is_oc, candidate;
+ Attribute *attr;
+ BerVarray abv, v;
+ char **vs;
+ struct berval mapped;
+ LDAPMessage *result, *e;
+ char *gattr[ 2 ];
+ LDAP *ld;
+
+ *vals = NULL;
+ if ( target != NULL && dn_match( &target->e_nname, ndn ) ) {
+ /* we already have a copy of the entry */
+ /* attribute and objectclass mapping has already been done */
+ attr = attr_find( target->e_attrs, entry_at );
+ if ( attr == NULL ) {
+ return 1;
+ }
+
+ for ( count = 0; attr->a_vals[ count ].bv_val != NULL; count++ )
+ ;
+ v = ( BerVarray )ch_calloc( ( count + 1 ), sizeof( struct berval ) );
+ if ( v == NULL ) {
+ return 1;
+ }
+
+ for ( j = 0, abv = attr->a_vals; --count >= 0; abv++ ) {
+ if ( abv->bv_len > 0 ) {
+ ber_dupbv( &v[ j ], abv );
+ if ( v[ j ].bv_val == NULL ) {
+ break;
+ }
+ }
+ }
+ v[ j ].bv_val = NULL;
+ *vals = v;
+
+ return 0;
+ } /* else */
+
+ candidate = meta_back_select_unique_candidate( li, ndn );
+ if ( candidate == -1 ) {
+ return 1;
+ }
+
+ ldap_back_map( &li->targets[ candidate ]->at_map,
+ &entry_at->ad_cname, &mapped, BACKLDAP_MAP );
+ if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' )
+ return 1;
+
+ rc = ldap_initialize( &ld, li->targets[ candidate ]->uri );
+ if ( rc != LDAP_SUCCESS ) {
+ return 1;
+ }
+
+ rc = ldap_bind_s( ld, li->targets[ candidate ]->binddn.bv_val,
+ li->targets[ candidate ]->bindpw.bv_val, LDAP_AUTH_SIMPLE );
+ if ( rc != LDAP_SUCCESS) {
+ return 1;
+ }
+
+ gattr[ 0 ] = mapped.bv_val;
+ gattr[ 1 ] = NULL;
+ if ( ldap_search_ext_s( ld, ndn->bv_val, LDAP_SCOPE_BASE,
+ "(objectClass=*)",
+ gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
+ LDAP_NO_LIMIT, &result) == LDAP_SUCCESS) {
+ if ( ( e = ldap_first_entry( ld, result ) ) != NULL ) {
+ vs = ldap_get_values( ld, e, mapped.bv_val );
+ if ( vs != NULL ) {
+ for ( count = 0; vs[ count ] != NULL;
+ count++ ) { }
+ v = ( BerVarray )ch_calloc( ( count + 1 ),
+ sizeof( struct berval ) );
+ if ( v == NULL ) {
+ ldap_value_free( vs );
+ } else {
+ is_oc = ( strcasecmp( "objectclass", mapped.bv_val ) == 0 );
+ for ( i = 0, j = 0; i < count; i++ ) {
+ ber_str2bv( vs[ i ], 0, 0, &v[ j ] );
+ if ( !is_oc ) {
+ if ( v[ j ].bv_val == NULL ) {
+ ch_free( vs[ i ] );
+ } else {
+ j++;
+ }
+ } else {
+ ldap_back_map( &li->targets[ candidate ]->oc_map, &v[ j ], &mapped, BACKLDAP_REMAP );
+ if ( mapped.bv_val && mapped.bv_val[0] != '\0' ) {
+ ber_dupbv( &v[ j ], &mapped );
+ if ( v[ j ].bv_val ) {
+ j++;
+ }
+ }
+ ch_free( vs[ i ] );
+ }
+ }
+ v[ j ].bv_val = NULL;
+ *vals = v;
+ rc = 0;
+ ch_free( vs );
+ }
+ }
+ }
+ ldap_msgfree( result );
+ }
+ ldap_unbind( ld );
+
+ return(rc);
+}
+
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*
* Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
LDAP *ld;
struct berval bound_dn;
+ struct berval cred;
int bound;
#define META_UNBOUND 0
#define META_BOUND 1
ldap_pvt_thread_mutex_t conn_mutex;
Avlnode *conntree;
+
+ int savecred;
};
#define META_OP_ALLOW_MULTIPLE 0x00
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*
* Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
#include "../back-ldap/back-ldap.h"
#include "back-meta.h"
+static LDAP_REBIND_PROC meta_back_rebind;
+
static int
meta_back_do_single_bind(
struct metainfo *li,
lc->conns[ candidate ].bound = META_BOUND;
lc->bound_target = candidate;
+ if ( li->savecred ) {
+ if ( lc->conns[ candidate ].cred.bv_val )
+ ch_free( lc->conns[ candidate ].cred.bv_val );
+ ber_dupbv( &lc->conns[ candidate ].cred, cred );
+ ldap_set_rebind_proc( lc->conns[ candidate ].ld,
+ meta_back_rebind,
+ &lc->conns[ candidate ] );
+ }
+
if ( li->cache.ttl != META_DNCACHE_DISABLED
&& ndn->bv_len != 0 ) {
( void )meta_dncache_update_entry( &li->cache,
return 0;
}
+/*
+ * meta_back_rebind
+ *
+ * This is a callback used for chasing referrals using the same
+ * credentials as the original user on this session.
+ */
+static int
+meta_back_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
+ ber_int_t msgid, void *params )
+{
+ struct metasingleconn *lc = params;
+
+ return ldap_bind_s( ld, lc->bound_dn.bv_val, lc->cred.bv_val, LDAP_AUTH_SIMPLE );
+}
+
/*
* FIXME: error return must be handled in a cleaner way ...
*/
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*
* Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
struct berval mapped_value = ava->aa_value;
if ( lsc->candidate != META_CANDIDATE ) {
+ msgid[ i ] = -1;
continue;
}
/*
* if attr is objectClass, try to remap the value
*/
- if ( ava->aa_desc->ad_type->sat_oid
- == slap_schema.si_ad_objectClass->ad_type->sat_oid ) {
+ if ( ava->aa_desc == slap_schema.si_ad_objectClass ) {
ldap_back_map( &li->targets[ i ]->oc_map,
- &ava->aa_value, &mapped_value, 0 );
+ &ava->aa_value, &mapped_value,
+ BACKLDAP_MAP );
- if ( mapped_value.bv_val == NULL ) {
- lsc->candidate = META_NOT_CANDIDATE;
+ if ( mapped_value.bv_val == NULL || mapped_value.bv_val[0] == '\0' ) {
continue;
}
/*
*/
} else {
ldap_back_map( &li->targets[ i ]->at_map,
- &ava->aa_desc->ad_cname, &mapped_attr, 0 );
- if ( mapped_attr.bv_val == NULL ) {
- lsc->candidate = META_NOT_CANDIDATE;
+ &ava->aa_desc->ad_cname, &mapped_attr,
+ BACKLDAP_MAP );
+ if ( mapped_attr.bv_val == NULL || mapped_attr.bv_val[0] == '\0' ) {
continue;
}
}
*/
msgid[ i ] = ldap_compare( lc->conns[ i ].ld, mdn,
mapped_attr.bv_val, mapped_value.bv_val );
- if ( msgid[ i ] == -1 ) {
- lsc->candidate = META_NOT_CANDIDATE;
- continue;
- }
-
if ( mdn != dn->bv_val ) {
free( mdn );
}
free( mapped_value.bv_val );
}
+ if ( msgid[ i ] == -1 ) {
+ continue;
+ }
+
++candidates;
}
int lrc;
LDAPMessage *res = NULL;
- if ( lsc->candidate != META_CANDIDATE ) {
+ if ( msgid[ i ] == -1 ) {
continue;
}
last = i;
break;
}
- lsc->candidate = META_NOT_CANDIDATE;
+ msgid[ i ] = -1;
--candidates;
+
} else {
- lsc->candidate = META_NOT_CANDIDATE;
+ msgid[ i ] = -1;
--candidates;
if ( res ) {
ldap_msgfree( res );
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*
* Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
#include "slap.h"
#include "../back-ldap/back-ldap.h"
+#include "../../../libraries/libldap/ldap-int.h"
#include "back-meta.h"
static struct metatarget *
#if 0
int j;
#endif /* uncomment if uri MUST be a branch of suffix */
- LDAPURLDesc *ludp;
- char *last;
+ LDAPURLDesc *ludp, *tmpludp;
struct berval dn;
int rc;
/*
* uri MUST be legal!
*/
- if ( ldap_url_parse( argv[ 1 ], &ludp ) != LDAP_SUCCESS ) {
+ if ( ldap_url_parselist_ext( &ludp, argv[ 1 ], "\t" ) != LDAP_SUCCESS ) {
fprintf( stderr,
"%s: line %d: unable to parse URI"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
return( 1 );
}
- li->targets[ i ]->uri = ch_strdup( argv[ 1 ] );
- last = strstr( li->targets[ i ]->uri, ludp->lud_dn );
- assert( last != NULL );
- last[ 0 ] = '\0';
+ ludp->lud_dn[ 0 ] = '\0';
+
+ for ( tmpludp = ludp->lud_next; tmpludp; tmpludp = tmpludp->lud_next ) {
+ if ( tmpludp->lud_dn != NULL && tmpludp->lud_dn[ 0 ] != '\0' ) {
+ fprintf( stderr, "%s: line %d: "
+ "multiple URIs must have no DN part\n",
+ fname, lineno, argv[ 1 ] );
+ return( 1 );
+
+ }
+ }
+
+ li->targets[ i ]->uri = ldap_url_list2urls( ludp );
+ ldap_free_urllist( ludp );
+ if ( li->targets[ i ]->uri == NULL) {
+ fprintf( stderr, "%s: line %d: no memory?\n",
+ fname, lineno );
+ return( 1 );
+ }
/*
* uri MUST be a branch of suffix!
}
}
#endif
-
- ldap_free_urldesc( ludp );
#if 0
fprintf(stderr, "%s: line %d: URI \"%s\", suffix \"%s\"\n",
}
ber_str2bv( argv[ 1 ], 0L, 1, &li->targets[ i ]->bindpw );
+ /* save bind creds for referral rebinds? */
+ } else if ( strcasecmp( argv[0], "rebind-as-user" ) == 0 ) {
+ if (argc != 1) {
+ fprintf( stderr,
+ "%s: line %d: rebind-as-user takes no arguments\n",
+ fname, lineno );
+ return( 1 );
+ }
+ li->savecred = 1;
+
/* name to use as pseudo-root dn */
} else if ( strcasecmp( argv[ 0 ], "pseudorootdn" ) == 0 ) {
int i = li->ntargets-1;
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*
* Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
Connection *conn,
Operation *op,
struct metatarget *lt,
- int vers,
struct metasingleconn *lsc
)
{
- int err;
+ int err, vers;
/*
* Already init'ed
if ( err != LDAP_SUCCESS ) {
return ldap_back_map_result( err );
}
-
+
/*
* Set LDAP version. This will always succeed: If the client
* bound with a particular version, then so can we.
*/
+ vers = conn->c_protocol;
ldap_set_option( lsc->ld, LDAP_OPT_PROTOCOL_VERSION, &vers );
/*
int *candidate )
{
struct metaconn *lc, lc_curr;
- int vers, cached = -1, i = -1, err = LDAP_SUCCESS;
+ int cached = -1, i = -1, err = LDAP_SUCCESS;
int new_conn = 0;
/* Searches for a metaconn in the avl tree */
new_conn = 1;
}
- vers = conn->c_protocol;
-
/*
* looks in cache, if any
*/
* sends the appropriate result.
*/
err = init_one_conn( conn, op, li->targets[ i ],
- vers, &lc->conns[ i ] );
+ &lc->conns[ i ] );
if ( err != LDAP_SUCCESS ) {
/*
* also init'd
*/
int lerr = init_one_conn( conn, op, li->targets[ i ],
- vers, &lc->conns[ i ] );
+ &lc->conns[ i ] );
if ( lerr != LDAP_SUCCESS ) {
/*
*/
int lerr = init_one_conn( conn, op,
li->targets[ i ],
- vers, &lc->conns[ i ] );
+ &lc->conns[ i ] );
if ( lerr != LDAP_SUCCESS ) {
/*
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*
* Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
}
ldap_back_map( &li->targets[ candidate ]->oc_map,
- &group_oc_name, &group_oc_name, 0 );
- if ( group_oc_name.bv_val == NULL ) {
+ &group_oc_name, &group_oc_name, BACKLDAP_MAP );
+ if ( group_oc_name.bv_val == NULL || group_oc_name.bv_val[0] == '\0' ) {
goto cleanup;
}
ldap_back_map( &li->targets[ candidate ]->at_map,
- &group_at_name, &group_at_name, 0 );
- if ( group_at_name.bv_val == NULL ) {
+ &group_at_name, &group_at_name, BACKLDAP_MAP );
+ if ( group_at_name.bv_val == NULL || group_at_name.bv_val[0] == '\0' ) {
goto cleanup;
}
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*
* Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
static void
conn_free(
- struct metaconn *lc
+ void *v_lc
)
{
+ struct metaconn *lc = v_lc;
struct metasingleconn *lsc;
for ( lsc = lc->conns; !META_LAST(lsc); lsc++ ) {
rewrite_info_delete( lt->rwinfo );
}
avl_free( lt->oc_map.remap, NULL );
- avl_free( lt->oc_map.map, ( AVL_FREE )mapping_free );
+ avl_free( lt->oc_map.map, mapping_free );
avl_free( lt->at_map.remap, NULL );
- avl_free( lt->at_map.map, ( AVL_FREE )mapping_free );
+ avl_free( lt->at_map.map, mapping_free );
}
int
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
if ( li->conntree ) {
- avl_free( li->conntree,
- ( AVL_FREE )conn_free );
+ avl_free( li->conntree, conn_free );
}
/*
ldap_pvt_thread_mutex_lock( &li->cache.mutex );
if ( li->cache.tree ) {
- avl_free( li->cache.tree,
- ( AVL_FREE )meta_dncache_free );
+ avl_free( li->cache.tree, meta_dncache_free );
}
ldap_pvt_thread_mutex_unlock( &li->cache.mutex );
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*
* Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
}
ldap_back_map( &li->targets[ candidate ]->at_map,
- &ml->sml_desc->ad_cname, &mapped, 0 );
- if ( mapped.bv_val == NULL ) {
+ &ml->sml_desc->ad_cname, &mapped,
+ BACKLDAP_MAP );
+ if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {
continue;
}
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*
* Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
char *mapped_filter, **mapped_attrs;
if ( lsc->candidate != META_CANDIDATE ) {
+ msgid[ i ] = -1;
continue;
}
/*
* this target is no longer candidate
*/
- lsc->candidate = META_NOT_CANDIDATE;
+ msgid[ i ] = -1;
continue;
}
break;
/*
* this target is no longer candidate
*/
- lsc->candidate = META_NOT_CANDIDATE;
+ msgid[ i ] = -1;
continue;
}
* Maps attributes in filter
*/
mapped_filter = ldap_back_map_filter( &li->targets[ i ]->at_map,
- &li->targets[ i ]->oc_map, &mfilter, 0 );
+ &li->targets[ i ]->oc_map, &mfilter,
+ BACKLDAP_MAP );
if ( mapped_filter == NULL ) {
mapped_filter = ( char * )mfilter.bv_val;
} else {
* Maps required attributes
*/
mapped_attrs = ldap_back_map_attrs( &li->targets[ i ]->at_map,
- attrs, 0 );
+ attrs, BACKLDAP_MAP );
if ( mapped_attrs == NULL && attrs) {
for ( count=0; attrs[ count ].an_name.bv_val; count++ );
mapped_attrs = ch_malloc( ( count + 1 ) * sizeof(char *));
*/
msgid[ i ] = ldap_search( lsc->ld, mbase, realscope,
mapped_filter, mapped_attrs, attrsonly );
- if ( msgid[ i ] == -1 ) {
- lsc->candidate = META_NOT_CANDIDATE;
- continue;
- }
-
if ( mapped_attrs ) {
free( mapped_attrs );
mapped_attrs = NULL;
mbase = NULL;
}
+ if ( msgid[ i ] == -1 ) {
+ continue;
+ }
+
++candidates;
}
ab = op->o_abandon;
for ( i = 0, lsc = lc->conns; !META_LAST(lsc); lsc++, i++ ) {
- if ( lsc->candidate != META_CANDIDATE ) {
+ if ( msgid[ i ] == -1 ) {
continue;
}
* When no candidates are left,
* the outer cycle finishes
*/
- lsc->candidate = META_NOT_CANDIDATE;
+ msgid[ i ] = -1;
--candidates;
}
}
while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
ldap_back_map( &li->targets[ target ]->at_map,
- &a, &mapped, 1 );
- if ( mapped.bv_val == NULL ) {
+ &a, &mapped, BACKLDAP_REMAP );
+ if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {
continue;
}
attr = ( Attribute * )ch_malloc( sizeof( Attribute ) );
for ( last = 0; attr->a_vals[ last ].bv_val; ++last );
for ( i = 0, bv = attr->a_vals; bv->bv_val; bv++, i++ ) {
ldap_back_map( &li->targets[ target]->oc_map,
- bv, &mapped, 1 );
- if ( mapped.bv_val == NULL ) {
+ bv, &mapped, BACKLDAP_REMAP );
+ if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
free( bv->bv_val );
bv->bv_val = NULL;
if ( --last < 0 ) {
/* database.c - deals with database subsystem */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/*
}
if ( slap_str2ad( "seeAlso", &ad_seeAlso, &text ) != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, CRIT,
+ "monitor_subsys_database_init: "
+ "unable to find 'seeAlso' attribute description\n",
+ 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "monitor_subsys_database_init: "
+ "unable to find 'seeAlso' attribute description\n",
+ 0, 0, 0 );
+#endif
return( -1 );
}
--- /dev/null
+
+Differences from 2.0 Perl API:
+
+- Perl 5.6 is supported
+
+- backend methods return actual LDAP result codes, not
+ true/false; this gives the Perl module finer control
+ of the error returned to the client
+
+- a filterSearchResults configuration file directive was
+ added to tell the backend glue that the results returned
+ from the Perl module are candidates only
+
+- the "init" method is called after the backend has been
+ initialized - this lets you do some initialization after
+ *all* configuration file directives have been read
+
+- the interface for the search method is improved to
+ pass the scope, deferencing policy, size limit, etc.
+ See SampleLDAP.pm for details.
+
+These changes were sponsored by myinternet Limited.
+
+Luke Howard <lukeh@padl.com>
+
return rc;
}
-int
-backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi )
+static int
+backsql_get_attr_vals( void *v_at, void *v_bsi )
{
+ backsql_at_map_rec *at = v_at;
+ backsql_srch_info *bsi = v_bsi;
RETCODE rc;
SQLHSTMT sth;
BACKSQL_ROW_NTS row;
} else {
Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
"retrieving all attributes\n", 0, 0, 0 );
- avl_apply( bsi->oc->attrs, (AVL_APPLY)backsql_get_attr_vals,
+ avl_apply( bsi->oc->attrs, backsql_get_attr_vals,
bsi, 0, AVL_INORDER );
}
* Uses the pointer to the ObjectClass structure
*/
static int
-backsql_cmp_oc( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
+backsql_cmp_oc( const void *v_m1, const void *v_m2 )
{
+ const backsql_oc_map_rec *m1 = v_m1, *m2 = v_m2;
return ( m1->oc < m2->oc ? -1 : ( m1->oc > m2->oc ? 1 : 0 ) );
}
static int
-backsql_cmp_oc_id( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
+backsql_cmp_oc_id( const void *v_m1, const void *v_m2 )
{
+ const backsql_oc_map_rec *m1 = v_m1, *m2 = v_m2;
return ( m1->id < m2->id ? -1 : ( m1->id > m2->id ? 1 : 0 ) );
}
* Uses the pointer to the AttributeDescription structure
*/
static int
-backsql_cmp_attr( backsql_at_map_rec *m1, backsql_at_map_rec *m2 )
+backsql_cmp_attr( const void *v_m1, const void *v_m2 )
{
+ const backsql_at_map_rec *m1 = v_m1, *m2 = v_m2;
return ( m1->ad < m2->ad ? -1 : ( m1->ad > m2->ad ? 1 : 0 ) );
}
at_map->param_order = 0;
at_map->expect_return = 0;
backsql_make_attr_query( oc_map, at_map );
- avl_insert( &oc_map->attrs, at_map,
- (AVL_CMP)backsql_cmp_attr, NULL );
+ avl_insert( &oc_map->attrs, at_map, backsql_cmp_attr, NULL );
at_map = (backsql_at_map_rec *)ch_calloc( 1,
sizeof( backsql_at_map_rec ) );
at_map->param_order = 0;
at_map->expect_return = 0;
backsql_make_attr_query( oc_map, at_map );
- avl_insert( &oc_map->attrs, at_map,
- (AVL_CMP)backsql_cmp_attr, NULL );
+ avl_insert( &oc_map->attrs, at_map, backsql_cmp_attr, NULL );
return 1;
}
*/
oc_map->attrs = NULL;
- avl_insert( &si->oc_by_oc, oc_map,
- (AVL_CMP)backsql_cmp_oc, NULL );
- avl_insert( &si->oc_by_id, oc_map,
- (AVL_CMP)backsql_cmp_oc_id, NULL );
+ avl_insert( &si->oc_by_oc, oc_map, backsql_cmp_oc, NULL );
+ avl_insert( &si->oc_by_id, oc_map, backsql_cmp_oc_id, NULL );
oc_id = oc_map->id;
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
"objectClass '%s': keytbl='%s' keycol='%s'\n",
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
"preconstructed query '%s'\n",
at_map->query, 0, 0 );
- avl_insert( &oc_map->attrs, at_map,
- (AVL_CMP)backsql_cmp_attr, NULL );
+ avl_insert( &oc_map->attrs, at_map, backsql_cmp_attr, NULL );
}
backsql_FreeRow( &at_row );
SQLFreeStmt( at_sth, SQL_CLOSE );
#endif /* BACKSQL_TRACE */
tmp.oc = oc;
- res = (backsql_oc_map_rec *)avl_find( si->oc_by_oc, &tmp,
- (AVL_CMP)backsql_cmp_oc );
+ res = (backsql_oc_map_rec *)avl_find( si->oc_by_oc, &tmp, backsql_cmp_oc );
#ifdef BACKSQL_TRACE
if ( res != NULL ) {
Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): "
return NULL;
}
- res = (backsql_oc_map_rec *)avl_find( si->oc_by_oc, &tmp,
- (AVL_CMP)backsql_cmp_oc );
+ res = (backsql_oc_map_rec *)avl_find( si->oc_by_oc, &tmp, backsql_cmp_oc );
#ifdef BACKSQL_TRACE
if ( res != NULL ) {
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
tmp.id = id;
res = (backsql_oc_map_rec *)avl_find( si->oc_by_id, &tmp,
- (AVL_CMP)backsql_cmp_oc_id );
+ backsql_cmp_oc_id );
#ifdef BACKSQL_TRACE
if ( res != NULL ) {
tmp.ad = ad;
res = (backsql_at_map_rec *)avl_find( objclass->attrs, &tmp,
- (AVL_CMP)backsql_cmp_attr );
+ backsql_cmp_attr );
#ifdef BACKSQL_TRACE
if ( res != NULL ) {
}
res = (backsql_at_map_rec *)avl_find( objclass->attrs, &tmp,
- (AVL_CMP)backsql_cmp_attr );
+ backsql_cmp_attr );
#ifdef BACKSQL_TRACE
if ( res != NULL ) {
}
static void
-backsql_free_attr( backsql_at_map_rec *at )
+backsql_free_attr( void *v_at )
{
+ backsql_at_map_rec *at = v_at;
Debug( LDAP_DEBUG_TRACE, "==>free_attr(): '%s'\n",
at->ad->ad_cname.bv_val, 0, 0 );
ch_free( at->sel_expr.bv_val );
}
static void
-backsql_free_oc( backsql_oc_map_rec *oc )
+backsql_free_oc( void *v_oc )
{
+ backsql_oc_map_rec *oc = v_oc;
Debug( LDAP_DEBUG_TRACE, "==>free_oc(): '%s'\n",
BACKSQL_OC_NAME( oc ), 0, 0 );
- avl_free( oc->attrs, (AVL_FREE)backsql_free_attr );
+ avl_free( oc->attrs, backsql_free_attr );
ch_free( oc->keytbl.bv_val );
ch_free( oc->keycol.bv_val );
if ( oc->create_proc != NULL ) {
backsql_destroy_schema_map( backsql_info *si )
{
Debug( LDAP_DEBUG_TRACE, "==>destroy_schema_map()\n", 0, 0, 0 );
- avl_free( si->oc_by_oc, NULL );
- avl_free( si->oc_by_id, (AVL_FREE)backsql_free_oc );
+ avl_free( si->oc_by_oc, 0 );
+ avl_free( si->oc_by_id, backsql_free_oc );
Debug( LDAP_DEBUG_TRACE, "<==destroy_schema_map()\n", 0, 0, 0 );
return 0;
}
return ( query->bv_val == NULL ? 1 : 0 );
}
-int
-backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
+static int
+backsql_oc_get_candidates( void *v_oc, void *v_bsi )
{
+ backsql_oc_map_rec *oc = v_oc;
+ backsql_srch_info *bsi = v_bsi;
struct berval query;
SQLHSTMT sth;
RETCODE rc;
*/
srch_info.n_candidates = ( isroot ? -2 : limit->lms_s_unchecked == -1
? -2 : limit->lms_s_unchecked );
- avl_apply( bi->oc_by_oc, (AVL_APPLY)backsql_oc_get_candidates,
+ avl_apply( bi->oc_by_oc, backsql_oc_get_candidates,
&srch_info, BACKSQL_STOP, AVL_INORDER );
if ( !isroot && limit->lms_s_unchecked != -1 ) {
if ( srch_info.n_candidates == -1 ) {
}
static int
-backsql_cmp_connid( backsql_db_conn *c1, backsql_db_conn *c2 )
+backsql_cmp_connid( const void *v_c1, const void *v_c2 )
{
+ const backsql_db_conn *c1 = v_c1, *c2 = v_c2;
if ( c1->ldap_cid > c2->ldap_cid ) {
return 1;
}
Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(): "
"connected, adding to tree\n", 0, 0, 0 );
ldap_pvt_thread_mutex_lock( &si->dbconn_mutex );
- avl_insert( &si->db_conns, dbc, (AVL_CMP)backsql_cmp_connid, NULL );
+ avl_insert( &si->db_conns, dbc, backsql_cmp_connid, NULL );
ldap_pvt_thread_mutex_unlock( &si->dbconn_mutex );
Debug( LDAP_DEBUG_TRACE, "<==backsql_open_db_conn()\n", 0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "==>backsql_free_db_conn()\n", 0, 0, 0 );
tmp.ldap_cid = ldapc->c_connid;
ldap_pvt_thread_mutex_lock( &si->dbconn_mutex );
- conn = (backsql_db_conn *)avl_delete( &si->db_conns, &tmp,
- (AVL_CMP)backsql_cmp_connid );
+ conn = avl_delete( &si->db_conns, &tmp, backsql_cmp_connid );
ldap_pvt_thread_mutex_unlock( &si->dbconn_mutex );
/*
* we have one thread per connection, as I understand --
* so we do not need locking here
*/
- dbc = (backsql_db_conn *)avl_find( si->db_conns, &tmp,
- (AVL_CMP)backsql_cmp_connid );
+ dbc = avl_find( si->db_conns, &tmp, backsql_cmp_connid );
if ( !dbc ) {
rc = backsql_open_db_conn( si, ldapc->c_connid, &dbc );
if ( rc != LDAP_SUCCESS) {
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* backend.c - routines for dealing with back-end databases */
#include <ac/string.h>
#include <ac/socket.h>
-
#include <sys/stat.h>
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
#include "lutil.h"
#include "lber_pvt.h"
Operation *op
)
{
- int i;
+ int i;
+#if defined( LDAP_SLAPI )
+ Slapi_PBlock *pb = op->o_pb;
+
+ int rc;
+ slapi_x_connection_set_pb( pb, conn );
+ slapi_x_operation_set_pb( pb, op );
+#endif /* defined( LDAP_SLAPI ) */
for ( i = 0; i < nbackends; i++ ) {
+#if defined( LDAP_SLAPI )
+ slapi_pblock_set( pb, SLAPI_BACKEND, (void *)&backends[i] );
+ rc = doPluginFNs( &backends[i], SLAPI_PLUGIN_PRE_UNBIND_FN,
+ (Slapi_PBlock *)pb );
+ if ( rc != 0 ) {
+ /*
+ * A preoperation plugin failure will abort the
+ * entire operation.
+ */
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_bind: Unbind preoperation plugin "
+ "failed\n", 0, 0, 0);
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_bind: Unbind preoperation plugin "
+ "failed.\n", 0, 0, 0);
+#endif
+ return 0;
+ }
+#endif /* defined( LDAP_SLAPI ) */
+
if ( backends[i].be_unbind ) {
(*backends[i].be_unbind)( &backends[i], conn, op );
}
+
+#if defined( LDAP_SLAPI )
+ if ( doPluginFNs( &backends[i], SLAPI_PLUGIN_POST_UNBIND_FN,
+ (Slapi_PBlock *)pb ) != 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_unbind: Unbind postoperation plugins "
+ "failed\n", 0, 0, 0);
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_unbind: Unbind postoperation plugins "
+ "failed.\n", 0, 0, 0);
+#endif
+ }
+#endif /* defined( LDAP_SLAPI ) */
}
return 0;
}
}
+#ifdef LDAP_EXOP_X_CANCEL
+ {
+ struct berval bv = BER_BVC( LDAP_EXOP_X_CANCEL );
+ if ( bvmatch( opdata, &bv ) ) {
+ break;
+ }
+ }
+#endif
+
/* treat everything else as a modify */
opflag = SLAP_RESTRICT_OP_MODIFY;
updateop++;
/* backglue.c - backend glue routines */
/* $OpenLDAP$ */
/*
- * Copyright 2001-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 2001-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include <stdio.h>
+#include <ac/string.h>
#include <ac/socket.h>
#define SLAPD_TOOLS
return rc;
}
+static int
+glue_back_sendreference (
+ BackendDB *be,
+ Connection *c,
+ Operation *op,
+ Entry *e,
+ BerVarray bv,
+ LDAPControl **ctrls,
+ BerVarray *v2
+)
+{
+ slap_callback *tmp = op->o_callback;
+ glue_state *gs = tmp->sc_private;
+ int rc;
+
+ op->o_callback = gs->prevcb;
+ if (op->o_callback && op->o_callback->sc_sendreference) {
+ rc = op->o_callback->sc_sendreference( be, c, op, e, bv, ctrls, v2 );
+ } else {
+ rc = send_search_reference( be, c, op, e, bv, ctrls, v2 );
+ }
+ op->o_callback = tmp;
+ return rc;
+}
+
static int
glue_back_search (
BackendDB *b0,
BackendDB *be;
int i, rc = 0, t2limit = 0, s2limit = 0;
long stoptime = 0;
- glue_state gs = {0};
+ glue_state gs = {0, 0, 0, NULL, 0, NULL, NULL};
slap_callback cb;
cb.sc_response = glue_back_response;
s2limit, t2limit, filter, filterstr,
attrs, attrsonly);
}
+
+ switch ( gs.err ) {
+
+ /*
+ * Add errors that should result in dropping
+ * the search
+ */
+ case LDAP_SIZELIMIT_EXCEEDED:
+ case LDAP_TIMELIMIT_EXCEEDED:
+ case LDAP_ADMINLIMIT_EXCEEDED:
+ goto end_of_loop;
+
+ default:
+ break;
+ }
}
+end_of_loop:;
break;
}
op->o_callback = gs.prevcb;
/* bind.c - decode an ldap bind operation and pass it to a backend db */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "ldap_pvt.h"
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
+
int
do_bind(
struct berval cred = { 0, NULL };
Backend *be = NULL;
+#ifdef LDAP_SLAPI
+ Slapi_PBlock *pb = op->o_pb;
+#endif
+
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ENTRY, "do_bind: conn %d\n", conn->c_connid, 0, 0 );
#else
/* log authorization identity demotion */
if ( conn->c_dn.bv_len ) {
Statslog( LDAP_DEBUG_STATS,
- "conn=%lu op=%lu AUTHZ anonymous mech=implicit ssf=0",
+ "conn=%lu op=%lu BIND anonymous mech=implicit ssf=0",
op->o_connid, op->o_opid, 0, 0, 0 );
}
* }
*
* SaslCredentials ::= SEQUENCE {
- * mechanism LDAPString,
- * credentials OCTET STRING OPTIONAL
+ * mechanism LDAPString,
+ * credentials OCTET STRING OPTIONAL
* }
*/
/* log authorization identity */
Statslog( LDAP_DEBUG_STATS,
- "conn=%lu op=%lu AUTHZ dn=\"%s\" mech=%s ssf=%d\n",
+ "conn=%lu op=%lu BIND dn=\"%s\" mech=%s ssf=%d\n",
op->o_connid, op->o_opid,
- conn->c_dn.bv_val, conn->c_authmech.bv_val, ssf );
+ conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
+ conn->c_authmech.bv_val, ssf );
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, DETAIL1,
"do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
- conn->c_authmech.bv_val, conn->c_dn.bv_val, ssf );
+ conn->c_authmech.bv_val,
+ conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
+ ssf );
#else
Debug( LDAP_DEBUG_TRACE,
"do_bind: SASL/%s bind: dn=\"%s\" ssf=%d\n",
- conn->c_authmech.bv_val, conn->c_dn.bv_val, ssf );
+ conn->c_authmech.bv_val,
+ conn->c_dn.bv_val ? conn->c_dn.bv_val : "<empty>",
+ ssf );
#endif
} else if ( rc == LDAP_SASL_BIND_IN_PROGRESS ) {
goto cleanup;
}
+#if defined( LDAP_SLAPI )
+ slapi_x_backend_set_pb( pb, be );
+ slapi_x_connection_set_pb( pb, conn );
+ slapi_x_operation_set_pb( pb, op );
+ slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val );
+ slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method );
+ slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, (void *)&cred );
+ slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(0) );
+
+ rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_BIND_FN, pb );
+ if ( rc != SLAPI_BIND_SUCCESS ) {
+ /*
+ * Binding is a special case for SLAPI plugins. It is
+ * possible for a bind plugin to be successful *and*
+ * abort further processing; this means it has handled
+ * a bind request authoritatively. If we have reached
+ * here, a result has been sent to the client (XXX
+ * need to check with Sun whether SLAPI_BIND_ANONYMOUS
+ * means a result has been sent).
+ */
+ int ldapRc;
+
+ if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&ldapRc ) != 0 )
+ ldapRc = LDAP_OTHER;
+
+ edn.bv_val = NULL;
+ edn.bv_len = 0;
+ if ( rc != SLAPI_BIND_FAIL && ldapRc == LDAP_SUCCESS ) {
+ /* Set the new connection DN. */
+ if ( rc != SLAPI_BIND_ANONYMOUS ) {
+ slapi_pblock_get( pb, SLAPI_CONN_DN, (void *)&edn.bv_val );
+ }
+ rc = dnPrettyNormal( NULL, &edn, &pdn, &ndn );
+ ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+ conn->c_dn = pdn;
+ conn->c_ndn = ndn;
+ pdn.bv_val = NULL;
+ pdn.bv_len = 0;
+ ndn.bv_val = NULL;
+ ndn.bv_len = 0;
+ if ( conn->c_dn.bv_len != 0 ) {
+ ber_len_t max = sockbuf_max_incoming_auth;
+ ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
+ }
+ /* log authorization identity */
+ Statslog( LDAP_DEBUG_STATS,
+ "conn=%lu op=%lu BIND dn=\"%s\" mech=simple (SLAPI) ssf=0\n",
+ op->o_connid, op->o_opid,
+ conn->c_dn.bv_val, 0, 0 );
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ }
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_bind: Bind preoperation plugin returned %d\n",
+ rc, 0, 0);
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_bind: Bind preoperation plugin returned %d.\n",
+ rc, 0, 0);
+#endif
+ rc = ldapRc;
+ goto cleanup;
+ }
+#endif /* defined( LDAP_SLAPI ) */
+
if ( be->be_bind ) {
int ret;
/* log authorization identity */
Statslog( LDAP_DEBUG_STATS,
- "conn=%lu op=%lu AUTHZ dn=\"%s\" mech=simple ssf=0\n",
+ "conn=%lu op=%lu BIND dn=\"%s\" mech=simple ssf=0\n",
op->o_connid, op->o_opid,
conn->c_dn.bv_val, conn->c_authmech.bv_val, 0 );
NULL, NULL );
}
+#if defined( LDAP_SLAPI )
+ if ( doPluginFNs( be, SLAPI_PLUGIN_POST_BIND_FN, pb ) != 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_bind: Bind postoperation plugins failed\n",
+ 0, 0, 0);
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_bind: Bind postoperation plugins failed.\n",
+ 0, 0, 0);
+#endif
+ }
+#endif /* defined( LDAP_SLAPI ) */
+
cleanup:
conn->c_sasl_bindop = NULL;
--- /dev/null
+/* $OpenLDAP$ */
+/* cancel.c - LDAP cancel extended operation */
+/*
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/krb.h>
+#include <ac/socket.h>
+#include <ac/string.h>
+#include <ac/unistd.h>
+
+#include "slap.h"
+
+#ifdef LDAP_EXOP_X_CANCEL
+
+#include <lber_pvt.h>
+#include <lutil.h>
+
+int cancel_extop(
+ Connection *conn,
+ Operation *op,
+ const char *reqoid,
+ struct berval *reqdata,
+ char **rspoid,
+ struct berval **rspdata,
+ LDAPControl ***rspctrls,
+ const char **text,
+ BerVarray *refs )
+{
+ Backend *be;
+ int rc;
+ int found = 0;
+ int opid;
+ BerElement *ber;
+ int i;
+
+ assert( reqoid != NULL );
+ assert( strcmp( LDAP_EXOP_X_CANCEL, reqoid ) == 0 );
+
+ if ( reqdata == NULL ) {
+ *text = "no message ID supplied";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ ber = ber_init( reqdata );
+ if ( ber == NULL ) {
+ *text = "internal error";
+ return LDAP_OTHER;
+ }
+
+ if ( ber_scanf( ber, "{i}", &opid ) == LBER_ERROR ) {
+ *text = "message ID parse failed";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ (void) ber_free( ber, 1 );
+
+ if ( opid < 0 ) {
+ *text = "message ID invalid";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+ LDAP_STAILQ_FOREACH( op, &conn->c_pending_ops, o_next ) {
+ if ( op->o_msgid == opid ) {
+ LDAP_STAILQ_REMOVE( &conn->c_pending_ops, op, slap_op, o_next );
+ slap_op_free( op );
+ found = 1;
+ break;
+ }
+ }
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+
+ if ( found )
+ return LDAP_SUCCESS;
+
+ found = 0;
+ ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+ LDAP_STAILQ_FOREACH( op, &conn->c_ops, o_next ) {
+ if ( op->o_msgid == opid ) {
+ found = 1;
+ break;
+ }
+ }
+
+ if ( !found ) {
+#ifdef LDAP_SYNC
+ for ( i = 0; i < nbackends; i++ ) {
+ if ( strncmp( backends[i].be_type, "bdb", 3 ) ) continue;
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ if ( bdb_cancel( &backends[i], conn, opid ) == LDAP_SUCCESS ) {
+ return LDAP_SUCCESS;
+ } else {
+ *text = "message ID not found";
+ return LDAP_NO_SUCH_OPERATION;
+ }
+ }
+#else
+ *text = "message ID not found";
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ return LDAP_NO_SUCH_OPERATION;
+#endif
+ }
+
+ if ( op->o_cancel != LDAP_CANCEL_NONE ) {
+ *text = "message ID already being cancelled";
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ op->o_cancel = LDAP_CANCEL_REQ;
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+
+ while ( op->o_cancel == LDAP_CANCEL_REQ ) {
+ ldap_pvt_thread_yield();
+ }
+
+ if ( op->o_cancel == LDAP_CANCEL_ACK ) {
+ rc = LDAP_SUCCESS;
+ } else {
+ rc = op->o_cancel;
+ }
+
+ op->o_cancel = LDAP_CANCEL_DONE;
+
+ return rc;
+}
+
+#endif /* LDAP_EXOP_X_CANCEL */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/*
#include "ldap_pvt.h"
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
static int compare_entry(
Connection *conn,
struct berval ndn = { 0, NULL };
struct berval desc = { 0, NULL };
struct berval value = { 0, NULL };
- AttributeAssertion ava = { 0 };
+ AttributeAssertion ava = { NULL, { 0, NULL } };
Backend *be;
int rc = LDAP_SUCCESS;
const char *text = NULL;
int manageDSAit;
+#ifdef LDAP_SLAPI
+ Slapi_PBlock *pb = op->o_pb;
+#endif
+
ava.aa_desc = NULL;
#ifdef NEW_LOGGING
/* deref suffix alias if appropriate */
suffix_alias( be, &ndn );
+#if defined( LDAP_SLAPI )
+ slapi_x_backend_set_pb( pb, be );
+ slapi_x_connection_set_pb( pb, conn );
+ slapi_x_operation_set_pb( pb, op );
+ slapi_pblock_set( pb, SLAPI_COMPARE_TARGET, (void *)dn.bv_val );
+ slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
+ slapi_pblock_set( pb, SLAPI_COMPARE_TYPE, (void *)desc.bv_val );
+ slapi_pblock_set( pb, SLAPI_COMPARE_VALUE, (void *)&value );
+
+ rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_COMPARE_FN, pb );
+ if ( rc != 0 ) {
+ /*
+ * A preoperation plugin failure will abort the
+ * entire operation.
+ */
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_compare: compare preoperation plugin "
+ "failed\n", 0, 0, 0);
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_compare: compare preoperation plugin "
+ "failed.\n", 0, 0, 0);
+#endif
+ if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0)
+ rc = LDAP_OTHER;
+ goto cleanup;
+ }
+#endif /* defined( LDAP_SLAPI ) */
+
if ( be->be_compare ) {
(*be->be_compare)( be, conn, op, &pdn, &ndn, &ava );
} else {
NULL, NULL );
}
+#if defined( LDAP_SLAPI )
+ if ( doPluginFNs( be, SLAPI_PLUGIN_POST_COMPARE_FN, pb ) != 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_compare: compare postoperation plugins "
+ "failed\n", 0, 0, 0 );
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_compare: compare postoperation plugins "
+ "failed.\n", 0, 0, 0);
+#endif
+ }
+#endif /* defined( LDAP_SLAPI ) */
+
cleanup:
free( pdn.bv_val );
free( ndn.bv_val );
/* config.c - configuration file handling routines */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "lutil.h"
#include "ldap_pvt.h"
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
#define ARGS_STEP 512
SLAPD_DEFAULT_SIZELIMIT, /* backward compatible limits */
0,
- -1 /* no limit on unchecked size */
+ -1, /* no limit on unchecked size */
+ 0, /* page limit */
+ 0 /* hide number of entries left */
};
AccessControl *global_acl = NULL;
char *strtok_quote_ptr;
-#ifdef SLAPD_RLOOKUPS
-int use_reverse_lookup = 1;
-#else /* !SLAPD_RLOOKUPS */
int use_reverse_lookup = 0;
-#endif /* !SLAPD_RLOOKUPS */
static char *fp_getline(FILE *fp, int *lineno);
static void fp_getline_init(int *lineno);
lutil_salt_format( cargv[1] );
-#ifdef HAVE_CYRUS_SASL
/* SASL config options */
} else if ( strncasecmp( cargv[0], "sasl", 4 ) == 0 ) {
if ( slap_sasl_config( cargc, cargv, line, fname, lineno ) )
return 1;
-#endif /* HAVE_CYRUS_SASL */
} else if ( strcasecmp( cargv[0], "schemadn" ) == 0 ) {
struct berval dn;
struct berval alias, palias, nalias;
struct berval aliased, paliased, naliased;
- if( 1 ) {
-#ifdef NEW_LOGGING
- LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: suffixAlias is no longer supported.\n",
- fname, lineno, 0 );
-#else
- Debug( LDAP_DEBUG_ANY,
- "%s: line %d: suffixAlias is no longer supported.\n",
- fname, lineno, 0 );
-#endif
-
- return( 1 );
- }
-
if ( cargc < 2 ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT,
}
+ /* define attribute option(s) */
+ } else if ( strcasecmp( cargv[0], "attributeoptions" ) == 0 ) {
+ ad_define_option( NULL, NULL, 0 );
+ for ( i = 1; i < cargc; i++ )
+ if ( ad_define_option( cargv[i], fname, lineno ) != 0 )
+ return 1;
+
/* turn on/off schema checking */
} else if ( strcasecmp( cargv[0], "schemacheck" ) == 0 ) {
if ( cargc < 2 ) {
#endif
#endif /* !SLAPD_RLOOKUPS */
+ /* Netscape plugins */
+ } else if ( strcasecmp( cargv[0], "plugin" ) == 0 ) {
+#if defined( LDAP_SLAPI )
+
+#ifdef notdef /* allow global plugins, too */
+ /*
+ * a "plugin" line must be inside a database
+ * definition, since we implement pre-,post-
+ * and extended operation plugins
+ */
+ if ( be == NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, INFO,
+ "%s: line %d: plugin line must appear "
+ "inside a database definition.\n",
+ fname, lineno, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: plugin "
+ "line must appear inside a database "
+ "definition\n", fname, lineno, 0 );
+#endif
+ return( 1 );
+ }
+#endif /* notdef */
+
+ if ( netscape_plugin( be, fname, lineno, cargc, cargv )
+ != LDAP_SUCCESS ) {
+ return( 1 );
+ }
+
+#else /* !defined( LDAP_SLAPI ) */
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, INFO,
+ "%s: line %d: SLAPI not supported.\n",
+ fname, lineno, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: SLAPI "
+ "not supported.\n", fname, lineno, 0 );
+#endif
+ return( 1 );
+
+#endif /* !defined( LDAP_SLAPI ) */
+
+ /* Netscape plugins */
+ } else if ( strcasecmp( cargv[0], "pluginlog" ) == 0 ) {
+#if defined( LDAP_SLAPI )
+ if ( cargc < 2 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, INFO,
+ "%s: line %d: missing file name "
+ "in pluginlog <filename> line.\n",
+ fname, lineno, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: missing file name "
+ "in pluginlog <filename> line.\n",
+ fname, lineno, 0 );
+#endif
+ return( 1 );
+ }
+
+ if ( slapi_log_file != NULL ) {
+ ch_free( slapi_log_file );
+ }
+
+ slapi_log_file = ch_strdup( cargv[1] );
+#endif /* !defined( LDAP_SLAPI ) */
+
/* pass anything else to the current backend info/db config routine */
} else {
if ( bi != NULL ) {
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
if( c == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONNECTION, INFO,
- "connection_init: skt %d connection table full (%d/%d)\n",
- s, i, dtblsize );
+ "connection_init: skt %d connection table full "
+ "(%d/%d)\n", s, i, dtblsize );
#else
Debug( LDAP_DEBUG_ANY,
- "connection_init(%d): connection table full (%d/%d)\n",
- s, i, dtblsize);
+ "connection_init(%d): connection table full "
+ "(%d/%d)\n", s, i, dtblsize);
#endif
ldap_pvt_thread_mutex_unlock( &connections_mutex );
return -1;
}
- }
+ }
#endif
- assert( c != NULL );
+ assert( c != NULL );
if( c->c_struct_state == SLAP_C_UNINITIALIZED ) {
+ c->c_send_ldap_result = slap_send_ldap_result;
+ c->c_send_search_entry = slap_send_search_entry;
+ c->c_send_search_result = slap_send_search_result;
+ c->c_send_search_reference = slap_send_search_reference;
+ c->c_send_ldap_extended = slap_send_ldap_extended;
+#ifdef LDAP_RES_INTERMEDIATE_RESP
+ c->c_send_ldap_intermediate_resp = slap_send_ldap_intermediate_resp;
+#endif
+
c->c_authmech.bv_val = NULL;
c->c_authmech.bv_len = 0;
c->c_dn.bv_val = NULL;
#endif /* SLAPD_MONITOR */
ldap_pvt_thread_mutex_unlock( &num_ops_mutex );
+#ifdef LDAP_EXOP_X_CANCEL
+ if ( arg->co_op->o_cancel == LDAP_CANCEL_REQ ) {
+ arg->co_op->o_cancel = LDAP_TOO_LATE;
+ }
+
+ while ( arg->co_op->o_cancel != LDAP_CANCEL_NONE &&
+ arg->co_op->o_cancel != LDAP_CANCEL_DONE )
+ {
+ ldap_pvt_thread_yield();
+ }
+#endif
+
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
conn->c_n_ops_executing--;
LDAP_STAILQ_REMOVE( &conn->c_ops, arg->co_op, slap_op, o_next);
LDAP_STAILQ_NEXT(arg->co_op, o_next) = NULL;
+
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+ if ( arg->co_op->o_cancel == LDAP_CANCEL_ACK )
+ goto co_op_free;
+#endif
#ifdef LDAP_CLIENT_UPDATE
- if ( !( arg->co_op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
-#endif /* LDAP_CLIENT_UPDATE */
- {
- slap_op_free( arg->co_op );
- }
+ if ( ( arg->co_op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
+ goto no_co_op_free;
+#endif
+#ifdef LDAP_SYNC
+ if ( ( arg->co_op->o_sync_mode & SLAP_SYNC_PERSIST ) )
+ goto no_co_op_free;
+#endif
+
+co_op_free:
+
+ slap_op_free( arg->co_op );
+
+no_co_op_free:
+
arg->co_op = NULL;
arg->co_conn = NULL;
free( (char *) arg );
op->o_conn = conn;
op->vrFilter = NULL;
+#ifdef LDAP_CONTROL_PAGEDRESULTS
op->o_pagedresults_state = conn->c_pagedresults_state;
+#endif
#ifdef LDAP_CONNECTIONLESS
op->o_peeraddr = peeraddr;
if (cdn ) {
ber_str2bv( cdn, 0, 1, &op->o_dn );
op->o_protocol = LDAP_VERSION2;
}
+ if (conn->c_is_udp) {
+ int rc;
+
+ op->o_res_ber = ber_alloc_t( LBER_USE_DER );
+ if (op->o_res_ber == NULL)
+ return 1;
+
+ rc = ber_write(op->o_res_ber, (char *)&op->o_peeraddr, sizeof(struct sockaddr), 0);
+ if (rc != sizeof(struct sockaddr)) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONNECTION, INFO,
+ "connection_input: conn %lu ber_write failed\n",
+ conn->c_connid, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
#endif
+ return 1;
+ }
+
+ if (conn->c_protocol == LDAP_VERSION2) {
+ rc = ber_printf(op->o_res_ber, "{i{" /*}}*/, op->o_msgid);
+ if (rc == -1) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONNECTION, INFO,
+ "connection_input: conn %lu put outer sequence failed\n",
+ conn->c_connid, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
+#endif
+ return rc;
+ }
+ }
+ }
+#endif /* LDAP_CONNECTIONLESS */
if ( conn->c_conn_state == SLAP_C_BINDING
|| conn->c_conn_state == SLAP_C_CLOSING )
/* $OpenLDAP$ */
/*
- * Copyright 1999-2002 The OpenLDAP Foundation.
+ * Copyright 1999-2003 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted only
LDAPControl *ctrl,
const char **text ));
+static SLAP_CTRL_PARSE_FN parseProxyAuthz;
static SLAP_CTRL_PARSE_FN parseManageDSAit;
-static SLAP_CTRL_PARSE_FN parseSubentries;
static SLAP_CTRL_PARSE_FN parseNoOp;
static SLAP_CTRL_PARSE_FN parsePagedResults;
static SLAP_CTRL_PARSE_FN parseValuesReturnFilter;
+static SLAP_CTRL_PARSE_FN parsePermitModify;
+static SLAP_CTRL_PARSE_FN parseNoReferrals;
+#ifdef LDAP_CONTROL_SUBENTRIES
+static SLAP_CTRL_PARSE_FN parseSubentries;
+#endif
#ifdef LDAP_CLIENT_UPDATE
static SLAP_CTRL_PARSE_FN parseClientUpdate;
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
+#ifdef LDAP_SYNC
+static SLAP_CTRL_PARSE_FN parseLdupSync;
+#endif
#undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
+static char *proxy_authz_extops[] = {
+ LDAP_EXOP_MODIFY_PASSWD,
+ LDAP_EXOP_X_WHO_AM_I,
+ NULL
+};
+
+/*
+ * all known request control OIDs should be added to this list
+ */
+char *slap_known_controls[] = {
+ LDAP_CONTROL_MANAGEDSAIT,
+ LDAP_CONTROL_PROXY_AUTHZ,
+
+#ifdef LDAP_CONTROL_SUBENTRIES
+ LDAP_CONTROL_SUBENTRIES,
+#endif /* LDAP_CONTROL_SUBENTRIES */
+
+ LDAP_CONTROL_NOOP,
+
+#ifdef LDAP_CONTROL_DUPENT_REQUEST
+ LDAP_CONTROL_DUPENT_REQUEST,
+#endif /* LDAP_CONTROL_DUPENT_REQUEST */
+
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+ LDAP_CONTROL_PAGEDRESULTS,
+#endif
+
+#ifdef LDAP_CONTROL_SORTREQUEST
+ LDAP_CONTROL_SORTREQUEST,
+#endif /* LDAP_CONTROL_SORTREQUEST */
+
+#ifdef LDAP_CONTROL_VLVREQUEST
+ LDAP_CONTROL_VLVREQUEST,
+#endif /* LDAP_CONTROL_VLVREQUEST */
+
+ LDAP_CONTROL_VALUESRETURNFILTER,
+ NULL
+};
+
static struct slap_control {
char *sc_oid;
slap_mask_t sc_mask;
SLAP_CTRL_PARSE_FN *sc_parse;
} supportedControls[] = {
- { LDAP_CONTROL_MANAGEDSAIT,
- SLAP_CTRL_ACCESS, NULL,
- parseManageDSAit },
+ { LDAP_CONTROL_VALUESRETURNFILTER,
+ SLAP_CTRL_SEARCH, NULL,
+ parseValuesReturnFilter },
#ifdef LDAP_CONTROL_SUBENTRIES
{ LDAP_CONTROL_SUBENTRIES,
SLAP_CTRL_SEARCH, NULL,
parseSubentries },
#endif
-#ifdef LDAP_CONTROL_NOOP
{ LDAP_CONTROL_NOOP,
SLAP_CTRL_ACCESS, NULL,
parseNoOp },
-#endif
-#ifdef LDAP_CONTROL_PAGEDRESULTS_REQUEST
- { LDAP_CONTROL_PAGEDRESULTS_REQUEST,
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+ { LDAP_CONTROL_PAGEDRESULTS,
SLAP_CTRL_SEARCH, NULL,
parsePagedResults },
#endif
-#ifdef LDAP_CONTROL_VALUESRETURNFILTER
- { LDAP_CONTROL_VALUESRETURNFILTER,
- SLAP_CTRL_SEARCH, NULL,
- parseValuesReturnFilter },
+ { LDAP_CONTROL_MANAGEDSAIT,
+ SLAP_CTRL_ACCESS, NULL,
+ parseManageDSAit },
+ { LDAP_CONTROL_PROXY_AUTHZ,
+ SLAP_CTRL_FRONTEND|SLAP_CTRL_ACCESS, proxy_authz_extops,
+ parseProxyAuthz },
+#ifdef LDAP_CONTROL_PERMITMODIFY
+ { LDAP_CONTROL_PERMITMODIFY,
+ SLAP_CTRL_UPDATE, NULL,
+ parsePermitModify },
+#endif
+#ifdef LDAP_CONTROL_NOREFERRALS
+ { LDAP_CONTROL_NOREFERRALS,
+ SLAP_CTRL_SEARCH, NULL,
+ parseNoReferrals },
#endif
#ifdef LDAP_CLIENT_UPDATE
{ LDAP_CONTROL_CLIENT_UPDATE,
SLAP_CTRL_SEARCH, NULL,
parseClientUpdate },
-#endif /* LDAP_CLIENT_UPDATE */
- { NULL }
+#endif
+#ifdef LDAP_SYNC
+ { LDAP_CONTROL_SYNC,
+ SLAP_CTRL_SEARCH, NULL,
+ parseLdupSync },
+#endif
+ { NULL, 0, NULL, 0 }
};
char *
return supportedControls[index].sc_oid;
}
+slap_mask_t
+get_supported_ctrl_mask(int index)
+{
+ return supportedControls[index].sc_mask;
+}
+
static struct slap_control *
find_ctrl( const char *oid )
{
tagmask = SLAP_CTRL_ABANDON;
break;
case LDAP_REQ_EXTENDED:
- /* FIXME: check list of extended operations */
- tagmask = ~0U;
+ tagmask=~0L;
+ assert( op->o_extendedop != NULL );
+ if( sc->sc_extendedops != NULL ) {
+ int i;
+ for( i=0; sc->sc_extendedops[i] != NULL; i++ ) {
+ if( strcmp( op->o_extendedop, sc->sc_extendedops[i] )
+ == 0 )
+ {
+ tagmask=0L;
+ break;
+ }
+ }
+ }
break;
default:
rc = LDAP_OTHER;
return_results:
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, RESULTS,
- "get_ctrls: n=%d rc=%d err=%s\n", nctrls, rc, errmsg ? errmsg : "" );
+ "get_ctrls: n=%d rc=%d err=\"%s\"\n",
+ nctrls, rc, errmsg ? errmsg : "" );
#else
- Debug( LDAP_DEBUG_TRACE, "<= get_ctrls: n=%d rc=%d err=%s\n",
+ Debug( LDAP_DEBUG_TRACE,
+ "<= get_ctrls: n=%d rc=%d err=\"%s\"\n",
nctrls, rc, errmsg ? errmsg : "");
#endif
return LDAP_SUCCESS;
}
-#ifdef LDAP_CONTROL_SUBENTRIES
-static int parseSubentries (
+static int parseProxyAuthz (
Connection *conn,
Operation *op,
LDAPControl *ctrl,
const char **text )
{
- if ( op->o_subentries != SLAP_NO_CONTROL ) {
- *text = "subentries control specified multiple times";
- return LDAP_PROTOCOL_ERROR;
- }
+ int rc;
+ struct berval dn = { 0, NULL };
- /* FIXME: should use BER library */
- if( ( ctrl->ldctl_value.bv_len != 3 )
- && ( ctrl->ldctl_value.bv_val[0] != 0x01 )
- && ( ctrl->ldctl_value.bv_val[1] != 0x01 ))
- {
- *text = "subentries control value encoding is bogus";
+ if ( op->o_proxy_authz != SLAP_NO_CONTROL ) {
+ *text = "proxy authorization control specified multiple times";
return LDAP_PROTOCOL_ERROR;
}
- op->o_subentries = ctrl->ldctl_iscritical
+ op->o_proxy_authz = ctrl->ldctl_iscritical
? SLAP_CRITICAL_CONTROL
: SLAP_NONCRITICAL_CONTROL;
- op->o_subentries_visibility = (ctrl->ldctl_value.bv_val[2] != 0x00);
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, ARGS,
+ "parseProxyAuthz: conn %lu authzid=\"%s\"\n",
+ conn->c_connid,
+ ctrl->ldctl_value.bv_len ? ctrl->ldctl_value.bv_val : "anonymous",
+ 0 );
+#else
+ Debug( LDAP_DEBUG_ARGS,
+ "parseProxyAuthz: conn %lu authzid=\"%s\"\n",
+ conn->c_connid,
+ ctrl->ldctl_value.bv_len ? ctrl->ldctl_value.bv_val : "anonymous",
+ 0 );
+#endif
+
+ if( ctrl->ldctl_value.bv_len == 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, RESULTS,
+ "parseProxyAuthz: conn=%lu anonymous\n",
+ conn->c_connid, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "parseProxyAuthz: conn=%lu anonymous\n",
+ conn->c_connid, 0, 0 );
+#endif
+
+ /* anonymous */
+ free( op->o_dn.bv_val );
+ op->o_dn.bv_len = 0;
+ op->o_dn.bv_val = ch_strdup( "" );
+
+ free( op->o_ndn.bv_val );
+ op->o_ndn.bv_len = 0;
+ op->o_ndn.bv_val = ch_strdup( "" );
+
+ return LDAP_SUCCESS;
+ }
+
+ rc = slap_sasl_getdn( conn,
+ ctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_len,
+ NULL, &dn, SLAP_GETDN_AUTHZID );
+
+ if( rc != LDAP_SUCCESS || !dn.bv_len ) {
+ if ( dn.bv_val ) {
+ ch_free( dn.bv_val );
+ }
+ *text = "authzId mapping failed";
+ return LDAP_PROXY_AUTHZ_FAILURE;
+ }
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, RESULTS,
+ "parseProxyAuthz: conn=%lu \"%s\"\n",
+ conn->c_connid,
+ dn.bv_len ? dn.bv_val : "(NULL)", 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "parseProxyAuthz: conn=%lu \"%s\"\n",
+ conn->c_connid,
+ dn.bv_len ? dn.bv_val : "(NULL)", 0 );
+#endif
+
+ rc = slap_sasl_authorized( conn, &op->o_ndn, &dn );
+
+ if( rc ) {
+ ch_free( dn.bv_val );
+ *text = "not authorized to assume identity";
+ return LDAP_PROXY_AUTHZ_FAILURE;
+ }
+
+ ch_free( op->o_dn.bv_val );
+ ch_free( op->o_ndn.bv_val );
+
+ op->o_dn.bv_val = NULL;
+ op->o_ndn = dn;
+
+ /*
+ * NOTE: since slap_sasl_getdn() returns a normalized dn,
+ * from now on op->o_dn is normalized
+ */
+ ber_dupbv( &op->o_dn, &dn );
return LDAP_SUCCESS;
}
-#endif
-#ifdef LDAP_CONTROL_NOOP
static int parseNoOp (
Connection *conn,
Operation *op,
return LDAP_SUCCESS;
}
-#endif
-#ifdef LDAP_CONTROL_PAGEDRESULTS_REQUEST
+#ifdef LDAP_CONTROL_PAGEDRESULTS
static int parsePagedResults (
Connection *conn,
Operation *op,
}
if ( ctrl->ldctl_value.bv_len == 0 ) {
- *text = "paged results control value is empty";
+ *text = "paged results control value is empty (or absent)";
return LDAP_PROTOCOL_ERROR;
}
* -- requested page size from client
* -- result set size estimate from server
* cookie OCTET STRING
+ * }
*/
ber = ber_init( &ctrl->ldctl_value );
if( ber == NULL ) {
return LDAP_PROTOCOL_ERROR;
}
- if( size <= 0 ) {
+ if( size < 0 ) {
*text = "paged results control size invalid";
return LDAP_PROTOCOL_ERROR;
}
*text = "paged results cookie is invalid or old";
return LDAP_UNWILLING_TO_PERFORM;
}
+ } else {
+ /* Initial request. Initialize state. */
+ op->o_pagedresults_state.ps_cookie = 0;
+ op->o_pagedresults_state.ps_id = NOID;
}
- op->o_pagedresults_state.ps_cookie = op->o_opid;
op->o_pagedresults_size = size;
op->o_pagedresults = ctrl->ldctl_iscritical
}
#endif
-#ifdef LDAP_CONTROL_VALUESRETURNFILTER
int parseValuesReturnFilter (
Connection *conn,
Operation *op,
const char *err_msg = "";
if ( op->o_valuesreturnfilter != SLAP_NO_CONTROL ) {
- *text = "valuesreturnfilter control specified multiple times";
+ *text = "valuesReturnFilter control specified multiple times";
return LDAP_PROTOCOL_ERROR;
}
if ( ctrl->ldctl_value.bv_len == 0 ) {
- *text = "valuesreturnfilter control value is empty";
+ *text = "valuesReturnFilter control value is empty (or absent)";
return LDAP_PROTOCOL_ERROR;
}
return LDAP_SUCCESS;
}
+
+#ifdef LDAP_CONTROL_SUBENTRIES
+static int parseSubentries (
+ Connection *conn,
+ Operation *op,
+ LDAPControl *ctrl,
+ const char **text )
+{
+ if ( op->o_subentries != SLAP_NO_CONTROL ) {
+ *text = "subentries control specified multiple times";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ /* FIXME: should use BER library */
+ if( ( ctrl->ldctl_value.bv_len != 3 )
+ && ( ctrl->ldctl_value.bv_val[0] != 0x01 )
+ && ( ctrl->ldctl_value.bv_val[1] != 0x01 ))
+ {
+ *text = "subentries control value encoding is bogus";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ op->o_subentries = ctrl->ldctl_iscritical
+ ? SLAP_CRITICAL_CONTROL
+ : SLAP_NONCRITICAL_CONTROL;
+
+ op->o_subentries_visibility = (ctrl->ldctl_value.bv_val[2] != 0x00);
+
+ return LDAP_SUCCESS;
+}
+#endif
+
+#ifdef LDAP_CONTROL_PERMITMODIFY
+static int parsePermitModify (
+ Connection *conn,
+ Operation *op,
+ LDAPControl *ctrl,
+ const char **text )
+{
+ if ( op->o_permitmodify != SLAP_NO_CONTROL ) {
+ *text = "permitmodify control specified multiple times";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ if ( ctrl->ldctl_value.bv_len ) {
+ *text = "permitmodify control value not empty";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ op->o_permitmodify = ctrl->ldctl_iscritical
+ ? SLAP_CRITICAL_CONTROL
+ : SLAP_NONCRITICAL_CONTROL;
+
+ return LDAP_SUCCESS;
+}
+#endif
+
+#ifdef LDAP_CONTROL_NOREFERRALS
+static int parseNoReferrals (
+ Connection *conn,
+ Operation *op,
+ LDAPControl *ctrl,
+ const char **text )
+{
+ if ( op->o_noreferrals != SLAP_NO_CONTROL ) {
+ *text = "noreferrals control specified multiple times";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ if ( ctrl->ldctl_value.bv_len ) {
+ *text = "noreferrals control value not empty";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ op->o_noreferrals = ctrl->ldctl_iscritical
+ ? SLAP_CRITICAL_CONTROL
+ : SLAP_NONCRITICAL_CONTROL;
+
+ return LDAP_SUCCESS;
+}
#endif
#ifdef LDAP_CLIENT_UPDATE
return LDAP_PROTOCOL_ERROR;
}
+#ifdef LDAP_SYNC
+ if ( op->o_sync != SLAP_NO_CONTROL ) {
+ *text = "LDAP Client Update and Sync controls used together";
+ return LDAP_PROTOCOL_ERROR;
+ }
+#endif
+
if ( ctrl->ldctl_value.bv_len == 0 ) {
- *text = "LCUP client update control value is empty";
+ *text = "LCUP client update control value is empty (or absent)";
return LDAP_PROTOCOL_ERROR;
}
return LDAP_PROTOCOL_ERROR;
}
- if ( tag == LDAP_TAG_COOKIE ) {
+ if ( tag == LDAP_LCUP_TAG_COOKIE ) {
if ( (tag = ber_scanf( ber, /*{*/ "{mm}}",
&scheme, &cookie )) == LBER_ERROR ) {
*text = "LCUP client update control : decoding error";
return LDAP_SUCCESS;
}
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
+
+#ifdef LDAP_SYNC
+static int parseLdupSync (
+ Connection *conn,
+ Operation *op,
+ LDAPControl *ctrl,
+ const char **text )
+{
+ ber_tag_t tag;
+ BerElement *ber;
+ ber_int_t mode;
+ ber_len_t len;
+ struct berval cookie = { 0, NULL };
+
+ if ( op->o_sync != SLAP_NO_CONTROL ) {
+ *text = "LDAP Sync control specified multiple times";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+#ifdef LDAP_CLIENT_UPDATE
+ if ( op->o_clientupdate != SLAP_NO_CONTROL ) {
+ *text = "LDAP Sync and LDAP Client Update controls used together";
+ return LDAP_PROTOCOL_ERROR;
+ }
+#endif
+
+ if ( ctrl->ldctl_value.bv_len == 0 ) {
+ *text = "LDAP Sync control value is empty (or absent)";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ /* Parse the control value
+ * syncRequestValue ::= SEQUENCE {
+ * mode ENUMERATED {
+ * -- 0 unused
+ * refreshOnly (1),
+ * -- 2 reserved
+ * refreshAndPersist (3)
+ * },
+ * cookie syncCookie OPTIONAL
+ * }
+ */
+
+ ber = ber_init( &ctrl->ldctl_value );
+ if( ber == NULL ) {
+ *text = "internal error";
+ return LDAP_OTHER;
+ }
+
+ if ( (tag = ber_scanf( ber, "{i" /*}*/, &mode )) == LBER_ERROR ) {
+ *text = "LDAP Sync control : mode decoding error";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ switch( mode ) {
+ case LDAP_SYNC_REFRESH_ONLY:
+ mode = SLAP_SYNC_REFRESH;
+ break;
+ case LDAP_SYNC_REFRESH_AND_PERSIST:
+ mode = SLAP_SYNC_REFRESH_AND_PERSIST;
+ break;
+ default:
+ *text = "LDAP Sync control : unknown update mode";
+ return LDAP_PROTOCOL_ERROR;
+ }
+
+ tag = ber_peek_tag( ber, &len );
+
+ if ( tag == LDAP_SYNC_TAG_COOKIE ) {
+ if (( ber_scanf( ber, /*{*/ "m}",
+ &cookie )) == LBER_ERROR ) {
+ *text = "LDAP Sync control : cookie decoding error";
+ return LDAP_PROTOCOL_ERROR;
+ }
+ } else {
+ if (( ber_scanf( ber, /*{*/ "}")) == LBER_ERROR ) {
+ *text = "LDAP Sync control : decoding error";
+ return LDAP_PROTOCOL_ERROR;
+ }
+ cookie.bv_len = 0;
+ cookie.bv_val = NULL;
+ }
+
+ /* TODO : Cookie Scheme Validation */
+#if 0
+ if ( lcup_cookie_scheme_validate(scheme) != LDAP_SUCCESS ) {
+ *text = "Unsupported LCUP cookie scheme";
+ return LCUP_UNSUPPORTED_SCHEME;
+ }
+
+ if ( lcup_cookie_validate(scheme, cookie) != LDAP_SUCCESS ) {
+ *text = "Invalid LCUP cookie";
+ return LCUP_INVALID_COOKIE;
+ }
+#endif
+
+ ber_dupbv( &op->o_sync_state, &cookie );
+
+ (void) ber_free( ber, 1 );
+
+ op->o_sync_mode = (char) mode;
+
+ op->o_sync = ctrl->ldctl_iscritical
+ ? SLAP_CRITICAL_CONTROL
+ : SLAP_NONCRITICAL_CONTROL;
+
+ return LDAP_SUCCESS;
+}
+#endif
/* cr.c - content rule routines */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
};
static Avlnode *cr_index = NULL;
-static ContentRule *cr_list = NULL;
+static LDAP_SLIST_HEAD(CRList, slap_content_rule) cr_list
+ = LDAP_SLIST_HEAD_INITIALIZER(&cr_list);
static int
cr_index_cmp(
- struct cindexrec *cir1,
- struct cindexrec *cir2 )
+ const void *v_cir1,
+ const void *v_cir2 )
{
+ const struct cindexrec *cir1 = v_cir1;
+ const struct cindexrec *cir2 = v_cir2;
int i = cir1->cir_name.bv_len - cir2->cir_name.bv_len;
if (i)
return i;
static int
cr_index_name_cmp(
- struct berval *name,
- struct cindexrec *cir )
+ const void *v_name,
+ const void *v_cir )
{
+ const struct berval *name = v_name;
+ const struct cindexrec *cir = v_cir;
int i = name->bv_len - cir->cir_name.bv_len;
if (i)
return i;
{
struct cindexrec *cir;
- cir = (struct cindexrec *) avl_find( cr_index, crname,
- (AVL_CMP) cr_index_name_cmp );
+ cir = avl_find( cr_index, crname, cr_index_name_cmp );
if ( cir != NULL ) {
return( cir->cir_cr );
return( NULL );
}
+static int
+cr_destroy_one( ContentRule *c )
+{
+ assert( c != NULL );
+
+ if (c->scr_auxiliaries) ldap_memfree(c->scr_auxiliaries);
+ if (c->scr_required) ldap_memfree(c->scr_required);
+ if (c->scr_allowed) ldap_memfree(c->scr_allowed);
+ if (c->scr_precluded) ldap_memfree(c->scr_precluded);
+ ldap_contentrule_free((LDAPContentRule *)c);
+
+ return 0;
+}
+
void
cr_destroy( void )
{
- ContentRule *c, *n;
+ ContentRule *c;
avl_free(cr_index, ldap_memfree);
- for (c=cr_list; c; c=n)
- {
- n = c->scr_next;
- if (c->scr_auxiliaries) ldap_memfree(c->scr_auxiliaries);
- if (c->scr_required) ldap_memfree(c->scr_required);
- if (c->scr_allowed) ldap_memfree(c->scr_allowed);
- if (c->scr_precluded) ldap_memfree(c->scr_precluded);
- ldap_contentrule_free((LDAPContentRule *)c);
+
+ while( !LDAP_SLIST_EMPTY(&cr_list) ) {
+ c = LDAP_SLIST_FIRST(&cr_list);
+ LDAP_SLIST_REMOVE_HEAD(&cr_list, scr_next);
+
+ cr_destroy_one( c );
}
}
const char **err
)
{
- ContentRule **crp;
struct cindexrec *cir;
char **names;
- crp = &cr_list;
- while ( *crp != NULL ) {
- crp = &(*crp)->scr_next;
- }
- *crp = scr;
+ LDAP_SLIST_INSERT_HEAD(&cr_list, scr, scr_next);
if ( scr->scr_oid ) {
cir = (struct cindexrec *)
assert( cir->cir_cr );
if ( avl_insert( &cr_index, (caddr_t) cir,
- (AVL_CMP) cr_index_cmp,
- (AVL_DUP) avl_dup_error ) )
+ cr_index_cmp, avl_dup_error ) )
{
*err = scr->scr_oid;
ldap_memfree(cir);
assert( cir->cir_cr );
if ( avl_insert( &cr_index, (caddr_t) cir,
- (AVL_CMP) cr_index_cmp,
- (AVL_DUP) avl_dup_error ) )
+ cr_index_cmp, avl_dup_error ) )
{
*err = *names;
ldap_memfree(cir);
vals[1].bv_val = NULL;
- for ( cr = cr_list; cr; cr = cr->scr_next ) {
+ LDAP_SLIST_FOREACH(cr, &cr_list, scr_next) {
if ( ldap_contentrule2bv( &cr->scr_crule, vals ) == NULL ) {
return -1;
}
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
return -1;
#endif
} else {
-#ifdef LDAP_CONNECTIONLESS
- l.sl_is_udp = ( tmp == LDAP_PROTO_UDP );
-#endif
if( lud->lud_host == NULL || lud->lud_host[0] == '\0'
|| strcmp(lud->lud_host, "*") == 0 )
{
err = slap_get_listener_addresses(lud->lud_host, port, &sal);
}
}
+#ifdef LDAP_CONNECTIONLESS
+ l.sl_is_udp = ( tmp == LDAP_PROTO_UDP );
+#endif
#if defined(LDAP_PF_LOCAL) || defined(SLAP_X_LISTENER_MOD)
if ( lud->lud_exts ) {
fd_set writefds;
Sockaddr from;
-#if defined(SLAPD_RLOOKUPS)
- struct hostent *hp;
-#endif
struct timeval zero;
struct timeval *tvp;
case AF_LOCAL:
sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path );
ssf = LDAP_PVT_SASL_LOCAL_SSF;
+ {
+ uid_t uid;
+ gid_t gid;
+
+ if( getpeereid( s, &uid, &gid ) == 0 ) {
+ authid = ch_malloc(
+ sizeof("uidNumber=4294967295+gidNumber=4294967295,"
+ "cn=peercred,cn=external,cn=auth"));
+ sprintf(authid, "uidNumber=%d+gidNumber=%d,"
+ "cn=peercred,cn=external,cn=auth",
+ (int) uid, (int) gid);
+ }
+ }
dnsname = "local";
break;
#endif /* LDAP_PF_LOCAL */
}
Statslog( LDAP_DEBUG_STATS,
- "conn=%ld fd=%ld ACCEPT from %s "
- "(%s)\n",
+ "conn=%ld fd=%ld ACCEPT from %s (%s)\n",
id, (long) s,
peername,
slap_listeners[l]->sl_name.bv_val,
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/*
#include "ldap_pvt.h"
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
int
do_delete(
int rc;
int manageDSAit;
+#ifdef LDAP_SLAPI
+ Slapi_PBlock *pb = op->o_pb;
+#endif
+
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ENTRY,
"do_delete: conn %d\n", conn->c_connid, 0, 0 );
/* deref suffix alias if appropriate */
suffix_alias( be, &ndn );
+#if defined( LDAP_SLAPI )
+ slapi_x_backend_set_pb( pb, be );
+ slapi_x_connection_set_pb( pb, conn );
+ slapi_x_operation_set_pb( pb, op );
+ slapi_pblock_set( pb, SLAPI_DELETE_TARGET, (void *)dn.bv_val );
+ slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
+
+ rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_DELETE_FN, pb );
+ if ( rc != 0 ) {
+ /*
+ * A preoperation plugin failure will abort the
+ * entire operation.
+ */
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_delete: delete preoperation plugin "
+ "failed\n", 0, 0, 0 );
+#else
+ Debug (LDAP_DEBUG_TRACE, "do_delete: delete preoperation plugin failed.\n",
+ 0, 0, 0);
+#endif
+ if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0 )
+ rc = LDAP_OTHER;
+ goto cleanup;
+ }
+#endif /* defined( LDAP_SLAPI ) */
+
/*
* do the delete if 1 && (2 || 3)
* 1) there is a delete function implemented in this backend;
NULL, "operation not supported within namingContext", NULL, NULL );
}
+#if defined( LDAP_SLAPI )
+ if ( doPluginFNs( be, SLAPI_PLUGIN_POST_DELETE_FN, pb ) != 0) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_delete: delete postoperation plugins "
+ "failed\n", 0, 0, 0 );
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_delete: delete postoperation plugins "
+ "failed.\n", 0, 0, 0);
+#endif
+ }
+#endif /* defined( LDAP_SLAPI ) */
+
cleanup:
free( pdn.bv_val );
free( ndn.bv_val );
/* entry.c - routines for dealing with entries */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
}
int
-entry_dn_cmp( Entry *e1, Entry *e2 )
+entry_dn_cmp( const void *v_e1, const void *v_e2 )
{
/* compare their normalized UPPERCASED dn's */
+ const Entry *e1 = v_e1, *e2 = v_e2;
int rc = e1->e_nname.bv_len - e2->e_nname.bv_len;
if (rc) return rc;
return( strcmp( e1->e_ndn, e2->e_ndn ) );
}
int
-entry_id_cmp( Entry *e1, Entry *e2 )
+entry_id_cmp( const void *v_e1, const void *v_e2 )
{
+ const Entry *e1 = v_e1, *e2 = v_e2;
return( e1->e_id < e2->e_id ? -1 : (e1->e_id > e2->e_id ? 1 : 0) );
}
/* $OpenLDAP$ */
/*
- * Copyright 1999-2002 The OpenLDAP Foundation.
+ * Copyright 1999-2003 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted only
#include "portable.h"
#include <stdio.h>
+
#include <ac/socket.h>
#include <ac/string.h>
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
#include "lber_pvt.h"
+#define UNSUPPORTED_EXTENDEDOP "unsupported extended operation"
+
static struct extop_list {
struct extop_list *next;
struct berval oid;
struct berval oid;
SLAP_EXTOP_MAIN_FN *ext_main;
} builtin_extops[] = {
+ { BVC(LDAP_EXOP_X_WHO_AM_I), whoami_extop },
+ { BVC(LDAP_EXOP_MODIFY_PASSWD), passwd_extop },
+#ifdef LDAP_EXOP_X_CANCEL
+ { BVC(LDAP_EXOP_X_CANCEL), cancel_extop },
+#endif
#ifdef HAVE_TLS
{ BVC(LDAP_EXOP_START_TLS), starttls_extop },
#endif
- { BVC(LDAP_EXOP_MODIFY_PASSWD), passwd_extop },
- { BVC(LDAP_EXOP_X_WHO_AM_I), whoami_extop },
{ {0,NULL}, NULL }
};
struct berval *rspdata;
LDAPControl **rspctrls;
+#if defined(LDAP_SLAPI)
+ Slapi_PBlock *pb = op->o_pb;
+ SLAPI_FUNC funcAddr = NULL;
+ int extop_rc;
+ int msg_sent = FALSE;
+ char *result_msg = "";
+#endif /* defined(LDAP_SLAPI) */
+
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ENTRY, "do_extended: conn %d\n", conn->c_connid, 0, 0 );
#else
goto done;
}
- if( !(ext = find_extop(supp_ext_list, &reqoid)) ) {
+ if( !(ext = find_extop(supp_ext_list, &reqoid))
+#ifdef LDAP_SLAPI
+ && !(funcAddr)
+#endif
+ ) {
+#ifdef LDAP_SLAPI
+ /* Netscape extended operation */
+ getPluginFunc( &reqoid, &funcAddr );
+#endif
+
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
"do_extended: conn %d unsupported operation \"%s\"\n",
goto done;
}
+ op->o_extendedop = reqoid.bv_val;
+
tag = ber_peek_tag( op->o_ber, &len );
if( ber_peek_tag( op->o_ber, &len ) == LDAP_TAG_EXOP_REQ_VALUE ) {
text = NULL;
refs = NULL;
- rc = (ext->ext_main)( conn, op,
- reqoid.bv_val, reqdata.bv_val ? &reqdata : NULL,
- &rspoid, &rspdata, &rspctrls, &text, &refs );
+#if defined(LDAP_SLAPI)
+ if (ext != NULL) { /* OpenLDAP extended operation */
+#endif /* defined(LDAP_SLAPI) */
+
+ rc = (ext->ext_main)( conn, op,
+ reqoid.bv_val, reqdata.bv_val ? &reqdata : NULL,
+ &rspoid, &rspdata, &rspctrls, &text, &refs );
+
+ if( rc != SLAPD_ABANDON ) {
+ if ( rc == LDAP_REFERRAL && refs == NULL ) {
+ refs = referral_rewrite( default_referral,
+ NULL, NULL, LDAP_SCOPE_DEFAULT );
+ }
+
+ send_ldap_extended( conn, op, rc, NULL, text, refs,
+ rspoid, rspdata, rspctrls );
- if( rc != SLAPD_ABANDON ) {
- if ( rc == LDAP_REFERRAL && refs == NULL ) {
- refs = referral_rewrite( default_referral,
- NULL, NULL, LDAP_SCOPE_DEFAULT );
+ ber_bvarray_free( refs );
}
- send_ldap_extended( conn, op, rc, NULL, text, refs,
- rspoid, rspdata, rspctrls );
+ if ( rspoid != NULL ) {
+ free( rspoid );
+ }
- ber_bvarray_free( refs );
- }
+ if ( rspdata != NULL ) {
+ ber_bvfree( rspdata );
+ }
- if ( rspoid != NULL ) {
- free( rspoid );
- }
+#if defined( LDAP_SLAPI )
+ goto done; /* end of OpenLDAP extended operation */
- if ( rspdata != NULL ) {
- ber_bvfree( rspdata );
- }
+ } else { /* start of Netscape extended operation */
+ rc = slapi_pblock_set( pb, SLAPI_EXT_OP_REQ_OID,
+ (void *)reqoid.bv_val);
+ if ( rc != LDAP_SUCCESS ) {
+ rc = LDAP_OTHER;
+ goto done;
+ }
+
+ rc = slapi_pblock_set( pb, SLAPI_EXT_OP_REQ_VALUE,
+ (void *)&reqdata);
+ if ( rc != LDAP_SUCCESS ) {
+ rc = LDAP_OTHER;
+ goto done;
+ }
+
+ rc = slapi_x_connection_set_pb( pb, conn );
+ if ( rc != LDAP_SUCCESS ) {
+ rc = LDAP_OTHER;
+ goto done;
+ }
+
+ rc = slapi_x_operation_set_pb( pb, op );
+ if ( rc != LDAP_SUCCESS ) {
+ rc = LDAP_OTHER;
+ goto done;
+ }
+
+ extop_rc = (*funcAddr)( pb );
+ if ( extop_rc == SLAPI_PLUGIN_EXTENDED_SENT_RESULT ) {
+ msg_sent = TRUE;
+
+ } else if ( extop_rc == SLAPI_PLUGIN_EXTENDED_NOT_HANDLED ) {
+ rc = LDAP_PROTOCOL_ERROR;
+ result_msg = UNSUPPORTED_EXTENDEDOP;
+
+ } else {
+ rc = slapi_pblock_get( pb, SLAPI_EXT_OP_RET_OID,
+ &rspoid);
+ if ( rc != LDAP_SUCCESS ) {
+ goto done2;
+ }
+
+ rc = slapi_pblock_get( pb, SLAPI_EXT_OP_RET_VALUE,
+ &rspdata);
+ if ( rc != LDAP_SUCCESS ) {
+ goto done2;
+ }
+
+ send_ldap_extended( conn, op, extop_rc, NULL, text,
+ refs, rspoid, rspdata, rspctrls );
+ msg_sent = TRUE;
+ }
+
+done2:;
+ if ( rc != LDAP_SUCCESS && msg_sent == FALSE ) {
+ send_ldap_result( conn, op, rc, NULL, result_msg,
+ NULL, NULL );
+ }
+
+ if ( rspoid != NULL ) {
+ free( rspoid );
+ }
+
+ if ( rspdata != NULL ) {
+ ber_bvfree( rspdata );
+ }
+
+ } /* end of Netscape extended operation */
+#endif /* defined( LDAP_SLAPI ) */
done:
return rc;
/* filter.c - routines for parsing and dealing with filters */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
ber_tag_t tag;
ber_len_t len;
int err;
- ValuesReturnFilter *f;
+ ValuesReturnFilter *vrf;
#ifdef NEW_LOGGING
LDAP_LOG( FILTER, ENTRY,
return SLAPD_DISCONNECT;
}
- f = (ValuesReturnFilter *) ch_malloc( sizeof(ValuesReturnFilter) );
- f->f_next = NULL;
+ vrf = (ValuesReturnFilter *) ch_malloc( sizeof(ValuesReturnFilter) );
+ vrf->vrf_next = NULL;
err = LDAP_SUCCESS;
- f->f_choice = tag;
+ vrf->vrf_choice = tag;
- switch ( f->f_choice ) {
+ switch ( vrf->vrf_choice ) {
case LDAP_FILTER_EQUALITY:
#ifdef NEW_LOGGING
LDAP_LOG( FILTER, DETAIL2,
#else
Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
#endif
- err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY, text );
+ err = get_ava( ber, &vrf->vrf_ava, SLAP_MR_EQUALITY, text );
if ( err != LDAP_SUCCESS ) {
break;
}
- assert( f->f_ava != NULL );
+ assert( vrf->vrf_ava != NULL );
break;
case LDAP_FILTER_SUBSTRINGS:
#else
Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
#endif
- err = get_substring_filter( conn, ber, (Filter *)f, text );
+ err = get_substring_filter( conn, ber, (Filter *)vrf, text );
break;
case LDAP_FILTER_GE:
#else
Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
#endif
- err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
+ err = get_ava( ber, &vrf->vrf_ava, SLAP_MR_ORDERING, text );
if ( err != LDAP_SUCCESS ) {
break;
}
#else
Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
#endif
- err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text );
+ err = get_ava( ber, &vrf->vrf_ava, SLAP_MR_ORDERING, text );
if ( err != LDAP_SUCCESS ) {
break;
}
break;
}
- f->f_desc = NULL;
- err = slap_bv2ad( &type, &f->f_desc, text );
+ vrf->vrf_desc = NULL;
+ err = slap_bv2ad( &type, &vrf->vrf_desc, text );
if( err != LDAP_SUCCESS ) {
/* unrecognized attribute description or other error */
- f->f_choice = SLAPD_FILTER_COMPUTED;
- f->f_result = LDAP_COMPARE_FALSE;
+ vrf->vrf_choice = SLAPD_FILTER_COMPUTED;
+ vrf->vrf_result = LDAP_COMPARE_FALSE;
err = LDAP_SUCCESS;
break;
}
#else
Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
#endif
- err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY_APPROX, text );
+ err = get_ava( ber, &vrf->vrf_ava, SLAP_MR_EQUALITY_APPROX, text );
if ( err != LDAP_SUCCESS ) {
break;
}
Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n", 0, 0, 0 );
#endif
- err = get_mra( ber, &f->f_mra, text );
+ err = get_mra( ber, &vrf->vrf_mra, text );
if ( err != LDAP_SUCCESS ) {
break;
}
- assert( f->f_mra != NULL );
+ assert( vrf->vrf_mra != NULL );
break;
default:
#ifdef NEW_LOGGING
LDAP_LOG( FILTER, ERR,
"get_simple_vrFilter: conn %d unknown filter type=%lu\n",
- conn->c_connid, f->f_choice, 0 );
+ conn->c_connid, vrf->vrf_choice, 0 );
#else
Debug( LDAP_DEBUG_ANY, "get_simple_vrFilter: unknown filter type=%lu\n",
- f->f_choice, 0, 0 );
+ vrf->vrf_choice, 0, 0 );
#endif
- f->f_choice = SLAPD_FILTER_COMPUTED;
- f->f_result = SLAPD_COMPARE_UNDEFINED;
+ vrf->vrf_choice = SLAPD_FILTER_COMPUTED;
+ vrf->vrf_result = SLAPD_COMPARE_UNDEFINED;
break;
}
if ( err != LDAP_SUCCESS ) {
if( err != SLAPD_DISCONNECT ) {
/* ignore error */
- f->f_choice = SLAPD_FILTER_COMPUTED;
- f->f_result = SLAPD_COMPARE_UNDEFINED;
+ vrf->vrf_choice = SLAPD_FILTER_COMPUTED;
+ vrf->vrf_result = SLAPD_COMPARE_UNDEFINED;
err = LDAP_SUCCESS;
- *filt = f;
+ *filt = vrf;
} else {
- free(f);
+ free(vrf);
}
} else {
- *filt = f;
+ *filt = vrf;
}
#ifdef NEW_LOGGING
int
get_vrFilter( Connection *conn, BerElement *ber,
- ValuesReturnFilter **f,
+ ValuesReturnFilter **vrf,
const char **text )
{
/*
* matchValue [3] AssertionValue }
*/
- ValuesReturnFilter **new;
+ ValuesReturnFilter **n;
ber_tag_t tag;
ber_len_t len;
char *last;
return SLAPD_DISCONNECT;
}
- new = f;
- for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
+ n = vrf;
+ for ( tag = ber_first_element( ber, &len, &last );
+ tag != LBER_DEFAULT;
tag = ber_next_element( ber, &len, last ) )
{
- int err = get_simple_vrFilter( conn, ber, new, text );
+ int err = get_simple_vrFilter( conn, ber, n, text );
if ( err != LDAP_SUCCESS )
return( err );
- new = &(*new)->f_next;
+ n = &(*n)->vrf_next;
}
- *new = NULL;
+ *n = NULL;
#ifdef NEW_LOGGING
LDAP_LOG( FILTER, ENTRY,
}
void
-vrFilter_free( ValuesReturnFilter *f )
+vrFilter_free( ValuesReturnFilter *vrf )
{
ValuesReturnFilter *p, *next;
- if ( f == NULL ) {
+ if ( vrf == NULL ) {
return;
}
- for ( p = f; p != NULL; p = next ) {
- next = p->f_next;
+ for ( p = vrf; p != NULL; p = next ) {
+ next = p->vrf_next;
- switch ( f->f_choice ) {
+ switch ( vrf->vrf_choice ) {
case LDAP_FILTER_PRESENT:
break;
case LDAP_FILTER_GE:
case LDAP_FILTER_LE:
case LDAP_FILTER_APPROX:
- ava_free( f->f_ava, 1 );
+ ava_free( vrf->vrf_ava, 1 );
break;
case LDAP_FILTER_SUBSTRINGS:
- if ( f->f_sub_initial.bv_val != NULL ) {
- free( f->f_sub_initial.bv_val );
+ if ( vrf->vrf_sub_initial.bv_val != NULL ) {
+ free( vrf->vrf_sub_initial.bv_val );
}
- ber_bvarray_free( f->f_sub_any );
- if ( f->f_sub_final.bv_val != NULL ) {
- free( f->f_sub_final.bv_val );
+ ber_bvarray_free( vrf->vrf_sub_any );
+ if ( vrf->vrf_sub_final.bv_val != NULL ) {
+ free( vrf->vrf_sub_final.bv_val );
}
- ch_free( f->f_sub );
+ ch_free( vrf->vrf_sub );
break;
case LDAP_FILTER_EXT:
- mra_free( f->f_mra, 1 );
+ mra_free( vrf->vrf_mra, 1 );
break;
case SLAPD_FILTER_COMPUTED:
default:
#ifdef NEW_LOGGING
LDAP_LOG( FILTER, ERR,
- "filter_free: unknown filter type %lu\n", f->f_choice, 0, 0 );
+ "filter_free: unknown filter type %lu\n", vrf->vrf_choice, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY, "filter_free: unknown filter type=%lu\n",
- f->f_choice, 0, 0 );
+ vrf->vrf_choice, 0, 0 );
#endif
break;
}
- free( f );
+ free( vrf );
}
}
void
-vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
+vrFilter2bv( ValuesReturnFilter *vrf, struct berval *fstr )
{
ValuesReturnFilter *p;
struct berval tmp;
ber_len_t len;
- if ( f == NULL ) {
+ if ( vrf == NULL ) {
ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
return;
}
snprintf( fstr->bv_val, fstr->bv_len + 1, "()");
- for ( p = f; p != NULL; p = p->f_next ) {
+ for ( p = vrf; p != NULL; p = p->vrf_next ) {
len = fstr->bv_len;
simple_vrFilter2bv( p, &tmp );
}
static void
-simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
+simple_vrFilter2bv( ValuesReturnFilter *vrf, struct berval *fstr )
{
struct berval tmp;
ber_len_t len;
- if ( f == NULL ) {
+ if ( vrf == NULL ) {
ber_str2bv( "No filter!", sizeof("No filter!")-1, 1, fstr );
return;
}
- switch ( f->f_choice ) {
+ switch ( vrf->vrf_choice ) {
case LDAP_FILTER_EQUALITY:
- filter_escape_value( &f->f_av_value, &tmp );
+ filter_escape_value( &vrf->vrf_av_value, &tmp );
- fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
+ fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
tmp.bv_len + ( sizeof("(=)") - 1 );
fstr->bv_val = malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=%s)",
- f->f_av_desc->ad_cname.bv_val,
+ vrf->vrf_av_desc->ad_cname.bv_val,
tmp.bv_val );
ber_memfree( tmp.bv_val );
break;
case LDAP_FILTER_GE:
- filter_escape_value( &f->f_av_value, &tmp );
+ filter_escape_value( &vrf->vrf_av_value, &tmp );
- fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
+ fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
tmp.bv_len + ( sizeof("(>=)") - 1 );
fstr->bv_val = malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s>=%s)",
- f->f_av_desc->ad_cname.bv_val,
+ vrf->vrf_av_desc->ad_cname.bv_val,
tmp.bv_val );
ber_memfree( tmp.bv_val );
break;
case LDAP_FILTER_LE:
- filter_escape_value( &f->f_av_value, &tmp );
+ filter_escape_value( &vrf->vrf_av_value, &tmp );
- fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
+ fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
tmp.bv_len + ( sizeof("(<=)") - 1 );
fstr->bv_val = malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s<=%s)",
- f->f_av_desc->ad_cname.bv_val,
+ vrf->vrf_av_desc->ad_cname.bv_val,
tmp.bv_val );
ber_memfree( tmp.bv_val );
break;
case LDAP_FILTER_APPROX:
- filter_escape_value( &f->f_av_value, &tmp );
+ filter_escape_value( &vrf->vrf_av_value, &tmp );
- fstr->bv_len = f->f_av_desc->ad_cname.bv_len +
+ fstr->bv_len = vrf->vrf_av_desc->ad_cname.bv_len +
tmp.bv_len + ( sizeof("(~=)") - 1 );
fstr->bv_val = malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s~=%s)",
- f->f_av_desc->ad_cname.bv_val,
+ vrf->vrf_av_desc->ad_cname.bv_val,
tmp.bv_val );
ber_memfree( tmp.bv_val );
break;
case LDAP_FILTER_SUBSTRINGS:
- fstr->bv_len = f->f_sub_desc->ad_cname.bv_len +
+ fstr->bv_len = vrf->vrf_sub_desc->ad_cname.bv_len +
( sizeof("(=*)") - 1 );
fstr->bv_val = malloc( fstr->bv_len + 128 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
- f->f_sub_desc->ad_cname.bv_val );
+ vrf->vrf_sub_desc->ad_cname.bv_val );
- if ( f->f_sub_initial.bv_val != NULL ) {
+ if ( vrf->vrf_sub_initial.bv_val != NULL ) {
len = fstr->bv_len;
- filter_escape_value( &f->f_sub_initial, &tmp );
+ filter_escape_value( &vrf->vrf_sub_initial, &tmp );
fstr->bv_len += tmp.bv_len;
fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
ber_memfree( tmp.bv_val );
}
- if ( f->f_sub_any != NULL ) {
+ if ( vrf->vrf_sub_any != NULL ) {
int i;
- for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
+ for ( i = 0; vrf->vrf_sub_any[i].bv_val != NULL; i++ ) {
len = fstr->bv_len;
- filter_escape_value( &f->f_sub_any[i], &tmp );
+ filter_escape_value( &vrf->vrf_sub_any[i], &tmp );
fstr->bv_len += tmp.bv_len + 1;
fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
}
}
- if ( f->f_sub_final.bv_val != NULL ) {
+ if ( vrf->vrf_sub_final.bv_val != NULL ) {
len = fstr->bv_len;
- filter_escape_value( &f->f_sub_final, &tmp );
+ filter_escape_value( &vrf->vrf_sub_final, &tmp );
fstr->bv_len += tmp.bv_len;
fstr->bv_val = ch_realloc( fstr->bv_val, fstr->bv_len + 1 );
break;
case LDAP_FILTER_PRESENT:
- fstr->bv_len = f->f_desc->ad_cname.bv_len +
+ fstr->bv_len = vrf->vrf_desc->ad_cname.bv_len +
( sizeof("(=*)") - 1 );
fstr->bv_val = malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s=*)",
- f->f_desc->ad_cname.bv_val );
+ vrf->vrf_desc->ad_cname.bv_val );
break;
case LDAP_FILTER_EXT: {
struct berval ad;
- filter_escape_value( &f->f_mr_value, &tmp );
+ filter_escape_value( &vrf->vrf_mr_value, &tmp );
- if ( f->f_mr_desc ) {
- ad = f->f_mr_desc->ad_cname;
+ if ( vrf->vrf_mr_desc ) {
+ ad = vrf->vrf_mr_desc->ad_cname;
} else {
ad.bv_len = 0;
ad.bv_val = "";
}
fstr->bv_len = ad.bv_len +
- ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
- ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
+ ( vrf->vrf_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
+ ( vrf->vrf_mr_rule_text.bv_len ? vrf->vrf_mr_rule_text.bv_len+1 : 0 ) +
tmp.bv_len + ( sizeof("(:=)") - 1 );
fstr->bv_val = malloc( fstr->bv_len + 1 );
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
ad.bv_val,
- f->f_mr_dnattrs ? ":dn" : "",
- f->f_mr_rule_text.bv_len ? ":" : "",
- f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
+ vrf->vrf_mr_dnattrs ? ":dn" : "",
+ vrf->vrf_mr_rule_text.bv_len ? ":" : "",
+ vrf->vrf_mr_rule_text.bv_len ? vrf->vrf_mr_rule_text.bv_val : "",
tmp.bv_val );
ber_memfree( tmp.bv_val );
case SLAPD_FILTER_COMPUTED:
ber_str2bv(
- f->f_result == LDAP_COMPARE_FALSE ? "(?=false)" :
- f->f_result == LDAP_COMPARE_TRUE ? "(?=true)" :
- f->f_result == SLAPD_COMPARE_UNDEFINED ? "(?=undefined)" :
+ vrf->vrf_result == LDAP_COMPARE_FALSE ? "(?=false)" :
+ vrf->vrf_result == LDAP_COMPARE_TRUE ? "(?=true)" :
+ vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "(?=undefined)" :
"(?=error)",
- f->f_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
- f->f_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
- f->f_result == SLAPD_COMPARE_UNDEFINED ? sizeof("(?=undefined)")-1 :
+ vrf->vrf_result == LDAP_COMPARE_FALSE ? sizeof("(?=false)")-1 :
+ vrf->vrf_result == LDAP_COMPARE_TRUE ? sizeof("(?=true)")-1 :
+ vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? sizeof("(?=undefined)")-1 :
sizeof("(?=error)")-1,
1, fstr );
break;
get_substring_vrFilter(
Connection *conn,
BerElement *ber,
- ValuesReturnFilter *f,
+ ValuesReturnFilter *vrf,
const char **text )
{
ber_tag_t tag;
return SLAPD_DISCONNECT;
}
- f->f_sub = ch_calloc( 1, sizeof(SubstringsAssertion) );
- f->f_sub_desc = NULL;
- rc = slap_bv2ad( &bv, &f->f_sub_desc, text );
+ vrf->vrf_sub = ch_calloc( 1, sizeof(SubstringsAssertion) );
+ vrf->vrf_sub_desc = NULL;
+ rc = slap_bv2ad( &bv, &vrf->vrf_sub_desc, text );
if( rc != LDAP_SUCCESS ) {
text = NULL;
- ch_free( f->f_sub );
- f->f_choice = SLAPD_FILTER_COMPUTED;
- f->f_result = SLAPD_COMPARE_UNDEFINED;
+ ch_free( vrf->vrf_sub );
+ vrf->vrf_choice = SLAPD_FILTER_COMPUTED;
+ vrf->vrf_result = SLAPD_COMPARE_UNDEFINED;
return LDAP_SUCCESS;
}
- f->f_sub_initial.bv_val = NULL;
- f->f_sub_any = NULL;
- f->f_sub_final.bv_val = NULL;
+ vrf->vrf_sub_initial.bv_val = NULL;
+ vrf->vrf_sub_any = NULL;
+ vrf->vrf_sub_final.bv_val = NULL;
for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
tag = ber_next_element( ber, &len, last ) )
}
/* valiate using equality matching rule validator! */
- rc = value_validate( f->f_sub_desc->ad_type->sat_equality,
+ rc = value_validate( vrf->vrf_sub_desc->ad_type->sat_equality,
&value, text );
if( rc != LDAP_SUCCESS ) {
goto return_error;
}
- rc = value_normalize( f->f_sub_desc, usage,
+ rc = value_normalize( vrf->vrf_sub_desc, usage,
&value, &bv, text );
if( rc != LDAP_SUCCESS ) {
goto return_error;
Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
#endif
- if ( f->f_sub_initial.bv_val != NULL
- || f->f_sub_any != NULL
- || f->f_sub_final.bv_val != NULL )
+ if ( vrf->vrf_sub_initial.bv_val != NULL
+ || vrf->vrf_sub_any != NULL
+ || vrf->vrf_sub_final.bv_val != NULL )
{
free( value.bv_val );
goto return_error;
}
- f->f_sub_initial = value;
+ vrf->vrf_sub_initial = value;
break;
case LDAP_SUBSTRING_ANY:
Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
#endif
- if ( f->f_sub_final.bv_val != NULL ) {
+ if ( vrf->vrf_sub_final.bv_val != NULL ) {
free( value.bv_val );
goto return_error;
}
- ber_bvarray_add( &f->f_sub_any, &value );
+ ber_bvarray_add( &vrf->vrf_sub_any, &value );
break;
case LDAP_SUBSTRING_FINAL:
Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
#endif
- if ( f->f_sub_final.bv_val != NULL ) {
+ if ( vrf->vrf_sub_final.bv_val != NULL ) {
free( value.bv_val );
goto return_error;
}
- f->f_sub_final = value;
+ vrf->vrf_sub_final = value;
break;
default:
Debug( LDAP_DEBUG_FILTER, " error=%ld\n",
(long) rc, 0, 0 );
#endif
- free( f->f_sub_initial.bv_val );
- ber_bvarray_free( f->f_sub_any );
- free( f->f_sub_final.bv_val );
- ch_free( f->f_sub );
+ free( vrf->vrf_sub_initial.bv_val );
+ ber_bvarray_free( vrf->vrf_sub_any );
+ free( vrf->vrf_sub_final.bv_val );
+ ch_free( vrf->vrf_sub );
return rc;
}
}
/* filterentry.c - apply a filter to an entry */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
}
}
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
if ( ava->aa_desc == slap_schema.si_ad_hasSubordinates
&& be && be->be_has_subordinates ) {
int hasSubordinates;
return LDAP_COMPARE_FALSE;
}
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
return( LDAP_COMPARE_FALSE );
}
a = attrs_find( e->e_attrs, desc );
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
if ( a == NULL && desc == slap_schema.si_ad_hasSubordinates ) {
/*
return LDAP_COMPARE_FALSE;
}
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
return a != NULL ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
}
--- /dev/null
+/* index.c - index utilities */
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include "slap.h"
+
+int slap_str2index( const char *str, slap_mask_t *idx )
+{
+ if ( strcasecmp( str, "pres" ) == 0 ) {
+ *idx = SLAP_INDEX_PRESENT;
+ } else if ( strcasecmp( str, "eq" ) == 0 ) {
+ *idx = SLAP_INDEX_EQUALITY;
+ } else if ( strcasecmp( str, "approx" ) == 0 ) {
+ *idx = SLAP_INDEX_APPROX;
+ } else if ( strcasecmp( str, "subinitial" ) == 0 ) {
+ *idx = SLAP_INDEX_SUBSTR_INITIAL;
+ } else if ( strcasecmp( str, "subany" ) == 0 ) {
+ *idx = SLAP_INDEX_SUBSTR_ANY;
+ } else if ( strcasecmp( str, "subfinal" ) == 0 ) {
+ *idx = SLAP_INDEX_SUBSTR_FINAL;
+ } else if ( strcasecmp( str, "substr" ) == 0 ||
+ strcasecmp( str, "sub" ) == 0 )
+ {
+ *idx = SLAP_INDEX_SUBSTR_DEFAULT;
+ } else if ( strcasecmp( str, "nolang" ) == 0 || /* backwards compat */
+ strcasecmp( str, "notags" ) == 0 ) {
+ *idx = SLAP_INDEX_NOTAGS;
+ } else if ( strcasecmp( str, "nosubtypes" ) == 0 ) {
+ *idx = SLAP_INDEX_NOSUBTYPES;
+ } else {
+ return LDAP_OTHER;
+ }
+
+ return LDAP_SUCCESS;
+}
/* init.c - initialize various things */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
static const char* slap_name = NULL;
int slapMode = SLAP_UNDEFINED_MODE;
-/*
- * all known control OIDs should be added to this list
- */
-char *slap_known_controls[] = {
-#ifdef LDAP_CONTROL_REFERRALS
- LDAP_CONTROL_REFERRALS,
-#endif /* LDAP_CONTROL_REFERRALS */
-
-#ifdef LDAP_CONTROL_MANAGEDSAIT
- LDAP_CONTROL_MANAGEDSAIT,
-#endif /* LDAP_CONTROL_MANAGEDSAIT */
-
-#ifdef LDAP_CONTROL_SUBENTRIES
- LDAP_CONTROL_SUBENTRIES,
-#endif /* LDAP_CONTROL_SUBENTRIES */
-
-#ifdef LDAP_CONTROL_NOOP
- LDAP_CONTROL_NOOP,
-#endif /* LDAP_CONTROL_NOOP */
-
-#ifdef LDAP_CONTROL_DUPENT_REQUEST
- LDAP_CONTROL_DUPENT_REQUEST,
-#endif /* LDAP_CONTROL_DUPENT_REQUEST */
-
-#ifdef LDAP_CONTROL_DUPENT_RESPONSE
- LDAP_CONTROL_DUPENT_RESPONSE,
-#endif /* LDAP_CONTROL_DUPENT_RESPONSE */
-
-#ifdef LDAP_CONTROL_DUPENT_ENTRY
- LDAP_CONTROL_DUPENT_ENTRY,
-#endif /* LDAP_CONTROL_DUPENT_ENTRY */
-
-#ifdef LDAP_CONTROL_PAGEDRESULTS
- LDAP_CONTROL_PAGEDRESULTS,
-#endif /* LDAP_CONTROL_PAGEDRESULTS */
-
-#ifdef LDAP_CONTROL_SORTREQUEST
- LDAP_CONTROL_SORTREQUEST,
-#endif /* LDAP_CONTROL_SORTREQUEST */
-
-#ifdef LDAP_CONTROL_SORTRESPONSE
- LDAP_CONTROL_SORTRESPONSE,
-#endif /* LDAP_CONTROL_SORTRESPONSE */
-
-#ifdef LDAP_CONTROL_VLVREQUEST
- LDAP_CONTROL_VLVREQUEST,
-#endif /* LDAP_CONTROL_VLVREQUEST */
-
-#ifdef LDAP_CONTROL_VLVRESPONSE
- LDAP_CONTROL_VLVRESPONSE,
-#endif /* LDAP_CONTROL_VLVRESPONSE */
-
-#ifdef LDAP_CONTROL_VALUESRETURNFILTER
- LDAP_CONTROL_VALUESRETURNFILTER,
-#endif /* LDAP_CONTROL_VALUESRETURNFILTER */
-
- NULL
-};
-
int
slap_init( int mode, const char *name )
{
/* limits.c - routines to handle regex-based size and time limits */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
}
}
-#ifdef LDAP_CONTROL_PAGEDRESULTS
} else if ( strncasecmp( arg, "pr", sizeof( "pr" ) - 1 ) == 0 ) {
arg += sizeof( "pr" ) - 1;
if ( arg[0] != '=' ) {
return( 1 );
}
}
-#endif /* LDAP_CONTROL_PAGEDRESULTS */
} else {
return( 1 );
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "portable.h"
#include "ldap_pvt.h"
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
#include "lutil.h"
#include "ldif.h"
{ "LOCAL5", sizeof("LOCAL5"), LOG_LOCAL5 },
{ "LOCAL6", sizeof("LOCAL6"), LOG_LOCAL6 },
{ "LOCAL7", sizeof("LOCAL7"), LOG_LOCAL7 },
- { NULL }
+ { NULL, 0, 0 }
};
static int cnvt_str2int( char *, STRDISP_P, int );
}
#endif
-
#ifdef HAVE_NT_SERVICE_MANAGER
{
int *i;
Debug( LDAP_DEBUG_TRACE, "%s", Versionstr, 0, 0 );
#endif
-
if( serverName == NULL ) {
if ( (serverName = strrchr( argv[0], *LDAP_DIRSEP )) == NULL ) {
serverName = argv[0];
(void) ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &rc );
#endif
+#ifdef LDAP_SLAPI
+ if ( slapi_init() != 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, CRIT, "main: slapi initialization error\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "slapi initialization error\n",
+ 0, 0, 0 );
+#endif
+
+ goto destroy;
+ }
+#endif /* LDAP_SLAPI */
+
if ( read_config( configfile, 0 ) != 0 ) {
rc = 1;
SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 19 );
/* $OpenLDAP$ */
/*
- * Copyright 1999-2002 The OpenLDAP Foundation.
+ * Copyright 1999-2003 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted only
char ***e_flags
)
{
- ValuesReturnFilter *f;
+ ValuesReturnFilter *vrf;
int rc = LDAP_SUCCESS;
#ifdef NEW_LOGGING
Debug( LDAP_DEBUG_FILTER, "=> filter_matched_values\n", 0, 0, 0 );
#endif
- for ( f = op->vrFilter; f != NULL; f = f->f_next ) {
- switch ( f->f_choice ) {
+ for ( vrf = op->vrFilter; vrf != NULL; vrf = vrf->vrf_next ) {
+ switch ( vrf->vrf_choice ) {
case SLAPD_FILTER_COMPUTED:
#ifdef NEW_LOGGING
LDAP_LOG( FILTER, DETAIL1,
"test_vrFilter: COMPUTED %s (%d)\n",
- f->f_result == LDAP_COMPARE_FALSE ? "false" :
- f->f_result == LDAP_COMPARE_TRUE ? "true" :
- f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" :
- "error", f->f_result, 0 );
+ vrf->vrf_result == LDAP_COMPARE_FALSE ? "false" :
+ vrf->vrf_result == LDAP_COMPARE_TRUE ? "true" :
+ vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "undefined" :
+ "error", vrf->vrf_result, 0 );
#else
Debug( LDAP_DEBUG_FILTER, " COMPUTED %s (%d)\n",
- f->f_result == LDAP_COMPARE_FALSE ? "false" :
- f->f_result == LDAP_COMPARE_TRUE ? "true" :
- f->f_result == SLAPD_COMPARE_UNDEFINED ? "undefined" : "error",
- f->f_result, 0 );
+ vrf->vrf_result == LDAP_COMPARE_FALSE ? "false" :
+ vrf->vrf_result == LDAP_COMPARE_TRUE ? "true" :
+ vrf->vrf_result == SLAPD_COMPARE_UNDEFINED ? "undefined" : "error",
+ vrf->vrf_result, 0 );
#endif
/*This type of filter does not affect the result */
rc = LDAP_SUCCESS;
#else
Debug( LDAP_DEBUG_FILTER, " EQUALITY\n", 0, 0, 0 );
#endif
- rc = test_ava_vrFilter( be, conn, op, a, f->f_ava,
+ rc = test_ava_vrFilter( be, conn, op, a, vrf->vrf_ava,
LDAP_FILTER_EQUALITY, e_flags );
if( rc == -1 ) {
return rc;
#endif
rc = test_substrings_vrFilter( be, conn, op, a,
- f, e_flags );
+ vrf, e_flags );
if( rc == -1 ) {
return rc;
}
Debug( LDAP_DEBUG_FILTER, " PRESENT\n", 0, 0, 0 );
#endif
rc = test_presence_vrFilter( be, conn, op, a,
- f->f_desc, e_flags );
+ vrf->vrf_desc, e_flags );
if( rc == -1 ) {
return rc;
}
break;
case LDAP_FILTER_GE:
- rc = test_ava_vrFilter( be, conn, op, a, f->f_ava,
+ rc = test_ava_vrFilter( be, conn, op, a, vrf->vrf_ava,
LDAP_FILTER_GE, e_flags );
if( rc == -1 ) {
return rc;
break;
case LDAP_FILTER_LE:
- rc = test_ava_vrFilter( be, conn, op, a, f->f_ava,
+ rc = test_ava_vrFilter( be, conn, op, a, vrf->vrf_ava,
LDAP_FILTER_LE, e_flags );
if( rc == -1 ) {
return rc;
Debug( LDAP_DEBUG_FILTER, " EXT\n", 0, 0, 0 );
#endif
rc = test_mra_vrFilter( be, conn, op, a,
- f->f_mra, e_flags );
+ vrf->vrf_mra, e_flags );
if( rc == -1 ) {
return rc;
}
default:
#ifdef NEW_LOGGING
LDAP_LOG( FILTER, INFO,
- "test_vrFilter: unknown filter type %lu\n", f->f_choice, 0, 0 );
+ "test_vrFilter: unknown filter type %lu\n", vrf->vrf_choice, 0, 0 );
#else
Debug( LDAP_DEBUG_ANY, " unknown filter type %lu\n",
- f->f_choice, 0, 0 );
+ vrf->vrf_choice, 0, 0 );
#endif
rc = LDAP_PROTOCOL_ERROR;
}
Connection *conn,
Operation *op,
Attribute *a,
- ValuesReturnFilter *f,
+ ValuesReturnFilter *vrf,
char ***e_flags
)
{
MatchingRule *mr = a->a_desc->ad_type->sat_substr;
struct berval *bv;
- if ( !is_ad_subtype( a->a_desc, f->f_sub_desc ) ) {
+ if ( !is_ad_subtype( a->a_desc, vrf->vrf_sub_desc ) ) {
continue;
}
rc = value_match( &ret, a->a_desc, mr,
SLAP_MR_ASSERTION_SYNTAX_MATCH,
- bv, f->f_sub, &text );
+ bv, vrf->vrf_sub, &text );
if( rc != LDAP_SUCCESS ) {
return rc;
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/*
#include "ldap_pvt.h"
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
int
do_modify(
Modifications **modtail = &modlist;
#ifdef LDAP_DEBUG
Modifications *tmp;
+#endif
+#ifdef LDAP_SLAPI
+ LDAPMod **modv = NULL;
+ Slapi_PBlock *pb = op->o_pb;
#endif
Backend *be;
int rc;
mod->sml_type = tmp.sml_type;
mod->sml_bvalues = tmp.sml_bvalues;
mod->sml_desc = NULL;
- mod->sml_next =NULL;
+ mod->sml_next = NULL;
*modtail = mod;
switch( mop ) {
}
#endif
- Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MOD dn=\"%s\"\n",
- op->o_connid, op->o_opid, dn.bv_val, 0, 0 );
+ if ( StatslogTest( LDAP_DEBUG_STATS ) ) {
+ char abuf[BUFSIZ/2], *ptr = abuf;
+ int len = 0;
+
+ Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MOD dn=\"%s\"\n",
+ op->o_connid, op->o_opid, dn.bv_val, 0, 0 );
+
+ for ( tmp = modlist; tmp != NULL; tmp = tmp->sml_next ) {
+ if (len + 1 + tmp->sml_type.bv_len > sizeof(abuf)) {
+ Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MOD attr=%s\n",
+ op->o_connid, op->o_opid, abuf, 0, 0 );
+ len = 0;
+ ptr = abuf;
+ }
+ if (len) {
+ *ptr++ = ' ';
+ len++;
+ }
+ ptr = lutil_strcopy(ptr, tmp->sml_type.bv_val);
+ len += tmp->sml_type.bv_len;
+ }
+ if (len) {
+ Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MOD attr=%s\n",
+ op->o_connid, op->o_opid, abuf, 0, 0 );
+ }
+ }
manageDSAit = get_manageDSAit( op );
/* deref suffix alias if appropriate */
suffix_alias( be, &ndn );
+#if defined( LDAP_SLAPI )
+ slapi_x_backend_set_pb( pb, be );
+ slapi_x_connection_set_pb( pb, conn );
+ slapi_x_operation_set_pb( pb, op );
+ slapi_pblock_set( pb, SLAPI_MODIFY_TARGET, (void *)dn.bv_val );
+ slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
+ modv = slapi_x_modifications2ldapmods( &modlist );
+ slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)modv );
+
+ rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_MODIFY_FN, pb );
+ if ( rc != 0 ) {
+ /*
+ * A preoperation plugin failure will abort the
+ * entire operation.
+ */
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_modify: modify preoperation plugin "
+ "failed\n", 0, 0, 0 );
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_modify: modify preoperation plugin failed.\n",
+ 0, 0, 0);
+#endif
+ if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0) {
+ rc = LDAP_OTHER;
+ }
+ ldap_mods_free( modv, 1 );
+ modv = NULL;
+ goto cleanup;
+ }
+
+ /*
+ * It's possible that the preoperation plugin changed the
+ * modification array, so we need to convert it back to
+ * a Modification list.
+ *
+ * Calling slapi_x_modifications2ldapmods() destroyed modlist so
+ * we don't need to free it.
+ */
+ slapi_pblock_get( pb, SLAPI_MODIFY_MODS, (void **)&modv );
+ modlist = slapi_x_ldapmods2modifications( modv );
+#endif /* defined( LDAP_SLAPI ) */
+
/*
* do the modify if 1 && (2 || 3)
* 1) there is a modify function implemented in this backend;
NULL, NULL );
}
+#if defined( LDAP_SLAPI )
+ if ( doPluginFNs( be, SLAPI_PLUGIN_POST_MODIFY_FN, pb ) != 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_modify: modify postoperation plugins "
+ "failed\n", 0, 0, 0 );
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_modify: modify postoperation plugins "
+ "failed.\n", 0, 0, 0);
+#endif
+ }
+#endif /* defined( LDAP_SLAPI ) */
+
cleanup:
free( pdn.bv_val );
free( ndn.bv_val );
- if ( modlist != NULL )
- slap_mods_free( modlist );
+ if ( modlist != NULL ) slap_mods_free( modlist );
+#if defined( LDAP_SLAPI )
+ if ( modv != NULL ) slapi_x_free_ldapmods( modv );
+#endif
return rc;
}
return LDAP_UNDEFINED_TYPE;
}
- if( slap_ad_is_lang_range( ad )) {
+ if( slap_ad_is_tag_range( ad )) {
/* attribute requires binary transfer */
snprintf( textbuf, textlen,
- "%s: inappropriate use of language range option",
+ "%s: inappropriate use of tag range option",
ml->sml_type.bv_val );
*text = textbuf;
return LDAP_UNDEFINED_TYPE;
*modtail = NULL;
return LDAP_SUCCESS;
}
+
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/*
#include "ldap_pvt.h"
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
int
do_modrdn(
const char *text;
int manageDSAit;
+#ifdef LDAP_SLAPI
+ Slapi_PBlock *pb = op->o_pb;
+#endif
+
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ENTRY, "do_modrdn: begin\n", 0, 0, 0 );
#else
/* deref suffix alias if appropriate */
suffix_alias( be, &ndn );
+#if defined( LDAP_SLAPI )
+ slapi_x_backend_set_pb( pb, be );
+ slapi_x_connection_set_pb( pb, conn );
+ slapi_x_operation_set_pb( pb, op );
+ slapi_pblock_set( pb, SLAPI_MODRDN_TARGET, (void *)dn.bv_val );
+ slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn.bv_val );
+ slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR,
+ (void *)newSuperior.bv_val );
+ slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, (void *)deloldrdn );
+ slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
+
+ rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_MODRDN_FN, pb );
+ if ( rc != 0 ) {
+ /*
+ * A preoperation plugin failure will abort the
+ * entire operation.
+ */
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_modrdn: modrdn preoperation plugin "
+ "failed\n", 0, 0, 0 );
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_modrdn: modrdn preoperation plugin "
+ "failed.\n", 0, 0, 0);
+#endif
+ if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0)
+ rc = LDAP_OTHER;
+ goto cleanup;
+ }
+#endif /* defined( LDAP_SLAPI ) */
+
/*
* do the add if 1 && (2 || 3)
* 1) there is an add function implemented in this backend;
NULL, NULL );
}
+#if defined( LDAP_SLAPI )
+ if ( doPluginFNs( be, SLAPI_PLUGIN_POST_MODRDN_FN, pb ) != 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "do_modrdn: modrdn postoperation plugins "
+ "failed\n", 0, 0, 0 );
+#else
+ Debug(LDAP_DEBUG_TRACE, "do_modrdn: modrdn postoperation plugins "
+ "failed.\n", 0, 0, 0);
+#endif
+ }
+#endif /* defined( LDAP_SLAPI ) */
+
cleanup:
free( pdn.bv_val );
free( ndn.bv_val );
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/*
MatchingRule *mr,
BerVarray vals,
BerVarray mods,
+ int permissive,
const char **text,
char *textbuf, size_t textlen )
{
int i, j, numvals = 0, nummods,
- rc = LDAP_SUCCESS;
+ rc = LDAP_SUCCESS, matched;
BerVarray nvals = NULL, nmods = NULL;
/*
}
if ( numvals > 0 && numvals < nummods ) {
- for ( j = 0; nvals[ j ].bv_val; j++ ) {
+ for ( matched = 0, j = 0; nvals[ j ].bv_val; j++ ) {
int match;
rc = (*mr->smr_match)( &match,
ad->ad_cname.bv_val );
goto return_results;
}
-
+
if ( match == 0 ) {
+ if ( permissive ) {
+ matched++;
+ continue;
+ }
*text = textbuf;
snprintf( textbuf, textlen,
"%s: value #%d provided more than once",
goto return_results;
}
}
+
+ if ( permissive && matched == j ) {
+ nmods[ i + 1 ].bv_val = NULL;
+ rc = LDAP_TYPE_OR_VALUE_EXISTS;
+ goto return_results;
+ }
}
- for ( j = 0; j < i; j++ ) {
+ for ( matched = 0, j = 0; j < i; j++ ) {
int match;
rc = (*mr->smr_match)( &match,
}
if ( match == 0 ) {
+ if ( permissive ) {
+ matched++;
+ continue;
+ }
*text = textbuf;
snprintf( textbuf, textlen,
"%s: value #%d provided more than once",
goto return_results;
}
}
+
+ if ( permissive && matched == j ) {
+ nmods[ i + 1 ].bv_val = NULL;
+ rc = LDAP_TYPE_OR_VALUE_EXISTS;
+ goto return_results;
+ }
}
nmods[ i ].bv_val = NULL;
goto return_results;
}
- for ( i = 0; nmods[ i ].bv_val; i++ ) {
+ for ( matched = 0, i = 0; nmods[ i ].bv_val; i++ ) {
int match;
rc = (*mr->smr_match)( &match,
}
if ( match == 0 ) {
+ if ( permissive ) {
+ matched++;
+ continue;
+ }
*text = textbuf;
snprintf( textbuf, textlen,
"%s: value #%d provided more than once",
}
}
+ if ( permissive && matched == i ) {
+ rc = LDAP_TYPE_OR_VALUE_EXISTS;
+ goto return_results;
+ }
}
}
modify_add_values(
Entry *e,
Modification *mod,
+ int permissive,
const char **text,
char *textbuf, size_t textlen
)
{
int i, j;
+ int matched;
Attribute *a;
MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
const char *op;
a = attr_find( e->e_attrs, mod->sm_desc );
+ /*
+ * With permissive set, as long as the attribute being added
+ * has the same value(s?) as the existing attribute, then the
+ * modify will succeed.
+ */
+
/* check if the values we're adding already exist */
if( mr == NULL || !mr->smr_match ) {
if ( a != NULL ) {
for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) {
/* test asserted values against existing values */
if( a ) {
- for( j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
+ for( matched = 0, j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
if ( bvmatch( &mod->sm_bvalues[i],
&a->a_vals[j] ) ) {
-
+ if ( permissive ) {
+ matched++;
+ continue;
+ }
/* value exists already */
*text = textbuf;
snprintf( textbuf, textlen,
return LDAP_TYPE_OR_VALUE_EXISTS;
}
}
+ if ( permissive && matched == j ) {
+ /* values already exist; do nothing */
+ return LDAP_SUCCESS;
+ }
}
/* test asserted values against themselves */
return rc;
}
- for ( i = 0; a->a_vals[ i ].bv_val; i++ ) {
+ for ( matched = 0, i = 0; a->a_vals[ i ].bv_val; i++ ) {
int match;
rc = value_match( &match, mod->sm_desc, mr,
&a->a_vals[ i ], &asserted, text );
if( rc == LDAP_SUCCESS && match == 0 ) {
+ if ( permissive ) {
+ matched++;
+ continue;
+ }
free( asserted.bv_val );
*text = textbuf;
snprintf( textbuf, textlen,
return LDAP_TYPE_OR_VALUE_EXISTS;
}
}
+ if ( permissive && matched == i ) {
+ /* values already exist; do nothing */
+ return LDAP_SUCCESS;
+ }
}
} else {
rc = modify_check_duplicates( mod->sm_desc, mr,
a ? a->a_vals : NULL, mod->sm_bvalues,
+ permissive,
text, textbuf, textlen );
-
+
+ if ( permissive && rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
+ return LDAP_SUCCESS;
+ }
+
if ( rc != LDAP_SUCCESS ) {
return rc;
}
modify_delete_values(
Entry *e,
Modification *mod,
+ int permissive,
const char **text,
char *textbuf, size_t textlen
)
BerVarray nvals = NULL;
char dummy = '\0';
+ /*
+ * If permissive is set, then the non-existence of an
+ * attribute is not treated as an error.
+ */
+
/* delete the entire attribute */
if ( mod->sm_bvalues == NULL ) {
rc = attr_delete( &e->e_attrs, mod->sm_desc );
- if( rc != LDAP_SUCCESS ) {
+ if( permissive ) {
+ rc = LDAP_SUCCESS;
+ } else if( rc != LDAP_SUCCESS ) {
*text = textbuf;
snprintf( textbuf, textlen,
"modify/delete: %s: no such attribute",
/* delete specific values - find the attribute first */
if ( (a = attr_find( e->e_attrs, mod->sm_desc )) == NULL ) {
+ if( permissive ) {
+ return LDAP_SUCCESS;
+ }
*text = textbuf;
snprintf( textbuf, textlen,
"modify/delete: %s: no such attribute",
modify_replace_values(
Entry *e,
Modification *mod,
+ int permissive,
const char **text,
char *textbuf, size_t textlen
)
(void) attr_delete( &e->e_attrs, mod->sm_desc );
if ( mod->sm_bvalues ) {
- return modify_add_values( e, mod, text, textbuf, textlen );
+ return modify_add_values( e, mod, permissive, text, textbuf, textlen );
}
return LDAP_SUCCESS;
}
/* call module's terminate routine, if present */
- if (terminate = lt_dlsym(module->lib, "term_module")) {
+ if ((terminate = lt_dlsym(module->lib, "term_module"))) {
terminate();
}
/* mr.c - routines to manage matching rule definitions */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
};
static Avlnode *mr_index = NULL;
-static MatchingRule *mr_list = NULL;
-static MatchingRuleUse *mru_list = NULL;
+static LDAP_SLIST_HEAD(MRList, slap_matching_rule) mr_list
+ = LDAP_SLIST_HEAD_INITIALIZER(&mr_list);
+static LDAP_SLIST_HEAD(MRUList, slap_matching_rule_use) mru_list
+ = LDAP_SLIST_HEAD_INITIALIZER(&mru_list);
static int
mr_index_cmp(
- struct mindexrec *mir1,
- struct mindexrec *mir2
+ const void *v_mir1,
+ const void *v_mir2
)
{
+ const struct mindexrec *mir1 = v_mir1;
+ const struct mindexrec *mir2 = v_mir2;
int i = mir1->mir_name.bv_len - mir2->mir_name.bv_len;
if (i) return i;
return (strcmp( mir1->mir_name.bv_val, mir2->mir_name.bv_val ));
static int
mr_index_name_cmp(
- struct berval *name,
- struct mindexrec *mir
+ const void *v_name,
+ const void *v_mir
)
{
+ const struct berval *name = v_name;
+ const struct mindexrec *mir = v_mir;
int i = name->bv_len - mir->mir_name.bv_len;
if (i) return i;
return (strncmp( name->bv_val, mir->mir_name.bv_val, name->bv_len ));
{
struct mindexrec *mir = NULL;
- if ( (mir = (struct mindexrec *) avl_find( mr_index, mrname,
- (AVL_CMP) mr_index_name_cmp )) != NULL ) {
+ if ( (mir = avl_find( mr_index, mrname, mr_index_name_cmp )) != NULL ) {
return( mir->mir_mr );
}
return( NULL );
void
mr_destroy( void )
{
- MatchingRule *m, *n;
+ MatchingRule *m;
avl_free(mr_index, ldap_memfree);
- for (m=mr_list; m; m=n) {
- n = m->smr_next;
+ while( !LDAP_SLIST_EMPTY(&mr_list) ) {
+ m = LDAP_SLIST_FIRST(&mr_list);
+ LDAP_SLIST_REMOVE_HEAD(&mr_list, smr_next);
ch_free( m->smr_str.bv_val );
ldap_matchingrule_free((LDAPMatchingRule *)m);
}
const char **err
)
{
- MatchingRule **mrp;
struct mindexrec *mir;
char **names;
- mrp = &mr_list;
- while ( *mrp != NULL ) {
- mrp = &(*mrp)->smr_next;
- }
- *mrp = smr;
+ LDAP_SLIST_INSERT_HEAD(&mr_list, smr, smr_next);
if ( smr->smr_oid ) {
mir = (struct mindexrec *)
mir->mir_name.bv_len = strlen( smr->smr_oid );
mir->mir_mr = smr;
if ( avl_insert( &mr_index, (caddr_t) mir,
- (AVL_CMP) mr_index_cmp,
- (AVL_DUP) avl_dup_error ) ) {
+ mr_index_cmp, avl_dup_error ) ) {
*err = smr->smr_oid;
ldap_memfree(mir);
return SLAP_SCHERR_MR_DUP;
mir->mir_name.bv_len = strlen( *names );
mir->mir_mr = smr;
if ( avl_insert( &mr_index, (caddr_t) mir,
- (AVL_CMP) mr_index_cmp,
- (AVL_DUP) avl_dup_error ) ) {
+ mr_index_cmp, avl_dup_error ) ) {
*err = *names;
ldap_memfree(mir);
return SLAP_SCHERR_MR_DUP;
void
mru_destroy( void )
{
- MatchingRuleUse *m, *n;
+ MatchingRuleUse *m;
+
+ while( !LDAP_SLIST_EMPTY(&mru_list) ) {
+ m = LDAP_SLIST_FIRST(&mru_list);
+ LDAP_SLIST_REMOVE_HEAD(&mru_list, smru_next);
- for (m=mru_list; m; m=n) {
- n = m->smru_next;
if ( m->smru_str.bv_val ) {
ch_free( m->smru_str.bv_val );
}
matching_rule_use_init( void )
{
MatchingRule *mr;
- MatchingRuleUse **mru_ptr = &mru_list;
+ MatchingRuleUse **mru_ptr = &LDAP_SLIST_FIRST(&mru_list);
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, INFO, "matching_rule_use_init\n", 0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "matching_rule_use_init\n", 0, 0, 0 );
#endif
- for ( mr = mr_list; mr; mr = mr->smr_next ) {
+ LDAP_SLIST_FOREACH( mr, &mr_list, smr_next ) {
AttributeType *at;
- MatchingRuleUse _mru, *mru = &_mru;
+ MatchingRuleUse mru_storage, *mru = &mru_storage;
char **applies_oids = NULL;
mru->smru_mr = mr;
mru->smru_obsolete = mr->smr_obsolete;
mru->smru_applies_oids = NULL;
- mru->smru_next = NULL;
+ LDAP_SLIST_NEXT(mru, smru_next) = NULL;
mru->smru_oid = mr->smr_oid;
mru->smru_names = mr->smr_names;
mru->smru_desc = mr->smr_desc;
/* call-forward from MatchingRule to MatchingRuleUse */
mr->smr_mru = mru;
/* copy static data to newly allocated struct */
- *mru = _mru;
+ *mru = mru_storage;
/* append the struct pointer to the end of the list */
*mru_ptr = mru;
/* update the list head pointer */
- mru_ptr = &mru->smru_next;
+ mru_ptr = &LDAP_SLIST_NEXT(mru,smru_next);
}
}
int mr_schema_info( Entry *e )
{
- MatchingRule *mr;
+ MatchingRule *mr;
AttributeDescription *ad_matchingRules = slap_schema.si_ad_matchingRules;
- for ( mr = mr_list; mr; mr = mr->smr_next ) {
+ LDAP_SLIST_FOREACH(mr, &mr_list, smr_next ) {
if ( mr->smr_usage & SLAP_MR_HIDE ) {
/* skip hidden rules */
continue;
AttributeDescription *ad_matchingRuleUse
= slap_schema.si_ad_matchingRuleUse;
- for ( mru = mru_list; mru; mru = mru->smru_next ) {
+ LDAP_SLIST_FOREACH( mru, &mru_list, smru_next ) {
assert( !( mru->smru_usage & SLAP_MR_HIDE ) );
/* oc.c - object class routines */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
if( set_flags && ( e->e_ocflags & SLAP_OC__END )) {
/* flags are set, use them */
- return e->e_ocflags & oc->soc_flags & SLAP_OC__MASK;
+ return (e->e_ocflags & oc->soc_flags & SLAP_OC__MASK) != 0;
}
/*
/* mark flags as set */
e->e_ocflags |= SLAP_OC__END;
- return e->e_ocflags & oc->soc_flags & SLAP_OC__MASK;
+ return (e->e_ocflags & oc->soc_flags & SLAP_OC__MASK) != 0;
}
};
static Avlnode *oc_index = NULL;
-static ObjectClass *oc_list = NULL;
+static LDAP_SLIST_HEAD(OCList, slap_object_class) oc_list
+ = LDAP_SLIST_HEAD_INITIALIZER(&oc_list);
static int
oc_index_cmp(
- struct oindexrec *oir1,
- struct oindexrec *oir2 )
+ const void *v_oir1,
+ const void *v_oir2 )
{
+ const struct oindexrec *oir1 = v_oir1, *oir2 = v_oir2;
int i = oir1->oir_name.bv_len - oir2->oir_name.bv_len;
if (i)
return i;
static int
oc_index_name_cmp(
- struct berval *name,
- struct oindexrec *oir )
+ const void *v_name,
+ const void *v_oir )
{
+ const struct berval *name = v_name;
+ const struct oindexrec *oir = v_oir;
int i = name->bv_len - oir->oir_name.bv_len;
if (i)
return i;
{
struct oindexrec *oir;
- oir = (struct oindexrec *) avl_find( oc_index, ocname,
- (AVL_CMP) oc_index_name_cmp );
+ oir = avl_find( oc_index, ocname, oc_index_name_cmp );
if ( oir != NULL ) {
return( oir->oir_oc );
void
oc_destroy( void )
{
- ObjectClass *o, *n;
+ ObjectClass *o;
avl_free(oc_index, ldap_memfree);
- for (o=oc_list; o; o=n)
- {
- n = o->soc_next;
+ while( !LDAP_SLIST_EMPTY(&oc_list) ) {
+ o = LDAP_SLIST_FIRST(&oc_list);
+ LDAP_SLIST_REMOVE_HEAD(&oc_list, soc_next);
+
if (o->soc_sups) ldap_memfree(o->soc_sups);
if (o->soc_required) ldap_memfree(o->soc_required);
if (o->soc_allowed) ldap_memfree(o->soc_allowed);
const char **err
)
{
- ObjectClass **ocp;
struct oindexrec *oir;
char **names;
- ocp = &oc_list;
- while ( *ocp != NULL ) {
- ocp = &(*ocp)->soc_next;
- }
- *ocp = soc;
+ LDAP_SLIST_INSERT_HEAD( &oc_list, soc, soc_next );
if ( soc->soc_oid ) {
oir = (struct oindexrec *)
assert( oir->oir_oc );
if ( avl_insert( &oc_index, (caddr_t) oir,
- (AVL_CMP) oc_index_cmp,
- (AVL_DUP) avl_dup_error ) )
+ oc_index_cmp, avl_dup_error ) )
{
*err = soc->soc_oid;
ldap_memfree(oir);
assert( oir->oir_oc );
if ( avl_insert( &oc_index, (caddr_t) oir,
- (AVL_CMP) oc_index_cmp,
- (AVL_DUP) avl_dup_error ) )
+ oc_index_cmp, avl_dup_error ) )
{
*err = *names;
ldap_memfree(oir);
vals[1].bv_val = NULL;
- for ( oc = oc_list; oc; oc = oc->soc_next ) {
+ LDAP_SLIST_FOREACH( oc, &oc_list, soc_next ) {
if( oc->soc_flags & SLAP_OC_HIDE ) continue;
if ( ldap_objectclass2bv( &oc->soc_oclass, vals ) == NULL ) {
/* schemaparse.c - routines to parse config file objectclass definitions */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "slap.h"
-static OidMacro *om_list = NULL;
+static LDAP_SLIST_HEAD(OidMacroList, slap_oid_macro) om_list
+ = LDAP_SLIST_HEAD_INITIALIZER(om_list);
/* Replace an OID Macro invocation with its full numeric OID.
* If the macro is used with "macroname:suffix" append ".suffix"
return oid;
}
- for (om = om_list; om; om=om->som_next) {
+ LDAP_SLIST_FOREACH( om, &om_list, som_next ) {
char **names = om->som_names;
if( names == NULL ) {
void
oidm_destroy()
{
- OidMacro *om, *n;
+ OidMacro *om;
+
+ while( !LDAP_SLIST_EMPTY( &om_list )) {
+ om = LDAP_SLIST_FIRST( &om_list );
- for (om = om_list; om; om = n) {
- n = om->som_next;
ldap_charray_free(om->som_names);
free(om->som_oid.bv_val);
free(om);
+
+ LDAP_SLIST_REMOVE_HEAD( &om_list, som_next );
}
}
}
om->som_oid.bv_len = strlen( om->som_oid.bv_val );
- om->som_next = om_list;
- om_list = om;
+
+ LDAP_SLIST_INSERT_HEAD( &om_list, om, som_next );
return 0;
}
/* operation.c - routines to deal with pending ldap operations */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include <ac/socket.h>
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
void
ldap_controls_free( op->o_ctrls );
}
+#ifdef LDAP_CONNECTIONLESS
+ if ( op->o_res_ber != NULL ) {
+ ber_free( op->o_res_ber, 1 );
+ }
+#endif
#ifdef LDAP_CLIENT_UPDATE
if ( op->o_clientupdate_state.bv_val != NULL ) {
free( op->o_clientupdate_state.bv_val );
}
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
+#ifdef LDAP_SYNC
+ if ( op->o_sync_state.bv_val != NULL ) {
+ free( op->o_sync_state.bv_val );
+ }
+#endif
+
+#if defined( LDAP_SLAPI )
+ if ( op->o_pb != NULL ) {
+ slapi_pblock_destroy( (Slapi_PBlock *)op->o_pb );
+ }
+#endif /* defined( LDAP_SLAPI ) */
free( (char *) op );
}
op->o_time = slap_get_time();
op->o_opid = id;
+#ifdef LDAP_CONNECTIONLESS
+ op->o_res_ber = NULL;
+#endif
+
+#if defined( LDAP_SLAPI )
+ op->o_pb = slapi_pblock_new();
+#endif /* defined( LDAP_SLAPI ) */
return( op );
}
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#ifndef PROTO_SLAP_H
AttributeDescription **ad,
const char **text ));
-LDAP_SLAPD_F (AttributeDescription *) ad_find_lang LDAP_P((
+LDAP_SLAPD_F (AttributeDescription *) ad_find_tags LDAP_P((
AttributeType *type,
- struct berval *lang ));
+ struct berval *tags ));
LDAP_SLAPD_F (AttributeName *) str2anlist LDAP_P(( AttributeName *an,
char *str, const char *brkstr ));
-LDAP_SLAPD_F (int) an_find LDAP_P(( AttributeName *a, struct berval *s ));
+LDAP_SLAPD_F (int) an_find LDAP_P(( AttributeName *a, struct berval *s ));
+LDAP_SLAPD_F (int) ad_define_option LDAP_P(( const char *name,
+ const char *fname, int lineno ));
+
+/*
+ * add.c
+ */
+LDAP_SLAPD_F (int) slap_mods2entry LDAP_P(( Modifications *mods, Entry **e,
+ int repl_user, const char **text, char *textbuf, size_t textlen ));
/*
* at.c
LDAP_SLAPD_F (char *) get_supported_ctrl LDAP_P((int index));
+LDAP_SLAPD_F (slap_mask_t) get_supported_ctrl_mask LDAP_P((int index));
+
/*
* config.c
*/
LDAP_SLAPD_F (void) entry_free LDAP_P(( Entry *e ));
LDAP_SLAPD_F (int) entry_cmp LDAP_P(( Entry *a, Entry *b ));
-LDAP_SLAPD_F (int) entry_dn_cmp LDAP_P(( Entry *a, Entry *b ));
-LDAP_SLAPD_F (int) entry_id_cmp LDAP_P(( Entry *a, Entry *b ));
+LDAP_SLAPD_F (int) entry_dn_cmp LDAP_P(( const void *v_a, const void *v_b ));
+LDAP_SLAPD_F (int) entry_id_cmp LDAP_P(( const void *v_a, const void *v_b ));
/*
* extended.c
LDAP_SLAPD_F (struct berval *) get_supported_extop LDAP_P((int index));
+/*
+ * * cancel.c
+ * */
+LDAP_SLAPD_F ( SLAP_EXTOP_MAIN_FN ) cancel_extop;
+
/*
* filter.c
*/
LDAP_SLAPD_F (void) vrFilter_free LDAP_P(( ValuesReturnFilter *f ));
LDAP_SLAPD_F (void) vrFilter2bv LDAP_P(( ValuesReturnFilter *f, struct berval *fstr ));
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
LDAP_SLAPD_F (int) filter_has_subordinates LDAP_P(( Filter *filter ));
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
/*
* filterentry.c
*/
LDAP_SLAPD_F( int ) modify_check_duplicates(
AttributeDescription *ad, MatchingRule *mr,
- BerVarray vals, BerVarray mods,
+ BerVarray vals, BerVarray mods, int permissive,
const char **text, char *textbuf, size_t textlen );
LDAP_SLAPD_F( int ) modify_add_values( Entry *e,
Modification *mod,
+ int permissive,
const char **text, char *textbuf, size_t textlen );
LDAP_SLAPD_F( int ) modify_delete_values( Entry *e,
Modification *mod,
+ int permissive,
const char **text, char *textbuf, size_t textlen );
LDAP_SLAPD_F( int ) modify_replace_values( Entry *e,
Modification *mod,
+ int permissive,
const char **text, char *textbuf, size_t textlen );
LDAP_SLAPD_F( void ) slap_mod_free( Modification *mod, int freeit );
LDAP_SLAPD_F (int) is_entry_objectclass LDAP_P((
Entry *, ObjectClass *oc, int set_flags ));
#define is_entry_alias(e) \
- (((e)->e_ocflags & SLAP_OC__END) ? ((e)->e_ocflags & SLAP_OC_ALIAS) : \
- is_entry_objectclass((e), slap_schema.si_oc_alias, 1))
+ (((e)->e_ocflags & SLAP_OC__END) \
+ ? (((e)->e_ocflags & SLAP_OC_ALIAS) != 0) \
+ : is_entry_objectclass((e), slap_schema.si_oc_alias, 1))
#define is_entry_referral(e) \
- (((e)->e_ocflags & SLAP_OC__END) ? ((e)->e_ocflags & SLAP_OC_REFERRAL) : \
- is_entry_objectclass((e), slap_schema.si_oc_referral, 1))
+ (((e)->e_ocflags & SLAP_OC__END) \
+ ? (((e)->e_ocflags & SLAP_OC_REFERRAL) != 0) \
+ : is_entry_objectclass((e), slap_schema.si_oc_referral, 1))
#define is_entry_subentry(e) \
- (((e)->e_ocflags & SLAP_OC__END) ? ((e)->e_ocflags & SLAP_OC_SUBENTRY) : \
- is_entry_objectclass((e), slap_schema.si_oc_subentry, 1))
+ (((e)->e_ocflags & SLAP_OC__END) \
+ ? (((e)->e_ocflags & SLAP_OC_SUBENTRY) != 0) \
+ : is_entry_objectclass((e), slap_schema.si_oc_subentry, 1))
#define is_entry_collectiveAttributeSubentry(e) \
- (((e)->e_ocflags & SLAP_OC__END) ? ((e)->e_ocflags & SLAP_OC_COLLECTIVEATTRIBUTESUBENTRY) : \
- is_entry_objectclass((e), slap_schema.si_oc_collectiveAttributeSubentry, 1))
+ (((e)->e_ocflags & SLAP_OC__END) \
+ ? (((e)->e_ocflags & SLAP_OC_COLLECTIVEATTRIBUTESUBENTRY) != 0) \
+ : is_entry_objectclass((e), slap_schema.si_oc_collectiveAttributeSubentry, 1))
#define is_entry_dynamicObject(e) \
- (((e)->e_ocflags & SLAP_OC__END) ? ((e)->e_ocflags & SLAP_OC_DYNAMICOBJECT) : \
- is_entry_objectclass((e), slap_schema.si_oc_dynamicObject, 1))
+ (((e)->e_ocflags & SLAP_OC__END) \
+ ? (((e)->e_ocflags & SLAP_OC_DYNAMICOBJECT) != 0) \
+ : is_entry_objectclass((e), slap_schema.si_oc_dynamicObject, 1))
LDAP_SLAPD_F (int) oc_schema_info( Entry *e );
/*
* result.c
*/
-LDAP_SLAPD_F (void) send_ldap_result LDAP_P((
+LDAP_SLAPD_F (void) slap_send_ldap_result LDAP_P((
Connection *conn, Operation *op,
ber_int_t err, const char *matched, const char *text,
BerVarray refs,
Connection *conn, Operation *op,
ber_int_t err, const char *text ));
-LDAP_SLAPD_F (void) send_ldap_extended LDAP_P((
+LDAP_SLAPD_F (void) slap_send_ldap_extended LDAP_P((
+ Connection *conn, Operation *op,
+ ber_int_t err, const char *matched,
+ const char *text, BerVarray refs,
+ const char *rspoid, struct berval *rspdata,
+ LDAPControl **ctrls ));
+
+LDAP_SLAPD_F (void) slap_send_ldap_intermediate_resp LDAP_P((
Connection *conn, Operation *op,
ber_int_t err, const char *matched,
const char *text, BerVarray refs,
const char *rspoid, struct berval *rspdata,
LDAPControl **ctrls ));
-LDAP_SLAPD_F (void) send_search_result LDAP_P((
+LDAP_SLAPD_F (void) slap_send_search_result LDAP_P((
Connection *conn, Operation *op,
ber_int_t err, const char *matched, const char *text,
BerVarray refs,
LDAPControl **ctrls,
int nentries ));
-LDAP_SLAPD_F (int) send_search_reference LDAP_P((
+LDAP_SLAPD_F (int) slap_send_search_reference LDAP_P((
Backend *be, Connection *conn, Operation *op,
Entry *e, BerVarray refs,
LDAPControl **ctrls,
BerVarray *v2refs ));
-LDAP_SLAPD_F (int) send_search_entry LDAP_P((
+LDAP_SLAPD_F (int) slap_send_search_entry LDAP_P((
Backend *be, Connection *conn, Operation *op,
Entry *e, AttributeName *attrs, int attrsonly,
LDAPControl **ctrls ));
const char *fname,
int lineno );
+LDAP_SLAPD_F (int) slap_sasl_getdn( Connection *conn,
+ char *id, int len,
+ char *user_realm, struct berval *dn, int flags );
/*
* saslauthz.c
LDAP_SLAPD_F (int) slap_sasl_setpolicy LDAP_P(( const char * ));
LDAP_SLAPD_F (slap_response) slap_cb_null_response;
LDAP_SLAPD_F (slap_sresult) slap_cb_null_sresult;
+LDAP_SLAPD_F (slap_sendreference) slap_cb_null_sreference;
/*
/* result.c - routines to send ldap results, errors, and referrals */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include <ac/unistd.h>
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
static char *v2ref( BerVarray ref, const char *text )
{
return;
}
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp)
+ ber = op->o_res_ber;
+ else
+#endif
+
ber_init_w_nullc( ber, LBER_USE_DER );
#ifdef NEW_LOGGING
}
#ifdef LDAP_CONNECTIONLESS
- if( conn->c_is_udp ) {
- rc = ber_write(ber,
- (char *)&op->o_peeraddr, sizeof(struct sockaddr), 0);
- if (rc != sizeof(struct sockaddr)) {
-#ifdef NEW_LOGGING
- LDAP_LOG( OPERATION, ERR,
- "send_ldap_response: conn %lu ber_write failed\n",
- conn ? conn->c_connid : 0 , 0, 0);
-#else
- Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
-#endif
- ber_free_buf( ber );
- return;
- }
- }
- if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2) {
- rc = ber_printf( ber, "{is{t{ess" /*"}}}"*/,
- msgid, "", tag, err,
+ if (conn->c_is_udp && conn->c_protocol == LDAP_VERSION2) {
+ rc = ber_printf( ber, "t{ess" /*"}}"*/,
+ tag, err,
matched == NULL ? "" : matched,
text == NULL ? "" : text );
- } else
+ } else
#endif
{
rc = ber_printf( ber, "{it{ess" /*"}}"*/,
rc = ber_printf( ber, /*"{"*/ "N}" );
}
-#ifdef LDAP_CONNECTIONLESS
- if( conn->c_is_udp && op->o_protocol == LDAP_VERSION2 && rc != -1 ) {
- rc = ber_printf( ber, /*"{"*/ "N}" );
- }
-#endif
-
if ( rc == -1 ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
#endif
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
+#endif
ber_free_buf( ber );
return;
}
/* send BER */
bytes = send_ldap_ber( conn, ber );
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
+#endif
ber_free_buf( ber );
if ( bytes < 0 ) {
return;
}
+#ifdef LDAP_SLAPI
+ slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE, (void *)err );
+ slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED, ( matched != NULL ) ? (void *)ch_strdup( matched ) : NULL );
+ slapi_pblock_set( op->o_pb, SLAPI_RESULT_TEXT, ( text != NULL ) ? (void *)ch_strdup( text ) : NULL );
+#endif /* LDAP_SLAPI */
+
ldap_pvt_thread_mutex_lock( &num_sent_mutex );
num_bytes_sent += bytes;
num_pdu_sent++;
}
void
-send_ldap_result(
+slap_send_ldap_result(
Connection *conn,
Operation *op,
ber_int_t err,
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ENTRY,
- "send_ldap_result : conn %lu op=%lu p=%d\n",
+ "send_ldap_result: conn %lu op=%lu p=%d\n",
op->o_connid, op->o_opid, op->o_protocol );
#else
Debug( LDAP_DEBUG_TRACE,
assert( err != LDAP_PARTIAL_RESULTS );
if ( err == LDAP_REFERRAL ) {
+#ifdef LDAP_CONTROL_NOREFERRALS
+ if( op->o_noreferrals ) {
+ ref = NULL;
+ }
+#endif
if( ref == NULL ) {
err = LDAP_NO_SUCH_OBJECT;
} else if ( op->o_protocol < LDAP_VERSION3 ) {
}
void
-send_ldap_extended(
+slap_send_ldap_extended(
Connection *conn,
Operation *op,
ber_int_t err,
rspdata != NULL ? rspdata->bv_len : 0 );
#else
Debug( LDAP_DEBUG_TRACE,
- "send_ldap_extended err=%d oid=%s len=%ld\n",
+ "send_ldap_extended: err=%d oid=%s len=%ld\n",
err,
rspoid ? rspoid : "",
rspdata != NULL ? rspdata->bv_len : 0 );
#endif
-
tag = req2res( op->o_tag );
msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
rspoid, rspdata, NULL, ctrls );
}
+#ifdef LDAP_RES_INTERMEDIATE_RESP
+void
+slap_send_ldap_intermediate_resp(
+ Connection *conn,
+ Operation *op,
+ ber_int_t err,
+ const char *matched,
+ const char *text,
+ BerVarray refs,
+ const char *rspoid,
+ struct berval *rspdata,
+ LDAPControl **ctrls )
+{
+ ber_tag_t tag;
+ ber_int_t msgid;
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, ENTRY,
+ "send_ldap_intermediate: err=%d oid=%s len=%ld\n",
+ err, rspoid ? rspoid : "",
+ rspdata != NULL ? rspdata->bv_len : 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "send_ldap_intermediate: err=%d oid=%s len=%ld\n",
+ err,
+ rspoid ? rspoid : "",
+ rspdata != NULL ? rspdata->bv_len : 0 );
+#endif
+ tag = LDAP_RES_INTERMEDIATE_RESP;
+ msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
+ send_ldap_response( conn, op, tag, msgid,
+ err, matched, text, refs,
+ rspoid, rspdata, NULL, ctrls );
+}
+#endif
void
-send_search_result(
+slap_send_search_result(
Connection *conn,
Operation *op,
ber_int_t err,
}
int
-send_search_entry(
+slap_send_search_entry(
Backend *be,
Connection *conn,
Operation *op,
char *edn;
int userattrs;
int opattrs;
- static AccessControlState acl_state_init = ACL_STATE_INIT;
- AccessControlState acl_state;
+ AccessControlState acl_state = ACL_STATE_INIT;
+#ifdef LDAP_SLAPI
+ /* Support for computed attribute plugins */
+ computed_attr_context ctx;
+ AttributeName *anp;
+#endif
AttributeDescription *ad_entry = slap_schema.si_ad_entry;
edn = e->e_ndn;
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp)
+ ber = op->o_res_ber;
+ else
+#endif
ber_init_w_nullc( ber, LBER_USE_DER );
#ifdef LDAP_CONNECTIONLESS
- if (conn->c_is_udp) {
- rc = ber_write(ber,
- (char *)&op->o_peeraddr, sizeof(struct sockaddr), 0);
- if (rc != sizeof(struct sockaddr)) {
-#ifdef NEW_LOGGING
- LDAP_LOG( OPERATION, ERR,
- "send_search_entry: conn %lu ber_write failed\n",
- conn ? conn->c_connid : 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
-#endif
- ber_free_buf( ber );
- return( 1 );
- }
- }
- if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2) {
- rc = ber_printf( ber, "{is{t{O{" /*}}}*/,
- op->o_msgid, "", LDAP_RES_SEARCH_ENTRY, &e->e_name );
+ if (conn->c_is_udp && conn->c_protocol == LDAP_VERSION2) {
+ rc = ber_printf(ber, "t{0{" /*}}*/,
+ LDAP_RES_SEARCH_ENTRY, &e->e_name);
} else
-#endif /* LDAP_CONNECTIONLESS */
+#endif
{
rc = ber_printf( ber, "{it{O{" /*}}}*/, op->o_msgid,
LDAP_RES_SEARCH_ENTRY, &e->e_name );
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
#endif
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
+#endif
ber_free_buf( ber );
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "encoding DN error", NULL, NULL );
#else
Debug( LDAP_DEBUG_ANY,
"matched values filtering failed\n", 0, 0, 0 );
+#endif
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
#endif
ber_free( ber, 1 );
}
}
- acl_state = acl_state_init;
-
if ( ! access_allowed( be, conn, op, e, desc, NULL,
ACL_READ, &acl_state ) )
{
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
#endif
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
+#endif
ber_free_buf( ber );
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "encoding description error", NULL, NULL );
"ber_printf failed\n", 0, 0, 0 );
#endif
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
+#endif
ber_free_buf( ber );
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "encoding values error",
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
#endif
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
+#endif
ber_free_buf( ber );
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "encode end error", NULL, NULL );
#else
Debug( LDAP_DEBUG_ANY,
"matched values filtering failed\n", 0, 0, 0 );
+#endif
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
#endif
ber_free( ber, 1 );
}
}
- acl_state = acl_state_init;
-
if ( ! access_allowed( be, conn, op, e, desc, NULL,
ACL_READ, &acl_state ) )
{
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
#endif
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
+#endif
ber_free_buf( ber );
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "encoding description error", NULL, NULL );
"ber_printf failed\n", 0, 0, 0 );
#endif
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
+#endif
ber_free_buf( ber );
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "encoding values error",
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
#endif
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
+#endif
ber_free_buf( ber );
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "encode end error", NULL, NULL );
}
}
+#ifdef LDAP_SLAPI
+ /*
+ * First, setup the computed attribute context that is
+ * passed to all plugins.
+ */
+ ctx.cac_pb = op->o_pb;
+ ctx.cac_attrs = attrs;
+ ctx.cac_attrsonly = attrsonly;
+ ctx.cac_userattrs = userattrs;
+ ctx.cac_opattrs = opattrs;
+ ctx.cac_acl_state = acl_state;
+ ctx.cac_private = (void *)ber;
+
+ /*
+ * For each client requested attribute, call the plugins.
+ */
+ if ( attrs != NULL ) {
+ for ( anp = attrs; anp->an_name.bv_val != NULL; anp++ ) {
+ rc = compute_evaluator( &ctx, anp->an_name.bv_val, e, slapi_x_compute_output_ber );
+ if ( rc == 1 ) {
+ break;
+ }
+ }
+ } else {
+ /*
+ * Technically we shouldn't be returning operational attributes
+ * when the user requested only user attributes. We'll let the
+ * plugin decide whether to be naughty or not.
+ */
+ rc = compute_evaluator( &ctx, "*", e, slapi_x_compute_output_ber );
+ }
+ if ( rc == 1 ) {
+ ber_free_buf( ber );
+ send_ldap_result( conn, op, LDAP_OTHER,
+ NULL, "computed attribute error", NULL, NULL );
+ goto error_return;
+ }
+#endif /* LDAP_SLAPI */
+
/* free e_flags */
if ( e_flags ) {
free( e_flags );
rc = ber_printf( ber, /*{*/ "N}" );
}
-#ifdef LDAP_CONNECTIONLESS
- if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2 && rc != -1) {
- rc = ber_printf( ber, "}" );
- }
-#endif
if ( rc == -1 ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
#endif
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
+#endif
ber_free_buf( ber );
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "encode entry end error", NULL, NULL );
return( 1 );
}
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0) {
+#endif
bytes = op->o_noop ? 0 : send_ldap_ber( conn, ber );
ber_free_buf( ber );
num_pdu_sent++;
ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
+#ifdef LDAP_CONNECTIONLESS
+ }
+#endif
+
Statslog( LDAP_DEBUG_STATS2, "conn=%lu op=%lu ENTRY dn=\"%s\"\n",
conn->c_connid, op->o_opid, e->e_dn, 0, 0 );
}
int
-send_search_reference(
+slap_send_search_reference(
Backend *be,
Connection *conn,
Operation *op,
AttributeDescription *ad_ref = slap_schema.si_ad_ref;
AttributeDescription *ad_entry = slap_schema.si_ad_entry;
+ if (op->o_callback && op->o_callback->sc_sendreference) {
+ return op->o_callback->sc_sendreference( be, conn, op, e, refs, ctrls, v2refs );
+ }
+
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ENTRY,
"send_search_reference: conn %lu dn=\"%s\"\n",
e ? e->e_dn : "(null)", 0, 0 );
#endif
-
if ( e && ! access_allowed( be, conn, op, e,
ad_entry, NULL, ACL_READ, NULL ) )
{
return( 1 );
}
+#ifdef LDAP_CONTROL_NOREFERRALS
+ if( op->o_noreferrals ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, ERR,
+ "send_search_reference: conn %lu noreferrals control in (%s).\n",
+ op->o_connid, e->e_dn, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "send_search_reference: noreferrals control in (%s)\n",
+ e->e_dn, 0, 0 );
+#endif
+
+ return( 0 );
+ }
+#endif
+
if( refs == NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ERR,
return 0;
}
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp)
+ ber = op->o_res_ber;
+ else
+#endif
ber_init_w_nullc( ber, LBER_USE_DER );
rc = ber_printf( ber, "{it{W}" /*"}"*/ , op->o_msgid,
"send_search_reference: ber_printf failed\n", 0, 0, 0 );
#endif
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0)
+#endif
ber_free_buf( ber );
send_ldap_result( conn, op, LDAP_OTHER,
NULL, "encode DN error", NULL, NULL );
return -1;
}
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp == 0) {
+#endif
bytes = op->o_noop ? 0 : send_ldap_ber( conn, ber );
ber_free_buf( ber );
num_refs_sent++;
num_pdu_sent++;
ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
+#ifdef LDAP_CONNECTIONLESS
+ }
+#endif
Statslog( LDAP_DEBUG_STATS2, "conn=%lu op=%lu REF dn=\"%s\"\n",
conn->c_connid, op->o_opid, e ? e->e_dn : "(null)", 0, 0 );
/* $OpenLDAP$ */
/* root_dse.c - Provides the ROOT DSA-Specific Entry
*
- * Copyright 1999-2002 The OpenLDAP Foundation.
+ * Copyright 1999-2003 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted only
#include "portable.h"
#include <stdio.h>
+
#include <ac/string.h>
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+#endif
#include <ldif.h>
#include "lber_pvt.h"
return LDAP_OTHER;
}
+#ifdef LDAP_SLAPI
+ /* netscape supportedExtension */
+ for ( i = 0; (bv = ns_get_supported_extop(i)) != NULL; i++ ) {
+ vals[0] = *bv;
+ attr_merge( e, ad_supportedExtension, vals );
+ }
+#endif /* LDAP_SLAPI */
+
/* supportedFeatures */
if( attr_merge( e, ad_supportedFeatures, supportedFeatures ) )
return LDAP_OTHER;
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "slap.h"
-#ifdef HAVE_CYRUS_SASL
#include <limits.h>
-#ifdef HAVE_SASL_SASL_H
-#include <sasl/sasl.h>
-#else
-#include <sasl.h>
-#endif
+#ifdef HAVE_CYRUS_SASL
+# ifdef HAVE_SASL_SASL_H
+# include <sasl/sasl.h>
+# else
+# include <sasl.h>
+# endif
+
+# if SASL_VERSION_MAJOR >= 2
+# include <sasl/saslplug.h>
+# define SASL_CONST const
+# else
+# define SASL_CONST
+# endif
-#include <lutil.h>
-#if SASL_VERSION_MAJOR >= 2
-#include <sasl/saslplug.h>
-#define SASL_CONST const
-#else
-#define SASL_CONST
-#endif
+static sasl_security_properties_t sasl_secprops;
+#endif /* HAVE_CYRUS_SASL */
#include "ldap_pvt.h"
#include "lber_pvt.h"
-
-/* Flags for telling slap_sasl_getdn() what type of identity is being passed */
-#define FLAG_GETDN_AUTHCID 2
-#define FLAG_GETDN_AUTHZID 4
-
-static sasl_security_properties_t sasl_secprops;
+#include <lutil.h>
int slap_sasl_config( int cargc, char **cargv, char *line,
const char *fname, int lineno )
if ( cargc != 2 ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: missing policy in \"sasl-authz-policy <policy>\" line\n",
- fname, lineno, 0 );
+ "%s: line %d: missing policy in"
+ " \"sasl-authz-policy <policy>\" line\n",
+ fname, lineno, 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing policy in \"sasl-authz-policy <policy>\" line\n",
+ "%s: line %d: missing policy in"
+ " \"sasl-authz-policy <policy>\" line\n",
fname, lineno, 0 );
#endif
#endif
return( 1 );
}
-
+ } else if ( !strcasecmp( cargv[0], "sasl-regexp" )
+ || !strcasecmp( cargv[0], "saslregexp" ) )
+ {
+ int rc;
+ if ( cargc != 3 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( CONFIG, CRIT,
+ "%s: line %d: need 2 args in "
+ "\"saslregexp <match> <replace>\"\n",
+ fname, lineno, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "%s: line %d: need 2 args in "
+ "\"saslregexp <match> <replace>\"\n",
+ fname, lineno, 0 );
+#endif
+
+ return( 1 );
+ }
+ rc = slap_sasl_regexp_config( cargv[1], cargv[2] );
+ if ( rc ) {
+ return rc;
+ }
+
+#ifdef HAVE_CYRUS_SASL
/* set SASL host */
} else if ( strcasecmp( cargv[0], "sasl-host" ) == 0 ) {
if ( cargc < 2 ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: missing host in \"sasl-host <host>\" line\n",
- fname, lineno, 0 );
+ "%s: line %d: missing host in \"sasl-host <host>\" line\n",
+ fname, lineno, 0 );
#else
Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing host in \"sasl-host <host>\" line\n",
+ "%s: line %d: missing host in \"sasl-host <host>\" line\n",
fname, lineno, 0 );
#endif
if ( global_host != NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: already set sasl-host!\n",
- fname, lineno, 0 );
+ "%s: line %d: already set sasl-host!\n",
+ fname, lineno, 0 );
#else
Debug( LDAP_DEBUG_ANY,
"%s: line %d: already set sasl-host!\n",
} else if ( strcasecmp( cargv[0], "sasl-realm" ) == 0 ) {
if ( cargc < 2 ) {
#ifdef NEW_LOGGING
- LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: missing realm in \"sasl-realm <realm>\" line.\n",
- fname, lineno, 0 );
+ LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
+ "missing realm in \"sasl-realm <realm>\" line.\n",
+ fname, lineno, 0 );
#else
- Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing realm in \"sasl-realm <realm>\" line\n",
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "missing realm in \"sasl-realm <realm>\" line.\n",
fname, lineno, 0 );
#endif
if ( global_realm != NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: already set sasl-realm!\n",
- fname, lineno, 0 );
+ "%s: line %d: already set sasl-realm!\n",
+ fname, lineno, 0 );
#else
Debug( LDAP_DEBUG_ANY,
"%s: line %d: already set sasl-realm!\n",
global_realm = ch_strdup( cargv[1] );
}
- } else if ( !strcasecmp( cargv[0], "sasl-regexp" )
- || !strcasecmp( cargv[0], "saslregexp" ) )
- {
- int rc;
- if ( cargc != 3 ) {
-#ifdef NEW_LOGGING
- LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: need 2 args in "
- "\"saslregexp <match> <replace>\"\n",
- fname, lineno, 0 );
-#else
- Debug( LDAP_DEBUG_ANY,
- "%s: line %d: need 2 args in \"saslregexp <match> <replace>\"\n",
- fname, lineno, 0 );
-#endif
-
- return( 1 );
- }
- rc = slap_sasl_regexp_config( cargv[1], cargv[2] );
- if ( rc ) {
- return rc;
- }
-
/* SASL security properties */
} else if ( strcasecmp( cargv[0], "sasl-secprops" ) == 0 ) {
char *txt;
if ( cargc < 2 ) {
#ifdef NEW_LOGGING
- LDAP_LOG( CONFIG, CRIT,
- "%s: line %d: missing flags in "
- "\"sasl-secprops <properties>\" line\n",
- fname, lineno, 0 );
+ LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
+ "missing flags in \"sasl-secprops <properties>\" line\n",
+ fname, lineno, 0 );
#else
- Debug( LDAP_DEBUG_ANY,
- "%s: line %d: missing flags in \"sasl-secprops <properties>\" line\n",
+ Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+ "missing flags in \"sasl-secprops <properties>\" line\n",
fname, lineno, 0 );
#endif
if ( txt != NULL ) {
#ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT,
- "%s: line %d sasl-secprops: %s\n",
- fname, lineno, txt );
+ "%s: line %d sasl-secprops: %s\n",
+ fname, lineno, txt );
#else
Debug( LDAP_DEBUG_ANY,
- "%s: line %d: sasl-secprops: %s\n",
+ "%s: line %d: sasl-secprops: %s\n",
fname, lineno, txt );
#endif
return 1;
}
+#endif /* HAVE_CYRUS_SASL */
}
return LDAP_SUCCESS;
}
-static int
+#ifdef HAVE_CYRUS_SASL
+
+int
slap_sasl_log(
void *context,
int priority,
}
-/* Take any sort of identity string and return a DN with the "dn:" prefix. The
- string returned in *dn is in its own allocated memory, and must be free'd
- by the calling process.
- -Mark Adamson, Carnegie Mellon
-
- The "dn:" prefix is no longer used anywhere inside slapd. It is only used
- on strings passed in directly from SASL.
- -Howard Chu, Symas Corp.
-*/
-
-#define SET_DN 1
-#define SET_U 2
-
-static struct berval ext_bv = BER_BVC( "EXTERNAL" );
-
-int slap_sasl_getdn( Connection *conn, char *id, int len,
- char *user_realm, struct berval *dn, int flags )
-{
- char *c1;
- int rc, is_dn = 0, do_norm = 1;
- sasl_conn_t *ctx;
- struct berval dn2;
-
-#ifdef NEW_LOGGING
- LDAP_LOG( TRANSPORT, ENTRY,
- "slap_sasl_getdn: conn %d id=%s\n",
- conn ? conn->c_connid : -1, id ? (*id ? id : "<empty>") : "NULL", 0 );
-#else
- Debug( LDAP_DEBUG_ARGS, "slap_sasl_getdn: id=%s\n",
- id?(*id?id:"<empty>"):"NULL",0,0 );
-#endif
-
- dn->bv_val = NULL;
- dn->bv_len = 0;
-
- if ( id ) {
- if ( len == 0 ) len = strlen( id );
-
- /* Blatantly anonymous ID */
- if ( len == sizeof("anonymous") - 1 &&
- !strcasecmp( id, "anonymous" ) ) {
- return( LDAP_SUCCESS );
- }
- } else {
- len = 0;
- }
-
- ctx = conn->c_sasl_context;
-
- /* An authcID needs to be converted to authzID form. Set the
- * values directly into *dn; they will be normalized later. (and
- * normalizing always makes a new copy.) An ID from a TLS certificate
- * is already normalized, so copy it and skip normalization.
- */
- if( flags & FLAG_GETDN_AUTHCID ) {
-#ifdef HAVE_TLS
- if( conn->c_is_tls &&
- conn->c_sasl_bind_mech.bv_len == ext_bv.bv_len &&
- strcasecmp( ext_bv.bv_val, conn->c_sasl_bind_mech.bv_val ) == 0 )
- {
- /* X.509 DN is already normalized */
- do_norm = 0;
- is_dn = SET_DN;
- ber_str2bv( id, len, 1, dn );
-
- } else
-#endif
- {
- /* convert to u:<username> form */
- is_dn = SET_U;
- dn->bv_val = id;
- dn->bv_len = len;
- }
- }
- if( !is_dn ) {
- if( !strncasecmp( id, "u:", sizeof("u:")-1 )) {
- is_dn = SET_U;
- dn->bv_val = id+2;
- dn->bv_len = len-2;
- } else if ( !strncasecmp( id, "dn:", sizeof("dn:")-1) ) {
- is_dn = SET_DN;
- dn->bv_val = id+3;
- dn->bv_len = len-3;
- }
- }
-
- /* No other possibilities from here */
- if( !is_dn ) {
- dn->bv_val = NULL;
- dn->bv_len = 0;
- return( LDAP_INAPPROPRIATE_AUTH );
- }
-
- /* Username strings */
- if( is_dn == SET_U ) {
- char *p, *realm;
- len = dn->bv_len + sizeof("uid=")-1 + sizeof(",cn=auth")-1;
-
- /* username may have embedded realm name */
- if( ( realm = strchr( dn->bv_val, '@') ) ) {
- *realm++ = '\0';
- len += sizeof(",cn=")-2;
- } else if( user_realm && *user_realm ) {
- len += strlen( user_realm ) + sizeof(",cn=")-1;
- }
-
- if( conn->c_sasl_bind_mech.bv_len ) {
- len += conn->c_sasl_bind_mech.bv_len + sizeof(",cn=")-1;
- }
-
- /* Build the new dn */
- c1 = dn->bv_val;
- dn->bv_val = SLAP_MALLOC( len+1 );
- if( dn->bv_val == NULL ) {
-#ifdef NEW_LOGGING
- LDAP_LOG( TRANSPORT, ERR,
- "slap_sasl_getdn: SLAP_MALLOC failed", 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_ANY,
- "slap_sasl_getdn: SLAP_MALLOC failed", 0, 0, 0 );
-#endif
- return LDAP_OTHER;
- }
- p = lutil_strcopy( dn->bv_val, "uid=" );
- p = lutil_strncopy( p, c1, dn->bv_len );
-
- if( realm ) {
- int rlen = dn->bv_len - ( realm - c1 );
- p = lutil_strcopy( p, ",cn=" );
- p = lutil_strncopy( p, realm, rlen );
- realm[-1] = '@';
- } else if( user_realm && *user_realm ) {
- p = lutil_strcopy( p, ",cn=" );
- p = lutil_strcopy( p, user_realm );
- }
-
- if( conn->c_sasl_bind_mech.bv_len ) {
- p = lutil_strcopy( p, ",cn=" );
- p = lutil_strcopy( p, conn->c_sasl_bind_mech.bv_val );
- }
- p = lutil_strcopy( p, ",cn=auth" );
- dn->bv_len = p - dn->bv_val;
-
-#ifdef NEW_LOGGING
- LDAP_LOG( TRANSPORT, ENTRY,
- "slap_sasl_getdn: u:id converted to %s.\n", dn->bv_val, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE, "getdn: u:id converted to %s\n", dn->bv_val,0,0 );
-#endif
- }
-
- /* All strings are in DN form now. Normalize if needed. */
- if ( do_norm ) {
- rc = dnNormalize2( NULL, dn, &dn2 );
-
- /* User DNs were constructed above and must be freed now */
- if ( is_dn == SET_U )
- ch_free( dn->bv_val );
-
- if ( rc != LDAP_SUCCESS ) {
- dn->bv_val = NULL;
- dn->bv_len = 0;
- return rc;
- }
- *dn = dn2;
- }
-
- /* Run thru regexp */
- slap_sasl2dn( conn, dn, &dn2 );
- if( dn2.bv_val ) {
- ch_free( dn->bv_val );
- *dn = dn2;
-#ifdef NEW_LOGGING
- LDAP_LOG( TRANSPORT, ENTRY,
- "slap_sasl_getdn: dn:id converted to %s.\n", dn->bv_val, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE, "getdn: dn:id converted to %s\n",
- dn->bv_val, 0, 0 );
-#endif
- }
-
- return( LDAP_SUCCESS );
-}
-
#if SASL_VERSION_MAJOR >= 2
static const char *slap_propnames[] = {
"*slapConn", "*authcDN", "*authzDN", NULL };
Backend *be;
Operation op = {0};
slap_callback cb = { slap_cb_null_response,
- slap_cb_null_sresult, sasl_ap_lookup, NULL };
+ slap_cb_null_sresult, sasl_ap_lookup, slap_cb_null_sreference, NULL };
cb.sc_private = &sl;
*/
rc = slap_sasl_getdn( conn, (char *)username, 0, NULL, &dn,
- FLAG_GETDN_AUTHCID );
+ SLAP_GETDN_AUTHCID );
if ( rc != LDAP_SUCCESS ) {
sasl_seterror( sconn, 0, ldap_err2string( rc ) );
return SASL_NOUSER;
if ( be && be->be_search ) {
Operation op = {0};
slap_callback cb = { slap_cb_null_response,
- slap_cb_null_sresult, sasl_cb_checkpass, NULL };
+ slap_cb_null_sresult, sasl_cb_checkpass, slap_cb_null_sreference, NULL };
ci.cred.bv_val = (char *)pass;
ci.cred.bv_len = passlen;
LDAP_LOG( TRANSPORT, ENTRY,
"slap_sasl_canonicalize: conn %d %s=\"%s\"\n",
conn ? conn->c_connid : -1,
- (flags & SASL_CU_AUTHID) ? "authcid" : "authzid", in ? in : "<empty>");
+ (flags & SASL_CU_AUTHID) ? "authcid" : "authzid",
+ in ? in : "<empty>");
#else
- Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: "
- "%s=\"%s\"\n",
- conn ? conn->c_connid : -1,
- (flags & SASL_CU_AUTHID) ? "authcid" : "authzid",
- in ? in : "<empty>" );
+ Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: %s=\"%s\"\n",
+ conn ? conn->c_connid : -1,
+ (flags & SASL_CU_AUTHID) ? "authcid" : "authzid",
+ in ? in : "<empty>");
#endif
/* If name is too big, just truncate. We don't care, we're
}
rc = slap_sasl_getdn( conn, (char *)in, inlen, (char *)user_realm, &dn,
- (flags & SASL_CU_AUTHID) ? FLAG_GETDN_AUTHCID : FLAG_GETDN_AUTHZID );
+ (flags & SASL_CU_AUTHID) ? SLAP_GETDN_AUTHCID : SLAP_GETDN_AUTHZID );
if ( rc != LDAP_SUCCESS ) {
sasl_seterror( sconn, 0, ldap_err2string( rc ) );
return SASL_NOAUTHZ;
#ifdef NEW_LOGGING
LDAP_LOG( TRANSPORT, ENTRY,
"slap_sasl_canonicalize: conn %d %s=\"%s\"\n",
- conn ? conn->c_connid : -1, names[0]+1, dn.bv_val );
+ conn ? conn->c_connid : -1, names[0]+1,
+ dn.bv_val ? dn.bv_val : "<EMPTY>" );
#else
- Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: "
- "%s=\"%s\"\n",
- conn ? conn->c_connid : -1,
- names[0]+1, dn.bv_val );
+ Debug( LDAP_DEBUG_ARGS, "SASL Canonicalize [conn=%ld]: %s=\"%s\"\n",
+ conn ? conn->c_connid : -1, names[0]+1,
+ dn.bv_val ? dn.bv_val : "<EMPTY>" );
#endif
-done: AC_MEMCPY( out, in, inlen );
+
+done:
+ AC_MEMCPY( out, in, inlen );
out[inlen] = '\0';
*out_len = inlen;
/* Convert the identities to DN's. If no authzid was given, client will
be bound as the DN matching their username */
- rc = slap_sasl_getdn( conn, (char *)authcid, 0, realm, &authcDN, FLAG_GETDN_AUTHCID );
+ rc = slap_sasl_getdn( conn, (char *)authcid, 0, realm,
+ &authcDN, SLAP_GETDN_AUTHCID );
if( rc != LDAP_SUCCESS ) {
*errstr = ldap_err2string( rc );
return SASL_NOAUTHZ;
conn->c_sasl_dn = authcDN;
goto ok;
}
- rc = slap_sasl_getdn( conn, (char *)authzid, 0, realm, &authzDN, FLAG_GETDN_AUTHZID );
+ rc = slap_sasl_getdn( conn, (char *)authzid, 0, realm,
+ &authzDN, SLAP_GETDN_AUTHZID );
if( rc != LDAP_SUCCESS ) {
ch_free( authcDN.bv_val );
*errstr = ldap_err2string( rc );
}
#endif
-
int slap_sasl_init( void )
{
#ifdef HAVE_CYRUS_SASL
done:
return rc;
}
+#endif /* HAVE_CYRUS_SASL */
+
+/* Take any sort of identity string and return a DN with the "dn:" prefix. The
+ string returned in *dn is in its own allocated memory, and must be free'd
+ by the calling process.
+ -Mark Adamson, Carnegie Mellon
+
+ The "dn:" prefix is no longer used anywhere inside slapd. It is only used
+ on strings passed in directly from SASL.
+ -Howard Chu, Symas Corp.
+*/
+
+#define SET_NONE 0
+#define SET_DN 1
+#define SET_U 2
+
+static struct berval ext_bv = BER_BVC( "EXTERNAL" );
+
+int slap_sasl_getdn( Connection *conn, char *id, int len,
+ char *user_realm, struct berval *dn, int flags )
+{
+ char *c1;
+ int rc, is_dn = SET_NONE, do_norm = 1;
+ struct berval dn2;
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( TRANSPORT, ENTRY,
+ "slap_sasl_getdn: conn %d id=%s [len=%d]\n",
+ conn ? conn->c_connid : -1, id ? (*id ? id : "<empty>") : "NULL", len );
+#else
+ Debug( LDAP_DEBUG_ARGS, "slap_sasl_getdn: id=%s [len=%d]\n",
+ id ? ( *id ? id : "<empty>" ) : "NULL", len, 0 );
#endif
+
+ dn->bv_val = NULL;
+ dn->bv_len = 0;
+
+ if ( id ) {
+ if ( len == 0 ) len = strlen( id );
+
+ /* Blatantly anonymous ID */
+ if ( len == sizeof("anonymous") - 1 &&
+ !strcasecmp( id, "anonymous" ) ) {
+ return( LDAP_SUCCESS );
+ }
+ } else {
+ len = 0;
+ }
+
+ /* An authcID needs to be converted to authzID form. Set the
+ * values directly into *dn; they will be normalized later. (and
+ * normalizing always makes a new copy.) An ID from a TLS certificate
+ * is already normalized, so copy it and skip normalization.
+ */
+ if( flags & SLAP_GETDN_AUTHCID ) {
+ if( conn->c_sasl_bind_mech.bv_len == ext_bv.bv_len &&
+ strcasecmp( ext_bv.bv_val, conn->c_sasl_bind_mech.bv_val ) == 0 )
+ {
+ /* EXTERNAL DNs are already normalized */
+ do_norm = 0;
+ is_dn = SET_DN;
+ ber_str2bv( id, len, 1, dn );
+
+ } else {
+ /* convert to u:<username> form */
+ is_dn = SET_U;
+ dn->bv_val = id;
+ dn->bv_len = len;
+ }
+ }
+ if( is_dn == SET_NONE ) {
+ if( !strncasecmp( id, "u:", sizeof("u:")-1 )) {
+ is_dn = SET_U;
+ dn->bv_val = id+2;
+ dn->bv_len = len-2;
+ } else if ( !strncasecmp( id, "dn:", sizeof("dn:")-1) ) {
+ is_dn = SET_DN;
+ dn->bv_val = id+3;
+ dn->bv_len = len-3;
+ }
+ }
+
+ /* No other possibilities from here */
+ if( is_dn == SET_NONE ) {
+ dn->bv_val = NULL;
+ dn->bv_len = 0;
+ return( LDAP_INAPPROPRIATE_AUTH );
+ }
+
+ /* Username strings */
+ if( is_dn == SET_U ) {
+ char *p, *realm;
+ len = dn->bv_len + sizeof("uid=")-1 + sizeof(",cn=auth")-1;
+
+ /* username may have embedded realm name */
+ if( ( realm = strchr( dn->bv_val, '@') ) ) {
+ *realm++ = '\0';
+ len += sizeof(",cn=")-2;
+ } else if( user_realm && *user_realm ) {
+ len += strlen( user_realm ) + sizeof(",cn=")-1;
+ }
+
+ if( conn->c_sasl_bind_mech.bv_len ) {
+ len += conn->c_sasl_bind_mech.bv_len + sizeof(",cn=")-1;
+ }
+
+ /* Build the new dn */
+ c1 = dn->bv_val;
+ dn->bv_val = SLAP_MALLOC( len+1 );
+ if( dn->bv_val == NULL ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( TRANSPORT, ERR,
+ "slap_sasl_getdn: SLAP_MALLOC failed", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "slap_sasl_getdn: SLAP_MALLOC failed", 0, 0, 0 );
+#endif
+ return LDAP_OTHER;
+ }
+ p = lutil_strcopy( dn->bv_val, "uid=" );
+ p = lutil_strncopy( p, c1, dn->bv_len );
+
+ if( realm ) {
+ int rlen = dn->bv_len - ( realm - c1 );
+ p = lutil_strcopy( p, ",cn=" );
+ p = lutil_strncopy( p, realm, rlen );
+ realm[-1] = '@';
+ } else if( user_realm && *user_realm ) {
+ p = lutil_strcopy( p, ",cn=" );
+ p = lutil_strcopy( p, user_realm );
+ }
+
+ if( conn->c_sasl_bind_mech.bv_len ) {
+ p = lutil_strcopy( p, ",cn=" );
+ p = lutil_strcopy( p, conn->c_sasl_bind_mech.bv_val );
+ }
+ p = lutil_strcopy( p, ",cn=auth" );
+ dn->bv_len = p - dn->bv_val;
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( TRANSPORT, ENTRY,
+ "slap_sasl_getdn: u:id converted to %s.\n", dn->bv_val, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "getdn: u:id converted to %s\n", dn->bv_val,0,0 );
+#endif
+ } else {
+
+ /* Dup the DN in any case, so we don't risk
+ * leaks or dangling pointers later,
+ * and the DN value is '\0' terminated */
+ ber_dupbv( &dn2, dn );
+ dn->bv_val = dn2.bv_val;
+ }
+
+ /* All strings are in DN form now. Normalize if needed. */
+ if ( do_norm ) {
+ rc = dnNormalize2( NULL, dn, &dn2 );
+
+ /* User DNs were constructed above and must be freed now */
+ ch_free( dn->bv_val );
+
+ if ( rc != LDAP_SUCCESS ) {
+ dn->bv_val = NULL;
+ dn->bv_len = 0;
+ return rc;
+ }
+ *dn = dn2;
+ }
+
+ /* Run thru regexp */
+ slap_sasl2dn( conn, dn, &dn2 );
+ if( dn2.bv_val ) {
+ ch_free( dn->bv_val );
+ *dn = dn2;
+#ifdef NEW_LOGGING
+ LDAP_LOG( TRANSPORT, ENTRY,
+ "slap_sasl_getdn: dn:id converted to %s.\n", dn->bv_val, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "getdn: dn:id converted to %s\n",
+ dn->bv_val, 0, 0 );
+#endif
+ }
+
+ return( LDAP_SUCCESS );
+}
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/*
#include "slap.h"
-#ifdef HAVE_CYRUS_SASL
#include <limits.h>
-#ifdef HAVE_SASL_SASL_H
-#include <sasl/sasl.h>
-#else
-#include <sasl.h>
-#endif
-
#include <ldap_pvt.h>
#define SASLREGEX_REPLACE 10
{
}
+int slap_cb_null_sreference( BackendDB *db, Connection *conn, Operation *o,
+ Entry *e, BerVarray r, LDAPControl **c, BerVarray *v2)
+{
+ return 0;
+}
+
/* This callback actually does some work...*/
static int sasl_sc_sasl2dn( BackendDB *be, Connection *conn, Operation *o,
Entry *e, AttributeName *an, int ao, LDAPControl **c)
ndn->bv_val = NULL;
#ifdef NEW_LOGGING
- LDAP_LOG( TRANSPORT, DETAIL1,
- "slap_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
+ LDAP_LOG( TRANSPORT, DETAIL1,
+ "slap_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"slap_sasl2dn: search DN returned more than 1 entry\n", 0,0,0 );
return 0;
}
-/*
- * Given a SASL name (e.g. "UID=name,cn=REALM,cn=MECH,cn=AUTH")
- * return the LDAP DN to which it matches. The SASL regexp rules in the config
- * file turn the SASL name into an LDAP URI. If the URI is just a DN (or a
- * search with scope=base), just return the URI (or its searchbase). Otherwise
- * an internal search must be done, and if that search returns exactly one
- * entry, return the DN of that one entry.
- */
-
-void slap_sasl2dn( Connection *conn,
- struct berval *saslname, struct berval *sasldn )
-{
- int rc;
- Backend *be = NULL;
- struct berval dn = { 0, NULL };
- int scope = LDAP_SCOPE_BASE;
- Filter *filter = NULL;
- slap_callback cb = {slap_cb_null_response, slap_cb_null_sresult, sasl_sc_sasl2dn, NULL};
- Operation op = {0};
- struct berval regout = { 0, NULL };
-
-#ifdef NEW_LOGGING
- LDAP_LOG( TRANSPORT, ENTRY,
- "slap_sasl2dn: converting SASL name %s to DN.\n",
- saslname->bv_val, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE, "==>slap_sasl2dn: "
- "converting SASL name %s to a DN\n",
- saslname->bv_val, 0,0 );
-#endif
-
- sasldn->bv_val = NULL;
- sasldn->bv_len = 0;
- cb.sc_private = sasldn;
-
- /* Convert the SASL name into a minimal URI */
- if( !slap_sasl_regexp( saslname, ®out ) ) {
- goto FINISHED;
- }
-
- rc = slap_parseURI( ®out, &dn, &scope, &filter );
- if( regout.bv_val ) ch_free( regout.bv_val );
- if( rc != LDAP_SUCCESS ) {
- goto FINISHED;
- }
-
- /* Must do an internal search */
- be = select_backend( &dn, 0, 1 );
-
- /* Massive shortcut: search scope == base */
- if( scope == LDAP_SCOPE_BASE ) {
- *sasldn = dn;
- dn.bv_len = 0;
- dn.bv_val = NULL;
- goto FINISHED;
- }
-
-#ifdef NEW_LOGGING
- LDAP_LOG( TRANSPORT, DETAIL1,
- "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
- dn.bv_val, scope, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE,
- "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
- dn.bv_val, scope, 0 );
-#endif
-
- if(( be == NULL ) || ( be->be_search == NULL)) {
- goto FINISHED;
- }
- suffix_alias( be, &dn );
-
- op.o_tag = LDAP_REQ_SEARCH;
- op.o_protocol = LDAP_VERSION3;
- op.o_ndn = *saslname;
- op.o_callback = &cb;
- op.o_time = slap_get_time();
- op.o_do_not_cache = 1;
- op.o_threadctx = conn->c_sasl_bindop->o_threadctx;
-
- (*be->be_search)( be, conn, &op, NULL, &dn,
- scope, LDAP_DEREF_NEVER, 1, 0,
- filter, NULL, NULL, 1 );
-
-FINISHED:
- if( sasldn->bv_len ) {
- conn->c_authz_backend = be;
- }
- if( dn.bv_len ) ch_free( dn.bv_val );
- if( filter ) filter_free( filter );
-
-#ifdef NEW_LOGGING
- LDAP_LOG( TRANSPORT, ENTRY,
- "slap_sasl2dn: Converted SASL name to %s\n",
- sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE, "<==slap_sasl2dn: Converted SASL name to %s\n",
- sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
-#endif
-
- return;
-}
typedef struct smatch_info {
struct berval *dn;
Filter *filter=NULL;
regex_t reg;
smatch_info sm;
- slap_callback cb = { slap_cb_null_response, slap_cb_null_sresult, sasl_sc_smatch, NULL };
+ slap_callback cb = {
+ slap_cb_null_response,
+ slap_cb_null_sresult,
+ sasl_sc_smatch,
+ NULL
+ };
Operation op = {0};
#ifdef NEW_LOGGING
return( rc );
}
-#endif /* HAVE_CYRUS_SASL */
+
+/*
+ * Given a SASL name (e.g. "UID=name,cn=REALM,cn=MECH,cn=AUTH")
+ * return the LDAP DN to which it matches. The SASL regexp rules in the config
+ * file turn the SASL name into an LDAP URI. If the URI is just a DN (or a
+ * search with scope=base), just return the URI (or its searchbase). Otherwise
+ * an internal search must be done, and if that search returns exactly one
+ * entry, return the DN of that one entry.
+ */
+void slap_sasl2dn( Connection *conn,
+ struct berval *saslname, struct berval *sasldn )
+{
+ int rc;
+ Backend *be = NULL;
+ struct berval dn = { 0, NULL };
+ int scope = LDAP_SCOPE_BASE;
+ Filter *filter = NULL;
+ slap_callback cb = { slap_cb_null_response,
+ slap_cb_null_sresult, sasl_sc_sasl2dn, slap_cb_null_sreference, NULL};
+ Operation op = {0};
+ struct berval regout = { 0, NULL };
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( TRANSPORT, ENTRY,
+ "slap_sasl2dn: converting SASL name %s to DN.\n",
+ saslname->bv_val, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "==>slap_sasl2dn: "
+ "converting SASL name %s to a DN\n",
+ saslname->bv_val, 0,0 );
+#endif
+
+ sasldn->bv_val = NULL;
+ sasldn->bv_len = 0;
+ cb.sc_private = sasldn;
+
+ /* Convert the SASL name into a minimal URI */
+ if( !slap_sasl_regexp( saslname, ®out ) ) {
+ goto FINISHED;
+ }
+
+ rc = slap_parseURI( ®out, &dn, &scope, &filter );
+ if( regout.bv_val ) ch_free( regout.bv_val );
+ if( rc != LDAP_SUCCESS ) {
+ goto FINISHED;
+ }
+
+ /* Must do an internal search */
+ be = select_backend( &dn, 0, 1 );
+
+ /* Massive shortcut: search scope == base */
+ if( scope == LDAP_SCOPE_BASE ) {
+ *sasldn = dn;
+ dn.bv_len = 0;
+ dn.bv_val = NULL;
+ goto FINISHED;
+ }
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( TRANSPORT, DETAIL1,
+ "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
+ dn.bv_val, scope, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
+ dn.bv_val, scope, 0 );
+#endif
+
+ if(( be == NULL ) || ( be->be_search == NULL)) {
+ goto FINISHED;
+ }
+ suffix_alias( be, &dn );
+
+ op.o_tag = LDAP_REQ_SEARCH;
+ op.o_protocol = LDAP_VERSION3;
+ op.o_ndn = conn->c_ndn;
+ op.o_callback = &cb;
+ op.o_time = slap_get_time();
+ op.o_do_not_cache = 1;
+ op.o_threadctx = conn->c_sasl_bindop->o_threadctx;
+
+ (*be->be_search)( be, conn, &op, NULL, &dn,
+ scope, LDAP_DEREF_NEVER, 1, 0,
+ filter, NULL, NULL, 1 );
+
+FINISHED:
+ if( sasldn->bv_len ) {
+ conn->c_authz_backend = be;
+ }
+ if( dn.bv_len ) ch_free( dn.bv_val );
+ if( filter ) filter_free( filter );
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( TRANSPORT, ENTRY,
+ "slap_sasl2dn: Converted SASL name to %s\n",
+ sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "<==slap_sasl2dn: Converted SASL name to %s\n",
+ sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
+#endif
+
+ return;
+}
/* Check if a bind can SASL authorize to another identity.
{
int rc = LDAP_INAPPROPRIATE_AUTH;
-#ifdef HAVE_CYRUS_SASL
/* User binding as anonymous */
if ( authzDN == NULL ) {
rc = LDAP_SUCCESS;
authcDN->bv_val, authzDN->bv_val, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
- "==>slap_sasl_authorized: can %s become %s?\n", authcDN->bv_val, authzDN->bv_val, 0 );
+ "==>slap_sasl_authorized: can %s become %s?\n",
+ authcDN->bv_val, authzDN->bv_val, 0 );
#endif
/* If person is authorizing to self, succeed */
goto DONE;
}
+ /* Allow the manager to authorize as any DN. */
+ if( be_isroot( conn->c_authz_backend, authcDN )) {
+ rc = LDAP_SUCCESS;
+ goto DONE;
+ }
+
/* Check source rules */
if( authz_policy & SASL_AUTHZ_TO ) {
rc = slap_sasl_check_authz( conn, authcDN, authzDN,
rc = LDAP_INAPPROPRIATE_AUTH;
DONE:
-#endif
#ifdef NEW_LOGGING
LDAP_LOG( TRANSPORT, RESULTS, "slap_sasl_authorized: return %d\n", rc,0,0 );
/* schema_check.c - routines to enforce schema definitions */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
int subentry = is_entry_subentry( e );
int collectiveSubentry = 0;
-#if 0
if( subentry ) {
collectiveSubentry = is_entry_collectiveAttributeSubentry( e );
}
-#endif
*text = textbuf;
} else if ( sc != oc ) {
snprintf( textbuf, textlen,
- "structural object class modification from '%s' to '%s' not allowed",
+ "structural object class modification "
+ "from '%s' to '%s' not allowed",
asc->a_vals[0].bv_val, nsc.bv_val );
return LDAP_NO_OBJECT_CLASS_MODS;
}
+ { /* naming check */
+ LDAPRDN *rdn;
+ const char *p;
+ ber_len_t cnt;
+
+ /*
+ * Get attribute type(s) and attribute value(s) of our RDN
+ */
+ if ( ldap_bv2rdn( &e->e_name, &rdn, (char **)&p,
+ LDAP_DN_FORMAT_LDAP ) )
+ {
+ *text = "unrecongized attribute type(s) in RDN";
+ return LDAP_INVALID_DN_SYNTAX;
+ }
+
+ /* Check that each AVA of the RDN is present in the entry */
+ /* FIXME: Should also check that each AVA lists a distinct type */
+ for ( cnt = 0; rdn[0][cnt]; cnt++ ) {
+ LDAPAVA *ava = rdn[0][cnt];
+ AttributeDescription *desc = NULL;
+ Attribute *attr;
+ const char *errtext;
+
+ rc = slap_bv2ad( &ava->la_attr, &desc, &errtext );
+ if ( rc != LDAP_SUCCESS ) {
+ snprintf( textbuf, textlen, "%s (in RDN)", errtext );
+ return rc;
+ }
+
+ /* find the naming attribute */
+ attr = attr_find( e->e_attrs, desc );
+ if ( attr == NULL ) {
+ snprintf( textbuf, textlen,
+ "naming attribute '%s' is not present in entry",
+ ava->la_attr );
+ return LDAP_NO_SUCH_ATTRIBUTE;
+ }
+
+ if ( value_find( desc, attr->a_vals, &ava->la_value ) != 0 ) {
+ snprintf( textbuf, textlen,
+ "value of naming attribute '%s' is not present in entry",
+ ava->la_attr );
+ return LDAP_NO_SUCH_ATTRIBUTE;
+ }
+ }
+ }
+
#ifdef SLAP_EXTENDED_SCHEMA
/* find the content rule for the structural class */
cr = cr_find( sc->soc_oid );
/* schema_init.c - init builtin schema */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
long lValue, lAssertedValue;
/* safe to assume integers are NUL terminated? */
- lValue = strtoul(value->bv_val, NULL, 10);
+ lValue = strtol(value->bv_val, NULL, 10);
if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
return LDAP_CONSTRAINT_VIOLATION;
}
long lValue, lAssertedValue;
/* safe to assume integers are NUL terminated? */
- lValue = strtoul(value->bv_val, NULL, 10);
+ lValue = strtol(value->bv_val, NULL, 10);
if(( lValue == LONG_MIN || lValue == LONG_MAX) && errno == ERANGE ) {
return LDAP_CONSTRAINT_VIOLATION;
}
/* schema_init.c - init builtin schema */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
"MUST cn )",
0, SLAP_OC_OPERATIONAL,
offsetof(struct slap_internal_schema, si_oc_monitor) },
+#ifdef LDAP_DEVEL
+ { "collectiveAttributeSubentry", "( 2.5.17.2 "
+ "NAME 'collectiveAttributeSubentry' "
+ "AUXILIARY )",
+ subentryObjectClass,
+ SLAP_OC_COLLECTIVEATTRIBUTESUBENTRY|SLAP_OC_OPERATIONAL|SLAP_OC_HIDE,
+ offsetof(struct slap_internal_schema, si_oc_collectiveAttributeSubentry) },
+ { "dynamicObject", "( 1.3.6.1.4.1.1466.101.119.2 "
+ "NAME 'dynamicObject' "
+ "DESC 'RFC2589: Dynamic Object' "
+ "SUP top AUXILIARY )",
+ dynamicObjectClass, SLAP_OC_DYNAMICOBJECT,
+ offsetof(struct slap_internal_schema, si_oc_dynamicObject) },
+#endif
{ NULL, NULL, NULL, 0, 0 }
};
NULL, 0,
NULL, NULL, NULL, NULL, NULL,
offsetof(struct slap_internal_schema, si_ad_subschemaSubentry) },
+#ifdef LDAP_DEVEL
+ { "collectiveAttributeSubentries", "( 2.5.18.12 "
+ "NAME 'collectiveAttributeSubentries' "
+ "EQUALITY distinguishedNameMatch "
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
+ "NO-USER-MODIFICATION USAGE directoryOperation )",
+ NULL, SLAP_AT_HIDE,
+ NULL, NULL, NULL, NULL, NULL,
+ offsetof(struct slap_internal_schema, si_ad_collectiveSubentries) },
+ { "collectiveExclusions", "( 2.5.18.7 NAME 'collectiveExclusions' "
+ "EQUALITY objectIdentifierMatch "
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
+ "USAGE directoryOperation )",
+ NULL, SLAP_AT_HIDE,
+ NULL, NULL, NULL, NULL, NULL,
+ offsetof(struct slap_internal_schema, si_ad_collectiveExclusions) },
+#endif
{ "entryUUID", "( 1.3.6.1.4.1.4203.666.1.6 NAME 'entryUUID' "
"DESC 'LCUP/LDUP: UUID of the entry' "
offsetof(struct slap_internal_schema, si_ad_aci) },
#endif
+#ifdef LDAP_DEVEL
+ { "entryTtl", "( 1.3.6.1.4.1.1466.101.119.3 NAME 'entryTtl' "
+ "DESC 'RFC2589: entry time-to-live' "
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE "
+ "NO-USER-MODIFICATION USAGE dSAOperation )",
+ dynamicAttribute, 0,
+ NULL, NULL, NULL, NULL, NULL,
+ offsetof(struct slap_internal_schema, si_ad_entryTtl) },
+ { "dynamicSubtrees", "( 1.3.6.1.4.1.1466.101.119.4 "
+ "NAME 'dynamicSubtrees' "
+ "DESC 'RFC2589: dynamic subtrees' "
+ "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION "
+ "USAGE dSAOperation )",
+ rootDseAttribute, 0,
+ NULL, NULL, NULL, NULL, NULL,
+ offsetof(struct slap_internal_schema, si_ad_dynamicSubtrees) },
+#endif
+
/* userApplication attributes (which system schema depends upon) */
{ "distinguishedName", "( 2.5.4.49 NAME 'distinguishedName' "
"DESC 'RFC2256: common supertype of DN attributes' "
offsetof(struct slap_internal_schema, si_ad_krbName) },
#endif
- { NULL, NULL, NULL, 0, NULL, NULL, NULL, 0 }
+ { NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0 }
};
static AttributeType slap_at_undefined = {
{ "1.1.1", NULL, NULL, 1, NULL,
NULL, NULL, NULL, NULL,
- 0, 0, 0, 1, 3 }, /* LDAPAttributeType */
+ 0, 0, 0, 1, 3, NULL }, /* LDAPAttributeType */
{ sizeof("UNDEFINED")-1, "UNDEFINED" }, /* cname */
NULL, /* sup */
NULL, /* subtypes */
NULL, /* syntax (this may need to be defined) */
(AttributeTypeSchemaCheckFN *) 0, /* schema check function */
SLAP_AT_ABSTRACT|SLAP_AT_FINAL, /* mask */
- NULL, /* next */
+ { NULL }, /* next */
NULL /* attribute description */
/* mutex (don't know how to initialize it :) */
};
attr->a_desc->ad_cname.bv_val );
return LDAP_OBJECT_CLASS_VIOLATION;
}
+
+static int dynamicAttribute (
+ Backend *be,
+ Entry *e,
+ Attribute *attr,
+ const char** text,
+ char *textbuf, size_t textlen )
+{
+ *text = textbuf;
+
+ if( !SLAP_DYNAMIC(be) ) {
+ snprintf( textbuf, textlen,
+ "attribute \"%s\" not supported in context",
+ attr->a_desc->ad_cname.bv_val );
+ return LDAP_OBJECT_CLASS_VIOLATION;
+ }
+
+ if( !is_entry_dynamicObject( e ) ) {
+ snprintf( textbuf, textlen,
+ "attribute \"%s\" only allowed in dynamic object",
+ attr->a_desc->ad_cname.bv_val );
+ return LDAP_OBJECT_CLASS_VIOLATION;
+ }
+
+ return LDAP_SUCCESS;
+}
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* Portions
#include <ac/socket.h>
#include "ldap_pvt.h"
+#include "lutil.h"
#include "slap.h"
+#ifdef LDAP_SLAPI
+#include "slapi.h"
+static char **anlist2charray( AttributeName *an );
+static Slapi_PBlock *initSearchPlugin( Backend *be, Connection *conn, Operation *op,
+ struct berval *base, int scope, int deref, int sizelimit, int timelimit,
+ Filter *filter, struct berval *fstr, char **attrs,
+ int attrsonly, int managedsait );
+static int doPreSearchPluginFNs( Backend *be, Slapi_PBlock *pb );
+static int doSearchRewriteFNs( Backend *be, Slapi_PBlock *pb, Filter **filter, struct berval *fstr );
+static void doPostSearchPluginFNs( Backend *be, Slapi_PBlock *pb );
+#endif /* LDAPI_SLAPI */
+
int
do_search(
Connection *conn, /* where to send results */
int rc;
const char *text;
int manageDSAit;
+#ifdef LDAP_SLAPI
+ Slapi_PBlock *pb = NULL;
+ char **attrs = NULL;
+#endif
#ifdef NEW_LOGGING
LDAP_LOG( OPERATION, ENTRY, "do_search: conn %d\n", conn->c_connid, 0, 0 );
Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 );
#endif
- Statslog( LDAP_DEBUG_STATS,
- "conn=%lu op=%lu SRCH base=\"%s\" scope=%d filter=\"%s\"\n",
- op->o_connid, op->o_opid, pbase.bv_val, scope, fstr.bv_val );
+ if ( StatslogTest( LDAP_DEBUG_STATS ) ) {
+ char abuf[BUFSIZ/2], *ptr = abuf;
+ int len = 0, alen;
+
+ Statslog( LDAP_DEBUG_STATS,
+ "conn=%lu op=%lu SRCH base=\"%s\" scope=%d filter=\"%s\"\n",
+ op->o_connid, op->o_opid, pbase.bv_val, scope, fstr.bv_val );
+
+ for ( i = 0; i<siz; i++ ) {
+ alen = an[i].an_name.bv_len;
+ if (alen >= sizeof(abuf)) {
+ alen = sizeof(abuf)-1;
+ }
+ if (len && (len + 1 + alen >= sizeof(abuf))) {
+ Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu SRCH attr=%s\n",
+ op->o_connid, op->o_opid, abuf, 0, 0 );
+ len = 0;
+ ptr = abuf;
+ }
+ if (len) {
+ *ptr++ = ' ';
+ len++;
+ }
+ ptr = lutil_strncopy(ptr, an[i].an_name.bv_val, alen);
+ len += alen;
+ *ptr = '\0';
+ }
+ if (len) {
+ Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu SRCH attr=%s\n",
+ op->o_connid, op->o_opid, abuf, 0, 0 );
+ }
+ }
manageDSAit = get_manageDSAit( op );
if ( nbase.bv_len == 0 ) {
#ifdef LDAP_CONNECTIONLESS
/* Ignore LDAPv2 CLDAP Root DSE queries */
- if (op->o_protocol==LDAP_VERSION2 && conn->c_is_udp) {
+ if (op->o_protocol == LDAP_VERSION2 && conn->c_is_udp) {
goto return_results;
}
#endif
goto return_results;
}
+#ifdef LDAP_SLAPI
+ attrs = anlist2charray( an );
+ pb = initSearchPlugin( NULL, conn, op, &nbase, scope,
+ deref, sizelimit, timelimit, filter, &fstr,
+ attrs, attrsonly, manageDSAit );
+ rc = doPreSearchPluginFNs( NULL, pb );
+ if ( rc == LDAP_SUCCESS ) {
+ doSearchRewriteFNs( NULL, pb, &filter, &fstr );
+#endif /* LDAP_SLAPI */
rc = root_dse_info( conn, &entry, &text );
+#ifdef LDAP_SLAPI
+ }
+#endif /* LDAP_SLAPI */
} else if ( bvmatch( &nbase, &global_schemandn ) ) {
/* check restrictions */
goto return_results;
}
+#ifdef LDAP_SLAPI
+ attrs = anlist2charray( an );
+ pb = initSearchPlugin( NULL, conn, op, &nbase, scope,
+ deref, sizelimit, timelimit, filter, &fstr,
+ attrs, attrsonly, manageDSAit );
+ rc = doPreSearchPluginFNs( NULL, pb );
+ if ( rc == LDAP_SUCCESS ) {
+ doSearchRewriteFNs( NULL, pb, &filter, &fstr );
+#endif /* LDAP_SLAPI */
rc = schema_info( &entry, &text );
+#ifdef LDAP_SLAPI
+ }
+#endif /* LDAP_SLAPI */
}
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
+#ifdef LDAP_SLAPI
+ doPostSearchPluginFNs( NULL, pb );
+#endif /* LDAP_SLAPI */
goto return_results;
} else if ( entry != NULL ) {
send_ldap_result( conn, op, LDAP_SUCCESS,
NULL, NULL, NULL, NULL );
-
+#ifdef LDAP_SLAPI
+ doPostSearchPluginFNs( NULL, pb );
+#endif /* LDAP_SLAPI */
goto return_results;
}
}
/* deref the base if needed */
suffix_alias( be, &nbase );
+#ifdef LDAP_SLAPI
+ attrs = anlist2charray( an );
+ pb = initSearchPlugin( be, conn, op, &pbase,
+ scope, deref, sizelimit,
+ timelimit, filter, &fstr, attrs, attrsonly,
+ manageDSAit );
+ rc = doPreSearchPluginFNs( be, pb );
+ if ( rc != LDAP_SUCCESS ) {
+ goto return_results;
+ }
+
+ doSearchRewriteFNs( be, pb, &filter, &fstr );
+#endif /* LDAP_SLAPI */
+
/* actually do the search and send the result(s) */
if ( be->be_search ) {
(*be->be_search)( be, conn, op, &pbase, &nbase,
NULL, NULL );
}
+#ifdef LDAP_SLAPI
+ doPostSearchPluginFNs( be, pb );
+#endif /* LDAP_SLAPI */
+
return_results:;
+
#ifdef LDAP_CLIENT_UPDATE
- if ( !( op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
-#endif /* LDAP_CLIENT_UPDATE */
- {
- if( pbase.bv_val != NULL) free( pbase.bv_val );
- if( nbase.bv_val != NULL) free( nbase.bv_val );
+ if ( ( op->o_clientupdate_type & SLAP_LCUP_PERSIST ) )
+ return rc;
+#endif
+#if defined(LDAP_CLIENT_UPDATE) && defined(LDAP_SYNC)
+ else
+#endif
+#ifdef LDAP_SYNC
+ if ( ( op->o_sync_mode & SLAP_SYNC_PERSIST ) )
+ return rc;
+#endif
+
+ if( pbase.bv_val != NULL) free( pbase.bv_val );
+ if( nbase.bv_val != NULL) free( nbase.bv_val );
+
+ if( fstr.bv_val != NULL) free( fstr.bv_val );
+ if( filter != NULL) filter_free( filter );
+ if( an != NULL ) free( an );
+#ifdef LDAP_SLAPI
+ if( attrs != NULL) ch_free( attrs );
+#endif /* LDAP_SLAPI */
+
+ return rc;
+}
+
+#ifdef LDAP_SLAPI
+
+static char **anlist2charray( AttributeName *an )
+{
+ char **attrs;
+ int i;
- if( fstr.bv_val != NULL) free( fstr.bv_val );
- if( filter != NULL) filter_free( filter );
- if( an != NULL ) free( an );
+ if ( an != NULL ) {
+ for ( i = 0; an[i].an_name.bv_val != NULL; i++ )
+ ;
+ attrs = (char **)ch_malloc( (i + 1) * sizeof(char *) );
+ for ( i = 0; an[i].an_name.bv_val != NULL; i++ ) {
+ attrs[i] = an[i].an_name.bv_val;
+ }
+ attrs[i] = NULL;
+ } else {
+ attrs = NULL;
+ }
+
+ return attrs;
+}
+
+static Slapi_PBlock *initSearchPlugin( Backend *be, Connection *conn, Operation *op,
+ struct berval *base, int scope, int deref, int sizelimit,
+ int timelimit, Filter *filter, struct berval *fstr,
+ char **attrs, int attrsonly, int managedsait )
+{
+ Slapi_PBlock *pb;
+
+ pb = op->o_pb;
+
+ slapi_x_backend_set_pb( pb, be );
+ slapi_x_connection_set_pb( pb, conn );
+ slapi_x_operation_set_pb( pb, op );
+ slapi_pblock_set( pb, SLAPI_SEARCH_TARGET, (void *)base->bv_val );
+ slapi_pblock_set( pb, SLAPI_SEARCH_SCOPE, (void *)scope );
+ slapi_pblock_set( pb, SLAPI_SEARCH_DEREF, (void *)deref );
+ slapi_pblock_set( pb, SLAPI_SEARCH_SIZELIMIT, (void *)sizelimit );
+ slapi_pblock_set( pb, SLAPI_SEARCH_TIMELIMIT, (void *)timelimit );
+ slapi_pblock_set( pb, SLAPI_SEARCH_FILTER, (void *)filter );
+ slapi_pblock_set( pb, SLAPI_SEARCH_STRFILTER, (void *)fstr->bv_val );
+ slapi_pblock_set( pb, SLAPI_SEARCH_ATTRS, (void *)attrs );
+ slapi_pblock_set( pb, SLAPI_SEARCH_ATTRSONLY, (void *)attrsonly );
+ slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)managedsait );
+
+ return pb;
+}
+
+static int doPreSearchPluginFNs( Backend *be, Slapi_PBlock *pb )
+{
+ int rc;
+
+ rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_SEARCH_FN, pb );
+ if ( rc != 0 ) {
+ /*
+ * A preoperation plugin failure will abort the
+ * entire operation.
+ */
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "doPreSearchPluginFNs: search preoperation plugin "
+ "returned %d\n", rc, 0, 0 );
+#else
+ Debug(LDAP_DEBUG_TRACE, "doPreSearchPluginFNs: search preoperation plugin "
+ "returned %d.\n", rc, 0, 0);
+#endif
+ if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0)
+ rc = LDAP_OTHER;
+ } else {
+ rc = LDAP_SUCCESS;
}
return rc;
}
+
+static int doSearchRewriteFNs( Backend *be, Slapi_PBlock *pb, Filter **filter, struct berval *fstr )
+{
+ if ( doPluginFNs( be, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, pb ) == 0 ) {
+ /*
+ * The plugin can set the SLAPI_SEARCH_FILTER.
+ * SLAPI_SEARCH_STRFILER is not normative.
+ */
+ slapi_pblock_get( pb, SLAPI_SEARCH_FILTER, (void *)filter);
+ ch_free( fstr->bv_val );
+ filter2bv( *filter, fstr );
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, ARGS,
+ "doSearchRewriteFNs: after compute_rewrite_search filter: %s\n",
+ fstr->bv_len ? fstr->bv_val : "empty", 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ARGS, " after compute_rewrite_search filter: %s\n",
+ fstr->bv_len ? fstr->bv_val : "empty", 0, 0 );
+#endif
+ }
+
+ return LDAP_SUCCESS;
+}
+
+static void doPostSearchPluginFNs( Backend *be, Slapi_PBlock *pb )
+{
+ if ( doPluginFNs( be, SLAPI_PLUGIN_POST_SEARCH_FN, pb ) != 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, INFO, "doPostSearchPluginFNs: search postoperation plugins "
+ "failed\n", 0, 0, 0 );
+#else
+ Debug(LDAP_DEBUG_TRACE, "doPostSearchPluginFNs: search postoperation plugins "
+ "failed.\n", 0, 0, 0);
+#endif
+ }
+}
+
+void dummy(void)
+{
+ /*
+ * XXX slapi_search_internal() was no getting pulled
+ * in; all manner of linker flags failed to link it.
+ * FIXME
+ */
+ slapi_search_internal( NULL, 0, NULL, NULL, NULL, 0 );
+}
+#endif /* LDAP_SLAPI */
+
--- /dev/null
+/* $OpenLDAP$ */
+/*
+ * Copyright 2000-2003 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#ifndef SLAP_SETS_H_
+#define SLAP_SETS_H_
+
+#include <ldap_cdefs.h>
+
+LDAP_BEGIN_DECL
+
+/* this routine needs to return the bervals instead of
+ * plain strings, since syntax is not known. It should
+ * also return the syntax or some "comparison cookie"
+ * that is used by set_filter.
+ */
+typedef BerVarray (SLAP_SET_GATHER)(
+ void *cookie, struct berval *name, struct berval *attr);
+
+LDAP_SLAPD_F (long) slap_set_size(BerVarray set);
+LDAP_SLAPD_F (void) slap_set_dispose(BerVarray set);
+
+LDAP_SLAPD_F (int) slap_set_filter(
+ SLAP_SET_GATHER gatherer,
+ void *cookie, struct berval *filter,
+ struct berval *user, struct berval *this, BerVarray *results);
+
+LDAP_END_DECL
+
+#endif
/* slap.h - stand alone ldap server include file */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#define SLAPD_ANONYMOUS "cn=anonymous"
/* LDAPMod.mod_op value ===> Must be kept in sync with ldap.h!
- *
* This is a value used internally by the backends. It is needed to allow
* adding values that already exist without getting an error as required by
* modrdn when the new rdn was already an attribute value itself.
- * JCG 05/1999 (gomez@engr.sgi.com)
*/
#define SLAP_MOD_SOFTADD 0x1000
#define SLAPD_ACI_SYNTAX "1.3.6.1.4.1.4203.666.2.1"
#endif
-#define SLAPD_OCTETSTRING_SYNTAX "1.3.6.1.4.1.1466.115.121.1.40"
-
/* change this to "OpenLDAPset" */
#define SLAPD_ACI_SET_ATTR "template"
slap_ssf_t sss_simple_bind;
} slap_ssf_set_t;
+/* Flags for telling slap_sasl_getdn() what type of identity is being passed */
+#define SLAP_GETDN_AUTHCID 2
+#define SLAP_GETDN_AUTHZID 4
+
/*
* Index types
*/
#define SLAP_INDEX_FLAGS 0xF000UL
#define SLAP_INDEX_NOSUBTYPES 0x1000UL /* don't use index w/ subtypes */
-#define SLAP_INDEX_NOLANG 0x2000UL /* don't use index w/ lang */
+#define SLAP_INDEX_NOTAGS 0x2000UL /* don't use index w/ tags */
/*
* there is a single index for each attribute. these prefixes ensure
typedef struct slap_oid_macro {
struct berval som_oid;
char **som_names;
- struct slap_oid_macro *som_next;
+ LDAP_SLIST_ENTRY(slap_oid_macro) som_next;
} OidMacro;
/* forward declarations */
slap_syntax_transform_func *ssyn_str2ber;
#endif
- struct slap_syntax *ssyn_next;
+ LDAP_SLIST_ENTRY(slap_syntax) ssyn_next;
} Syntax;
#define slap_syntax_is_flag(s,flag) ((int)((s)->ssyn_flags & (flag)) ? 1 : 0)
struct berval smr_str;
/*
* Note: the former
- ber_len_t smr_oidlen;
+ * ber_len_t smr_oidlen;
* has been replaced by a struct berval that uses the value
* provided by smr_mrule.mr_oid; a macro that expands to
* the bv_len field of the berval is provided for backward
#define SLAP_MR_ASSERTION_SYNTAX_MATCH 0x0000U
#define SLAP_MR_VALUE_SYNTAX_MATCH 0x0001U
#define SLAP_MR_VALUE_SYNTAX_CONVERTED_MATCH 0x0003U
-#define SLAP_MR_VALUE_NORMALIZED_MATCH 0x0004U
+#define SLAP_MR_VALUE_NORMALIZED_MATCH 0x0004U
#define SLAP_IS_MR_ASSERTION_SYNTAX_MATCH( usage ) \
(!((usage) & SLAP_MR_VALUE_SYNTAX_MATCH))
slap_mr_filter_func *smr_filter;
/*
- * null terminated list of syntaxes compatible with this syntax
+ * null terminated array 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 **smr_compat_syntaxes;
struct slap_matching_rule *smr_associated;
- struct slap_matching_rule *smr_next;
+ LDAP_SLIST_ENTRY(slap_matching_rule)smr_next;
#define smr_oid smr_mrule.mr_oid
#define smr_names smr_mrule.mr_names
/* RFC2252 string representation */
struct berval smru_str;
- struct slap_matching_rule_use *smru_next;
+ LDAP_SLIST_ENTRY(slap_matching_rule_use) smru_next;
#define smru_oid smru_mruleuse.mru_oid
#define smru_names smru_mruleuse.mru_names
#define SLAP_AT_HIDE 0x8000U /* hide attribute */
slap_mask_t sat_flags;
- struct slap_attribute_type *sat_next;
+ LDAP_SLIST_ENTRY(slap_attribute_type) sat_next;
#define sat_oid sat_atype.at_oid
#define sat_names sat_atype.at_names
#define soc_at_oids_may soc_oclass.oc_at_oids_may
#define soc_extensions soc_oclass.oc_extensions
- struct slap_object_class *soc_next;
+ LDAP_SLIST_ENTRY(slap_object_class) soc_next;
} ObjectClass;
#define SLAP_OC_ALIAS 0x0001
#define scr_at_oids_may scr_crule.cr_at_oids_may
#define scr_at_oids_not scr_crule.cr_at_oids_not
- struct slap_content_rule *scr_next;
+ LDAP_SLIST_ENTRY( slap_content_rule ) scr_next;
} ContentRule;
-/*
- * represents a recognized attribute description ( type + options )
- */
+/* Represents a recognized attribute description ( type + options ). */
typedef struct slap_attr_desc {
struct slap_attr_desc *ad_next;
AttributeType *ad_type; /* attribute type, must be specified */
struct berval ad_cname; /* canonical name, must be specified */
- struct berval ad_lang; /* empty if no language tags */
+ struct berval ad_tags; /* empty if no tagging options */
unsigned ad_flags;
#define SLAP_DESC_NONE 0x00U
#define SLAP_DESC_BINARY 0x01U
-#define SLAP_DESC_LANG_RANGE 0x80U
+#define SLAP_DESC_TAG_RANGE 0x80U
} AttributeDescription;
typedef struct slap_attr_name {
ObjectClass *an_oc;
} AttributeName;
-#define slap_ad_is_lang(ad) ( (ad)->ad_lang.bv_len != 0 )
-#define slap_ad_is_lang_range(ad) \
- ( ((ad)->ad_flags & SLAP_DESC_LANG_RANGE) ? 1 : 0 )
+#define slap_ad_is_tagged(ad) ( (ad)->ad_tags.bv_len != 0 )
+#define slap_ad_is_tag_range(ad) \
+ ( ((ad)->ad_flags & SLAP_DESC_TAG_RANGE) ? 1 : 0 )
#define slap_ad_is_binary(ad) \
( ((ad)->ad_flags & SLAP_DESC_BINARY) ? 1 : 0 )
ObjectClass *si_oc_subentry;
ObjectClass *si_oc_subschema;
ObjectClass *si_oc_monitor;
+ ObjectClass *si_oc_collectiveAttributeSubentry;
+ ObjectClass *si_oc_dynamicObject;
/* objectClass attribute descriptions */
AttributeDescription *si_ad_objectClass;
AttributeDescription *si_ad_modifyTimestamp;
AttributeDescription *si_ad_hasSubordinates;
AttributeDescription *si_ad_subschemaSubentry;
+ AttributeDescription *si_ad_collectiveSubentries;
+ AttributeDescription *si_ad_collectiveExclusions;
AttributeDescription *si_ad_entryUUID;
AttributeDescription *si_ad_entryCSN;
AttributeDescription *si_ad_superiorUUID;
AttributeDescription *si_ad_aci;
#endif
+ /* dynamic entries */
+ AttributeDescription *si_ad_entryTtl;
+ AttributeDescription *si_ad_dynamicSubtrees;
+
/* Other attributes descriptions */
AttributeDescription *si_ad_distinguishedName;
AttributeDescription *si_ad_name;
#define SLAPD_COMPARE_UNDEFINED ((ber_int_t) -1)
typedef struct slap_valuesreturnfilter {
- ber_tag_t f_choice;
+ ber_tag_t vrf_choice;
union vrf_un_u {
/* precomputed result */
- ber_int_t f_un_result;
+ ber_int_t vrf_un_result;
/* DN */
- char *f_un_dn;
+ char *vrf_un_dn;
/* present */
- AttributeDescription *f_un_desc;
+ AttributeDescription *vrf_un_desc;
/* simple value assertion */
- AttributeAssertion *f_un_ava;
+ AttributeAssertion *vrf_un_ava;
/* substring assertion */
- SubstringsAssertion *f_un_ssa;
+ SubstringsAssertion *vrf_un_ssa;
/* matching rule assertion */
- MatchingRuleAssertion *f_un_mra;
- } f_un;
-
- struct slap_valuesreturnfilter *f_next;
+ MatchingRuleAssertion *vrf_un_mra;
+
+#define vrf_result vrf_un.vrf_un_result
+#define vrf_dn vrf_un.vrf_un_dn
+#define vrf_desc vrf_un.vrf_un_desc
+#define vrf_ava vrf_un.vrf_un_ava
+#define vrf_av_desc vrf_un.vrf_un_ava->aa_desc
+#define vrf_av_value vrf_un.vrf_un_ava->aa_value
+#define vrf_ssa vrf_un.vrf_un_ssa
+#define vrf_sub vrf_un.vrf_un_ssa
+#define vrf_sub_desc vrf_un.vrf_un_ssa->sa_desc
+#define vrf_sub_initial vrf_un.vrf_un_ssa->sa_initial
+#define vrf_sub_any vrf_un.vrf_un_ssa->sa_any
+#define vrf_sub_final vrf_un.vrf_un_ssa->sa_final
+#define vrf_mra vrf_un.vrf_un_mra
+#define vrf_mr_rule vrf_un.vrf_un_mra->ma_rule
+#define vrf_mr_rule_text vrf_un.vrf_un_mra->ma_rule_text
+#define vrf_mr_desc vrf_un.vrf_un_mra->ma_desc
+#define vrf_mr_value vrf_un.vrf_un_mra->ma_value
+#define vrf_mr_dnattrs vrf_un.vrf_un_mra->ma_dnattrs
+
+
+ } vrf_un;
+
+ struct slap_valuesreturnfilter *vrf_next;
} ValuesReturnFilter;
/*
/* Access state */
AccessControl *as_vd_acl;
+ AccessControl *as_vi_acl;
slap_mask_t as_vd_acl_mask;
regmatch_t as_vd_acl_matches[MAXREMATCHES];
int as_vd_acl_count;
int as_vd_access_count;
int as_result;
+ AttributeDescription *as_vd_ad;
} AccessControlState;
-#define ACL_STATE_INIT { ACL_STATE_NOT_RECORDED, NULL, 0UL, { { 0, 0 } }, 0, NULL, 0, 0 }
+#define ACL_STATE_INIT { ACL_STATE_NOT_RECORDED, NULL, NULL, 0UL, \
+ { { 0, 0 } }, 0, NULL, 0, 0, NULL }
/*
* replog moddn param structure
int lms_s_soft;
int lms_s_hard;
int lms_s_unchecked;
+ int lms_s_pr;
+ int lms_s_pr_hide;
};
struct slap_limits {
* (in previous use there was a flaw with back-bdb and back-ldbm; now it
* is fixed).
*/
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
#define be_has_subordinates bd_info->bi_has_subordinates
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
#define be_controls bd_info->bi_controls
BerVarray be_update_refs; /* where to refer modifying clients to */
char *be_realm;
void *be_private; /* anything the backend database needs */
+
+ void *be_pb; /* Netscape plugin */
};
struct slap_conn;
struct slap_conn *c, struct slap_op *o,
Entry *e, AttributeName *attrs, int opattrs, Attribute **a ));
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
typedef int (BI_has_subordinates) LDAP_P((Backend *bd,
struct slap_conn *c, struct slap_op *o,
Entry *e, int *has_subordinates ));
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
typedef int (BI_connection_init) LDAP_P((BackendDB *bd,
struct slap_conn *c));
BI_acl_attribute *bi_acl_attribute;
BI_operational *bi_operational;
-#ifdef SLAP_X_FILTER_HASSUBORDINATES
BI_has_subordinates *bi_has_subordinates;
-#endif /* SLAP_X_FILTER_HASSUBORDINATES */
BI_connection_init *bi_connection_init;
BI_connection_destroy *bi_connection_destroy;
typedef int (slap_sendentry)( BackendDB *, struct slap_conn *,
struct slap_op *, Entry *, AttributeName *, int, LDAPControl **);
+typedef int (slap_sendreference)( BackendDB *, struct slap_conn *,
+ struct slap_op *, Entry *, BerVarray, LDAPControl **, BerVarray * );
+
typedef struct slap_callback {
slap_response *sc_response;
slap_sresult *sc_sresult;
slap_sendentry *sc_sendentry;
+ slap_sendreference *sc_sendreference;
void *sc_private;
} slap_callback;
} PagedResultsState;
-#ifdef LDAP_CLIENT_UPDATE
-#define LCUP_PSEARCH_BY_ADD 0x01
-#define LCUP_PSEARCH_BY_DELETE 0x02
-#define LCUP_PSEARCH_BY_PREMODIFY 0x03
-#define LCUP_PSEARCH_BY_MODIFY 0x04
-#define LCUP_PSEARCH_BY_SCOPEOUT 0x05
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+#define LDAP_PSEARCH_BY_ADD 0x01
+#define LDAP_PSEARCH_BY_DELETE 0x02
+#define LDAP_PSEARCH_BY_PREMODIFY 0x03
+#define LDAP_PSEARCH_BY_MODIFY 0x04
+#define LDAP_PSEARCH_BY_SCOPEOUT 0x05
-struct lcup_search_spec {
+struct ldap_psearch_spec {
struct slap_op *op;
struct berval *base;
struct berval *nbase;
struct berval *filterstr;
AttributeName *attrs;
int attrsonly;
- struct lcup_entry *elist;
- ldap_pvt_thread_mutex_t elist_mutex;
+ int protocol;
int entry_count;
- LDAP_LIST_ENTRY(lcup_search_spec) link;
+ LDAP_LIST_ENTRY(ldap_psearch_spec) link;
};
struct psid_entry {
- struct lcup_search_spec* ps;
+ struct ldap_psearch_spec* ps;
LDAP_LIST_ENTRY(psid_entry) link;
};
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
/*
ber_tag_t o_tag; /* tag of the request */
time_t o_time; /* time op was initiated */
+ char * o_extendedop; /* extended operation OID */
+
ldap_pvt_thread_t o_tid; /* thread handling this op */
volatile sig_atomic_t o_abandon; /* abandon flag */
+ volatile sig_atomic_t o_cancel; /* cancel flag */
char o_do_not_cache; /* don't cache from this op */
#define SLAP_NONCRITICAL_CONTROL 1
#define SLAP_CRITICAL_CONTROL 2
char o_managedsait;
+#define get_manageDSAit(op) ((int)(op)->o_managedsait)
+
char o_noop;
+ char o_proxy_authz;
+
char o_subentries;
+#define get_subentries(op) ((int)(op)->o_subentries)
char o_subentries_visibility;
+#define get_subentries_visibility(op) ((int)(op)->o_subentries_visibility)
+
char o_valuesreturnfilter;
+#ifdef LDAP_CONTROL_PERMITMODIFY
+ char o_permitmodify;
+#define get_permitmodify(op) ((int)(op)->o_permitmodify)
+#else
+#define get_permitmodify(op) (0)
+#endif
+
+#ifdef LDAP_CONTROL_NOREFERRALS
+ char o_noreferrals;
+#endif
+
+#ifdef LDAP_CONTROL_PAGEDRESULTS
char o_pagedresults;
+#define get_pagedresults(op) ((int)(op)->o_pagedresults)
ber_int_t o_pagedresults_size;
PagedResultsState o_pagedresults_state;
+#else
+#define get_pagedresults(op) (0)
+#endif
#ifdef LDAP_CLIENT_UPDATE
char o_clientupdate;
#define SLAP_LCUP_NONE (0x0)
#define SLAP_LCUP_SYNC (0x1)
#define SLAP_LCUP_PERSIST (0x2)
-#define SLAP_LCUP_SYNC_AND_PERSIST (0x3)
+#define SLAP_LCUP_SYNC_AND_PERSIST (0x3)
ber_int_t o_clientupdate_interval;
struct berval o_clientupdate_state;
- LDAP_LIST_HEAD(lss, lcup_search_spec) psearch_spec;
+#endif
+
+#ifdef LDAP_SYNC
+ char o_sync;
+ char o_sync_mode;
+#define SLAP_SYNC_NONE (0x0)
+#define SLAP_SYNC_REFRESH (0x1)
+#define SLAP_SYNC_PERSIST (0x2)
+#define SLAP_SYNC_REFRESH_AND_PERSIST (0x3)
+ struct berval o_sync_state;
+#endif
+
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+ LDAP_LIST_HEAD(lss, ldap_psearch_spec) psearch_spec;
LDAP_LIST_HEAD(pe, psid_entry) premodify_list;
LDAP_LIST_ENTRY(slap_op) link;
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
#ifdef LDAP_CONNECTIONLESS
Sockaddr o_peeraddr; /* UDP peer address */
AuthorizationInformation o_authz;
BerElement *o_ber; /* ber of the request */
+#ifdef LDAP_CONNECTIONLESS
+ BerElement *o_res_ber; /* ber of the reply */
+#endif
slap_callback *o_callback; /* callback pointers */
LDAPControl **o_ctrls; /* controls */
LDAP_STAILQ_ENTRY(slap_op) o_next; /* next operation in list */
ValuesReturnFilter *vrFilter; /* Structure represents ValuesReturnFilter */
+
+#ifdef LDAP_SLAPI
+ void *o_pb; /* NS-SLAPI plugin */
+#endif
} Operation;
-#define get_manageDSAit(op) ((int)(op)->o_managedsait)
-#define get_subentries(op) ((int)(op)->o_subentries)
-#define get_subentries_visibility(op) ((int)(op)->o_subentries_visibility)
+typedef void (*SEND_LDAP_RESULT)(
+ struct slap_conn *conn,
+ struct slap_op *op,
+ ber_int_t err,
+ const char *matched,
+ const char *text,
+ BerVarray ref,
+ LDAPControl **ctrls
+ );
+
+#define send_ldap_result( conn, op, err, matched, text, ref, ctrls ) \
+(*conn->c_send_ldap_result)( conn, op, err, matched, text, ref, ctrls )
+
+
+typedef int (*SEND_SEARCH_ENTRY)(
+ struct slap_backend_db *be,
+ struct slap_conn *conn,
+ struct slap_op *op,
+ struct slap_entry *e,
+ AttributeName *attrs,
+ int attrsonly,
+ LDAPControl **ctrls
+ );
+
+#define send_search_entry( be, conn, op, e, attrs, attrsonly, ctrls) \
+(*conn->c_send_search_entry)( be, conn, op, e, attrs, attrsonly, ctrls)
+
+
+typedef void (*SEND_SEARCH_RESULT)(
+ struct slap_conn *conn,
+ struct slap_op *op,
+ ber_int_t err,
+ const char *matched,
+ const char *text,
+ BerVarray refs,
+ LDAPControl **ctrls,
+ int nentries
+ );
+
+#define send_search_result( conn, op, err, matched, text, refs, ctrls, nentries ) \
+(*conn->c_send_search_result)( conn, op, err, matched, text, refs, ctrls, nentries )
+
+
+typedef int (*SEND_SEARCH_REFERENCE)(
+ struct slap_backend_db *be,
+ struct slap_conn *conn,
+ struct slap_op *op,
+ struct slap_entry *e,
+ BerVarray refs,
+ LDAPControl **ctrls,
+ BerVarray *v2refs
+ );
+
+#define send_search_reference( be, conn, op, e, refs, ctrls, v2refs ) \
+(*conn->c_send_search_reference)( be, conn, op, e, refs, ctrls, v2refs )
+
+
+typedef void (*SEND_LDAP_EXTENDED)(
+ struct slap_conn *conn,
+ struct slap_op *op,
+ ber_int_t err,
+ const char *matched,
+ const char *text,
+ BerVarray refs,
+ const char *rspoid,
+ struct berval *rspdata,
+ LDAPControl **ctrls
+ );
+
+#define send_ldap_extended( conn, op, err, matched, text, refs, rspoid, rspdata, ctrls) \
+(*conn->c_send_ldap_extended)( conn, op, err, matched, text, refs, rspoid, rspdata, ctrls )
+
+typedef void (*SEND_LDAP_INTERMEDIATE_RESP)(
+ struct slap_conn *conn,
+ struct slap_op *op,
+ ber_int_t err,
+ const char *matched,
+ const char *text,
+ BerVarray refs,
+ const char *rspoid,
+ struct berval *rspdata,
+ LDAPControl **ctrls
+ );
+
+#define send_ldap_intermediate_resp( conn, op, err, matched, text, refs, \
+ rspoid, rspdata, ctrls) \
+ (*conn->c_send_ldap_intermediate_resp)( conn, op, err, matched, text, \
+ refs, rspoid, rspdata, ctrls )
/*
* Caches the result of a backend_group check for ACL evaluation
long c_n_get; /* num of get calls */
long c_n_read; /* num of read calls */
long c_n_write; /* num of write calls */
+
+ void *c_pb; /* Netscape plugin */
+
+ /*
+ * These are the "callbacks" that are available for back-ends to
+ * supply data back to connected clients that are connected
+ * through the "front-end".
+ */
+ SEND_LDAP_RESULT c_send_ldap_result;
+ SEND_SEARCH_ENTRY c_send_search_entry;
+ SEND_SEARCH_RESULT c_send_search_result;
+ SEND_SEARCH_REFERENCE c_send_search_reference;
+ SEND_LDAP_EXTENDED c_send_ldap_extended;
+#ifdef LDAP_RES_INTERMEDIATE_RESP
+ SEND_LDAP_INTERMEDIATE_RESP c_send_ldap_intermediate_resp;
+#endif
+
} Connection;
#if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG)
syslog( ldap_syslog_level, (fmt), (connid), (opid), (arg1), \
(arg2), (arg3) ); \
} while (0)
+#define StatslogTest( level ) ((ldap_debug | ldap_syslog) & (level))
+#elif defined(LDAP_DEBUG)
+#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) \
+ do { \
+ if ( ldap_debug & (level) ) \
+ fprintf( stderr, (fmt), (connid), (opid), (arg1), (arg2), (arg3) );\
+ } while (0)
+#define StatslogTest( level ) (ldap_debug & (level))
+#elif defined(LDAP_SYSLOG)
+#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) \
+ do { \
+ if ( ldap_syslog & (level) ) \
+ syslog( ldap_syslog_level, (fmt), (connid), (opid), (arg1), \
+ (arg2), (arg3) ); \
+ } while (0)
+#define StatslogTest( level ) (ldap_syslog & (level))
#else
#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 )
+#define StatslogTest( level ) (0)
#endif
/*
#define SLAP_LCUP_ENTRY_DELETED_FALSE 0
#endif /* LDAP_CLIENT_UPDATE */
+#if defined(LDAP_CLIENT_UPDATE) || defined(LDAP_SYNC)
+#define SLAP_SEARCH_MAX_CTRLS 10
+#endif
+
LDAP_END_DECL
#include "proto-slap.h"
/* syntax.c - routines to manage syntax definitions */
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
};
static Avlnode *syn_index = NULL;
-static Syntax *syn_list = NULL;
+static LDAP_SLIST_HEAD(SyntaxList, slap_syntax) syn_list
+ = LDAP_SLIST_HEAD_INITIALIZER(&syn_list);
static int
syn_index_cmp(
- struct sindexrec *sir1,
- struct sindexrec *sir2
+ const void *v_sir1,
+ const void *v_sir2
)
{
+ const struct sindexrec *sir1 = v_sir1, *sir2 = v_sir2;
return (strcmp( sir1->sir_name, sir2->sir_name ));
}
static int
syn_index_name_cmp(
- const char *name,
- struct sindexrec *sir
+ const void *name,
+ const void *sir
)
{
- return (strcmp( name, sir->sir_name ));
+ return (strcmp( name, ((const struct sindexrec *)sir)->sir_name ));
}
Syntax *
{
struct sindexrec *sir = NULL;
- if ( (sir = (struct sindexrec *) avl_find( syn_index, synname,
- (AVL_CMP) syn_index_name_cmp )) != NULL ) {
+ if ( (sir = avl_find( syn_index, synname, syn_index_name_cmp )) != NULL ) {
return( sir->sir_syn );
}
return( NULL );
{
Syntax *synp;
- for (synp = syn_list; synp; synp = synp->ssyn_next)
- if ((*len = dscompare( synp->ssyn_syn.syn_desc, syndesc, '{')))
+ LDAP_SLIST_FOREACH(synp, &syn_list, ssyn_next) {
+ if ((*len = dscompare( synp->ssyn_syn.syn_desc, syndesc, '{' /*'}'*/ ))) {
return synp;
+ }
+ }
return( NULL );
}
void
syn_destroy( void )
{
- Syntax *s, *n;
+ Syntax *s;
avl_free(syn_index, ldap_memfree);
- for (s=syn_list; s; s=n) {
- n = s->ssyn_next;
+ while( !LDAP_SLIST_EMPTY(&syn_list) ) {
+ s = LDAP_SLIST_FIRST(&syn_list);
+ LDAP_SLIST_REMOVE_HEAD(&syn_list, ssyn_next);
ldap_syntax_free((LDAPSyntax *)s);
}
}
const char **err
)
{
- Syntax **synp;
struct sindexrec *sir;
- synp = &syn_list;
- while ( *synp != NULL ) {
- synp = &(*synp)->ssyn_next;
- }
- *synp = ssyn;
-
+ LDAP_SLIST_INSERT_HEAD( &syn_list, ssyn, ssyn_next );
+
if ( ssyn->ssyn_oid ) {
sir = (struct sindexrec *)
SLAP_CALLOC( 1, sizeof(struct sindexrec) );
sir->sir_name = ssyn->ssyn_oid;
sir->sir_syn = ssyn;
if ( avl_insert( &syn_index, (caddr_t) sir,
- (AVL_CMP) syn_index_cmp,
- (AVL_DUP) avl_dup_error ) ) {
+ syn_index_cmp, avl_dup_error ) ) {
*err = ssyn->ssyn_oid;
ldap_memfree(sir);
return SLAP_SCHERR_SYN_DUP;
AC_MEMCPY( &ssyn->ssyn_syn, syn, sizeof(LDAPSyntax) );
- ssyn->ssyn_next = NULL;
+ LDAP_SLIST_NEXT(ssyn,ssyn_next) = NULL;
/*
* note: ssyn_bvoid uses the same memory of ssyn_syn.syn_oid;
vals[1].bv_val = NULL;
- for ( syn = syn_list; syn; syn = syn->ssyn_next ) {
+ LDAP_SLIST_FOREACH(syn, &syn_list, ssyn_next ) {
if ( ! syn->ssyn_validate ) {
/* skip syntaxes without validators */
continue;
# $OpenLDAP$
-## Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+## Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
## COPYING RESTRICTIONS APPLY, see COPYRIGHT file
#-----------------------------------------------------------------------------
# Portions Copyright (c) 1995 Regents of the University of Michigan.
XXLIBS = $(SLAPD_LIBS) \
$(LDBM_LIBS) $(SECURITY_LIBS) \
$(LDIF_LIBS) $(LUTIL_LIBS)
-XXXLIBS = $(MODULES_LIBS) $(LTHREAD_LIBS)
+XXXLIBS = $(LTHREAD_LIBS) $(MODULES_LIBS)
STATIC_DEPENDS=@SLAPD_NO_STATIC@ ../libbackends.a
../entry.o ../dn.o ../filter.o ../str2filter.o ../ava.o \
../init.o ../controls.o ../kerberos.o ../passwd.o \
../index.o ../extended.o ../starttls.o ../sets.o ../mra.o \
- ../referral.o ../backglue.o ../oidm.o ../mods.o
+ ../referral.o ../backglue.o ../oidm.o ../mods.o ../operation.o \
+ ../cancel.o
SLAPOBJS = $(SLAPD_OBJS) slapcommon.o mimic.o
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/*
}
void
-send_ldap_extended(
+slap_send_ldap_extended(
Connection *conn,
Operation *op,
ber_int_t err,
assert(0);
}
+void
+slap_send_ldap_intermediate_resp(
+ Connection *conn,
+ Operation *op,
+ ber_int_t err,
+ const char *matched,
+ const char *text,
+ BerVarray refs,
+ const char *rspoid,
+ struct berval *rspdata,
+ LDAPControl **ctrls
+)
+{
+ assert(0);
+}
+
void
send_ldap_sasl(
Connection *conn,
}
void
-send_ldap_result(
+slap_send_ldap_result(
Connection *conn,
Operation *op,
ber_int_t err,
}
void
-send_search_result(
+slap_send_search_result(
Connection *conn,
Operation *op,
ber_int_t err,
}
int
-send_search_entry(
+slap_send_search_entry(
Backend *be,
Connection *conn,
Operation *op,
return -1;
}
-int send_search_reference(
+int
+slap_send_search_reference(
Backend *be,
Connection *conn,
Operation *op,
return 0;
}
+int
+slap_mods2entry(
+ Modifications *mods,
+ Entry **e,
+ int repl_user,
+ const char **text,
+ char *textbuf, size_t textlen )
+{
+ return 0;
+}
+
+int slap_sasl_getdn( Connection *conn, char *id, int len,
+ char *user_realm, struct berval *dn, int flags )
+{
+ return -1;
+}
+
+int slap_sasl_authorized( Connection *conn,
+ struct berval *authcDN, struct berval *authzDN )
+{
+ return -1;
+}
+
/* $OpenLDAP$ */
/*
- * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* slapcommon.c - common routine for the slap tools */
case 'b':
base.bv_val = strdup( optarg );
base.bv_len = strlen( base.bv_val );
+ break;
case 'c': /* enable continue mode */
continuemode++;
rc = slap_init( mode, progname );
- if (rc != 0 ) {
+ if ( rc != 0 ) {
fprintf( stderr, "%s: slap_init failed!\n", progname );
exit( EXIT_FAILURE );
}
rc = slap_schema_init();
- if (rc != 0 ) {
+ if ( rc != 0 ) {
fprintf( stderr, "%s: slap_schema_init failed!\n", progname );
exit( EXIT_FAILURE );
}
rc = glue_sub_init();
- if (rc != 0 ) {
+ if ( rc != 0 ) {
fprintf( stderr, "Subordinate configuration error\n" );
exit( EXIT_FAILURE );
}
rc = slap_schema_check();
- if (rc != 0 ) {
+ if ( rc != 0 ) {
fprintf( stderr, "%s: slap_schema_prep failed!\n", progname );
exit( EXIT_FAILURE );
}