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