1 /* Copyright (c) 2003 by International Business Machines, Inc.
3 * International Business Machines, Inc. (hereinafter called IBM) grants
4 * permission under its copyrights to use, copy, modify, and distribute this
5 * Software with or without fee, provided that the above copyright notice and
6 * all paragraphs of this notice appear in all copies, and that the name of IBM
7 * not be used in connection with the marketing of any product incorporating
8 * the Software or modifications thereof, without specific, written prior
11 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
12 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
13 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
14 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
15 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
16 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
23 #include <ac/socket.h>
24 #include <ac/string.h>
29 #include "../back-ldap/back-ldap.h"
30 #include "back-meta.h"
32 #undef ldap_debug /* silence a warning in ldap-int.h */
34 #include "../../../libraries/libldap/ldap-int.h"
39 static struct berval bv_queryid_any = BER_BVC( "(queryid=*)" );
54 add_attribute(AttributeDescription *ad,
72 normalize_values( Attribute* attr );
80 struct timeval tv; /* time */
81 enum type_of_result err;
90 struct exception* result )
99 result->type = SUCCESS;
101 if ( e->e_dn != NULL ) {
102 tmplen = strlen( e->e_dn );
103 size = LDIF_SIZE_NEEDED( 2, tmplen );
106 for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
107 for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
109 tmplen = a->a_desc->ad_cname.bv_len;
110 size += LDIF_SIZE_NEEDED( tmplen, bv.bv_len);
113 if ((size < size_init) && result) {
114 result->type = SIZE_ERR;
119 /* quick hack: call the right callback */
121 add_merge_func( Operation *op, SlapReply *rs )
123 switch ( rs->sr_type ) {
125 merge_func( op, rs );
142 struct berval* query_uuid,
143 struct exception* result )
145 struct entry_info info;
146 struct berval normdn;
147 struct berval prettydn;
149 SlapReply sreply = {REP_RESULT};
151 Operation op_tmp = *op;
152 slap_callback cb = { add_merge_func, NULL };
154 Filter* filter = str2filter( bv_queryid_any.bv_val );
155 sreply.sr_entry = NULL;
156 sreply.sr_nentries = 0;
158 dnPrettyNormal(0, &rs->sr_entry->e_name, &prettydn, &normdn,
161 free(rs->sr_entry->e_name.bv_val);
162 rs->sr_entry->e_name = prettydn;
163 if (rs->sr_entry->e_nname.bv_val) free(rs->sr_entry->e_nname.bv_val);
164 rs->sr_entry->e_nname = normdn;
166 info.entry = rs->sr_entry;
167 info.uuid = query_uuid;
171 info.glue_be = op->o_bd;
173 cb.sc_private = &info;
175 op_tmp.o_tag = LDAP_REQ_SEARCH;
176 op_tmp.o_protocol = LDAP_VERSION3;
177 op_tmp.o_callback = &cb;
178 op_tmp.o_caching_on = 1;
179 op_tmp.o_time = slap_get_time();
180 op_tmp.o_do_not_cache = 1;
182 op_tmp.o_req_dn = rs->sr_entry->e_name;
183 op_tmp.o_req_ndn = rs->sr_entry->e_nname;
184 op_tmp.ors_scope = LDAP_SCOPE_BASE;
185 op_tmp.ors_deref = LDAP_DEREF_NEVER;
186 op_tmp.ors_slimit = 1;
187 op_tmp.ors_tlimit = 0;
188 op_tmp.ors_filter = filter;
189 op_tmp.ors_filterstr = bv_queryid_any;
190 op_tmp.ors_attrs = NULL;
191 op_tmp.ors_attrsonly = 0;
193 op->o_bd->be_search( &op_tmp, &sreply );
194 result->type = info.err;
195 if ( result->type == SUCCESS )
196 result->rc = info.added;
199 return ( info.size_final - info.size_init );
210 Attribute *a_new, *a;
215 struct timeval time; /* time */
216 long timediff; /* time */
217 struct entry_info *info = op->o_callback->sc_private;
218 Filter *filter = str2filter( bv_queryid_any.bv_val );
219 Entry *entry = info->entry;
220 struct berval *uuid = info->uuid;
221 Modifications *modhead = NULL;
223 Modifications **modtail = &modhead;
224 AttributeDescription *a_new_desc;
225 const char *text = NULL;
226 Operation op_tmp = *op;
227 SlapReply sreply = {REP_RESULT};
228 SlapReply sreply1 = {REP_RESULT};
232 be = select_backend(&entry->e_nname, 0, 0);
234 info->size_init = get_entry_size(rs->sr_entry, 0, 0);
235 a_new = entry->e_attrs;
237 while (a_new != NULL) {
238 a_new_desc = a_new->a_desc;
239 mod = (Modifications *) malloc( sizeof(Modifications) );
240 mod->sml_op = LDAP_MOD_REPLACE;
241 ber_dupbv(&mod->sml_type, &a_new_desc->ad_cname);
243 for ( count = 0; a_new->a_vals[count].bv_val; count++ )
246 mod->sml_bvalues = (struct berval*) malloc(
247 (count+1) * sizeof( struct berval) );
249 mod->sml_nvalues = (struct berval*) malloc(
250 (count+1) * sizeof( struct berval) );
252 for ( i = 0; i < count; i++ ) {
253 ber_dupbv(mod->sml_bvalues+i, a_new->a_vals+i);
254 if ( a_new->a_desc->ad_type->sat_equality &&
255 a_new->a_desc->ad_type->sat_equality->smr_normalize ) {
256 rc = a_new->a_desc->ad_type->sat_equality->smr_normalize(
258 a_new->a_desc->ad_type->sat_syntax,
259 a_new->a_desc->ad_type->sat_equality,
260 a_new->a_vals+i, mod->sml_nvalues+i, NULL );
262 info->err = MERGE_ERR;
267 ber_dupbv( mod->sml_nvalues+i, a_new->a_vals+i );
271 mod->sml_bvalues[count].bv_val = 0;
272 mod->sml_bvalues[count].bv_len = 0;
274 mod->sml_nvalues[count].bv_val = 0;
275 mod->sml_nvalues[count].bv_len = 0;
277 mod->sml_desc = NULL;
278 slap_bv2ad(&mod->sml_type, &mod->sml_desc, &text);
281 modtail = &mod->sml_next;
282 a_new = a_new->a_next;
285 /* add query UUID to queryid attribute */
286 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
287 mod->sml_op = LDAP_MOD_ADD;
288 mod->sml_desc = slap_schema.si_ad_queryid;
289 ber_dupbv(&mod->sml_type, &mod->sml_desc->ad_cname);
291 mod->sml_bvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
292 ber_dupbv( mod->sml_bvalues, uuid );
293 mod->sml_bvalues[1].bv_val = NULL;
294 mod->sml_bvalues[1].bv_len = 0;
296 mod->sml_nvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
297 ber_dupbv( mod->sml_nvalues, uuid );
298 mod->sml_nvalues[1].bv_val = NULL;
299 mod->sml_nvalues[1].bv_len = 0;
302 mod->sml_next = NULL;
305 op_tmp.o_req_dn = entry->e_name;
306 op_tmp.o_req_ndn = entry->e_nname;
307 op_tmp.orm_modlist = modhead;
309 op_tmp.o_callback->sc_response = null_response;
310 /* FIXME: &op_tmp ??? */
311 if (be->be_modify(&op_tmp, &sreply ) != 0 ) {
312 /* FIXME: cleanup ? */
313 info->err = MERGE_ERR;
317 /* compute the size of the entry */
318 op_tmp.o_callback->sc_response = get_size_func;
320 op_tmp.ors_scope = LDAP_SCOPE_BASE;
321 op_tmp.ors_deref = LDAP_DEREF_NEVER;
322 op_tmp.ors_slimit = 1;
323 op_tmp.ors_tlimit = 0;
324 op_tmp.ors_filter = filter;
325 op_tmp.ors_filterstr = bv_queryid_any;
326 op_tmp.ors_attrs = NULL;
327 op_tmp.ors_attrsonly = 0;
329 sreply1.sr_entry = NULL;
330 sreply1.sr_nentries = 0;
332 if (be->be_search( &op_tmp, &sreply1 ) != 0) {
333 info->err = GET_SIZE_ERR;
337 if ( modhead != NULL) {
338 slap_mods_free( modhead );
350 struct entry_info *info = op->o_callback->sc_private;
351 Entry *entry = info->entry;
352 struct berval *uuid = info->uuid;
354 BerVarray value_array;
358 SlapReply sreply = {REP_RESULT};
360 struct timeval time; /* time */
361 long timediff; /* time */
363 Operation op_tmp = *op;
366 * new entry, construct an entry with
367 * the projected attributes
369 if (rs->sr_nentries) {
373 op_tmp.o_callback->sc_response = null_response;
374 be = select_backend(&entry->e_nname, 0, 0);
375 e = (Entry*)malloc(sizeof(Entry));
377 ber_dupbv(&e->e_name,&entry->e_name);
378 ber_dupbv(&e->e_nname,&entry->e_nname);
384 /* add queryid attribute */
385 value_array = (struct berval *)malloc(2 * sizeof( struct berval) );
386 ber_dupbv(value_array, uuid);
387 value_array[1].bv_val = NULL;
388 value_array[1].bv_len = 0;
390 a = add_attribute(slap_schema.si_ad_queryid,
393 /* append the attribute list from the fetched entry */
394 a->a_next = entry->e_attrs;
395 entry->e_attrs = NULL;
397 for ( attr = e->e_attrs; attr; attr = attr->a_next ) {
398 if ( normalize_values( attr ) ) {
399 info->err = MERGE_ERR;
404 info->size_final = get_entry_size( e, 0, NULL );
409 if ( be->be_add( &op_tmp, &sreply ) == 0 ) {
411 be_entry_release_w( &op_tmp, e );
413 info->err = MERGE_ERR;
419 add_attribute(AttributeDescription *ad,
421 BerVarray value_array)
423 Attribute* new_attr, *last_attr;
426 if (e->e_attrs == NULL)
429 for (last_attr = e->e_attrs; last_attr->a_next;
430 last_attr = last_attr->a_next)
433 new_attr = (Attribute*)malloc(sizeof(Attribute));
435 last_attr->a_next = new_attr;
437 e->e_attrs = new_attr;
439 new_attr->a_next = NULL;
440 new_attr->a_desc = NULL;
441 new_attr->a_vals = value_array;
442 new_attr->a_desc = ad;
453 struct entry_info *info = op->o_callback->sc_private;
454 struct exception result;
456 if ( rs->sr_type == REP_SEARCH ) {
457 result.type = info->err;
458 info->size_final = get_entry_size(rs->sr_entry,
459 info->size_init, &result);
475 normalize_values( Attribute* attr )
479 if (attr->a_vals == NULL) {
480 attr->a_nvals = NULL;
484 for ( nvals = 0; attr->a_vals[nvals].bv_val; nvals++ )
487 attr->a_nvals = (struct berval*)ch_malloc((nvals+1)*sizeof(struct berval));
489 if ( attr->a_desc->ad_type->sat_equality &&
490 attr->a_desc->ad_type->sat_equality->smr_normalize )
492 for ( i = 0; i < nvals; i++ ) {
493 rc = attr->a_desc->ad_type->sat_equality->smr_normalize(
495 attr->a_desc->ad_type->sat_syntax,
496 attr->a_desc->ad_type->sat_equality,
497 &attr->a_vals[i], &attr->a_nvals[i], NULL );
500 LDAP_LOG( OPERATION, DETAIL1,
501 "Error in normalizing attribute %s value %d (%d)\n",
502 attr->a_desc->ad_cname.bv_val, i, rc );
504 Debug( LDAP_DEBUG_ANY,
505 "Error in normalizing attribute %s value %d (%d)\n",
506 attr->a_desc->ad_cname.bv_val, i, rc );
512 for ( i = 0; i < nvals; i++ ) {
513 ber_dupbv( &attr->a_nvals[i], &attr->a_vals[i] );
517 attr->a_nvals[i].bv_val = NULL;
518 attr->a_nvals[i].bv_len = 0;
523 #endif /* LDAP_CACHING */