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