]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_ops.c
17b566b6f37d03c19e7c8ca91db69e19b35c2b37
[openldap] / servers / slapd / slapi / slapi_ops.c
1 /*\r
2  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.\r
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file\r
4  */\r
5 /*\r
6  * (C) Copyright IBM Corp. 1997,2002\r
7  * Redistribution and use in source and binary forms are permitted\r
8  * provided that this notice is preserved and that due credit is\r
9  * given to IBM Corporation. This software is provided ``as is''\r
10  * without express or implied warranty.\r
11  */\r
12 \r
13 #include "portable.h"\r
14 #include "slapi_common.h"\r
15 #include <slap.h>\r
16 #include <slapi.h>\r
17 #include <lber.h>\r
18 #include "../../../libraries/liblber/lber-int.h"\r
19 \r
20 \r
21 int bvptr2obj( struct berval **bvptr, struct berval **bvobj );\r
22 \r
23 static void\r
24 internal_result_v3(\r
25         Connection      *conn, \r
26         Operation       *op, \r
27         ber_int_t       err,\r
28         const char      *matched, \r
29         const char      *text, \r
30         BerVarray       referrals,\r
31         LDAPControl     **ctrls )\r
32 {\r
33         return;\r
34 }\r
35 \r
36 static int\r
37 internal_search_entry(\r
38         Backend         *be, \r
39         Connection      *conn, \r
40         Operation       *op, \r
41         Entry           *e, \r
42         AttributeName   *attrs, \r
43         int             attrsonly, \r
44         LDAPControl     **ctrls ) \r
45 {\r
46         char *ent2str = NULL;\r
47         int nentries = 0, len = 0, i = 0;\r
48         Slapi_Entry **head = NULL, **tp;\r
49         \r
50         ent2str = slapi_entry2str( e, &len );\r
51         if ( ent2str == NULL ) {\r
52                 return 1;\r
53         }\r
54 \r
55         slapi_pblock_get( (Slapi_PBlock *)op->o_pb,\r
56                         SLAPI_NENTRIES, &nentries );\r
57         slapi_pblock_get( (Slapi_PBlock *)op->o_pb,\r
58                         SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head );\r
59         \r
60         i = nentries + 1;\r
61         if ( nentries == 0 ) {\r
62                 tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) );\r
63                 if ( tp == NULL ) {\r
64                         return 1;\r
65                 }\r
66 \r
67                 tp[ 0 ] = (Slapi_Entry *)str2entry( ent2str );\r
68                 if ( tp[ 0 ] == NULL ) { \r
69                         return 1;\r
70                 }\r
71 \r
72         } else {\r
73                 tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head,\r
74                                 sizeof(Slapi_Entry *) * ( i + 1 ) );\r
75                 if ( tp == NULL ) {\r
76                         return 1;\r
77                 }\r
78                 tp[ i - 1 ] = (Slapi_Entry *)str2entry( ent2str );\r
79                 if ( tp[ i - 1 ] == NULL ) { \r
80                         return 1;\r
81                 }\r
82         }\r
83         tp[ i ] = NULL;\r
84                   \r
85         slapi_pblock_set( (Slapi_PBlock *)op->o_pb,\r
86                         SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, (void *)tp );\r
87         slapi_pblock_set( (Slapi_PBlock *)op->o_pb,\r
88                         SLAPI_NENTRIES, (void *)i );\r
89 \r
90         return LDAP_SUCCESS;\r
91 }\r
92 \r
93 static void\r
94 internal_search_result(\r
95         Connection      *conn, \r
96         Operation       *op,\r
97         ber_int_t       err, \r
98         const char      *matched, \r
99         const char      *text, \r
100         BerVarray       refs,\r
101         LDAPControl     **ctrls,\r
102         int             nentries ) \r
103 {\r
104         slapi_pblock_set( (Slapi_PBlock *)op->o_pb,\r
105                         SLAPI_NENTRIES, (void *)nentries );\r
106 \r
107         return;\r
108 }\r
109 \r
110 static void\r
111 internal_result_ext(\r
112         Connection      *conn, \r
113         Operation       *op, \r
114         ber_int_t       errnum, \r
115         const char      *matched,\r
116         const char      *text,\r
117         BerVarray       refs,\r
118         const char      *rspoid,\r
119         struct berval   *rspdata,\r
120         LDAPControl     **ctrls )\r
121 {\r
122         return;\r
123 }\r
124 \r
125 static int\r
126 internal_search_reference(\r
127         Backend         *be,\r
128         Connection      *conn, \r
129         Operation       *op, \r
130         Entry           *e,\r
131         BerVarray       refs,\r
132         LDAPControl     **ctrls,\r
133         BerVarray       *v2refs )\r
134 {\r
135         return LDAP_SUCCESS;\r
136 }\r
137 \r
138 static Connection *\r
139 fakeConnection(\r
140         char *DN, \r
141         int OpType ) \r
142\r
143         Connection *pConn, *c;\r
144         ber_len_t max = sockbuf_max_incoming;\r
145 \r
146         pConn = (Connection *) slapi_ch_calloc(1, sizeof(Connection));\r
147         if (pConn == NULL) {\r
148                 return (Connection *)NULL;\r
149         }\r
150 \r
151         LDAP_STAILQ_INIT( &pConn->c_pending_ops );\r
152 \r
153         pConn->c_pending_ops.stqh_first =\r
154                 (Operation *) slapi_ch_calloc( 1, sizeof(Operation) );\r
155         if ( pConn->c_pending_ops.stqh_first == NULL ) { \r
156                 slapi_ch_free( (void **)&pConn );\r
157                 return (Connection *)NULL;\r
158         }\r
159 \r
160         pConn->c_pending_ops.stqh_first->o_pb = \r
161                 (Slapi_PBlock *) slapi_pblock_new();\r
162         if ( pConn->c_pending_ops.stqh_first->o_pb == NULL ) {\r
163                 slapi_ch_free( (void **)&pConn->c_pending_ops.stqh_first );\r
164                 slapi_ch_free( (void **)&pConn );\r
165                 return (Connection *)NULL;\r
166         }\r
167 \r
168         c = pConn;\r
169 \r
170         /* operation object */\r
171         c->c_pending_ops.stqh_first->o_tag = OpType;\r
172         c->c_pending_ops.stqh_first->o_protocol = LDAP_VERSION3; \r
173         c->c_pending_ops.stqh_first->o_authmech.bv_val = NULL; \r
174         c->c_pending_ops.stqh_first->o_authmech.bv_len = 0; \r
175         c->c_pending_ops.stqh_first->o_time = slap_get_time();\r
176         c->c_pending_ops.stqh_first->o_do_not_cache = 1;\r
177         c->c_pending_ops.stqh_first->o_threadctx = ldap_pvt_thread_pool_context( &connection_pool );\r
178 \r
179         /* connection object */\r
180         c->c_authmech.bv_val = NULL;\r
181         c->c_authmech.bv_len = 0;\r
182         c->c_dn.bv_val = NULL;\r
183         c->c_dn.bv_len = 0;\r
184         c->c_ndn.bv_val = NULL;\r
185         c->c_ndn.bv_len = 0;\r
186         c->c_groups = NULL;\r
187 \r
188         c->c_listener = NULL;\r
189         c->c_peer_domain.bv_val = NULL;\r
190         c->c_peer_domain.bv_len = 0;\r
191         c->c_peer_name.bv_val = NULL;\r
192         c->c_peer_name.bv_len = 0;\r
193 \r
194         LDAP_STAILQ_INIT( &c->c_ops );\r
195 \r
196         c->c_sasl_bind_mech.bv_val = NULL;\r
197         c->c_sasl_bind_mech.bv_len = 0;\r
198         c->c_sasl_context = NULL;\r
199         c->c_sasl_extra = NULL;\r
200 \r
201         c->c_sb = ber_sockbuf_alloc( );\r
202 \r
203         ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );\r
204 \r
205         c->c_currentber = NULL;\r
206 \r
207         /* should check status of thread calls */\r
208         ldap_pvt_thread_mutex_init( &c->c_mutex );\r
209         ldap_pvt_thread_mutex_init( &c->c_write_mutex );\r
210         ldap_pvt_thread_cond_init( &c->c_write_cv );\r
211 \r
212         c->c_n_ops_received = 0;\r
213         c->c_n_ops_executing = 0;\r
214         c->c_n_ops_pending = 0;\r
215         c->c_n_ops_completed = 0;\r
216 \r
217         c->c_n_get = 0;\r
218         c->c_n_read = 0;\r
219         c->c_n_write = 0;\r
220 \r
221         c->c_protocol = LDAP_VERSION3; \r
222 \r
223         c->c_activitytime = c->c_starttime = slap_get_time();\r
224 \r
225         c->c_connid = 0;\r
226 \r
227         c->c_conn_state  = 0x01;        /* SLAP_C_ACTIVE */\r
228         c->c_struct_state = 0x02;       /* SLAP_C_USED */\r
229 \r
230         c->c_ssf = c->c_transport_ssf = 0;\r
231         c->c_tls_ssf = 0;\r
232 \r
233         backend_connection_init( c );\r
234 \r
235         pConn->c_send_ldap_result = internal_result_v3;\r
236         pConn->c_send_search_entry = internal_search_entry;\r
237         pConn->c_send_search_result = internal_search_result;\r
238         pConn->c_send_ldap_extended = internal_result_ext;\r
239         pConn->c_send_search_reference = internal_search_reference;\r
240 \r
241         return pConn;\r
242 }\r
243 \r
244 /* \r
245  * Function : ValuestoBValues \r
246  * Convert an array of char ptrs to an array of berval ptrs.\r
247  * return value : LDAP_SUCCESS\r
248  *                LDAP_NO_MEMORY\r
249  *                LDAP_OTHER\r
250 */\r
251 \r
252 static int \r
253 ValuesToBValues(\r
254         char **ppValue, \r
255         struct berval ***pppBV )\r
256 {\r
257         int  rc = LDAP_SUCCESS;\r
258         int  i;\r
259         struct berval *pTmpBV;\r
260         struct berval **ppNewBV;\r
261 \r
262         /* count the number of char ptrs. */\r
263         for ( i = 0; ppValue != NULL && ppValue[i] != NULL; i++ ) {\r
264                 ;       /* NULL */\r
265         }\r
266 \r
267         if ( i == 0 ) {\r
268                 rc = LDAP_OTHER;\r
269         } else {\r
270                 *pppBV = ppNewBV = (struct berval **)slapi_ch_malloc( (i+1)*(sizeof(struct berval *)) );\r
271                 if ( *pppBV == NULL ) {\r
272                         rc = LDAP_NO_MEMORY;\r
273                 } else {\r
274                         while ( ppValue != NULL && *ppValue != NULL && rc == LDAP_SUCCESS ) {\r
275                                 pTmpBV = (struct berval *)slapi_ch_malloc(sizeof(struct berval));\r
276                                 if ( pTmpBV == NULL) {\r
277                                         rc = LDAP_NO_MEMORY;\r
278                                 } else {\r
279                                         pTmpBV->bv_val = slapi_ch_strdup(*ppValue);\r
280                                         if ( pTmpBV->bv_val == NULL ) {\r
281                                                 rc = LDAP_NO_MEMORY;\r
282                                         } else {\r
283                                                 pTmpBV->bv_len = strlen(*ppValue);\r
284                                                 *ppNewBV = pTmpBV;\r
285                                                 ppNewBV++;\r
286                                         }\r
287                                         ppValue++;\r
288                                 }\r
289                         }\r
290                         /* null terminate the array of berval ptrs */\r
291                         *ppNewBV = NULL;\r
292                 }\r
293         }\r
294         return( rc );\r
295 }\r
296 \r
297 \r
298 /*\r
299  * Function : LDAPModToEntry \r
300  * convert a dn plus an array of LDAPMod struct ptrs to an entry structure\r
301  * with a link list of the correspondent attributes.\r
302  * Return value : LDAP_SUCCESS\r
303  *                LDAP_NO_MEMORY\r
304  *                LDAP_OTHER\r
305 */\r
306 Entry *\r
307 LDAPModToEntry(\r
308         char *ldn, \r
309         LDAPMod **mods )\r
310 {\r
311         struct berval           dn = { 0, NULL };\r
312         Entry                   *pEntry=NULL;\r
313         LDAPMod                 *pMod;\r
314         struct berval           *bv;\r
315         struct berval           **ppBV;\r
316         Backend                 *be;\r
317         Operation               *op;\r
318 \r
319         Modifications           *modlist = NULL;\r
320         Modifications           **modtail = &modlist;\r
321         Modifications           tmp;\r
322 \r
323         int                     rc = LDAP_SUCCESS;\r
324         int                     i;\r
325 \r
326         const char              *text = NULL;\r
327 \r
328 \r
329         op = (Operation *) slapi_ch_calloc(1, sizeof(Operation));\r
330         if ( pEntry == NULL) {\r
331                 rc = LDAP_NO_MEMORY;\r
332                 goto cleanup;\r
333         }  \r
334         op->o_tag = LDAP_REQ_ADD;\r
335 \r
336         pEntry = (Entry *) ch_calloc( 1, sizeof(Entry) );\r
337         if ( pEntry == NULL) {\r
338                 rc = LDAP_NO_MEMORY;\r
339                 goto cleanup;\r
340         } \r
341 \r
342         dn.bv_val = slapi_ch_strdup(ldn);\r
343         dn.bv_len = strlen(ldn);\r
344 \r
345         rc = dnPrettyNormal( NULL, &dn, &pEntry->e_name, &pEntry->e_nname );\r
346         if (rc != LDAP_SUCCESS) goto cleanup;\r
347 \r
348         if ( rc == LDAP_SUCCESS ) {\r
349                 for ( i=0, pMod=mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod=mods[++i]) {\r
350                         Modifications *mod;\r
351                         if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {\r
352                                 /* attr values are in berval format */\r
353                                 /* convert an array of pointers to bervals to an array of bervals */\r
354                                 rc = bvptr2obj(pMod->mod_bvalues, &bv);\r
355                                 if (rc != LDAP_SUCCESS) goto cleanup;\r
356                                 tmp.sml_type.bv_val = slapi_ch_strdup(pMod->mod_type);\r
357                                 tmp.sml_type.bv_len = slapi_ch_stlen(pMod->mod_type);\r
358                                 tmp.sml_bvalues = bv;\r
359                 \r
360                                 mod  = (Modifications *) ch_malloc( sizeof(Modifications) );\r
361 \r
362                                 mod->sml_op = LDAP_MOD_ADD;\r
363                                 mod->sml_next = NULL;\r
364                                 mod->sml_desc = NULL;\r
365                                 mod->sml_type = tmp.sml_type;\r
366                                 mod->sml_bvalues = tmp.sml_bvalues;\r
367 \r
368                                 *modtail = mod;\r
369                                 modtail = &mod->sml_next;\r
370 \r
371                         } else {\r
372                                 /* attr values are in string format, need to be converted */\r
373                                 /* to an array of bervals */ \r
374                                 if ( pMod->mod_values == NULL ) {\r
375                                         rc = LDAP_OTHER;\r
376                                 } else {\r
377                                         rc = ValuesToBValues( pMod->mod_values, &ppBV );\r
378                                         if (rc != LDAP_SUCCESS) goto cleanup;\r
379                                         rc = bvptr2obj(ppBV, &bv);\r
380                                         if (rc != LDAP_SUCCESS) goto cleanup;\r
381                                         tmp.sml_type.bv_val = slapi_ch_strdup(pMod->mod_type);\r
382                                         tmp.sml_type.bv_len = slapi_ch_stlen(pMod->mod_type);\r
383                                         tmp.sml_bvalues = bv;\r
384                 \r
385                                         mod  = (Modifications *) ch_malloc( sizeof(Modifications) );\r
386 \r
387                                         mod->sml_op = LDAP_MOD_ADD;\r
388                                         mod->sml_next = NULL;\r
389                                         mod->sml_desc = NULL;\r
390                                         mod->sml_type = tmp.sml_type;\r
391                                         mod->sml_bvalues = tmp.sml_bvalues;\r
392 \r
393                                         *modtail = mod;\r
394                                         modtail = &mod->sml_next;\r
395 \r
396                                         if ( ppBV != NULL ) {\r
397                                                 ber_bvecfree( ppBV );\r
398                                         }\r
399                                 }\r
400                         }\r
401                 } /* for each LDAPMod */\r
402         }\r
403 \r
404         be = select_backend(&dn, 0, 0);\r
405         if ( be == NULL ) {\r
406                 rc =  LDAP_PARTIAL_RESULTS;\r
407                 goto cleanup;\r
408         }\r
409 \r
410         if ( be ) {\r
411                 int repl_user = be_isupdate(be, &be->be_rootdn );\r
412                 if ( !be->be_update_ndn.bv_len || repl_user ) {\r
413                         int update = be->be_update_ndn.bv_len;\r
414                         char textbuf[SLAP_TEXT_BUFLEN];\r
415                         size_t textlen = sizeof textbuf;\r
416 \r
417                         rc = slap_mods_check( modlist, update, &text, \r
418                                         textbuf, textlen );\r
419                         if ( rc != LDAP_SUCCESS) {\r
420                                 goto cleanup;\r
421                         }\r
422 \r
423                         if ( !repl_user ) {\r
424                                 rc = slap_mods_opattrs( be, op,\r
425                                                 modlist, modtail, &text, \r
426                                                 textbuf, textlen );\r
427                                 if ( rc != LDAP_SUCCESS) {\r
428                                         goto cleanup;\r
429                                 }\r
430                         }\r
431 \r
432                         /*\r
433                          * FIXME: slap_mods2entry is declared static \r
434                          * in servers/slapd/add.c\r
435                          */\r
436                         rc = slap_mods2entry( modlist, &pEntry, repl_user,\r
437                                         &text, textbuf, textlen );\r
438                         if (rc != LDAP_SUCCESS) {\r
439                                 goto cleanup;\r
440                         }\r
441 \r
442                 } else {\r
443                         rc = LDAP_REFERRAL;\r
444                 }\r
445         } else {\r
446                 rc = LDAP_UNWILLING_TO_PERFORM;\r
447         }\r
448 \r
449 cleanup:\r
450 \r
451         if ( dn.bv_val ) slapi_ch_free( (void **)&dn.bv_val );\r
452         if ( op ) slapi_ch_free( (void **)&op );\r
453         if ( modlist != NULL ) slap_mods_free( modlist );\r
454         if ( rc != LDAP_SUCCESS ) {\r
455                 if ( pEntry != NULL ) {\r
456                         slapi_entry_free( pEntry );\r
457                 }\r
458                 pEntry = NULL;\r
459         }\r
460 \r
461         return( pEntry );\r
462 }\r
463 \r
464 /* Function : slapi_delete_internal\r
465  *\r
466  * Description : Plugin functions call this routine to delete an entry \r
467  *               in the backend directly\r
468  * Return values : LDAP_SUCCESS\r
469  *                 LDAP_PARAM_ERROR\r
470  *                 LDAP_NO_MEMORY\r
471  *                 LDAP_OTHER\r
472  *                 LDAP_UNWILLING_TO_PERFORM\r
473 */\r
474 Slapi_PBlock *\r
475 slapi_delete_internal(\r
476         char *ldn, \r
477         LDAPControl **controls, \r
478         int log_change )\r
479 {\r
480 #if defined(LDAP_SLAPI)\r
481         Backend                 *be;\r
482         Connection              *pConn = NULL;\r
483         Operation               *op = NULL;\r
484         Slapi_PBlock            *pPB = NULL;\r
485         Slapi_PBlock            *pSavePB = NULL;\r
486 \r
487         struct berval dn  = { 0, NULL };\r
488         struct berval pdn = { 0, NULL };\r
489         struct berval ndn = { 0, NULL };\r
490 \r
491         int                             rc=LDAP_SUCCESS;\r
492         int                             manageDsaIt = 0;\r
493         int                             isCritical;\r
494 \r
495         if ( ldn == NULL ) {\r
496                 rc = LDAP_PARAM_ERROR; \r
497                 goto cleanup;\r
498         }\r
499 \r
500         pConn = fakeConnection( NULL,  LDAP_REQ_DELETE );\r
501         if (pConn == NULL) {\r
502                 rc = LDAP_NO_MEMORY;\r
503                 goto cleanup;\r
504         }\r
505 \r
506         op = (Operation *)pConn->c_pending_ops.stqh_first;\r
507         pPB = (Slapi_PBlock *)op->o_pb;\r
508         op->o_ctrls = controls;\r
509 \r
510         dn.bv_val = slapi_ch_strdup(ldn);\r
511         dn.bv_len = slapi_strlen(ldn);\r
512         rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );\r
513         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
514 \r
515         if ( slapi_control_present( controls, \r
516                         SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical) ) {\r
517                 manageDsaIt = 1; \r
518         }\r
519 \r
520         be = select_backend( &dn, manageDsaIt, 0 );\r
521         if ( be == NULL ) {\r
522                 rc =  LDAP_PARTIAL_RESULTS;\r
523                 goto cleanup;\r
524         }\r
525 \r
526         op->o_ndn.bv_val = slapi_ch_strdup(be->be_rootdn.bv_val);\r
527         op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
528         pConn->c_dn.bv_val = slapi_ch_strdup(be->be_rootdn.bv_val);\r
529         pConn->c_dn.bv_len = be->be_rootdn.bv_len;\r
530 \r
531         suffix_alias( be, &ndn );\r
532 \r
533         if ( be->be_delete ) {\r
534                 int repl_user = be_isupdate( be, &op->o_ndn );\r
535                 if ( !be->be_update_ndn.bv_len || repl_user ) {\r
536                         rc = (*be->be_delete)( be, pConn, op, &pdn, &ndn );\r
537                         if ( rc == 0 ) {\r
538                                 if (log_change) {\r
539                                         replog( be, op, &pdn, &ndn, NULL );\r
540                                 }\r
541                                 rc = LDAP_SUCCESS;\r
542                         } else {\r
543                                 rc = LDAP_OPERATIONS_ERROR;\r
544                         }\r
545                 } else {\r
546                         rc = LDAP_REFERRAL;\r
547                 }\r
548         } else {\r
549                 rc = LDAP_UNWILLING_TO_PERFORM;\r
550         }\r
551 \r
552 cleanup:\r
553         if (pPB != NULL) \r
554                 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
555 \r
556         if (dn.bv_val) slapi_ch_free( (void **)&dn.bv_val );\r
557         if (pdn.bv_val) slapi_ch_free( (void **)&pdn.bv_val );\r
558         if (ndn.bv_val) slapi_ch_free( (void **)&ndn.bv_val );\r
559 \r
560         if ( pConn != NULL ) {\r
561                 if ( pConn->c_dn.bv_val ) slapi_ch_free( (void **)&pConn->c_dn.bv_val );\r
562                 if ( op->o_dn.bv_val ) slapi_ch_free( (void **)&op->o_dn.bv_val );\r
563                 if ( op ) slapi_ch_free( (void **)&op );\r
564                 pSavePB = pPB;\r
565                 free( pConn );\r
566         }\r
567         \r
568         return (pSavePB);\r
569 #endif /* LDAP_SLAPI */\r
570         return NULL;\r
571 }\r
572 \r
573 Slapi_PBlock * \r
574 slapi_add_entry_internal(\r
575         Slapi_Entry *e, \r
576         LDAPControl **controls, \r
577         int log_changes ) \r
578 {\r
579 #if defined(LDAP_SLAPI)\r
580         Connection              *pConn = NULL;\r
581         Operation               *op = NULL;\r
582         Slapi_PBlock            *pPB = NULL, *pSavePB = NULL;\r
583         Backend                 *be;\r
584 \r
585         int                     manageDsaIt = 0;\r
586         int                     isCritical;\r
587         int                     rc = LDAP_SUCCESS;\r
588 \r
589         if ( e == NULL ) {\r
590                 rc = LDAP_PARAM_ERROR;\r
591                 goto cleanup;\r
592         }\r
593         \r
594         pConn = fakeConnection( NULL, LDAP_REQ_ADD );\r
595         if ( pConn == NULL ) {\r
596                 rc = LDAP_NO_MEMORY;\r
597                 goto cleanup;\r
598         }\r
599 \r
600         if ( slapi_control_present( controls, LDAP_CONTROL_MANAGEDSAIT,\r
601                                 NULL, &isCritical ) ) {\r
602                 manageDsaIt = 1; \r
603         }\r
604 \r
605         op = (Operation *)pConn->c_pending_ops.stqh_first;\r
606         pPB = (Slapi_PBlock *)op->o_pb;\r
607         op->o_ctrls = controls;\r
608 \r
609         be = select_backend( &e->e_nname, manageDsaIt, 0 );\r
610         if ( be == NULL ) {\r
611                 rc = LDAP_PARTIAL_RESULTS;\r
612                 goto cleanup;\r
613         }\r
614 \r
615         op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
616         op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
617         pConn->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
618         pConn->c_dn.bv_len = be->be_rootdn.bv_len;\r
619 \r
620         if ( be->be_add ) {\r
621                 int repl_user = be_isupdate( be, &op->o_ndn );\r
622                 if ( !be->be_update_ndn.bv_len || repl_user ){\r
623                         if ( (*be->be_add)( be, pConn, op, e ) == 0 ) {\r
624                                 if ( log_changes ) {\r
625                                         replog( be, op, &e->e_name, \r
626                                                         &e->e_nname, e );\r
627                                 }\r
628                                 rc = LDAP_SUCCESS;\r
629                         }\r
630                 } else {\r
631                         rc = LDAP_REFERRAL;\r
632                 }\r
633         } else {\r
634                 rc = LDAP_UNWILLING_TO_PERFORM;\r
635         }\r
636 \r
637 cleanup:\r
638 \r
639         if ( pPB != NULL ) {\r
640                 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
641         }\r
642 \r
643         if ( pConn != NULL ) {\r
644                 if ( pConn->c_dn.bv_val ) slapi_ch_free( (void **)&pConn->c_dn.bv_val );\r
645                 if ( op ) {\r
646                         if ( op->o_ndn.bv_val ) {\r
647                                 slapi_ch_free( (void **)&op->o_ndn.bv_val );\r
648                         }\r
649                         free(op);\r
650                 }\r
651                 pSavePB = pPB;\r
652                 free( pConn );\r
653         }\r
654         return( pSavePB );\r
655 #endif /* LDAP_SLAPI */\r
656         return NULL;\r
657 }\r
658 \r
659 \r
660 Slapi_PBlock *\r
661 slapi_add_internal(\r
662         char *dn, \r
663         LDAPMod **mods, \r
664         LDAPControl **controls, \r
665         int log_changes  ) \r
666 {\r
667 #if defined(LDAP_SLAPI)\r
668         LDAPMod                 *pMod = NULL;\r
669         Slapi_PBlock            *pb = NULL;\r
670         Entry                   *pEntry = NULL;\r
671         int                     i, rc=LDAP_SUCCESS;\r
672 \r
673         if ( mods == NULL || *mods == NULL || dn == NULL || *dn == '\0' ) {\r
674                 rc = LDAP_PARAM_ERROR ;\r
675         }\r
676 \r
677         if ( rc == LDAP_SUCCESS ) {\r
678                 for ( i = 0, pMod = mods[0]; pMod != NULL; pMod = mods[++i] ) {\r
679                         if ( (pMod->mod_op & ~LDAP_MOD_BVALUES) != LDAP_MOD_ADD ) {\r
680                                 rc = LDAP_OTHER;\r
681                                 break;\r
682                         }\r
683                 }\r
684         }\r
685 \r
686         if ( rc == LDAP_SUCCESS ) {\r
687                 if((pEntry = LDAPModToEntry( dn, mods )) == NULL) {\r
688                         rc = LDAP_OTHER;\r
689                 }\r
690         }\r
691 \r
692         if ( rc != LDAP_SUCCESS ) {\r
693                 pb = slapi_pblock_new();\r
694                 slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
695         } else {\r
696                 pb = slapi_add_entry_internal( pEntry, controls, log_changes );\r
697         }\r
698 \r
699         if ( pEntry ) {\r
700                 slapi_entry_free(pEntry);\r
701         }\r
702 \r
703         return(pb);\r
704 #endif /* LDAP_SLAPI */\r
705         return NULL;\r
706 }\r
707 \r
708 /* Function : slapi_modrdn_internal\r
709  *\r
710  * Description : Plugin functions call this routine to modify the rdn \r
711  *                               of an entry in the backend directly\r
712  * Return values : LDAP_SUCCESS\r
713  *                 LDAP_PARAM_ERROR\r
714  *                 LDAP_OPERATIONS_ERROR\r
715  *                 LDAP_NO_MEMORY\r
716  *                 LDAP_OTHER\r
717  *                 LDAP_UNWILLING_TO_PERFORM\r
718  *\r
719  * NOTE: This function does not support the "newSuperior" option from LDAP V3.\r
720  */\r
721 Slapi_PBlock *\r
722 slapi_modrdn_internal(\r
723         char *olddn, \r
724         char *lnewrdn, \r
725         int deloldrdn, \r
726         LDAPControl **controls, \r
727         int log_change )\r
728 {\r
729 #if defined(LDAP_SLAPI)\r
730         int                     rc = LDAP_SUCCESS;\r
731 \r
732         struct berval           dn = { 0, NULL };\r
733         struct berval           pdn = { 0, NULL };\r
734         struct berval           ndn = { 0, NULL };\r
735 \r
736         struct berval           newrdn = { 0, NULL };\r
737         struct berval           pnewrdn = { 0, NULL };\r
738         struct berval           nnewrdn = { 0, NULL };\r
739 \r
740 #if 0 /* currently unused */\r
741         struct berval           newSuperior = { 0, NULL };\r
742 #endif\r
743         struct berval           pnewSuperior = { 0, NULL }; \r
744 #if 0 /* currently unused */\r
745         struct berval           nnewSuperior = { 0, NULL }; \r
746 #endif\r
747 \r
748         struct berval           *pnewS = NULL;\r
749         struct berval           *nnewS = NULL;\r
750 \r
751         Connection              *pConn = NULL;\r
752         Operation               *op = NULL;\r
753         Slapi_PBlock            *pPB = NULL;\r
754         Slapi_PBlock            *pSavePB = NULL;\r
755 \r
756         Backend                 *be;\r
757 #if 0 /* currently unused */\r
758         Backend                 *newSuperior_be = NULL;\r
759 #endif\r
760 \r
761         int                     manageDsaIt = 0;\r
762         int                     isCritical;\r
763 #if 0 /* currently unused */\r
764         const char              *text = NULL;\r
765 #endif\r
766 \r
767         dn.bv_val = slapi_ch_strdup(olddn);\r
768         dn.bv_len = slapi_ch_stlen(olddn);\r
769 \r
770         rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );\r
771 \r
772         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
773 \r
774         if ( ndn.bv_len == 0 ) {\r
775                 rc = LDAP_UNWILLING_TO_PERFORM;\r
776                 goto cleanup;\r
777         }\r
778 \r
779         newrdn.bv_val = slapi_ch_strdup( lnewrdn );\r
780         newrdn.bv_len = slapi_ch_stlen( lnewrdn );\r
781 \r
782         rc = dnPrettyNormal( NULL, &newrdn, &pnewrdn, &nnewrdn );\r
783 \r
784         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
785 \r
786         if ( rdnValidate( &pnewrdn ) != LDAP_SUCCESS ) goto cleanup;\r
787 \r
788         pConn = fakeConnection( NULL,  LDAP_REQ_MODRDN);\r
789         if ( pConn == NULL) {\r
790                 rc = LDAP_NO_MEMORY;\r
791                 goto cleanup;\r
792         }\r
793 \r
794         op = (Operation *)pConn->c_pending_ops.stqh_first;\r
795         pPB = (Slapi_PBlock *)op->o_pb;\r
796         op->o_ctrls = controls;\r
797 \r
798         if ( slapi_control_present( controls, \r
799                         SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {\r
800                 manageDsaIt = 1;\r
801         }\r
802 \r
803         be = select_backend( &dn, manageDsaIt, 0 );\r
804         if ( be == NULL ) {\r
805                 rc =  LDAP_PARTIAL_RESULTS;\r
806                 goto cleanup;\r
807         }\r
808 \r
809         op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
810         op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
811         pConn->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
812         pConn->c_dn.bv_len = be->be_rootdn.bv_len;\r
813 \r
814         suffix_alias( be, &ndn );\r
815 \r
816         if ( be->be_modrdn ) {\r
817                 int repl_user = be_isupdate( be, &op->o_ndn );\r
818                 if ( !be->be_update_ndn.bv_len || repl_user ) {\r
819                         rc = (*be->be_modrdn)( be, pConn, op, &pdn, &ndn,\r
820                                         &pnewrdn, &nnewrdn, deloldrdn, pnewS,\r
821                                         nnewS );\r
822                         if ( rc == 0 ) {\r
823                                 struct slap_replog_moddn moddn;\r
824                                 moddn.newrdn = &pnewrdn;\r
825                                 moddn.deloldrdn = deloldrdn;\r
826                                 moddn.newsup = &pnewSuperior;\r
827                                 if ( log_change ) {\r
828                                         replog( be, op, &pdn, &ndn, &moddn );\r
829                                 }\r
830                                 rc = LDAP_SUCCESS;\r
831 \r
832                         } else {\r
833                                 rc = LDAP_OPERATIONS_ERROR;\r
834                         }\r
835 \r
836                 } else {\r
837                         rc = LDAP_REFERRAL;\r
838                 }\r
839 \r
840         } else {\r
841                 rc = LDAP_UNWILLING_TO_PERFORM;\r
842         }\r
843 \r
844 cleanup:\r
845 \r
846         if ( pPB != NULL ) {\r
847                 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
848         }\r
849         \r
850         if ( dn.bv_val ) ch_free( dn.bv_val );\r
851         if ( pdn.bv_val ) ch_free( pdn.bv_val );\r
852         if ( ndn.bv_val ) ch_free( ndn.bv_val );\r
853 \r
854         if ( newrdn.bv_val ) ch_free( newrdn.bv_val );\r
855         if ( pnewrdn.bv_val ) ch_free( newrdn.bv_val );\r
856         if ( nnewrdn.bv_val ) ch_free( newrdn.bv_val );\r
857 \r
858         if ( pConn != NULL ) {\r
859                 if ( pConn->c_dn.bv_val ) slapi_ch_free( (void **)&pConn->c_dn.bv_val );\r
860                 if ( op ) {\r
861                         if ( op->o_dn.bv_val ) slapi_ch_free( (void **)&op->o_dn.bv_val );\r
862                         slapi_ch_free( (void **)&op );\r
863                 }\r
864                 pSavePB = pPB;\r
865                 free( pConn );\r
866         }\r
867 \r
868         return( pSavePB );\r
869 #endif /* LDAP_SLAPI */\r
870         return NULL;\r
871 }\r
872 \r
873 /* Function : slapi_modify_internal\r
874  *\r
875  * Description: Plugin functions call this routine to modify an entry \r
876  *                              in the backend directly\r
877  * Return values : LDAP_SUCCESS\r
878  *                 LDAP_PARAM_ERROR\r
879  *                 LDAP_NO_MEMORY\r
880  *                 LDAP_OPERATIONS_ERROR\r
881  *                 LDAP_OTHER\r
882  *                 LDAP_UNWILLING_TO_PERFORM\r
883 */\r
884 Slapi_PBlock *\r
885 slapi_modify_internal(\r
886         char *ldn,      \r
887         LDAPMod **mods, \r
888         LDAPControl **controls, \r
889         int log_change )\r
890 {\r
891 #if defined(LDAP_SLAPI)\r
892         int                     i, rc = LDAP_SUCCESS;\r
893         Connection              *pConn = NULL;\r
894         Operation               *op = NULL;\r
895         Slapi_PBlock            *pPB = NULL;\r
896         Slapi_PBlock            *pSavePB = NULL;\r
897 \r
898         struct berval dn = { 0, NULL };\r
899         struct berval pdn = { 0, NULL };\r
900         struct berval ndn = { 0, NULL };\r
901 \r
902         int                     manageDsaIt = 0;\r
903         int                     isCritical;\r
904         Backend                 *be;\r
905         struct berval           *bv;\r
906         struct berval           **ppBV;\r
907         LDAPMod                 *pMod;\r
908 \r
909         Modifications           *modlist = NULL;\r
910         Modifications           **modtail = &modlist;\r
911         Modifications           tmp;\r
912 \r
913         if ( mods == NULL || *mods == NULL || ldn == NULL ) {\r
914                 rc = LDAP_PARAM_ERROR ;\r
915                 goto cleanup;\r
916         }\r
917 \r
918         pConn = fakeConnection( NULL,  LDAP_REQ_MODIFY );\r
919         if ( pConn == NULL ) {\r
920                 rc = LDAP_NO_MEMORY;\r
921                 goto cleanup;\r
922         }\r
923 \r
924         op = (Operation *)pConn->c_pending_ops.stqh_first;\r
925         pPB = (Slapi_PBlock *)op->o_pb;\r
926         op->o_ctrls = controls;\r
927 \r
928         dn.bv_val = slapi_ch_strdup( ldn );\r
929         dn.bv_len = slapi_strlen( ldn );\r
930         rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );\r
931         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
932 \r
933         if ( slapi_control_present( controls, \r
934                         SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {\r
935                 manageDsaIt = 1;\r
936         }\r
937 \r
938         be = select_backend( &dn, manageDsaIt, 0 );\r
939         if ( be == NULL ) {\r
940                 rc =  LDAP_PARTIAL_RESULTS;\r
941                 goto cleanup;\r
942         }\r
943 \r
944         op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
945         op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
946         pConn->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
947         pConn->c_dn.bv_len = be->be_rootdn.bv_len;\r
948 \r
949         suffix_alias( be, &ndn );\r
950 \r
951         for ( i = 0, pMod = mods[0]; rc == LDAP_SUCCESS && pMod != NULL; \r
952                         pMod = mods[++i] ) {\r
953                 Modifications *mod;\r
954                 if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {\r
955                         /*\r
956                          * attr values are in berval format\r
957                          * convert an array of pointers to bervals\r
958                          * to an array of bervals\r
959                          */\r
960                         rc = bvptr2obj( pMod->mod_bvalues, &bv );\r
961                         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
962                         tmp.sml_type.bv_val = slapi_ch_strdup( pMod->mod_type );\r
963                         tmp.sml_type.bv_len = slapi_ch_stlen( pMod->mod_type );\r
964                         tmp.sml_bvalues = bv;\r
965 \r
966                         mod  = (Modifications *)ch_malloc( sizeof(Modifications) );\r
967 \r
968                         mod->sml_op = pMod->mod_op;\r
969                         mod->sml_next = NULL;\r
970                         mod->sml_desc = NULL;\r
971                         mod->sml_type = tmp.sml_type;\r
972                         mod->sml_bvalues = tmp.sml_bvalues;\r
973                 } else { \r
974                         rc = ValuesToBValues( pMod->mod_values, &ppBV );\r
975                         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
976                         rc = bvptr2obj( ppBV, &bv );\r
977                         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
978                         tmp.sml_type.bv_val = slapi_ch_strdup( pMod->mod_type );\r
979                         tmp.sml_type.bv_len = slapi_ch_stlen( pMod->mod_type );\r
980                         tmp.sml_bvalues = bv;\r
981 \r
982                         mod  = (Modifications *) ch_malloc( sizeof(Modifications) );\r
983 \r
984                         mod->sml_op = pMod->mod_op;\r
985                         mod->sml_next = NULL;\r
986                         mod->sml_desc = NULL;\r
987                         mod->sml_type = tmp.sml_type;\r
988                         mod->sml_bvalues = tmp.sml_bvalues;\r
989 \r
990                         if ( ppBV != NULL ) {\r
991                                 ber_bvecfree( ppBV );\r
992                         }\r
993                 }\r
994                 *modtail = mod;\r
995                 modtail = &mod->sml_next;\r
996 \r
997                 switch( pMod->mod_op ) {\r
998                 case LDAP_MOD_ADD:\r
999                 if ( mod->sml_bvalues == NULL ) {\r
1000                         rc = LDAP_PROTOCOL_ERROR;\r
1001                         goto cleanup;\r
1002                 }\r
1003 \r
1004                 /* fall through */\r
1005                 case LDAP_MOD_DELETE:\r
1006                 case LDAP_MOD_REPLACE:\r
1007                 break;\r
1008 \r
1009                 default:\r
1010                         rc = LDAP_PROTOCOL_ERROR;\r
1011                         goto cleanup;\r
1012                 }\r
1013         } \r
1014         *modtail = NULL;\r
1015 \r
1016         if ( ndn.bv_len == 0 ) {\r
1017                 rc = LDAP_UNWILLING_TO_PERFORM;\r
1018                 goto cleanup;\r
1019         }\r
1020 \r
1021         if ( be->be_modify ) {\r
1022                 int repl_user = be_isupdate( be, &op->o_ndn );\r
1023                 if ( !be->be_update_ndn.bv_len || repl_user ) {\r
1024                         int update = be->be_update_ndn.bv_len;\r
1025                         const char *text = NULL;\r
1026                         char textbuf[SLAP_TEXT_BUFLEN];\r
1027                         size_t textlen = sizeof( textbuf );\r
1028 \r
1029                         rc = slap_mods_check( modlist, update,\r
1030                                         &text, textbuf, textlen );\r
1031                         if (rc != LDAP_SUCCESS) {\r
1032                                 goto cleanup;\r
1033                         }\r
1034 \r
1035                         if ( !repl_user ) {\r
1036                                 rc = slap_mods_opattrs( be, op, modlist,\r
1037                                                 modtail, &text, textbuf, \r
1038                                                 textlen );\r
1039                                 if (rc != LDAP_SUCCESS) {\r
1040                                         goto cleanup;\r
1041                                 }\r
1042                         }\r
1043                         rc = (*be->be_modify)( be, pConn, op,\r
1044                                         &pdn, &ndn, modlist );\r
1045                         if ( rc == 0 ) {\r
1046                                 if ( log_change ) {\r
1047                                         replog( be, op, &pdn, &ndn, modlist );\r
1048                                 }\r
1049                                 rc = LDAP_SUCCESS;\r
1050                         } else {\r
1051                                 rc = LDAP_OPERATIONS_ERROR;\r
1052                         }\r
1053                 } else {\r
1054                         rc = LDAP_REFERRAL;\r
1055                 }\r
1056         } else {\r
1057                 rc = LDAP_UNWILLING_TO_PERFORM;\r
1058         }\r
1059 \r
1060 cleanup:\r
1061 \r
1062         if ( pPB != NULL ) \r
1063                 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
1064 \r
1065         if ( dn.bv_val ) ch_free( dn.bv_val );\r
1066         if ( pdn.bv_val ) ch_free( pdn.bv_val );\r
1067         if ( ndn.bv_val ) ch_free( ndn.bv_val );\r
1068 \r
1069         if ( modlist != NULL ) slap_mods_free( modlist );\r
1070 \r
1071         if ( pConn != NULL ) {\r
1072                 if ( pConn->c_dn.bv_val ) slapi_ch_free( (void **)&pConn->c_dn.bv_val );\r
1073                 if ( op ) {\r
1074                         if ( op->o_dn.bv_val ) slapi_ch_free( (void **)&op->o_dn.bv_val );\r
1075                         slapi_ch_free( (void **)&op );\r
1076                 }\r
1077                 pSavePB = pPB;\r
1078                 free( pConn );\r
1079         }\r
1080 \r
1081         return ( pSavePB );\r
1082 \r
1083 #endif /* LDAP_SLAPI */\r
1084         return NULL;\r
1085 }\r
1086 \r
1087 Slapi_PBlock *\r
1088 slapi_search_internal_bind(\r
1089         char *bindDN, \r
1090         char *ldn, \r
1091         int scope, \r
1092         char *filStr, \r
1093         LDAPControl **controls, \r
1094         char **attrs, \r
1095         int attrsonly ) \r
1096 {       \r
1097 #if defined(LDAP_SLAPI)\r
1098         Backend                 *be;\r
1099         Connection              *c;\r
1100         Operation               *op = NULL;\r
1101         Slapi_PBlock            *ptr = NULL;            \r
1102         Slapi_PBlock            *pSavePB = NULL;                \r
1103         struct berval           dn = { 0, NULL };\r
1104         struct berval           pdn = { 0, NULL };\r
1105         struct berval           ndn = { 0, NULL };\r
1106         Filter                  *filter=NULL;\r
1107         struct berval           fstr = { 0, NULL };\r
1108         AttributeName           *an = NULL;\r
1109         const char              *text = NULL;\r
1110 \r
1111         int                     deref=0;\r
1112         int                     sizelimit=-1, timelimit=-1;\r
1113 \r
1114         int                     manageDsaIt = 0; \r
1115         int                     isCritical;\r
1116 \r
1117         int                     i, rc = LDAP_SUCCESS;\r
1118         \r
1119         c = fakeConnection( NULL, LDAP_REQ_SEARCH );\r
1120         if (c == NULL) {\r
1121                 rc = LDAP_NO_MEMORY;\r
1122                 goto cleanup;\r
1123         }\r
1124 \r
1125         op = (Operation *)c->c_pending_ops.stqh_first;\r
1126         ptr = (Slapi_PBlock *)op->o_pb;\r
1127         op->o_ctrls = controls;\r
1128 \r
1129         dn.bv_val = slapi_ch_strdup(ldn);\r
1130         dn.bv_len = slapi_strlen(ldn);\r
1131 \r
1132         rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );\r
1133         if (rc != LDAP_SUCCESS) goto cleanup;\r
1134 \r
1135         if ( scope != LDAP_SCOPE_BASE && \r
1136                         scope != LDAP_SCOPE_ONELEVEL && \r
1137                         scope != LDAP_SCOPE_SUBTREE ) {\r
1138                 rc = LDAP_PROTOCOL_ERROR;\r
1139                 goto cleanup;\r
1140         }\r
1141 \r
1142         filter = slapi_str2filter(filStr);\r
1143         if ( filter == NULL ) {\r
1144                 rc = LDAP_PROTOCOL_ERROR;\r
1145                 goto cleanup;\r
1146         }\r
1147 \r
1148         filter2bv( filter, &fstr );\r
1149 \r
1150         for ( i = 0; attrs != NULL && attrs[i] != NULL; i++ ) {\r
1151                 ; /* count the number of attributes */\r
1152         }\r
1153 \r
1154         if (i > 0) {\r
1155                 an = (AttributeName *)slapi_ch_calloc(1, sizeof(AttributeName));\r
1156                 for (i = 0; attrs[i] != 0; i++) {\r
1157                         an[i].an_desc = NULL;\r
1158                         an[i].an_oc = NULL;\r
1159                         an[i].an_name.bv_val = slapi_ch_strdup(attrs[i]);\r
1160                         an[i].an_name.bv_len = slapi_strlen(attrs[i]);\r
1161                         slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text );\r
1162                 }\r
1163         }\r
1164 \r
1165         if ( scope == LDAP_SCOPE_BASE ) {\r
1166                 Entry *entry = NULL;\r
1167 \r
1168                 if ( ndn.bv_len == 0 ) {\r
1169                         rc = root_dse_info( c, &entry, &text );\r
1170                 }\r
1171 \r
1172                 if( rc != LDAP_SUCCESS ) {\r
1173                         send_ldap_result( c, op, rc, NULL, text, NULL, NULL );\r
1174                         goto cleanup;\r
1175                 } else if ( entry != NULL ) {\r
1176                         rc = test_filter( NULL, c, op, entry, filter );\r
1177 \r
1178                         if( rc == LDAP_COMPARE_TRUE ) {\r
1179                                 send_search_entry( NULL, c, op, entry,\r
1180                                                 an, attrsonly, NULL );\r
1181                         }\r
1182 \r
1183                         entry_free( entry );\r
1184 \r
1185                         send_ldap_result( c, op, LDAP_SUCCESS, \r
1186                                         NULL, NULL, NULL, NULL );\r
1187 \r
1188                         rc = LDAP_SUCCESS;\r
1189 \r
1190                         goto cleanup;\r
1191                 }\r
1192         }\r
1193 \r
1194         if ( !ndn.bv_len && default_search_nbase.bv_len ) {\r
1195                 ch_free( pdn.bv_val );\r
1196                 ch_free( ndn.bv_val );\r
1197 \r
1198                 ber_dupbv( &pdn, &default_search_base );\r
1199                 ber_dupbv( &ndn, &default_search_nbase );\r
1200         }\r
1201 \r
1202         if ( slapi_control_present( controls,\r
1203                         LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {\r
1204                 manageDsaIt = 1;\r
1205         }\r
1206 \r
1207         be = select_backend( &ndn, manageDsaIt, 0 );\r
1208         if ( be == NULL ) {\r
1209                 if ( manageDsaIt == 1 ) {\r
1210                         rc = LDAP_NO_SUCH_OBJECT;\r
1211                 } else {\r
1212                         rc = LDAP_PARTIAL_RESULTS;\r
1213                 }\r
1214                 goto cleanup;\r
1215         } \r
1216 \r
1217         op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
1218         op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
1219         c->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
1220         c->c_dn.bv_len = be->be_rootdn.bv_len;\r
1221 \r
1222         if ( be->be_search ) {\r
1223                 rc = (*be->be_search)( be, c, op, &pdn, &ndn,\r
1224                         scope, deref, sizelimit, timelimit,\r
1225                         filter, &fstr, an, attrsonly );\r
1226                 if ( rc == 0 ) {\r
1227                         rc = LDAP_SUCCESS;\r
1228                 } else {\r
1229                         rc = LDAP_OPERATIONS_ERROR;\r
1230                 }\r
1231         } else {\r
1232                 rc = LDAP_UNWILLING_TO_PERFORM;\r
1233         }\r
1234 \r
1235 cleanup:\r
1236 \r
1237         if ( ptr != NULL )\r
1238                 slapi_pblock_set( ptr, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
1239 \r
1240         if ( dn.bv_val ) free( dn.bv_val );\r
1241         if ( ndn.bv_val ) free( ndn.bv_val );\r
1242         if ( pdn.bv_val ) free( pdn.bv_val );\r
1243 \r
1244         if ( filter ) slapi_filter_free( filter, 1 );\r
1245         if ( fstr.bv_val ) free ( fstr.bv_val );\r
1246 \r
1247         if ( an != NULL ) free( an );\r
1248 \r
1249         if ( c != NULL ) {\r
1250                 if ( c->c_dn.bv_val ) slapi_ch_free( (void **)&c->c_dn.bv_val );\r
1251                 if ( op ) {\r
1252                         if ( op->o_ndn.bv_val ) slapi_ch_free( (void **)&op->o_ndn.bv_val );\r
1253                         free( op );\r
1254                 }\r
1255                 pSavePB = ptr;\r
1256                 free( c );\r
1257         }\r
1258         return( pSavePB );\r
1259 #endif /* LDAP_SLAPI */\r
1260         return NULL;\r
1261 }\r
1262 \r
1263 Slapi_PBlock * \r
1264 slapi_search_internal(\r
1265         char *base,\r
1266         int scope,\r
1267         char *filStr, \r
1268         LDAPControl **controls,\r
1269         char **attrs,\r
1270         int attrsonly ) \r
1271 {\r
1272 #if defined(LDAP_SLAPI)\r
1273         return slapi_search_internal_bind( NULL, base, scope, filStr,\r
1274                         controls, attrs, attrsonly );\r
1275 #else\r
1276         return NULL;\r
1277 #endif /* LDAP_SLAPI */\r
1278 }\r
1279 \r