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