]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_ops.c
Happy new year
[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( 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( 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( pConn->c_pending_ops.stqh_first );\r
165                 slapi_ch_free( 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( dn.bv_val );\r
451         if ( op ) slapi_ch_free( 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_OPERAITONS_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_OPERATIONS_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(dn.bv_val);\r
556         if (pdn.bv_val) slapi_ch_free(pdn.bv_val);\r
557         if (ndn.bv_val) slapi_ch_free(ndn.bv_val);\r
558 \r
559         if ( pConn != NULL ) {\r
560                 if ( pConn->c_dn.bv_val ) slapi_ch_free( pConn->c_dn.bv_val );\r
561                 if ( op->o_dn.bv_val ) slapi_ch_free( op->o_dn.bv_val );\r
562                 if ( op ) slapi_ch_free( 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_OPERATIONS_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( pConn->c_dn.bv_val );\r
644                 if ( op ) {\r
645                         if ( op->o_ndn.bv_val ) {\r
646                                 slapi_ch_free( 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_OPERATIONS_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_OPERAITONS_ERROR\r
713  *                 LDAP_NO_MEMORY\r
714  *                 LDAP_OTHER\r
715  *                 LDAP_UNWILLING_TO_PERFORM\r
716  *\r
717  * NOTE: This function does not support the "newSuperior" option from LDAP V3.\r
718  */\r
719 Slapi_PBlock *\r
720 slapi_modrdn_internal(\r
721         char *olddn, \r
722         char *lnewrdn, \r
723         int deloldrdn, \r
724         LDAPControl **controls, \r
725         int log_change )\r
726 {\r
727 #if defined(LDAP_SLAPI)\r
728         int                     rc = LDAP_SUCCESS;\r
729 \r
730         struct berval           dn = { 0, NULL };\r
731         struct berval           pdn = { 0, NULL };\r
732         struct berval           ndn = { 0, NULL };\r
733 \r
734         struct berval           newrdn = { 0, NULL };\r
735         struct berval           pnewrdn = { 0, NULL };\r
736         struct berval           nnewrdn = { 0, NULL };\r
737 \r
738 #if 0 /* currently unused */\r
739         struct berval           newSuperior = { 0, NULL };\r
740 #endif\r
741         struct berval           pnewSuperior = { 0, NULL }; \r
742 #if 0 /* currently unused */\r
743         struct berval           nnewSuperior = { 0, NULL }; \r
744 #endif\r
745 \r
746         struct berval           *pnewS = NULL;\r
747         struct berval           *nnewS = NULL;\r
748 \r
749         Connection              *pConn = NULL;\r
750         Operation               *op = NULL;\r
751         Slapi_PBlock            *pPB = NULL;\r
752         Slapi_PBlock            *pSavePB = NULL;\r
753 \r
754         Backend                 *be;\r
755 #if 0 /* currently unused */\r
756         Backend                 *newSuperior_be = NULL;\r
757 #endif\r
758 \r
759         int                     manageDsaIt = 0;\r
760         int                     isCritical;\r
761 #if 0 /* currently unused */\r
762         const char              *text = NULL;\r
763 #endif\r
764 \r
765         dn.bv_val = slapi_ch_strdup(olddn);\r
766         dn.bv_len = slapi_ch_stlen(olddn);\r
767 \r
768         rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );\r
769 \r
770         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
771 \r
772         if ( ndn.bv_len == 0 ) {\r
773                 rc = LDAP_UNWILLING_TO_PERFORM;\r
774                 goto cleanup;\r
775         }\r
776 \r
777         newrdn.bv_val = slapi_ch_strdup( lnewrdn );\r
778         newrdn.bv_len = slapi_ch_stlen( lnewrdn );\r
779 \r
780         rc = dnPrettyNormal( NULL, &newrdn, &pnewrdn, &nnewrdn );\r
781 \r
782         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
783 \r
784         if ( rdnValidate( &pnewrdn ) != LDAP_SUCCESS ) goto cleanup;\r
785 \r
786         pConn = fakeConnection( NULL,  LDAP_REQ_MODRDN);\r
787         if ( pConn == NULL) {\r
788                 rc = LDAP_NO_MEMORY;\r
789                 goto cleanup;\r
790         }\r
791 \r
792         op = (Operation *)pConn->c_pending_ops.stqh_first;\r
793         pPB = (Slapi_PBlock *)op->o_pb;\r
794         op->o_ctrls = controls;\r
795 \r
796         if ( slapi_control_present( controls, \r
797                         SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {\r
798                 manageDsaIt = 1;\r
799         }\r
800 \r
801         be = select_backend( &dn, manageDsaIt, 0 );\r
802         if ( be == NULL ) {\r
803                 rc =  LDAP_PARTIAL_RESULTS;\r
804                 goto cleanup;\r
805         }\r
806 \r
807         op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
808         op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
809         pConn->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
810         pConn->c_dn.bv_len = be->be_rootdn.bv_len;\r
811 \r
812         suffix_alias( be, &ndn );\r
813 \r
814         if ( be->be_modrdn ) {\r
815                 int repl_user = be_isupdate( be, &op->o_ndn );\r
816                 if ( !be->be_update_ndn.bv_len || repl_user ) {\r
817                         rc = (*be->be_modrdn)( be, pConn, op, &pdn, &ndn,\r
818                                         &pnewrdn, &nnewrdn, deloldrdn, pnewS,\r
819                                         nnewS );\r
820                         if ( rc == 0 ) {\r
821                                 struct slap_replog_moddn moddn;\r
822                                 moddn.newrdn = &pnewrdn;\r
823                                 moddn.deloldrdn = deloldrdn;\r
824                                 moddn.newsup = &pnewSuperior;\r
825                                 if ( log_change ) {\r
826                                         replog( be, op, &pdn, &ndn, &moddn );\r
827                                 }\r
828                                 rc = LDAP_SUCCESS;\r
829 \r
830                         } else {\r
831                                 rc = LDAP_OPERATIONS_ERROR;\r
832                         }\r
833 \r
834                 } else {\r
835                         rc = LDAP_REFERRAL;\r
836                 }\r
837 \r
838         } else {\r
839                 rc = LDAP_UNWILLING_TO_PERFORM;\r
840         }\r
841 \r
842 cleanup:\r
843 \r
844         if ( pPB != NULL ) {\r
845                 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
846         }\r
847         \r
848         if ( dn.bv_val ) ch_free( dn.bv_val );\r
849         if ( pdn.bv_val ) ch_free( pdn.bv_val );\r
850         if ( ndn.bv_val ) ch_free( ndn.bv_val );\r
851 \r
852         if ( newrdn.bv_val ) ch_free( newrdn.bv_val );\r
853         if ( pnewrdn.bv_val ) ch_free( newrdn.bv_val );\r
854         if ( nnewrdn.bv_val ) ch_free( newrdn.bv_val );\r
855 \r
856         if ( pConn != NULL ) {\r
857                 if ( pConn->c_dn.bv_val ) slapi_ch_free( pConn->c_dn.bv_val );\r
858                 if ( op ) {\r
859                         if ( op->o_dn.bv_val ) slapi_ch_free( op->o_dn.bv_val );\r
860                         slapi_ch_free( op );\r
861                 }\r
862                 pSavePB = pPB;\r
863                 free( pConn );\r
864         }\r
865 \r
866         return( pSavePB );\r
867 #endif /* LDAP_SLAPI */\r
868         return NULL;\r
869 }\r
870 \r
871 /* Function : slapi_modify_internal\r
872  *\r
873  * Description: Plugin functions call this routine to modify an entry \r
874  *                              in the backend directly\r
875  * Return values : LDAP_SUCCESS\r
876  *                 LDAP_OPERAITONS_ERROR\r
877  *                 LDAP_NO_MEMORY\r
878  *                 LDAP_OTHER\r
879  *                 LDAP_UNWILLING_TO_PERFORM\r
880 */\r
881 Slapi_PBlock *\r
882 slapi_modify_internal(\r
883         char *ldn,      \r
884         LDAPMod **mods, \r
885         LDAPControl **controls, \r
886         int log_change )\r
887 {\r
888 #if defined(LDAP_SLAPI)\r
889         int                     i, rc = LDAP_SUCCESS;\r
890         Connection              *pConn = NULL;\r
891         Operation               *op = NULL;\r
892         Slapi_PBlock            *pPB = NULL;\r
893         Slapi_PBlock            *pSavePB = NULL;\r
894 \r
895         struct berval dn = { 0, NULL };\r
896         struct berval pdn = { 0, NULL };\r
897         struct berval ndn = { 0, NULL };\r
898 \r
899         int                     manageDsaIt = 0;\r
900         int                     isCritical;\r
901         Backend                 *be;\r
902         struct berval           *bv;\r
903         struct berval           **ppBV;\r
904         LDAPMod                 *pMod;\r
905 \r
906         Modifications           *modlist = NULL;\r
907         Modifications           **modtail = &modlist;\r
908         Modifications           tmp;\r
909 \r
910         if ( mods == NULL || *mods == NULL || ldn == NULL ) {\r
911                 rc = LDAP_OPERATIONS_ERROR ;\r
912                 goto cleanup;\r
913         }\r
914 \r
915         pConn = fakeConnection( NULL,  LDAP_REQ_MODIFY );\r
916         if ( pConn == NULL ) {\r
917                 rc = LDAP_NO_MEMORY;\r
918                 goto cleanup;\r
919         }\r
920 \r
921         op = (Operation *)pConn->c_pending_ops.stqh_first;\r
922         pPB = (Slapi_PBlock *)op->o_pb;\r
923         op->o_ctrls = controls;\r
924 \r
925         dn.bv_val = slapi_ch_strdup( ldn );\r
926         dn.bv_len = slapi_strlen( ldn );\r
927         rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );\r
928         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
929 \r
930         if ( slapi_control_present( controls, \r
931                         SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {\r
932                 manageDsaIt = 1;\r
933         }\r
934 \r
935         be = select_backend( &dn, manageDsaIt, 0 );\r
936         if ( be == NULL ) {\r
937                 rc =  LDAP_PARTIAL_RESULTS;\r
938                 goto cleanup;\r
939         }\r
940 \r
941         op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
942         op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
943         pConn->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
944         pConn->c_dn.bv_len = be->be_rootdn.bv_len;\r
945 \r
946         suffix_alias( be, &ndn );\r
947 \r
948         for ( i = 0, pMod = mods[0]; rc == LDAP_SUCCESS && pMod != NULL; \r
949                         pMod = mods[++i] ) {\r
950                 Modifications *mod;\r
951                 if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {\r
952                         /*\r
953                          * attr values are in berval format\r
954                          * convert an array of pointers to bervals\r
955                          * to an array of bervals\r
956                          */\r
957                         rc = bvptr2obj( pMod->mod_bvalues, &bv );\r
958                         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
959                         tmp.sml_type.bv_val = slapi_ch_strdup( pMod->mod_type );\r
960                         tmp.sml_type.bv_len = slapi_ch_stlen( pMod->mod_type );\r
961                         tmp.sml_bvalues = bv;\r
962 \r
963                         mod  = (Modifications *)ch_malloc( sizeof(Modifications) );\r
964 \r
965                         mod->sml_op = pMod->mod_op;\r
966                         mod->sml_next = NULL;\r
967                         mod->sml_desc = NULL;\r
968                         mod->sml_type = tmp.sml_type;\r
969                         mod->sml_bvalues = tmp.sml_bvalues;\r
970                 } else { \r
971                         rc = ValuesToBValues( pMod->mod_values, &ppBV );\r
972                         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
973                         rc = bvptr2obj( ppBV, &bv );\r
974                         if ( rc != LDAP_SUCCESS ) goto cleanup;\r
975                         tmp.sml_type.bv_val = slapi_ch_strdup( pMod->mod_type );\r
976                         tmp.sml_type.bv_len = slapi_ch_stlen( pMod->mod_type );\r
977                         tmp.sml_bvalues = bv;\r
978 \r
979                         mod  = (Modifications *) ch_malloc( sizeof(Modifications) );\r
980 \r
981                         mod->sml_op = pMod->mod_op;\r
982                         mod->sml_next = NULL;\r
983                         mod->sml_desc = NULL;\r
984                         mod->sml_type = tmp.sml_type;\r
985                         mod->sml_bvalues = tmp.sml_bvalues;\r
986 \r
987                         if ( ppBV != NULL ) {\r
988                                 ber_bvecfree( ppBV );\r
989                         }\r
990                 }\r
991                 *modtail = mod;\r
992                 modtail = &mod->sml_next;\r
993 \r
994                 switch( pMod->mod_op ) {\r
995                 case LDAP_MOD_ADD:\r
996                 if ( mod->sml_bvalues == NULL ) {\r
997                         rc = LDAP_PROTOCOL_ERROR;\r
998                         goto cleanup;\r
999                 }\r
1000 \r
1001                 /* fall through */\r
1002                 case LDAP_MOD_DELETE:\r
1003                 case LDAP_MOD_REPLACE:\r
1004                 break;\r
1005 \r
1006                 default:\r
1007                         rc = LDAP_PROTOCOL_ERROR;\r
1008                         goto cleanup;\r
1009                 }\r
1010         } \r
1011         *modtail = NULL;\r
1012 \r
1013         if ( ndn.bv_len == 0 ) {\r
1014                 rc = LDAP_UNWILLING_TO_PERFORM;\r
1015                 goto cleanup;\r
1016         }\r
1017 \r
1018         if ( be->be_modify ) {\r
1019                 int repl_user = be_isupdate( be, &op->o_ndn );\r
1020                 if ( !be->be_update_ndn.bv_len || repl_user ) {\r
1021                         int update = be->be_update_ndn.bv_len;\r
1022                         const char *text = NULL;\r
1023                         char textbuf[SLAP_TEXT_BUFLEN];\r
1024                         size_t textlen = sizeof( textbuf );\r
1025 \r
1026                         rc = slap_mods_check( modlist, update,\r
1027                                         &text, textbuf, textlen );\r
1028                         if (rc != LDAP_SUCCESS) {\r
1029                                 goto cleanup;\r
1030                         }\r
1031 \r
1032                         if ( !repl_user ) {\r
1033                                 rc = slap_mods_opattrs( be, op, modlist,\r
1034                                                 modtail, &text, textbuf, \r
1035                                                 textlen );\r
1036                                 if (rc != LDAP_SUCCESS) {\r
1037                                         goto cleanup;\r
1038                                 }\r
1039                         }\r
1040                         rc = (*be->be_modify)( be, pConn, op,\r
1041                                         &pdn, &ndn, modlist );\r
1042                         if ( rc == 0 ) {\r
1043                                 if ( log_change ) {\r
1044                                         replog( be, op, &pdn, &ndn, modlist );\r
1045                                 }\r
1046                                 rc = LDAP_SUCCESS;\r
1047                         } else {\r
1048                                 rc = LDAP_OPERATIONS_ERROR;\r
1049                         }\r
1050                 } else {\r
1051                         rc = LDAP_REFERRAL;\r
1052                 }\r
1053         } else {\r
1054                 rc = LDAP_UNWILLING_TO_PERFORM;\r
1055         }\r
1056 \r
1057 cleanup:\r
1058 \r
1059         if ( pPB != NULL ) \r
1060                 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
1061 \r
1062         if ( dn.bv_val ) ch_free( dn.bv_val );\r
1063         if ( pdn.bv_val ) ch_free( pdn.bv_val );\r
1064         if ( ndn.bv_val ) ch_free( ndn.bv_val );\r
1065 \r
1066         if ( modlist != NULL ) slap_mods_free( modlist );\r
1067 \r
1068         if ( pConn != NULL ) {\r
1069                 if ( pConn->c_dn.bv_val ) slapi_ch_free( pConn->c_dn.bv_val );\r
1070                 if ( op ) {\r
1071                         if ( op->o_dn.bv_val ) slapi_ch_free( op->o_dn.bv_val );\r
1072                         slapi_ch_free( op );\r
1073                 }\r
1074                 pSavePB = pPB;\r
1075                 free( pConn );\r
1076         }\r
1077 \r
1078         return ( pSavePB );\r
1079 \r
1080 #endif /* LDAP_SLAPI */\r
1081         return NULL;\r
1082 }\r
1083 \r
1084 Slapi_PBlock *\r
1085 slapi_search_internal_bind(\r
1086         char *bindDN, \r
1087         char *ldn, \r
1088         int scope, \r
1089         char *filStr, \r
1090         LDAPControl **controls, \r
1091         char **attrs, \r
1092         int attrsonly ) \r
1093 {       \r
1094 #if defined(LDAP_SLAPI)\r
1095         Backend                 *be;\r
1096         Connection              *c;\r
1097         Operation               *op = NULL;\r
1098         Slapi_PBlock            *ptr = NULL;            \r
1099         Slapi_PBlock            *pSavePB = NULL;                \r
1100         struct berval           dn = { 0, NULL };\r
1101         struct berval           pdn = { 0, NULL };\r
1102         struct berval           ndn = { 0, NULL };\r
1103         Filter                  *filter=NULL;\r
1104         struct berval           fstr = { 0, NULL };\r
1105         AttributeName           *an = NULL;\r
1106         const char              *text = NULL;\r
1107 \r
1108         int                     deref=0;\r
1109         int                     sizelimit=-1, timelimit=-1;\r
1110 \r
1111         int                     manageDsaIt = 0; \r
1112         int                     isCritical;\r
1113 \r
1114         int                     i, rc = LDAP_SUCCESS;\r
1115         \r
1116         c = fakeConnection( NULL, LDAP_REQ_SEARCH );\r
1117         if (c == NULL) {\r
1118                 rc = LDAP_NO_MEMORY;\r
1119                 goto cleanup;\r
1120         }\r
1121 \r
1122         op = (Operation *)c->c_pending_ops.stqh_first;\r
1123         ptr = (Slapi_PBlock *)op->o_pb;\r
1124         op->o_ctrls = controls;\r
1125 \r
1126         dn.bv_val = slapi_ch_strdup(ldn);\r
1127         dn.bv_len = slapi_strlen(ldn);\r
1128 \r
1129         rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );\r
1130         if (rc != LDAP_SUCCESS) goto cleanup;\r
1131 \r
1132         if ( scope != LDAP_SCOPE_BASE && \r
1133                         scope != LDAP_SCOPE_ONELEVEL && \r
1134                         scope != LDAP_SCOPE_SUBTREE ) {\r
1135                 rc = LDAP_PROTOCOL_ERROR;\r
1136                 goto cleanup;\r
1137         }\r
1138 \r
1139         filter = slapi_str2filter(filStr);\r
1140         if ( filter == NULL ) {\r
1141                 rc = LDAP_PROTOCOL_ERROR;\r
1142                 goto cleanup;\r
1143         }\r
1144 \r
1145         filter2bv( filter, &fstr );\r
1146 \r
1147         for ( i = 0; attrs != NULL && attrs[i] != NULL; i++ ) {\r
1148                 ; /* count the number of attributes */\r
1149         }\r
1150 \r
1151         if (i > 0) {\r
1152                 an = (AttributeName *)slapi_ch_calloc(1, sizeof(AttributeName));\r
1153                 for (i = 0; attrs[i] != 0; i++) {\r
1154                         an[i].an_desc = NULL;\r
1155                         an[i].an_oc = NULL;\r
1156                         an[i].an_name.bv_val = slapi_ch_strdup(attrs[i]);\r
1157                         an[i].an_name.bv_len = slapi_strlen(attrs[i]);\r
1158                         slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text );\r
1159                 }\r
1160         }\r
1161 \r
1162         if ( scope == LDAP_SCOPE_BASE ) {\r
1163                 Entry *entry = NULL;\r
1164 \r
1165                 if ( ndn.bv_len == 0 ) {\r
1166                         rc = root_dse_info( c, &entry, &text );\r
1167                 }\r
1168 \r
1169                 if( rc != LDAP_SUCCESS ) {\r
1170                         send_ldap_result( c, op, rc, NULL, text, NULL, NULL );\r
1171                         goto cleanup;\r
1172                 } else if ( entry != NULL ) {\r
1173                         rc = test_filter( NULL, c, op, entry, filter );\r
1174 \r
1175                         if( rc == LDAP_COMPARE_TRUE ) {\r
1176                                 send_search_entry( NULL, c, op, entry,\r
1177                                                 an, attrsonly, NULL );\r
1178                         }\r
1179 \r
1180                         entry_free( entry );\r
1181 \r
1182                         send_ldap_result( c, op, LDAP_SUCCESS, \r
1183                                         NULL, NULL, NULL, NULL );\r
1184 \r
1185                         rc = LDAP_SUCCESS;\r
1186 \r
1187                         goto cleanup;\r
1188                 }\r
1189         }\r
1190 \r
1191         if ( !ndn.bv_len && default_search_nbase.bv_len ) {\r
1192                 ch_free( pdn.bv_val );\r
1193                 ch_free( ndn.bv_val );\r
1194 \r
1195                 ber_dupbv( &pdn, &default_search_base );\r
1196                 ber_dupbv( &ndn, &default_search_nbase );\r
1197         }\r
1198 \r
1199         if ( slapi_control_present( controls,\r
1200                         LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {\r
1201                 manageDsaIt = 1;\r
1202         }\r
1203 \r
1204         be = select_backend( &dn, manageDsaIt, 0 );\r
1205         if ( be == NULL ) {\r
1206                 if ( manageDsaIt == 1 ) {\r
1207                         rc = LDAP_NO_SUCH_OBJECT;\r
1208                 } else {\r
1209                         rc = LDAP_PARTIAL_RESULTS;\r
1210                 }\r
1211                 goto cleanup;\r
1212         } \r
1213 \r
1214         op->o_ndn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
1215         op->o_ndn.bv_len = be->be_rootdn.bv_len;\r
1216         c->c_dn.bv_val = slapi_ch_strdup( be->be_rootdn.bv_val );\r
1217         c->c_dn.bv_len = be->be_rootdn.bv_len;\r
1218 \r
1219         if ( be->be_search ) {\r
1220                 rc = (*be->be_search)( be, c, op, &pdn, &ndn,\r
1221                         scope, deref, sizelimit, timelimit,\r
1222                         filter, &fstr, an, attrsonly );\r
1223                 if ( rc == 0 ) {\r
1224                         rc = LDAP_SUCCESS;\r
1225                 } else {\r
1226                         rc = LDAP_OPERATIONS_ERROR;\r
1227                 }\r
1228         } else {\r
1229                 rc = LDAP_UNWILLING_TO_PERFORM;\r
1230         }\r
1231 \r
1232 cleanup:\r
1233 \r
1234         if ( ptr != NULL )\r
1235                 slapi_pblock_set( ptr, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );\r
1236 \r
1237         if ( dn.bv_val ) free( dn.bv_val );\r
1238         if ( ndn.bv_val ) free( ndn.bv_val );\r
1239         if ( pdn.bv_val ) free( pdn.bv_val );\r
1240 \r
1241         if ( filter ) slapi_filter_free( filter, 1 );\r
1242         if ( fstr.bv_val ) free ( fstr.bv_val );\r
1243 \r
1244         if ( an != NULL ) free( an );\r
1245 \r
1246         if ( c != NULL ) {\r
1247                 if ( c->c_dn.bv_val ) slapi_ch_free( c->c_dn.bv_val );\r
1248                 if ( op ) {\r
1249                         if ( op->o_ndn.bv_val ) slapi_ch_free( op->o_ndn.bv_val );\r
1250                         free( op );\r
1251                 }\r
1252                 pSavePB = ptr;\r
1253                 free( c );\r
1254         }\r
1255         return( pSavePB );\r
1256 #endif /* LDAP_SLAPI */\r
1257         return NULL;\r
1258 }\r
1259 \r
1260 Slapi_PBlock * \r
1261 slapi_search_internal(\r
1262         char *base,\r
1263         int scope,\r
1264         char *filStr, \r
1265         LDAPControl **controls,\r
1266         char **attrs,\r
1267         int attrsonly ) \r
1268 {\r
1269 #if defined(LDAP_SLAPI)\r
1270         return slapi_search_internal_bind( NULL, base, scope, filStr,\r
1271                         controls, attrs, attrsonly );\r
1272 #endif\r
1273         return NULL;\r
1274 }\r
1275 \r