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,
71 struct timeval tv; /* time */
72 enum type_of_result err;
80 struct exception* result )
89 result->type = SUCCESS;
91 if ( e->e_dn != NULL ) {
92 tmplen = strlen( e->e_dn );
93 size = LDIF_SIZE_NEEDED( 2, tmplen );
96 for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
97 for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
99 tmplen = a->a_desc->ad_cname.bv_len;
100 size += LDIF_SIZE_NEEDED( tmplen, bv.bv_len);
103 if ((size < size_init) && result) {
104 result->type = SIZE_ERR;
109 /* quick hack: call the right callback */
111 add_merge_func( Operation *op, SlapReply *rs )
113 switch ( rs->sr_type ) {
119 merge_func( op, rs );
129 struct berval* query_uuid,
130 struct exception* result )
132 struct entry_info info;
133 struct berval normdn;
134 struct berval prettydn;
136 Operation op_tmp = *op;
137 slap_callback cb = { add_merge_func, NULL };
139 Filter* filter = str2filter( bv_queryid_any.bv_val );
141 dnPrettyNormal(0, &rs->sr_entry->e_name, &prettydn, &normdn,
144 free(rs->sr_entry->e_name.bv_val);
145 rs->sr_entry->e_name = prettydn;
146 if (rs->sr_entry->e_nname.bv_val) free(rs->sr_entry->e_nname.bv_val);
147 rs->sr_entry->e_nname = normdn;
149 info.entry = rs->sr_entry;
150 info.uuid = query_uuid;
154 info.glue_be = op->o_bd;
156 cb.sc_private = &info;
158 op_tmp.o_tag = LDAP_REQ_SEARCH;
159 op_tmp.o_protocol = LDAP_VERSION3;
160 op_tmp.o_callback = &cb;
161 op_tmp.o_caching_on = 1;
162 op_tmp.o_time = slap_get_time();
163 op_tmp.o_do_not_cache = 1;
165 op_tmp.o_req_dn = rs->sr_entry->e_name;
166 op_tmp.o_req_ndn = rs->sr_entry->e_nname;
167 op_tmp.ors_scope = LDAP_SCOPE_BASE;
168 op_tmp.ors_deref = LDAP_DEREF_NEVER;
169 op_tmp.ors_slimit = 1;
170 op_tmp.ors_tlimit = 0;
171 op_tmp.ors_filter = filter;
172 op_tmp.ors_filterstr = bv_queryid_any;
173 op_tmp.ors_attrs = NULL;
174 op_tmp.ors_attrsonly = 0;
176 op->o_bd->be_search( &op_tmp, rs );
177 result->type = info.err;
178 if ( result->type == SUCCESS )
179 result->rc = info.added;
182 return ( info.size_final - info.size_init );
193 Attribute *a_new, *a;
198 struct timeval time; /* time */
199 long timediff; /* time */
200 struct entry_info *info = op->o_callback->sc_private;
201 Filter *filter = str2filter( bv_queryid_any.bv_val );
202 Entry *entry = info->entry;
203 struct berval *uuid = info->uuid;
204 Modifications *modhead = NULL;
206 Modifications **modtail = &modhead;
207 AttributeDescription *a_new_desc;
208 const char *text = NULL;
209 Operation op_tmp = *op;
213 be = select_backend(&entry->e_nname, 0, 0);
215 info->size_init = get_entry_size(rs->sr_entry, 0, 0);
216 a_new = entry->e_attrs;
218 while (a_new != NULL) {
219 a_new_desc = a_new->a_desc;
220 mod = (Modifications *) malloc( sizeof(Modifications) );
221 mod->sml_op = LDAP_MOD_REPLACE;
222 ber_dupbv(&mod->sml_type, &a_new_desc->ad_cname);
224 for (count = 0; a_new->a_vals[count].bv_val; count++)
226 mod->sml_bvalues = (struct berval*) malloc(
227 (count+1) * sizeof( struct berval) );
229 for (i=0; i < count; i++) {
230 ber_dupbv(mod->sml_bvalues+i, a_new->a_vals+i);
233 mod->sml_bvalues[count].bv_val = 0;
234 mod->sml_bvalues[count].bv_len = 0;
236 mod->sml_desc = NULL;
237 slap_bv2ad(&mod->sml_type, &mod->sml_desc, &text);
240 modtail = &mod->sml_next;
241 a_new = a_new->a_next;
244 /* add query UUID to queryid attribute */
245 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
246 mod->sml_op = LDAP_MOD_ADD;
247 mod->sml_desc = slap_schema.si_ad_queryid;
248 ber_dupbv(&mod->sml_type, &mod->sml_desc->ad_cname);
249 mod->sml_bvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
250 ber_dupbv( mod->sml_bvalues, uuid );
251 mod->sml_bvalues[1].bv_val = NULL;
252 mod->sml_bvalues[1].bv_len = 0;
254 mod->sml_next = NULL;
257 op_tmp.o_req_dn = entry->e_name;
258 op_tmp.o_req_ndn = entry->e_nname;
259 op_tmp.orm_modlist = modhead;
261 if (be->be_modify(op, rs ) != 0 ) {
262 /* FIXME: cleanup ? */
263 info->err = MERGE_ERR;
267 /* compute the size of the entry */
268 op_tmp.o_callback->sc_response = get_size_func;
270 op_tmp.ors_scope = LDAP_SCOPE_BASE;
271 op_tmp.ors_deref = LDAP_DEREF_NEVER;
272 op_tmp.ors_slimit = 1;
273 op_tmp.ors_tlimit = 0;
274 op_tmp.ors_filter = filter;
275 op_tmp.ors_filterstr = bv_queryid_any;
276 op_tmp.ors_attrs = NULL;
277 op_tmp.ors_attrsonly = 0;
279 if (be->be_search( &op_tmp, rs ) != 0) {
280 info->err = GET_SIZE_ERR;
292 struct entry_info *info = op->o_callback->sc_private;
293 Entry *entry = info->entry;
294 struct berval *uuid = info->uuid;
296 BerVarray value_array;
300 struct timeval time; /* time */
301 long timediff; /* time */
303 Operation op_tmp = *op;
306 * new entry, construct an entry with
307 * the projected attributes
312 be = select_backend(&entry->e_nname, 0, 0);
313 e = (Entry*)malloc(sizeof(Entry));
315 ber_dupbv(&e->e_name,&entry->e_name);
316 ber_dupbv(&e->e_nname,&entry->e_nname);
322 /* add queryid attribute */
323 value_array = (struct berval *)malloc(2 * sizeof( struct berval) );
324 ber_dupbv(value_array, uuid);
325 value_array[1].bv_val = NULL;
326 value_array[1].bv_len = 0;
328 a = add_attribute(slap_schema.si_ad_queryid,
331 /* append the attribute list from the fetched entry */
332 a->a_next = entry->e_attrs;
333 entry->e_attrs = NULL;
335 info->size_final = get_entry_size(e, 0, NULL);
340 if ( be->be_add( &op_tmp, rs ) == 0 ) {
342 be_entry_release_w( &op_tmp, e );
344 info->err = MERGE_ERR;
350 add_attribute(AttributeDescription *ad,
352 BerVarray value_array)
354 Attribute* new_attr, *last_attr;
357 if (e->e_attrs == NULL)
360 for (last_attr = e->e_attrs; last_attr->a_next;
361 last_attr = last_attr->a_next)
364 new_attr = (Attribute*)malloc(sizeof(Attribute));
366 last_attr->a_next = new_attr;
368 e->e_attrs = new_attr;
370 new_attr->a_next = NULL;
371 new_attr->a_desc = NULL;
372 new_attr->a_vals = value_array;
373 new_attr->a_desc = ad;
384 struct entry_info *info = op->o_callback->sc_private;
385 struct exception result;
387 if ( rs->sr_type == REP_SEARCH ) {
388 result.type = info->err;
389 info->size_final = get_entry_size(rs->sr_entry,
390 info->size_init, &result);
396 #endif /* LDAP_CACHING */