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