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"
37 static struct berval bv_queryid_any = BER_BVC( "(queryid=*)" );
40 add_attribute(AttributeDescription *ad,
52 normalize_values( Attribute* attr );
60 struct timeval tv; /* time */
61 enum type_of_result err;
70 struct exception* result )
79 result->type = SUCCESS;
81 if ( e->e_dn != NULL ) {
82 tmplen = strlen( e->e_dn );
83 size = LDIF_SIZE_NEEDED( 2, tmplen );
86 for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
87 for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
89 tmplen = a->a_desc->ad_cname.bv_len;
90 size += LDIF_SIZE_NEEDED( tmplen, bv.bv_len);
93 if ((size < size_init) && result) {
94 result->type = SIZE_ERR;
103 struct berval* query_uuid,
104 struct exception* result )
106 struct entry_info info;
108 Modifications* modlist = NULL;
109 const char* text = NULL;
110 BerVarray value_array;
111 Attribute *uuid_attr, *attr;
114 SlapReply sreply = {REP_RESULT};
116 Operation op_tmp = *op;
119 sreply.sr_entry = NULL;
120 sreply.sr_nentries = 0;
122 e = ( Entry * ) ch_calloc( 1, sizeof( Entry ));
124 dnPrettyNormal(0, &rs->sr_entry->e_name, &op_tmp.o_req_dn, &op_tmp.o_req_ndn, op->o_tmpmemctx);
125 ber_dupbv( &e->e_name, &op_tmp.o_req_dn );
126 ber_dupbv( &e->e_nname, &op_tmp.o_req_ndn );
127 sl_free( op_tmp.o_req_ndn.bv_val, op->o_tmpmemctx );
128 sl_free( op_tmp.o_req_dn.bv_val, op->o_tmpmemctx );
129 op_tmp.o_req_dn = e->e_name;
130 op_tmp.o_req_ndn = e->e_nname;
134 e->e_bv.bv_val = NULL;
136 /* add queryid attribute */
137 value_array = (struct berval *)malloc(2 * sizeof( struct berval) );
138 ber_dupbv(value_array, query_uuid);
139 value_array[1].bv_val = NULL;
140 value_array[1].bv_len = 0;
142 uuid_attr = add_attribute(slap_schema.si_ad_queryid, e, value_array);
144 /* append the attribute list from the fetched entry */
145 uuid_attr->a_next = rs->sr_entry->e_attrs;
146 rs->sr_entry->e_attrs = NULL;
148 for ( attr = e->e_attrs; attr; attr = attr->a_next ) {
149 if ( normalize_values( attr ) ) {
150 info.err = MERGE_ERR;
151 result->rc = info.err;
157 info.uuid = query_uuid;
158 info.size_init = get_entry_size( rs->sr_entry, 0, 0 );
161 info.glue_be = op->o_bd;
163 cb.sc_private = &info;
164 cb.sc_response = null_response;
166 op_tmp.o_tag = LDAP_REQ_ADD;
167 op_tmp.o_protocol = LDAP_VERSION3;
168 op_tmp.o_callback = &cb;
169 op_tmp.o_time = slap_get_time();
170 op_tmp.o_do_not_cache = 1;
173 rc = op->o_bd->be_add( &op_tmp, &sreply );
175 if ( rc != LDAP_SUCCESS ) {
176 if ( rc == LDAP_ALREADY_EXISTS ) {
177 slap_entry2mods( e, &modlist, &text );
178 op_tmp.o_tag = LDAP_REQ_MODIFY;
179 op_tmp.orm_modlist = modlist;
180 op_tmp.o_req_dn = e->e_name;
181 op_tmp.o_req_ndn = e->e_nname;
182 rc = op->o_bd->be_modify( &op_tmp, &sreply );
183 result->rc = info.added;
184 } else if ( rc == LDAP_REFERRAL ||
185 rc == LDAP_NO_SUCH_OBJECT ) {
186 syncrepl_add_glue( &op_tmp, e );
187 result->rc = info.added;
191 if ( modlist != NULL ) slap_mods_free( modlist );
194 result->rc = info.added;
195 be_entry_release_w( &op_tmp, e );
199 info.size_final = get_entry_size( e, info.size_init, result );
201 info.size_final = info.size_init;
203 return ( info.size_final - info.size_init );
207 add_attribute(AttributeDescription *ad,
209 BerVarray value_array)
211 Attribute* new_attr, *last_attr;
214 if (e->e_attrs == NULL)
217 for (last_attr = e->e_attrs; last_attr->a_next;
218 last_attr = last_attr->a_next)
221 new_attr = (Attribute*)malloc(sizeof(Attribute));
223 last_attr->a_next = new_attr;
225 e->e_attrs = new_attr;
227 new_attr->a_next = NULL;
228 new_attr->a_desc = NULL;
229 new_attr->a_vals = value_array;
230 new_attr->a_desc = ad;
244 normalize_values( Attribute* attr )
248 if (attr->a_vals == NULL) {
249 attr->a_nvals = NULL;
253 for ( nvals = 0; attr->a_vals[nvals].bv_val; nvals++ )
256 attr->a_nvals = (struct berval*)ch_malloc((nvals+1)*sizeof(struct berval));
258 if ( attr->a_desc->ad_type->sat_equality &&
259 attr->a_desc->ad_type->sat_equality->smr_normalize )
261 for ( i = 0; i < nvals; i++ ) {
262 rc = attr->a_desc->ad_type->sat_equality->smr_normalize(
263 SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
264 attr->a_desc->ad_type->sat_syntax,
265 attr->a_desc->ad_type->sat_equality,
266 &attr->a_vals[i], &attr->a_nvals[i], NULL );
269 LDAP_LOG( OPERATION, DETAIL1,
270 "Error in normalizing attribute %s value %d (%d)\n",
271 attr->a_desc->ad_cname.bv_val, i, rc );
273 Debug( LDAP_DEBUG_ANY,
274 "Error in normalizing attribute %s value %d (%d)\n",
275 attr->a_desc->ad_cname.bv_val, i, rc );
281 for ( i = 0; i < nvals; i++ ) {
282 ber_dupbv( &attr->a_nvals[i], &attr->a_vals[i] );
286 attr->a_nvals[i].bv_val = NULL;
287 attr->a_nvals[i].bv_len = 0;