2 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
3 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
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.
14 #include "slapi_common.h"
18 #include "../../../libraries/liblber/lber-int.h"
22 bvptr2obj( struct berval **bvptr,
23 struct berval **bvobj);
26 slapi_simple_bind_internal( char *dn,
32 internal_result_v3( Connection *conn,
45 internal_search_entry( Backend *be,
54 int nentries = 0, len = 0, i = 0;
55 Slapi_Entry **head = NULL, **tp;
57 if((ent2str=slapi_entry2str(e,&len)) == NULL) {
58 return SLAPD_NO_MEMORY;
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);
65 if((tp=(Slapi_Entry **)slapi_ch_malloc(2 * sizeof(Slapi_Entry *))) == NULL) {
66 return SLAPD_NO_MEMORY;
68 if((tp[0]=(Slapi_Entry *)str2entry(ent2str)) == NULL) {
69 return SLAPD_NO_MEMORY;
72 if((tp=(Slapi_Entry **)slapi_ch_realloc((char *)head,
73 (sizeof(Slapi_Entry *) * (i+1)))) == NULL) {
74 return SLAPD_NO_MEMORY;
76 if((tp[i-1]=(Slapi_Entry *)str2entry(ent2str)) == NULL) {
77 return SLAPD_NO_MEMORY;
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);
89 internal_search_result( Connection *conn,
96 slapi_pblock_set((Slapi_PBlock *)op->o_pb,SLAPI_NENTRIES,(void *)nentries);
102 internal_result_ext( Connection *conn,
106 struct berval *response )
113 internal_search_reference( Connection *conn,
121 fakeConnection( char *DN,
124 Connection *pConn, *c;
126 if((pConn = (Connection *) slapi_ch_calloc(1, sizeof(Connection))) == NULL)
127 return (Connection *)NULL;
129 LDAP_STAILQ_INIT(&c->c_pending_ops);
130 LDAP_STAILQ_INIT(&c->c_ops);
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;
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;
145 c->c_pending_ops.stqh_first->o_tag = OpType;
146 c->c_sb = ber_sockbuf_alloc( );
147 c->c_protocol = LDAP_VERSION3;
149 time(&pConn->c_pending_ops.stqh_first->o_time);
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;
161 /* Function : slapi_delete_internal
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
169 * LDAP_UNWILLING_TO_PERFORM
172 slapi_delete_internal( char *ldn,
173 LDAPControl **controls,
179 Slapi_PBlock *pPB=NULL;
180 Slapi_PBlock *pSavePB=NULL;
181 Connection *pConn=NULL;
187 struct berval dn = { 0, NULL };
188 struct berval pdn = { 0, NULL };
189 struct berval ndn = { 0, NULL };
193 rc = LDAP_OPERATIONS_ERROR;
196 if ( rc == LDAP_SUCCESS ) {
197 pConn = fakeConnection( NULL, LDAP_REQ_DELETE );
200 if ( pConn == NULL ) {
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;
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;
212 if ( rc == LDAP_SUCCESS ) {
213 dn.bv_val = slapi_strdup(ldn);
214 dn.bv_len = slapi_strlen(ldn);
216 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
218 if( rc != LDAP_SUCCESS ) {
220 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
221 "do_delete: conn %d invalid dn (%s)\n",
222 conn->c_connid, dn.bv_val ));
224 Debug( LDAP_DEBUG_ANY,
225 "do_delete: invalid dn (%s)\n", dn.bv_val, 0, 0 );
230 if( ndn.bv_len == 0 ) {
232 LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_delete: conn %d: "
233 "Attempt to delete root DSE.\n", conn->c_connid ));
235 Debug( LDAP_DEBUG_ANY, "Attempt to delete root DSE.\n", 0, 0, 0 );
237 rc = LDAP_UNWILLING_TO_PERFORM;
239 #ifdef SLAPD_SCHEMA_DN
241 } else if ( strcasecmp( ndn.bv_val, SLAPD_SCHEMA_DN ) == 0 ) {
243 LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_delete: conn %d: "
244 "Attempt to delete subschema subentry.\n", conn->c_connid ));
246 Debug( LDAP_DEBUG_ANY, "Attempt to delete subschema subentry.\n", 0, 0, 0 );
248 rc = LDAP_UNWILLING_TO_PERFORM;
253 if ( rc = slapi_control_present( controls, LDAP_MANAGEDSAIT_OID, NULL, &isCritical)){
254 manageDsaIt = 1; /* turn off referral */
257 if ( rc == LDAP_SUCCESS ) {
258 be = select_backend(&bv, manageDsaIt, 0);
259 if ( be == NULL ) rc = LDAP_PARTIAL_RESULTS;
262 if ( rc == LDAP_SUCCESS ) {
263 rc = backend_check_restrictions( be, conn, op, NULL, &text ) ;
266 if ( rc == LDAP_SUCCESS ) {
267 rc = backend_check_referrals( be, conn, op, &pdn, &ndn );
270 suffix_alias( be, &ndn );
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 )
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 )
284 if (log_change) replog( be, op, &pdn, &ndn, NULL );
287 #ifndef SLAPD_MULTIMASTER
293 rc = LDAP_UNWILLING_TO_PERFORM;
297 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
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 );
307 slapi_ch_free(dn.bv_val);
309 slapi_ch_free(pdn.bv_val);
311 slapi_ch_free(ndn_bv.val);
319 /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
323 * Function : freeModList
324 * Free a list of LDAPMod structures which has the bvalue defined.
327 freeModList( LDAPMod *pMod )
331 while ( pMod != NULL ) {
332 pNextMod = pMod->mod_next;
333 free( pMod->mod_type );
334 ber_bvecfree( pMod->mod_bvalues );
342 * Function : duplicateBVMod
343 * Duplicate a LDAPMod structure in which the bervals are defined.
344 * return code : LDAP_SUCEESS,
350 duplicateBVMod( LDAPMod *pMod,
353 int rc = LDAP_SUCCESS;
355 struct berval **ppNewBV;
356 struct berval *pNewBV;
358 if ( pMod == NULL ) {
361 *ppNewMod = (LDAPMod *)slapi_ch_malloc(sizeof(LDAPMod));
362 if ( *ppNewMod == NULL ) {
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) {
371 if ( pMod->mod_bvalues == NULL ) {
372 (*ppNewMod)->mod_values = NULL;
374 for ( i=0; pMod->mod_bvalues[i] != NULL; i++ ) {
377 ppNewBV = (struct berval **)slapi_ch_malloc( (i+1)*sizeof(struct berval *));
378 if ( ppNewBV == NULL ) {
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 ) {
387 pNewBV->bv_val = slapi_ch_malloc(pMod->mod_bvalues[i]->bv_len+1);
388 if ( pNewBV->bv_val == NULL ) {
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);
397 } /* for each bvalue */
398 if ( rc == LDAP_SUCCESS ) {
400 (*ppNewMod)->mod_bvalues = ppNewBV;
411 * Function : ValuestoBValues
412 * Convert an array of char ptrs to an array of berval ptrs.
413 * return value : LDAP_SUCCESS
419 ValuesToBValues( char **ppValue,
420 struct berval ***pppBV )
422 int rc = LDAP_SUCCESS;
424 struct berval *pTmpBV;
425 struct berval **ppNewBV;
427 /* count the number of char ptrs. */
428 for ( i=0; ppValue != NULL && ppValue[i] != NULL; i++ ) {
435 *pppBV = ppNewBV = (struct berval **)slapi_ch_malloc( (i+1)*(sizeof(struct berval *)) );
436 if ( *pppBV == NULL ) {
439 while ( ppValue != NULL && *ppValue != NULL && rc == LDAP_SUCCESS ) {
440 pTmpBV = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
441 if ( pTmpBV == NULL) {
444 pTmpBV->bv_val = slapi_ch_strdup(*ppValue);
445 if ( pTmpBV->bv_val == NULL ) {
448 pTmpBV->bv_len = strlen(*ppValue);
455 /* null terminate the array of berval ptrs */
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
472 LDAPModToEntry( char *ldn,
479 struct berval **ppSaveBV;
480 struct berval **ppBV;
481 struct berval *pTmpBV;
485 AttributeDescription *ad;
489 Modifications *modlist = NULL;
490 Modifications **modtail = &modlist;
493 struct berval dn = { 0, NULL };
495 dn.ber_val = slapi_ch_strdup(ldn);
496 dn.ber_len = slapi_ch_strlen(ldn);
498 pEntry = (Entry *) ch_calloc( 1, sizeof(Entry) );
499 if ( pEntry == NULL) {
502 rc = dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );
503 if( rc != LDAP_SUCCESS ) {
505 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
506 "LDAPModToEntry: invalid dn (%s)\n", dn.bv_val ));
508 Debug( LDAP_DEBUG_ANY, "LDAPModToEntry: invalid dn (%s)\n", dn.bv_val, 0, 0 );
510 rc = LDAP_INVALID_DN_SYNTAX;
513 if ( rc == LDAP_SUCCESS ) {
514 for ( i=0, pMod=mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod=mods[++i]) {
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;
524 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
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;
533 modtail = &mod->sml_next;
536 /* attr values are in string format, need to be converted */
537 /* to an array of bervals */
538 if ( pMod->mod_values == NULL ) {
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;
548 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
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;
557 modtail = &mod->sml_next;
560 if ( ppBV != NULL ) {
561 ber_bvecfree( ppBV );
565 } /* for each LDAPMod */
568 if( e->e_nname.bv_len == 0 )
569 rc = LDAP_ALREADY_EXISTS;
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 */
576 if ( rc == LDAP_SUCCESS ) {
577 be = select_backend(&bv, manageDsaIt, 0);
578 if ( be == NULL ) rc = LDAP_PARTIAL_RESULTS;
581 if ( rc == LDAP_SUCCESS ) {
582 rc = backend_check_restrictions( be, conn, op, NULL, &text ) ;
585 if ( rc == LDAP_SUCCESS ) {
586 rc = backend_check_referrals( be, conn, op, &pdn, &ndn );
590 if ( rc != LDAP_SUCCESS ) {
591 if ( pEntry != NULL ) {
592 slapi_entry_free( pEntry );
599 /*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
602 slapi_add_entry_internal( Slapi_Entry *e,
603 LDAPControl **controls,
606 int rc=LDAP_SUCCESS, i;
608 Connection *pConn=NULL;
610 Slapi_PBlock *pPB=NULL, *pSavePB=NULL;
612 int manageDsaIt = 0; /* referral is on */
616 /* check if ManageDsaIt control is set */
617 if (slapi_control_present( controls, LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical)) {
618 manageDsaIt = 1; /* turn off referral */
621 pConn = fakeConnection(NULL, LDAP_REQ_ADD);
622 if ( pConn == NULL ) {
625 pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
627 rc = LDAP_OPERATIONS_ERROR;
629 if ( rc == LDAP_SUCCESS ) {
630 be = select_backend(&e->e_nname, manageDsaIt, 0);
632 rc = LDAP_PARTIAL_RESULTS;
633 } else if ( be->be_add == NULL) {
634 rc = LDAP_UNWILLING_TO_PERFORM;
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);
642 Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
648 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
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);
671 slapi_add_internal( char *dn,
673 LDAPControl **controls,
677 Slapi_PBlock *pb=NULL;
679 int i, rc=LDAP_SUCCESS;
682 if(mods == NULL || *mods == NULL || dn == NULL || *dn == NULL)
683 rc = LDAP_OPERATIONS_ERROR ;
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) {
694 if ( rc == LDAP_SUCCESS ) {
695 if((pEntry = LDAPModToEntry( dn, mods )) == NULL) {
700 if(rc != LDAP_SUCCESS) {
701 pb = slapi_pblock_new();
702 slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
704 pb = slapi_add_entry_internal(pEntry, controls, log_changes);
708 slapi_entry_free(pEntry);
714 /*dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd*/
715 /* Function : slapi_modify_internal
717 * Description : Plugin functions call this routine to modify an entry in the backend directly
718 * Return values : LDAP_SUCCESS
719 * LDAP_OPERAITONS_ERROR
722 * LDAP_UNWILLING_TO_PERFORM
725 slapi_modify_internal( char *dn, LDAPMod **mods, LDAPControl **controls, int log_change)
734 LDAPMod *pModList=NULL;
736 Slapi_PBlock *pPB=NULL;
737 Slapi_PBlock *pSavePB=NULL;
738 Connection *pConn=NULL;
744 AttributeDescription *ad;
747 Modifications *modlist = NULL;
748 Modifications **modtail = &modlist;
749 struct berval pdn = { 0, NULL };
750 struct berval ndn = { 0, NULL };
754 pConn = fakeConnection( NULL, LDAP_REQ_MODIFY );
755 if ( pConn == NULL ) {
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;
763 if ( rc == LDAP_SUCCESS ) {
766 Debug(LDAP_DEBUG_TRACE,"slapi modifying object %s.\n", dn, 0, 0);
767 rc = dn_check(dn, &dnBadChar);
768 if ( rc == LDAP_SUCCESS ) {
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.
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 */
780 bv.bv_val = strdup(dn);
781 bv.bv_len = strlen(dn);
782 be = select_backend(&bv, manageDsaIt, 0);
784 rc = LDAP_PARTIAL_RESULTS;
785 } else if ( be->be_modify == NULL ) {
786 rc = LDAP_UNWILLING_TO_PERFORM;
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 );
796 pNewMod = (LDAPMod *)slapi_ch_malloc(sizeof(LDAPMod));
797 if ( pNewMod == NULL ) {
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 ) {
806 if ( (pMod->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE ) {
807 rc = ValuesToBValues( pMod->mod_values, &(pNewMod->mod_bvalues) );
809 if ( pMod->mod_values == NULL ) {
810 Debug(LDAP_DEBUG_TRACE,
811 "slapi_modify_internal:mod_values is null\n",0, 0, 0);
814 rc = ValuesToBValues( pMod->mod_values,
815 &(pNewMod->mod_bvalues) );
821 if ( rc == LDAP_SUCCESS ) {
822 /* add the new mod to the end of mod list */
823 if ( pModList == NULL ) {
827 while ( pTmpMod != NULL ) {
829 pTmpMod = pTmpMod->mod_next;
831 pSaveMod->mod_next = pNewMod;
834 } /* for each LDAPMod */
837 if ( rc == LDAP_SUCCESS ) {
838 /* convert LDAPModList to Modification list */
840 while (pTmpMod != NULL) {
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;
847 rc = bvptr2obj(pTmpMod->mod_bvalues, &pbv);
848 mod->sml_bvalues = pbv;
850 rc = slap_str2ad(pTmpMod->mod_type, &ad, &text );
853 modtail = &mod->sml_next;
854 pTmpMod = pTmpMod->mod_next;
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);
871 Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
874 rc = LDAP_OPERATIONS_ERROR;
878 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
880 if (pModList != NULL) {
881 freeModList( pModList );
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 );
899 /* Function : slapi_modrdn_internal
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
907 * LDAP_UNWILLING_TO_PERFORM
910 slapi_modrdn_internal( char *olddn,
913 LDAPControl **controls,
921 Slapi_PBlock *pPB=NULL;
922 Slapi_PBlock *pSavePB=NULL;
923 Connection *pConn=NULL;
927 struct berval bv = { 0, NULL };
930 struct berval dn = { 0, NULL };
931 struct berval ndn = { 0, NULL };
932 struct berval pdn = { 0, NULL };
934 struct berval newrdnO = { 0, NULL };
935 struct berval nnewrdnO = { 0, NULL };
936 struct berval pnewrdnO = { 0, NULL };
938 struct berval *nnewS = NULL;
939 struct berval *pnewS = NULL;
942 dn.bv_val = ch_strdup(olddn);
943 if (dn.bv_val == NULL) {
946 dn.bv_len = strlen(olddn);
949 if (rc == LDAP_SUCCESS) {
950 newrdnO.bv_val = ch_strdup(newrdn);
951 if (newrdnO.bv_val == NULL) {
954 newrdnO.bv_len = strlen(newrdn);
958 if (rc == LDAP_SUCCESS) {
959 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
962 if (rc == LDAP_SUCCESS) {
963 rc = dnPrettyNormal( NULL, &newrdnO, &pnewrdnO, &nnewrdnO );
966 if ( rc == LDAP_SUCCESS ) {
967 pConn = fakeConnection(NULL, LDAP_REQ_MODRDN );
970 if ( pConn == NULL ) {
973 pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
974 if ( olddn == NULL || newrdn == NULL ) {
975 rc = LDAP_OPERATIONS_ERROR;
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);
983 if ( rc == LDAP_SUCCESS ) {
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. */
989 op = (Operation *)pConn->c_pending_ops.stqh_first;
990 op->o_ctrls = controls;
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 */
997 be = select_backend(&bv, manageDsaIt, 0);
999 rc = LDAP_PARTIAL_RESULTS;
1003 if ( rc == LDAP_SUCCESS ) {
1004 if ( be->be_modrdn == NULL ) {
1005 rc = LDAP_UNWILLING_TO_PERFORM;
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);
1013 Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
1020 ch_free(pdn.bv_val);
1022 ch_free(ndn.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);
1030 if ( pPB != NULL ) {
1031 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
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 );
1049 slapi_search_internal( char *base, int scope, char *filStr,
1050 LDAPControl **controls, char **attrs, int attrsonly )
1052 return slapi_search_internal_bind(NULL,base,scope,filStr,controls, attrs,attrsonly);
1056 slapi_search_internal_bind( char *bindDN, char *b, int scope, char *filStr,
1057 LDAPControl **controls, char **attrs, int attrsonly )
1062 Filter *filter=NULL;
1063 int i, deref=0, sizelimit=-1, timelimit=-1, rc, dnCheckJunk=0;
1064 int manageDsaIt = 0;
1069 struct berval base = { 0, NULL };
1070 struct berval pbase = { 0, NULL };
1071 struct berval nbase = { 0, NULL };
1074 struct berval fstr = { 0, NULL };
1078 c=fakeConnection(bindDN,LDAP_REQ_SEARCH);
1081 rc = LDAP_NO_MEMORY;
1083 ptr = (Slapi_PBlock *)c->c_pending_ops.stqh_first->o_pb;
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 */
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);
1098 rc=dn_check(b, &dnCheckJunk);
1099 if(rc != LDAP_SUCCESS) {
1100 slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)rc);
1104 if ( attrs != NULL ) {
1105 for ( i = 0; attrs[i] != NULL; i++ )
1106 attr_normalize( attrs[i] );
1108 if((filter=slapi_str2filter(filStr)) == NULL) {
1109 slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PROTOCOL_ERROR);
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 */
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);
1124 slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PARTIAL_RESULTS);
1127 } else if ( be->be_search == NULL ) {
1128 slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_UNWILLING_TO_PERFORM);
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);
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 );
1146 slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)rc);
1147 if ( c->c_pending_ops.stqh_first ){
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 );
1156 slapi_ch_free((void **)c);
1158 slapi_filter_free(filter,1);
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.
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.
1173 **slapi_get_supported_extended_ops(void)
1176 ExtendedOp *pTmpExtOp;
1179 char **ppExtOpOID = NULL;
1181 if ( pGExtendedOps != NULL ) {
1182 pTmpExtOp = pGExtendedOps;
1183 while ( pTmpExtOp != NULL ) {
1185 pTmpExtOp = pTmpExtOp->ext_next;
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;
1195 pTmpExtOp = pTmpExtOp->ext_next;
1197 ppExtOpOID[i] = NULL;
1202 return( ppExtOpOID );
1206 slapi_simple_bind_internal( char *d, struct berval *cred, int method, int version)
1209 int rc=LDAP_SUCCESS;
1210 Connection *pConn=NULL;
1212 Slapi_PBlock *pPB=NULL;
1217 struct berval dn = { 0, NULL };
1218 struct berval pdn = { 0, NULL };
1219 struct berval ndn = { 0, NULL };
1223 pConn = fakeConnection(NULL, LDAP_REQ_BIND );
1225 if ( pConn == NULL ) {
1226 rc = LDAP_NO_MEMORY;
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;
1234 rc = LDAP_OPERATIONS_ERROR;
1236 dn.bv_val = ch_strdup (d);
1237 dn.bv_len = strlen(d);
1238 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
1241 if ( rc == LDAP_SUCCESS ) {
1242 be = select_backend(&ndn, 0, 0 );
1244 rc = LDAP_PARTIAL_RESULTS;
1245 } else if ( be->be_bind == NULL ) {
1246 rc = LDAP_UNWILLING_TO_PERFORM;
1250 rc = (*be->be_bind)( be, pConn, op,
1251 &pdn, &ndn, method, cred, NULL );
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);
1261 Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
1265 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );