X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-mdb%2Fid2entry.c;h=4356363ea7184639bcb59bef27a0ce07ba6422d0;hb=8300eee0179798abe4a55cad6170044d1a80cf99;hp=7ca1658f94e035470c9700d8ddb041c8fa40af2f;hpb=a27a95571da6d9d4c319745d7958ae1a8ae30813;p=openldap diff --git a/servers/slapd/back-mdb/id2entry.c b/servers/slapd/back-mdb/id2entry.c index 7ca1658f94..4356363ea7 100644 --- a/servers/slapd/back-mdb/id2entry.c +++ b/servers/slapd/back-mdb/id2entry.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2000-2016 The OpenLDAP Foundation. + * Copyright 2000-2017 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -60,6 +60,46 @@ mdb_id2v_compare( return uv[sizeof(ID)/2] - cv[sizeof(ID)/2]; } +/* usrkey[0] is the key in DB format, as described at mdb_mval_put. + * usrkey[1] is the value we'll actually match against. + * usrkey[2] is the attributeDescription for this value. + */ +int +mdb_id2v_dupsort( + const MDB_val *usrkey, + const MDB_val *curkey +) +{ + AttributeDescription *ad = usrkey[2].mv_data; + struct berval bv1, bv2; + int rc, match, olen; + unsigned short s; + char *ptr; + + ptr = curkey->mv_data + curkey->mv_size - 2; + memcpy(&s, ptr, 2); + bv2.bv_val = curkey->mv_data; + bv2.bv_len = curkey->mv_size - 3; + if (s) + bv2.bv_len -= (s+1); + + bv1.bv_val = usrkey[1].mv_data; + bv1.bv_len = usrkey[1].mv_size; + + if (ad) { + MatchingRule *mr = ad->ad_type->sat_equality; + rc = mr->smr_match(&match, SLAP_MR_EQUALITY + | SLAP_MR_VALUE_OF_ASSERTION_SYNTAX + | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH + | SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH, + ad->ad_type->sat_syntax, mr, &bv1, &bv2); + } else { + match = ber_bvcmp(&bv1, &bv2); + } + + return match; +} + /* Values are stored as * [normalized-value NUL ] original-value NUL 2-byte-len * The trailing 2-byte-len is zero if there is no normalized value. @@ -68,7 +108,7 @@ mdb_id2v_compare( int mdb_mval_put(Operation *op, MDB_cursor *mc, ID id, Attribute *a) { struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private; - MDB_val key, data; + MDB_val key, data[3]; char *buf; char ivk[ID2VKSZ]; unsigned i; @@ -80,14 +120,24 @@ int mdb_mval_put(Operation *op, MDB_cursor *mc, ID id, Attribute *a) memcpy(ivk+sizeof(ID), &s, 2); key.mv_data = &ivk; key.mv_size = sizeof(ivk); + if ((a->a_desc->ad_type->sat_flags & SLAP_AT_ORDERED) || a->a_desc == slap_schema.si_ad_objectClass) + data[2].mv_data = NULL; + else + data[2].mv_data = a->a_desc; for (i=0; ia_numvals; i++) { len = a->a_nvals[i].bv_len + 1 + 2; - if (a->a_nvals != a->a_vals) + if (a->a_nvals != a->a_vals) { len += a->a_vals[i].bv_len + 1; - data.mv_size = len; + data[1].mv_data = a->a_nvals[i].bv_val; + data[1].mv_size = a->a_nvals[i].bv_len; + } else { + data[1].mv_data = a->a_vals[i].bv_val; + data[1].mv_size = a->a_vals[i].bv_len; + } + data[0].mv_size = len; buf = op->o_tmpalloc( len, op->o_tmpmemctx ); - data.mv_data = buf; + data[0].mv_data = buf; memcpy(buf, a->a_nvals[i].bv_val, a->a_nvals[i].bv_len); buf += a->a_nvals[i].bv_len; *buf++ = 0; @@ -101,8 +151,8 @@ int mdb_mval_put(Operation *op, MDB_cursor *mc, ID id, Attribute *a) *buf++ = 0; *buf++ = 0; } - rc = mdb_cursor_put(mc, &key, &data, 0); - op->o_tmpfree( data.mv_data, op->o_tmpmemctx ); + rc = mdb_cursor_put(mc, &key, data, 0); + op->o_tmpfree( data[0].mv_data, op->o_tmpmemctx ); if (rc) return rc; } @@ -112,7 +162,7 @@ int mdb_mval_put(Operation *op, MDB_cursor *mc, ID id, Attribute *a) int mdb_mval_del(Operation *op, MDB_cursor *mc, ID id, Attribute *a) { struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private; - MDB_val key, data; + MDB_val key, data[3]; char *ptr; char ivk[ID2VKSZ]; unsigned i; @@ -124,12 +174,23 @@ int mdb_mval_del(Operation *op, MDB_cursor *mc, ID id, Attribute *a) memcpy(ivk+sizeof(ID), &s, 2); key.mv_data = &ivk; key.mv_size = sizeof(ivk); + if ((a->a_desc->ad_type->sat_flags & SLAP_AT_ORDERED) || a->a_desc == slap_schema.si_ad_objectClass) + data[2].mv_data = NULL; + else + data[2].mv_data = a->a_desc; if (a->a_numvals) { for (i=0; ia_numvals; i++) { - data.mv_data = a->a_nvals[i].bv_val; - data.mv_size = a->a_nvals[i].bv_len+1; - rc = mdb_cursor_get(mc, &key, &data, MDB_GET_BOTH_RANGE); + data[0].mv_data = a->a_nvals[i].bv_val; + data[0].mv_size = a->a_nvals[i].bv_len+1; + if (a->a_nvals != a->a_vals) { + data[1].mv_data = a->a_nvals[i].bv_val; + data[1].mv_size = a->a_nvals[i].bv_len; + } else { + data[1].mv_data = a->a_vals[i].bv_val; + data[1].mv_size = a->a_vals[i].bv_len; + } + rc = mdb_cursor_get(mc, &key, data, MDB_GET_BOTH_RANGE); if (rc) return rc; rc = mdb_cursor_del(mc, 0); @@ -137,7 +198,7 @@ int mdb_mval_del(Operation *op, MDB_cursor *mc, ID id, Attribute *a) return rc; } } else { - rc = mdb_cursor_get(mc, &key, &data, MDB_SET); + rc = mdb_cursor_get(mc, &key, data, MDB_SET); if (rc) return rc; rc = mdb_cursor_del(mc, MDB_NODUPDATA); @@ -148,7 +209,7 @@ int mdb_mval_del(Operation *op, MDB_cursor *mc, ID id, Attribute *a) static int mdb_mval_get(Operation *op, MDB_cursor *mc, ID id, Attribute *a, int have_nvals) { struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private; - MDB_val key, data; + MDB_val key, data[3]; char *ptr; char ivk[ID2VKSZ]; unsigned i; @@ -161,28 +222,34 @@ static int mdb_mval_get(Operation *op, MDB_cursor *mc, ID id, Attribute *a, int key.mv_data = &ivk; key.mv_size = sizeof(ivk); + /* not needed */ + if ((a->a_desc->ad_type->sat_flags & SLAP_AT_ORDERED) || a->a_desc == slap_schema.si_ad_objectClass) + data[2].mv_data = NULL; + else + data[2].mv_data = a->a_desc; + if (have_nvals) a->a_nvals = a->a_vals + a->a_numvals + 1; else a->a_nvals = a->a_vals; for (i=0; ia_numvals; i++) { if (!i) - rc = mdb_cursor_get(mc, &key, &data, MDB_SET); + rc = mdb_cursor_get(mc, &key, data, MDB_SET); else - rc = mdb_cursor_get(mc, &key, &data, MDB_NEXT_DUP); + rc = mdb_cursor_get(mc, &key, data, MDB_NEXT_DUP); if (rc) return rc; - ptr = (char*)data.mv_data + data.mv_size - 2; + ptr = (char*)data[0].mv_data + data[0].mv_size - 2; memcpy(&s, ptr, 2); if (have_nvals) { - a->a_nvals[i].bv_val = data.mv_data; + a->a_nvals[i].bv_val = data[0].mv_data; a->a_vals[i].bv_len = s; a->a_vals[i].bv_val = ptr - a->a_vals[i].bv_len - 1; a->a_nvals[i].bv_len = a->a_vals[i].bv_val - a->a_nvals[i].bv_val - 1; } else { assert(!s); - a->a_vals[i].bv_val = data.mv_data; - a->a_vals[i].bv_len = data.mv_size - 3; + a->a_vals[i].bv_val = data[0].mv_data; + a->a_vals[i].bv_len = data[0].mv_size - 3; } } BER_BVZERO(&a->a_vals[i]); @@ -240,18 +307,23 @@ again: MDB_cursor *mvc; Attribute *a; rc = mdb_cursor_open( txn, mdb->mi_dbis[MDB_ID2VAL], &mvc ); - if( rc ) - return rc; - for ( a = ec.multi; a; a=a->a_next ) { - if (!(a->a_flags & SLAP_ATTR_BIG_MULTI)) - continue; - rc = mdb_mval_put( op, mvc, e->e_id, a ); - if( rc != LDAP_SUCCESS ) - break; + if( !rc ) { + for ( a = ec.multi; a; a=a->a_next ) { + if (!(a->a_flags & SLAP_ATTR_BIG_MULTI)) + continue; + rc = mdb_mval_put( op, mvc, e->e_id, a ); + if( rc ) + break; + } + mdb_cursor_close( mvc ); + } + if ( rc ) { + Debug( LDAP_DEBUG_ANY, + "mdb_id2entry_put: mdb_mval_put failed: %s(%d) \"%s\"\n", + mdb_strerror(rc), rc, + e->e_nname.bv_val ); + return LDAP_OTHER; } - mdb_cursor_close( mvc ); - if ( rc ) - return rc; } } if (rc) { @@ -317,7 +389,6 @@ int mdb_id2entry( ID id, Entry **e ) { - struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private; MDB_val key, data; int rc = 0; @@ -398,13 +469,21 @@ int mdb_id2entry_delete( return rc; rc = mdb_cursor_get( mvc, &key, NULL, MDB_SET_RANGE ); - if (rc && rc != MDB_NOTFOUND) + if (rc) { + if (rc == MDB_NOTFOUND) + rc = MDB_SUCCESS; return rc; + } while (*(ID *)key.mv_data == e->e_id ) { rc = mdb_cursor_del( mvc, MDB_NODUPDATA ); if (rc) return rc; - mdb_cursor_get( mvc, &key, NULL, MDB_GET_CURRENT ); + rc = mdb_cursor_get( mvc, &key, NULL, MDB_GET_CURRENT ); + if (rc) { + if (rc == MDB_NOTFOUND) + rc = MDB_SUCCESS; + break; + } } return rc; } @@ -459,7 +538,6 @@ int mdb_entry_release( { struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private; struct mdb_op_info *moi = NULL; - int rc; /* slapMode : SLAP_SERVER_MODE, SLAP_TOOL_MODE, SLAP_TRUNCATE_MODE, SLAP_UNDEFINED_MODE */ @@ -849,8 +927,7 @@ static int mdb_entry_partsize(struct mdb_info *mdb, MDB_txn *txn, Entry *e, static int mdb_entry_encode(Operation *op, Entry *e, MDB_val *data, Ecount *eh) { struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private; - ber_len_t len, i; - int rc; + ber_len_t i; Attribute *a; unsigned char *ptr; unsigned int *lp, l; @@ -873,10 +950,10 @@ static int mdb_entry_encode(Operation *op, Entry *e, MDB_val *data, Ecount *eh) if (!a->a_desc->ad_index) return LDAP_UNDEFINED_TYPE; l = mdb->mi_adxs[a->a_desc->ad_index]; - if (a->a_flags & SLAP_ATTR_SORTED_VALS) - l |= MDB_AT_SORTED; if (a->a_flags & SLAP_ATTR_BIG_MULTI) l |= MDB_AT_MULTI; + if (a->a_flags & SLAP_ATTR_SORTED_VALS) + l |= MDB_AT_SORTED; *lp++ = l; l = a->a_numvals; if (a->a_nvals != a->a_vals) @@ -929,7 +1006,6 @@ int mdb_entry_decode(Operation *op, MDB_txn *txn, MDB_val *data, ID id, Entry ** Attribute *a; Entry *x; const char *text; - AttributeDescription *ad; unsigned int *lp = (unsigned int *)data->mv_data; unsigned char *ptr; BerVarray bptr;