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