Replaced with bi_entry_get_rw.
Implemented for back-bdb, back-ldbm, back-ldap.
return 0;
}
+
+/* return LDAP_SUCCESS IFF we can retrieve the specified entry.
+ */
+int bdb_entry_get(
+ BackendDB *be,
+ Connection *c,
+ Operation *op,
+ struct berval *ndn,
+ ObjectClass *oc,
+ AttributeDescription *at,
+ int rw,
+ Entry **ent )
+{
+ struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+ struct bdb_op_info *boi = NULL;
+ DB_TXN *txn = NULL;
+ Entry *e;
+ int rc;
+ const char *at_name = at->ad_cname.bv_val;
+
+ u_int32_t locker = 0;
+ DB_LOCK lock;
+ int free_lock_id = 0;
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, ARGS,
+ "bdb_entry_get: ndn: \"%s\"\n", ndn->bv_val, 0, 0 );
+ LDAP_LOG( BACK_BDB, ARGS,
+ "bdb_entry_get: oc: \"%s\", at: \"%s\"\n",
+ oc ? oc->soc_cname.bv_val : "(null)", at_name, 0);
+#else
+ Debug( LDAP_DEBUG_ARGS,
+ "=> bdb_entry_get: ndn: \"%s\"\n", ndn->bv_val, 0, 0 );
+ Debug( LDAP_DEBUG_ARGS,
+ "=> bdb_entry_get: oc: \"%s\", at: \"%s\"\n",
+ oc ? oc->soc_cname.bv_val : "(null)", at_name, 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 if ( !locker ) {
+ rc = LOCK_ID ( bdb->bi_dbenv, &locker );
+ free_lock_id = 1;
+ switch(rc) {
+ case 0:
+ break;
+ default:
+ return LDAP_OTHER;
+ }
+ }
+
+dn2entry_retry:
+ /* can we find entry */
+ rc = bdb_dn2entry_rw( be, txn, ndn, &e, NULL, 0, rw, locker, &lock );
+ switch( rc ) {
+ case DB_NOTFOUND:
+ case 0:
+ break;
+ case DB_LOCK_DEADLOCK:
+ case DB_LOCK_NOTGRANTED:
+ /* the txn must abort and retry */
+ if ( txn ) {
+ boi->boi_err = rc;
+ return LDAP_BUSY;
+ }
+ ldap_pvt_thread_yield();
+ goto dn2entry_retry;
+ default:
+ boi->boi_err = rc;
+ if ( free_lock_id ) {
+ LOCK_ID_FREE( bdb->bi_dbenv, locker );
+ }
+ return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY;
+ }
+ if (e == NULL) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, INFO,
+ "bdb_entry_get: cannot find entry (%s)\n",
+ ndn->bv_val, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ACL,
+ "=> bdb_entry_get: cannot find entry: \"%s\"\n",
+ ndn->bv_val, 0, 0 );
+#endif
+ if ( free_lock_id ) {
+ LOCK_ID_FREE( bdb->bi_dbenv, locker );
+ }
+ return LDAP_NO_SUCH_OBJECT;
+ }
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, DETAIL1, "bdb_entry_get: found entry (%s)\n",
+ ndn->bv_val, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ACL,
+ "=> bdb_entry_get: found entry: \"%s\"\n",
+ ndn->bv_val, 0, 0 );
+#endif
+
+#ifdef BDB_ALIASES
+ /* find attribute values */
+ if( is_entry_alias( e ) ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, INFO,
+ "bdb_entry_get: entry (%s) is an alias\n", e->e_name.bv_val, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ACL,
+ "<= bdb_entry_get: entry is an alias\n", 0, 0, 0 );
+#endif
+ rc = LDAP_ALIAS_PROBLEM;
+ goto return_results;
+ }
+#endif
+
+ if( is_entry_referral( e ) ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, INFO,
+ "bdb_entry_get: entry (%s) is a referral.\n", e->e_name.bv_val, 0, 0);
+#else
+ Debug( LDAP_DEBUG_ACL,
+ "<= bdb_entry_get: entry is a referral\n", 0, 0, 0 );
+#endif
+ rc = LDAP_REFERRAL;
+ goto return_results;
+ }
+
+ if ( oc && !is_entry_objectclass( e, oc, 0 )) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, INFO,
+ "bdb_entry_get: failed to find objectClass.\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ACL,
+ "<= bdb_entry_get: failed to find objectClass\n",
+ 0, 0, 0 );
+#endif
+ rc = LDAP_NO_SUCH_ATTRIBUTE;
+ goto return_results;
+ }
+
+return_results:
+ if( rc != LDAP_SUCCESS ) {
+ /* free entry */
+ bdb_cache_return_entry_rw(bdb->bi_dbenv, &bdb->bi_cache, e, rw, &lock);
+ } else {
+ *ent = e;
+ }
+
+ if ( free_lock_id ) {
+ LOCK_ID_FREE( bdb->bi_dbenv, locker );
+ }
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, ENTRY, "bdb_entry_get: rc=%d\n", rc, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_entry_get: rc=%d\n",
+ rc, 0, 0 );
+#endif
+ return(rc);
+}
bi->bi_extended = bdb_extended;
-#if 1
- /*
- * these routines (and their callers) are not yet designed
- * to work with transaction. Using them may cause deadlock.
- */
- bi->bi_acl_group = bdb_group;
- bi->bi_acl_attribute = bdb_attribute;
-#else
- bi->bi_acl_group = 0;
- bi->bi_acl_attribute = 0;
-#endif
-
bi->bi_chk_referrals = bdb_referrals;
bi->bi_operational = bdb_operational;
bi->bi_has_subordinates = bdb_hasSubordinates;
bi->bi_entry_release_rw = bdb_entry_release;
+ bi->bi_entry_get_rw = bdb_entry_get;
/*
* hooks for slap tools
void bdb_attr_index_destroy LDAP_P(( Avlnode *tree ));
-/*
- * attribute.c
- */
-
-BI_acl_attribute bdb_attribute;
-
/*
* dbcache.c
*/
*/
int bdb_entry_return( Entry *e );
BI_entry_release_rw bdb_entry_release;
+BI_entry_get_rw bdb_entry_get;
/*
* error.c
ID *tmp,
ID *stack );
-/*
- * group.c
- */
-
-BI_acl_group bdb_group;
-
/*
* id2entry.c
*/
bi->bi_op_unbind = 0;
bi->bi_extended = 0;
- bi->bi_acl_group = 0;
- bi->bi_acl_attribute = 0;
bi->bi_connection_init = 0;
bi->bi_connection_destroy = 0;
extern int ldap_dnattr_rewrite( struct rewrite_info *rwinfo, BerVarray a_vals, void *cookie );
#endif /* ENABLE_REWRITE */
+int ldap_build_entry( Backend *be, Connection *c, LDAPMessage *e, Entry *ent,
+ struct berval *bdn, int private );
+
LDAP_END_DECL
#endif /* SLAPD_LDAP_H */
extern BI_op_extended ldap_back_extended;
-extern BI_acl_group ldap_back_group;
-
-extern BI_acl_attribute ldap_back_attribute;
+extern BI_entry_get_rw ldap_back_entry_get;
LDAP_END_DECL
bi->bi_extended = ldap_back_extended;
- bi->bi_acl_group = ldap_back_group;
- bi->bi_acl_attribute = ldap_back_attribute;
bi->bi_chk_referrals = 0;
+ bi->bi_entry_get_rw = ldap_back_entry_get;
bi->bi_connection_init = 0;
bi->bi_connection_destroy = ldap_back_conn_destroy;
#undef ldap_debug /* silence a warning in ldap-int.h */
#include "../../../libraries/libldap/ldap-int.h"
-static int ldap_send_entry( Backend *be, Operation *op, Connection *conn,
- LDAPMessage *e, AttributeName *attrs, int attrsonly );
+#include "lutil.h"
+
+static struct berval dummy = { 0, NULL };
int
ldap_back_search(
ldap_pvt_thread_yield();
} else if (rc == LDAP_RES_SEARCH_ENTRY) {
+ Entry ent;
+ struct berval bdn;
e = ldap_first_entry(lc->ld,res);
- if ( ldap_send_entry(be, op, conn, e, attrs, attrsonly)
- == LDAP_SUCCESS ) {
+ if ( ldap_build_entry(be, conn, e, &ent, &bdn, 1) == LDAP_SUCCESS ) {
+ Attribute *a;
count++;
+ send_search_entry( be, conn, op, &ent, attrs,
+ attrsonly, NULL );
+ while (ent.e_attrs) {
+ a = ent.e_attrs;
+ ent.e_attrs = a->a_next;
+ if (a->a_vals != &dummy)
+ ber_bvarray_free(a->a_vals);
+ ch_free(a);
+ }
+
+ if ( ent.e_dn && ( ent.e_dn != bdn.bv_val ) )
+ free( ent.e_dn );
+ if ( ent.e_ndn )
+ free( ent.e_ndn );
}
ldap_msgfree(res);
return rc;
}
-static int
-ldap_send_entry(
+int
+ldap_build_entry(
Backend *be,
- Operation *op,
Connection *conn,
LDAPMessage *e,
- AttributeName *attrs,
- int attrsonly
+ Entry *ent,
+ struct berval *bdn,
+ int private
)
{
struct ldapinfo *li = (struct ldapinfo *) be->be_private;
struct berval a, mapped;
- Entry ent;
BerElement ber = *e->lm_ber;
Attribute *attr, **attrp;
- struct berval dummy = { 0, NULL };
- struct berval *bv, bdn;
+ struct berval *bv;
const char *text;
- if ( ber_scanf( &ber, "{m{", &bdn ) == LBER_ERROR ) {
+ if ( ber_scanf( &ber, "{m{", bdn ) == LBER_ERROR ) {
return LDAP_DECODING_ERROR;
}
#ifdef ENABLE_REWRITE
* Rewrite the dn of the result, if needed
*/
switch ( rewrite_session( li->rwinfo, "searchResult",
- bdn.bv_val, conn, &ent.e_name.bv_val ) ) {
+ bdn->bv_val, conn, &ent->e_name.bv_val ) ) {
case REWRITE_REGEXEC_OK:
- if ( ent.e_name.bv_val == NULL ) {
- ent.e_name = bdn;
+ if ( ent->e_name.bv_val == NULL ) {
+ ent->e_name = *bdn;
} else {
#ifdef NEW_LOGGING
LDAP_LOG( BACK_LDAP, DETAIL1,
"[rw] searchResult: \"%s\"" " -> \"%s\"\n",
- bdn.bv_val, ent.e_dn, 0 );
+ bdn->bv_val, ent->e_dn, 0 );
#else /* !NEW_LOGGING */
Debug( LDAP_DEBUG_ARGS, "rw> searchResult: \"%s\""
- " -> \"%s\"\n%s", bdn.bv_val, ent.e_dn, "" );
+ " -> \"%s\"\n%s", bdn->bv_val, ent->e_dn, "" );
#endif /* !NEW_LOGGING */
- ent.e_name.bv_len = strlen( ent.e_name.bv_val );
+ ent->e_name.bv_len = strlen( ent->e_name.bv_val );
}
break;
return LDAP_OTHER;
}
#else /* !ENABLE_REWRITE */
- ldap_back_dn_massage( li, &bdn, &ent.e_name, 0, 0 );
+ ldap_back_dn_massage( li, bdn, &ent->e_name, 0, 0 );
#endif /* !ENABLE_REWRITE */
/*
*
* FIXME: should we log anything, or delegate to dnNormalize2?
*/
- if ( dnNormalize2( NULL, &ent.e_name, &ent.e_nname ) != LDAP_SUCCESS ) {
+ if ( dnNormalize2( NULL, &ent->e_name, &ent->e_nname ) != LDAP_SUCCESS ) {
return LDAP_INVALID_DN_SYNTAX;
}
- ent.e_id = 0;
- ent.e_attrs = 0;
- ent.e_private = 0;
- attrp = &ent.e_attrs;
+ ent->e_id = 0;
+ ent->e_attrs = 0;
+ ent->e_private = 0;
+ attrp = &ent->e_attrs;
while ( ber_scanf( &ber, "{m", &a ) != LBER_ERROR ) {
ldap_back_map(&li->at_map, &a, &mapped, BACKLDAP_REMAP);
* Note: attr->a_vals can be null when using
* values result filter
*/
- attr->a_vals = &dummy;
-
+ if (private) {
+ attr->a_vals = &dummy;
+ } else {
+ attr->a_vals = ch_malloc(sizeof(struct berval));
+ attr->a_vals->bv_val = NULL;
+ attr->a_vals->bv_len = 0;
+ }
} else if ( attr->a_desc == slap_schema.si_ad_objectClass
|| attr->a_desc == slap_schema.si_ad_structuralObjectClass ) {
int last;
*attrp = attr;
attrp = &attr->a_next;
}
- send_search_entry( be, conn, op, &ent, attrs, attrsonly, NULL );
- while (ent.e_attrs) {
- attr = ent.e_attrs;
- ent.e_attrs = attr->a_next;
- if (attr->a_vals != &dummy)
- ber_bvarray_free(attr->a_vals);
- ch_free(attr);
+ /* make sure it's free'able */
+ if (!private && ent->e_name.bv_val == bdn->bv_val)
+ ber_dupbv( &ent->e_name, bdn );
+ return LDAP_SUCCESS;
+}
+
+/* return 0 IFF we can retrieve the entry with ndn
+ */
+int
+ldap_back_entry_get(
+ Backend *be,
+ Connection *conn,
+ Operation *op,
+ struct berval *ndn,
+ ObjectClass *oc,
+ AttributeDescription *at,
+ int rw,
+ Entry **ent
+)
+{
+ struct ldapinfo *li = (struct ldapinfo *) be->be_private;
+ struct ldapconn *lc;
+ int rc = 1, is_oc;
+ struct berval mapped = { 0, NULL }, bdn;
+ LDAPMessage *result = NULL, *e = NULL;
+ char *gattr[3];
+ char *filter;
+
+ ldap_back_map(&li->at_map, &at->ad_cname, &mapped, BACKLDAP_MAP);
+ if (mapped.bv_val == NULL || mapped.bv_val[0] == '\0') {
+ return 1;
}
-
- if ( ent.e_dn && ( ent.e_dn != bdn.bv_val ) )
- free( ent.e_dn );
- if ( ent.e_ndn )
- free( ent.e_ndn );
- return LDAP_SUCCESS;
+ /* Tell getconn this is a privileged op */
+ is_oc = op->o_do_not_cache;
+ op->o_do_not_cache = 1;
+ lc = ldap_back_getconn(li, conn, op);
+ if ( !lc || !ldap_back_dobind(li, lc, NULL, op) ) {
+ op->o_do_not_cache = is_oc;
+ return 1;
+ }
+ op->o_do_not_cache = is_oc;
+
+ is_oc = (strcasecmp("objectclass", mapped.bv_val) == 0);
+ if (oc && !is_oc) {
+ gattr[0] = "objectclass";
+ gattr[1] = mapped.bv_val;
+ gattr[2] = NULL;
+ } else {
+ gattr[0] = mapped.bv_val;
+ gattr[1] = NULL;
+ }
+ if (oc) {
+ char *ptr;
+ filter = ch_malloc(sizeof("(objectclass=)" + oc->soc_cname.bv_len));
+ ptr = lutil_strcopy(filter, "(objectclass=");
+ ptr = lutil_strcopy(ptr, oc->soc_cname.bv_val);
+ *ptr++ = ')';
+ *ptr++ = '\0';
+ } else {
+ filter = "(objectclass=*)";
+ }
+
+ if (ldap_search_ext_s(lc->ld, ndn->bv_val, LDAP_SCOPE_BASE, filter,
+ gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
+ LDAP_NO_LIMIT, &result) != LDAP_SUCCESS)
+ {
+ goto cleanup;
+ }
+
+ if ((e = ldap_first_entry(lc->ld, result)) == NULL) {
+ goto cleanup;
+ }
+
+ *ent = ch_malloc(sizeof(Entry));
+
+ rc = ldap_build_entry(be, conn, e, *ent, &bdn, 0);
+
+ if (rc != LDAP_SUCCESS) {
+ ch_free(*ent);
+ *ent = NULL;
+ }
+
+cleanup:
+ if (result) {
+ ldap_msgfree(result);
+ }
+
+ return(rc);
}
+
return 0;
}
+
+/* return LDAP_SUCCESS IFF we can retrieve the specified entry.
+ */
+int ldbm_back_entry_get(
+ BackendDB *be,
+ Connection *c,
+ Operation *op,
+ struct berval *ndn,
+ ObjectClass *oc,
+ AttributeDescription *at,
+ int rw,
+ Entry **ent )
+{
+ struct ldbminfo *li = (struct ldbminfo *) be->be_private;
+ Entry *e;
+ int rc;
+ const char *at_name = at->ad_cname.bv_val;
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, ARGS,
+ "ldbm_back_entry_get: ndn: \"%s\"\n", ndn->bv_val, 0, 0 );
+ LDAP_LOG( BACK_BDB, ARGS,
+ "ldbm_back_entry_get: oc: \"%s\", at: \"%s\"\n",
+ oc ? oc->soc_cname.bv_val : "(null)", at_name, 0);
+#else
+ Debug( LDAP_DEBUG_ARGS,
+ "=> ldbm_back_entry_get: ndn: \"%s\"\n", ndn->bv_val, 0, 0 );
+ Debug( LDAP_DEBUG_ARGS,
+ "=> ldbm_back_entry_get: oc: \"%s\", at: \"%s\"\n",
+ oc ? oc->soc_cname.bv_val : "(null)", at_name, 0);
+#endif
+
+ /* can we find entry */
+ e = dn2entry_rw( be, ndn, NULL, rw );
+ if (e == NULL) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, INFO,
+ "ldbm_back_entry_get: cannot find entry (%s)\n",
+ ndn->bv_val, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ACL,
+ "=> ldbm_back_entry_get: cannot find entry: \"%s\"\n",
+ ndn->bv_val, 0, 0 );
+#endif
+ return LDAP_NO_SUCH_OBJECT;
+ }
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, DETAIL1, "ldbm_back_entry_get: found entry (%s)\n",
+ ndn->bv_val, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ACL,
+ "=> ldbm_back_entry_get: found entry: \"%s\"\n",
+ ndn->bv_val, 0, 0 );
+#endif
+
+#ifdef BDB_ALIASES
+ /* find attribute values */
+ if( is_entry_alias( e ) ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, INFO,
+ "ldbm_back_entry_get: entry (%s) is an alias\n", e->e_name.bv_val, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ACL,
+ "<= ldbm_back_entry_get: entry is an alias\n", 0, 0, 0 );
+#endif
+ rc = LDAP_ALIAS_PROBLEM;
+ goto return_results;
+ }
+#endif
+
+ if( is_entry_referral( e ) ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, INFO,
+ "ldbm_back_entry_get: entry (%s) is a referral.\n", e->e_name.bv_val, 0, 0);
+#else
+ Debug( LDAP_DEBUG_ACL,
+ "<= ldbm_back_entry_get: entry is a referral\n", 0, 0, 0 );
+#endif
+ rc = LDAP_REFERRAL;
+ goto return_results;
+ }
+
+ if ( oc && !is_entry_objectclass( e, oc, 0 )) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, INFO,
+ "ldbm_back_entry_get: failed to find objectClass.\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ACL,
+ "<= ldbm_back_entry_get: failed to find objectClass\n",
+ 0, 0, 0 );
+#endif
+ rc = LDAP_NO_SUCH_ATTRIBUTE;
+ goto return_results;
+ }
+
+ rc = LDAP_SUCCESS;
+
+return_results:
+ if( rc != LDAP_SUCCESS ) {
+ /* free entry */
+ cache_return_entry_rw(&li->li_cache, e, rw);
+ } else {
+ *ent = e;
+ }
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( BACK_BDB, ENTRY, "ldbm_back_entry_get: rc=%d\n", rc, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "ldbm_back_entry_get: rc=%d\n",
+ rc, 0, 0 );
+#endif
+ return(rc);
+}
extern BI_op_delete ldbm_back_delete;
-extern BI_acl_group ldbm_back_group;
-
-extern BI_acl_attribute ldbm_back_attribute;
-
extern BI_operational ldbm_back_operational;
extern BI_has_subordinates ldbm_back_hasSubordinates;
bi->bi_extended = ldbm_back_extended;
bi->bi_entry_release_rw = ldbm_back_entry_release_rw;
- bi->bi_acl_group = ldbm_back_group;
- bi->bi_acl_attribute = ldbm_back_attribute;
+ bi->bi_entry_get_rw = ldbm_back_entry_get;
bi->bi_chk_referrals = ldbm_back_referrals;
bi->bi_operational = ldbm_back_operational;
bi->bi_has_subordinates = ldbm_back_hasSubordinates;
Connection *conn, Operation *op,
Entry *e, int rw ));
+BI_entry_get_rw ldbm_back_entry_get;
+
/*
* filterindex.c
*/
extern BI_op_delete meta_back_delete;
extern BI_op_abandon meta_back_abandon;
-extern BI_acl_group meta_back_group;
-extern BI_acl_attribute meta_back_attribute;
-
LDAP_END_DECL
#endif /* META_EXTERNAL_H */
bi->bi_extended = 0;
- bi->bi_acl_group = meta_back_group;
- bi->bi_acl_attribute = meta_back_attribute;
bi->bi_chk_referrals = 0;
bi->bi_connection_init = 0;
bi->bi_extended = 0;
bi->bi_entry_release_rw = 0;
- bi->bi_acl_group = 0;
- bi->bi_acl_attribute = 0;
bi->bi_chk_referrals = 0;
bi->bi_operational = monitor_back_operational;
bi->bi_extended = 0;
- bi->bi_acl_group = 0;
- bi->bi_acl_attribute = 0;
bi->bi_chk_referrals = 0;
bi->bi_connection_init = 0;
bi->bi_extended = 0;
- bi->bi_acl_group = 0;
- bi->bi_acl_attribute = 0;
bi->bi_chk_referrals = 0;
bi->bi_connection_init = 0;
bi->bi_extended = 0;
- bi->bi_acl_group = 0;
- bi->bi_acl_attribute = 0;
bi->bi_chk_referrals = 0;
bi->bi_connection_init = 0;
bi->bi_op_add = backsql_add;
bi->bi_op_delete = backsql_delete;
- bi->bi_acl_group = 0;
- bi->bi_acl_attribute = 0;
bi->bi_chk_referrals = 0;
bi->bi_operational = backsql_operational;
return rc;
}
+int
+be_entry_get_rw(
+ Backend *be,
+ Connection *conn,
+ Operation *op,
+ struct berval *ndn,
+ ObjectClass *oc,
+ AttributeDescription *at,
+ int rw,
+ Entry **e )
+{
+ be = select_backend( ndn, 0, 0 );
+
+ if (be == NULL) {
+ return LDAP_NO_SUCH_OBJECT;
+ }
+
+ if ( be->be_fetch ) {
+ return be->be_fetch( be, conn, op, ndn,
+ oc, at, rw, e );
+ }
+
+ return LDAP_UNWILLING_TO_PERFORM;
+}
+
int
backend_group(
Backend *be,
AttributeDescription *group_at
)
{
+ Entry *e;
+ Attribute *a;
+ int i, j, rc;
GroupAssertion *g;
if ( op->o_abandon ) return SLAPD_ABANDON;
- if ( !dn_match( &target->e_nname, gr_ndn ) ) {
- /* we won't attempt to send it to a different backend */
-
- be = select_backend( gr_ndn, 0, 0 );
-
- if (be == NULL) {
- return LDAP_NO_SUCH_OBJECT;
- }
- }
-
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
for (g = conn->c_groups; g; g=g->ga_next) {
return g->ga_res;
}
- if( be->be_group ) {
- int res = be->be_group( be, conn, op,
- target, gr_ndn, op_ndn,
- group_oc, group_at );
-
- if ( op->o_tag != LDAP_REQ_BIND && !op->o_do_not_cache ) {
- g = ch_malloc(sizeof(GroupAssertion) + gr_ndn->bv_len);
- g->ga_be = be;
- g->ga_oc = group_oc;
- g->ga_at = group_at;
- g->ga_res = res;
- g->ga_len = gr_ndn->bv_len;
- strcpy(g->ga_ndn, gr_ndn->bv_val);
- ldap_pvt_thread_mutex_lock( &conn->c_mutex );
- g->ga_next = conn->c_groups;
- conn->c_groups = g;
- ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ if ( target && dn_match( &target->e_nname, gr_ndn ) ) {
+ e = target;
+ } else {
+ rc = be_entry_get_rw(be, conn, op, gr_ndn, group_oc, group_at,
+ 0, &e );
+ }
+ if ( e ) {
+ a = attr_find( e->e_attrs, group_at );
+ if ( a ) {
+#ifdef SLAP_NVALUES
+ rc = value_find_ex( group_at,
+ SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
+ SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
+ a->a_nvals, op_ndn );
+#else
+ rc = value_find_ex( group_at, 0, a->a_vals, op_ndn );
+#endif
+ } else {
+ rc = LDAP_NO_SUCH_ATTRIBUTE;
}
+ if (e != target ) {
+ be_entry_release_r( be, conn, op, e );
+ }
+ } else {
+ rc = LDAP_NO_SUCH_OBJECT;
+ }
- return res;
+ if ( op->o_tag != LDAP_REQ_BIND && !op->o_do_not_cache ) {
+ g = ch_malloc(sizeof(GroupAssertion) + gr_ndn->bv_len);
+ g->ga_be = be;
+ g->ga_oc = group_oc;
+ g->ga_at = group_at;
+ g->ga_res = rc;
+ g->ga_len = gr_ndn->bv_len;
+ strcpy(g->ga_ndn, gr_ndn->bv_val);
+ ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+ g->ga_next = conn->c_groups;
+ conn->c_groups = g;
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
}
- return LDAP_UNWILLING_TO_PERFORM;
+ return rc;
}
int
BerVarray *vals
)
{
- if ( target == NULL || !dn_match( &target->e_nname, edn ) ) {
- /* we won't attempt to send it to a different backend */
-
- be = select_backend( edn, 0, 0 );
+ Entry *e;
+ Attribute *a;
+ int i, j, rc;
+ AccessControlState acl_state = ACL_STATE_INIT;
- if (be == NULL) {
- return LDAP_NO_SUCH_OBJECT;
- }
+ if ( target && dn_match( &target->e_nname, edn ) ) {
+ e = target;
+ } else {
+ rc = be_entry_get_rw(be, conn, op, edn, NULL, entry_at,
+ 0, &e );
+ if ( rc != LDAP_SUCCESS ) return rc;
}
- if( be->be_attribute ) {
- return be->be_attribute( be, conn, op, target, edn,
- entry_at, vals );
+ if ( e ) {
+ a = attr_find( e->e_attrs, entry_at );
+ if ( a ) {
+ BerVarray v;
+
+ if ( conn && op && access_allowed( be,
+ conn, op, e, entry_at, NULL, ACL_AUTH,
+ &acl_state ) == 0 ) {
+ rc = LDAP_INSUFFICIENT_ACCESS;
+ goto freeit;
+ }
+
+ for ( i=0; a->a_vals[i].bv_val; i++ ) ;
+
+ v = ch_malloc( sizeof(struct berval) * (i+1) );
+ for ( i=0,j=0; a->a_vals[i].bv_val; i++ ) {
+ if ( conn && op && access_allowed( be,
+ conn, op, e, entry_at,
+#ifdef SLAP_NVALUES
+ &a->a_nvals[i],
+#else
+ &a->a_vals[i],
+#endif
+ ACL_AUTH, &acl_state ) == 0 ) {
+ continue;
+ }
+ ber_dupbv( &v[j],
+#ifdef SLAP_NVALUES
+ &a->a_nvals[i]
+#else
+ &a->a_vals[i]
+#endif
+ );
+ if (v[j].bv_val ) j++;
+ }
+ if (j == 0) {
+ ch_free( v );
+ *vals = NULL;
+ rc = LDAP_INSUFFICIENT_ACCESS;
+ } else {
+ v[j].bv_val = NULL;
+ v[j].bv_len = 0;
+ *vals = v;
+ rc = LDAP_SUCCESS;
+ }
+ }
+freeit: if (e != target ) {
+ be_entry_release_r( be, conn, op, e );
+ }
}
- return LDAP_UNWILLING_TO_PERFORM;
+ return rc;
}
Attribute *backend_operational(
Connection *conn, struct berval *ndn, struct berval *cred ));
LDAP_SLAPD_F (int) be_isupdate LDAP_P(( Backend *be, struct berval *ndn ));
LDAP_SLAPD_F (struct berval *) be_root_dn LDAP_P(( Backend *be ));
+LDAP_SLAPD_F (int) be_entry_get_rw LDAP_P(( BackendDB *bd,
+ struct slap_conn *c, struct slap_op *o,
+ struct berval *ndn, ObjectClass *oc,
+ AttributeDescription *at, int rw, Entry **e ));
LDAP_SLAPD_F (int) be_entry_release_rw LDAP_P((
BackendDB *be, Connection *c, Operation *o, Entry *e, int rw ));
#define be_entry_release_r( be, c, o, e ) be_entry_release_rw( be, c, o, e, 0 )
#define be_extended bd_info->bi_extended
+#define be_fetch bd_info->bi_entry_get_rw
#define be_release bd_info->bi_entry_release_rw
#define be_chk_referrals bd_info->bi_chk_referrals
#define be_group bd_info->bi_acl_group
const char ** text,
BerVarray *refs ));
+typedef int (BI_entry_get_rw) LDAP_P((BackendDB *bd,
+ struct slap_conn *c, struct slap_op *o,
+ struct berval *ndn, ObjectClass *oc,
+ AttributeDescription *at, int rw,
+ Entry **e ));
+
typedef int (BI_entry_release_rw) LDAP_P((BackendDB *bd,
struct slap_conn *c, struct slap_op *o,
Entry *e, int rw));
struct slap_conn *c, struct slap_op *o,
struct berval *dn, struct berval *ndn,
const char **text ));
-
-typedef int (BI_acl_group) LDAP_P((Backend *bd,
- struct slap_conn *c, struct slap_op *o,
- Entry *e,
- struct berval *bdn,
- struct berval *edn,
- ObjectClass *group_oc,
- AttributeDescription *group_at ));
-
-typedef int (BI_acl_attribute) LDAP_P((Backend *bd,
- struct slap_conn *c, struct slap_op *o,
- Entry *e, struct berval *edn,
- AttributeDescription *entry_at,
- BerVarray *vals ));
-
+
typedef int (BI_operational) LDAP_P((Backend *bd,
struct slap_conn *c, struct slap_op *o,
Entry *e, AttributeName *attrs, int opattrs, Attribute **a ));
BI_op_extended *bi_extended;
/* Auxilary Functions */
+ BI_entry_get_rw *bi_entry_get_rw;
BI_entry_release_rw *bi_entry_release_rw;
BI_chk_referrals *bi_chk_referrals;
- BI_acl_group *bi_acl_group;
- BI_acl_attribute *bi_acl_attribute;
-
BI_operational *bi_operational;
BI_has_subordinates *bi_has_subordinates;