2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1999-2003 The OpenLDAP Foundation.
5 * Portions Copyright 2003 IBM Corporation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 * This work was initially developed by the Apurva Kumar for inclusion
18 * in OpenLDAP Software.
25 #include <ac/socket.h>
26 #include <ac/string.h>
31 #include "../back-ldap/back-ldap.h"
32 #include "back-meta.h"
34 #undef ldap_debug /* silence a warning in ldap-int.h */
36 #include "../../../libraries/libldap/ldap-int.h"
39 static struct berval bv_queryid_any = BER_BVC( "(queryid=*)" );
42 add_attribute(AttributeDescription *ad,
54 normalize_values( Attribute* attr );
62 struct timeval tv; /* time */
63 enum type_of_result err;
72 struct exception* result )
81 result->type = SUCCESS;
83 if ( e->e_dn != NULL ) {
84 tmplen = strlen( e->e_dn );
85 size = LDIF_SIZE_NEEDED( 2, tmplen );
88 for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
89 for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
91 tmplen = a->a_desc->ad_cname.bv_len;
92 size += LDIF_SIZE_NEEDED( tmplen, bv.bv_len);
95 if ((size < size_init) && result) {
96 result->type = SIZE_ERR;
105 struct berval* query_uuid,
106 struct exception* result )
108 struct entry_info info;
110 Modifications* modlist = NULL;
111 const char* text = NULL;
112 BerVarray value_array;
113 Attribute *uuid_attr, *attr;
115 char textbuf[SLAP_TEXT_BUFLEN];
116 size_t textlen = sizeof(textbuf);
118 SlapReply sreply = {REP_RESULT};
120 Operation op_tmp = *op;
123 sreply.sr_entry = NULL;
124 sreply.sr_nentries = 0;
126 e = ( Entry * ) ch_calloc( 1, sizeof( Entry ));
128 dnPrettyNormal(0, &rs->sr_entry->e_name, &op_tmp.o_req_dn, &op_tmp.o_req_ndn, op->o_tmpmemctx);
129 ber_dupbv( &e->e_name, &op_tmp.o_req_dn );
130 ber_dupbv( &e->e_nname, &op_tmp.o_req_ndn );
131 sl_free( op_tmp.o_req_ndn.bv_val, op->o_tmpmemctx );
132 sl_free( op_tmp.o_req_dn.bv_val, op->o_tmpmemctx );
133 op_tmp.o_req_dn = e->e_name;
134 op_tmp.o_req_ndn = e->e_nname;
138 e->e_bv.bv_val = NULL;
140 /* add queryid attribute */
141 value_array = (struct berval *)malloc(2 * sizeof( struct berval) );
142 ber_dupbv(value_array, query_uuid);
143 value_array[1].bv_val = NULL;
144 value_array[1].bv_len = 0;
146 uuid_attr = add_attribute(slap_schema.si_ad_queryid, e, value_array);
148 /* append the attribute list from the fetched entry */
149 uuid_attr->a_next = rs->sr_entry->e_attrs;
150 rs->sr_entry->e_attrs = NULL;
152 for ( attr = e->e_attrs; attr; attr = attr->a_next ) {
153 if ( normalize_values( attr ) ) {
154 info.err = MERGE_ERR;
155 result->rc = info.err;
161 info.uuid = query_uuid;
162 info.size_init = get_entry_size( rs->sr_entry, 0, 0 );
165 info.glue_be = op->o_bd;
167 cb.sc_private = &info;
168 cb.sc_response = null_response;
170 op_tmp.o_tag = LDAP_REQ_ADD;
171 op_tmp.o_protocol = LDAP_VERSION3;
172 op_tmp.o_callback = &cb;
173 op_tmp.o_time = slap_get_time();
174 op_tmp.o_do_not_cache = 1;
177 rc = op->o_bd->be_add( &op_tmp, &sreply );
179 if ( rc != LDAP_SUCCESS ) {
180 if ( rc == LDAP_ALREADY_EXISTS ) {
181 slap_entry2mods( e, &modlist, &text, textbuf, textlen );
182 op_tmp.o_tag = LDAP_REQ_MODIFY;
183 op_tmp.orm_modlist = modlist;
184 op_tmp.o_req_dn = e->e_name;
185 op_tmp.o_req_ndn = e->e_nname;
186 rc = op->o_bd->be_modify( &op_tmp, &sreply );
187 result->rc = info.added;
188 } else if ( rc == LDAP_REFERRAL ||
189 rc == LDAP_NO_SUCH_OBJECT ) {
190 syncrepl_add_glue( &op_tmp, e );
191 result->rc = info.added;
195 if ( modlist != NULL ) slap_mods_free( modlist );
198 result->rc = info.added;
199 be_entry_release_w( &op_tmp, e );
203 info.size_final = get_entry_size( e, info.size_init, result );
205 info.size_final = info.size_init;
207 return ( info.size_final - info.size_init );
211 add_attribute(AttributeDescription *ad,
213 BerVarray value_array)
215 Attribute* new_attr, *last_attr;
218 if (e->e_attrs == NULL)
221 for (last_attr = e->e_attrs; last_attr->a_next;
222 last_attr = last_attr->a_next)
225 new_attr = (Attribute*)malloc(sizeof(Attribute));
227 last_attr->a_next = new_attr;
229 e->e_attrs = new_attr;
231 new_attr->a_next = NULL;
232 new_attr->a_desc = NULL;
233 new_attr->a_vals = value_array;
234 new_attr->a_desc = ad;
248 normalize_values( Attribute* attr )
252 if (attr->a_vals == NULL) {
253 attr->a_nvals = NULL;
257 for ( nvals = 0; attr->a_vals[nvals].bv_val; nvals++ )
260 attr->a_nvals = (struct berval*)ch_malloc((nvals+1)*sizeof(struct berval));
262 if ( attr->a_desc->ad_type->sat_equality &&
263 attr->a_desc->ad_type->sat_equality->smr_normalize )
265 for ( i = 0; i < nvals; i++ ) {
266 rc = attr->a_desc->ad_type->sat_equality->smr_normalize(
267 SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
268 attr->a_desc->ad_type->sat_syntax,
269 attr->a_desc->ad_type->sat_equality,
270 &attr->a_vals[i], &attr->a_nvals[i], NULL );
273 LDAP_LOG( OPERATION, DETAIL1,
274 "Error in normalizing attribute %s value %d (%d)\n",
275 attr->a_desc->ad_cname.bv_val, i, rc );
277 Debug( LDAP_DEBUG_ANY,
278 "Error in normalizing attribute %s value %d (%d)\n",
279 attr->a_desc->ad_cname.bv_val, i, rc );
285 for ( i = 0; i < nvals; i++ ) {
286 ber_dupbv( &attr->a_nvals[i], &attr->a_vals[i] );
290 attr->a_nvals[i].bv_val = NULL;
291 attr->a_nvals[i].bv_len = 0;