2 * Copyright 1998-2002 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"
21 bvptr2obj( struct berval **bvptr,
22 struct berval **bvobj);
25 slapi_simple_bind_internal( char *dn,
32 fakeConnection( char *DN,
35 Connection *pConn, *c;
37 if((pConn = (Connection *) slapi_ch_calloc(sizeof(Connection))) == NULL)
38 return (Connection *)NULL;
40 LDAP_STAILQ_INIT(&c->c_pending_ops);
41 LDAP_STAILQ_INIT(&c->c_ops);
43 if((pConn->c_pending_ops.stqh_first=(Operation *) slapi_ch_calloc(sizeof(Operation))) == NULL) {
44 slapi_ch_free( pConn );
45 return (Connection *)NULL;
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;
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;
62 c->c_authmech.bv_val = NULL;
63 c->c_authmech.bv_len = 0;
64 c->c_dn.bv_val = NULL;
66 c->c_ndn.bv_val = NULL;
68 c->c_cdn.bv_val = NULL;
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;
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;
86 c->c_sb = ber_sockbuf_alloc( );
88 c->c_currentber = NULL;
90 c->c_struct_state = SLAP_C_UNUSED;
96 c->c_protocol = LDAP_VERSION3;
98 time(&pConn->c_pending_ops.stqh_first->o_time);
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;
110 /* Function : slapi_delete_internal
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
118 * LDAP_UNWILLING_TO_PERFORM
121 slapi_delete_internal( char *ldn,
122 LDAPControl **controls,
128 Slapi_PBlock *pPB=NULL;
129 Slapi_PBlock *pSavePB=NULL;
130 Connection *pConn=NULL;
136 struct berval dn = { 0, NULL };
137 struct berval pdn = { 0, NULL };
138 struct berval ndn = { 0, NULL };
142 rc = LDAP_OPERATIONS_ERROR;
145 if ( rc == LDAP_SUCCESS ) {
146 pConn = fakeConnection( NULL, LDAP_REQ_DELETE );
149 if ( pConn == NULL ) {
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;
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;
161 if ( rc == LDAP_SUCCESS ) {
162 dn.bv_val = slapi_strdup(ldn);
163 dn.bv_len = slapi_strlen(ldn);
165 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
167 if( rc != LDAP_SUCCESS ) {
169 LDAP_LOG(( "operation", LDAP_LEVEL_INFO,
170 "do_delete: conn %d invalid dn (%s)\n",
171 conn->c_connid, dn.bv_val ));
173 Debug( LDAP_DEBUG_ANY,
174 "do_delete: invalid dn (%s)\n", dn.bv_val, 0, 0 );
179 if( ndn.bv_len == 0 ) {
181 LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_delete: conn %d: "
182 "Attempt to delete root DSE.\n", conn->c_connid ));
184 Debug( LDAP_DEBUG_ANY, "Attempt to delete root DSE.\n", 0, 0, 0 );
186 rc = LDAP_UNWILLING_TO_PERFORM;
188 #ifdef SLAPD_SCHEMA_DN
190 } else if ( strcasecmp( ndn.bv_val, SLAPD_SCHEMA_DN ) == 0 ) {
192 LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "do_delete: conn %d: "
193 "Attempt to delete subschema subentry.\n", conn->c_connid ));
195 Debug( LDAP_DEBUG_ANY, "Attempt to delete subschema subentry.\n", 0, 0, 0 );
197 rc = LDAP_UNWILLING_TO_PERFORM;
202 if ( rc = slapi_control_present( controls, LDAP_MANAGEDSAIT_OID, NULL, &isCritical)){
203 manageDsaIt = 1; /* turn off referral */
206 if ( rc == LDAP_SUCCESS ) {
207 be = select_backend(&bv, manageDsaIt, 0);
208 if ( be == NULL ) rc = LDAP_PARTIAL_RESULTS;
211 if ( rc == LDAP_SUCCESS ) {
212 rc = backend_check_restrictions( be, conn, op, NULL, &text ) ;
215 if ( rc == LDAP_SUCCESS ) {
216 rc = backend_check_referrals( be, conn, op, &pdn, &ndn );
219 suffix_alias( be, &ndn );
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 )
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 )
233 if (log_change) replog( be, op, &pdn, &ndn, NULL );
236 #ifndef SLAPD_MULTIMASTER
242 rc = LDAP_UNWILLING_TO_PERFORM;
246 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
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 );
256 slapi_ch_free(dn.bv_val);
258 slapi_ch_free(pdn.bv_val);
260 slapi_ch_free(ndn_bv.val);
267 /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
270 internal_result_v3( Connection *conn,
281 internal_result_ext( Connection *conn,
285 struct berval *response )
291 internal_search_reference( Connection *conn,
299 internal_search_result( Connection *conn,
306 slapi_pblock_set((Slapi_PBlock *)op->o_pb,SLAPI_NENTRIES,(void *)nentries);
312 internal_search_entry( Backend *be,
320 char *ent2str = NULL;
321 int nentries = 0, len = 0, i = 0;
322 Slapi_Entry **head = NULL, **tp;
324 if((ent2str=slapi_entry2str(e,&len)) == NULL) {
325 return SLAPD_NO_MEMORY;
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);
332 if((tp=(Slapi_Entry **)slapi_ch_malloc(2 * sizeof(Slapi_Entry *))) == NULL) {
333 return SLAPD_NO_MEMORY;
335 if((tp[0]=(Slapi_Entry *)str2entry(ent2str)) == NULL) {
336 return SLAPD_NO_MEMORY;
339 if((tp=(Slapi_Entry **)slapi_ch_realloc((char *)head,
340 (sizeof(Slapi_Entry *) * (i+1)))) == NULL) {
341 return SLAPD_NO_MEMORY;
343 if((tp[i-1]=(Slapi_Entry *)str2entry(ent2str)) == NULL) {
344 return SLAPD_NO_MEMORY;
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);
357 * Function : freeModList
358 * Free a list of LDAPMod structures which has the bvalue defined.
361 freeModList( LDAPMod *pMod )
365 while ( pMod != NULL ) {
366 pNextMod = pMod->mod_next;
367 free( pMod->mod_type );
368 ber_bvecfree( pMod->mod_bvalues );
376 * Function : duplicateBVMod
377 * Duplicate a LDAPMod structure in which the bervals are defined.
378 * return code : LDAP_SUCEESS,
384 duplicateBVMod( LDAPMod *pMod,
387 int rc = LDAP_SUCCESS;
389 struct berval **ppNewBV;
390 struct berval *pNewBV;
392 if ( pMod == NULL ) {
395 *ppNewMod = (LDAPMod *)slapi_ch_malloc(sizeof(LDAPMod));
396 if ( *ppNewMod == NULL ) {
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) {
405 if ( pMod->mod_bvalues == NULL ) {
406 (*ppNewMod)->mod_values = NULL;
408 for ( i=0; pMod->mod_bvalues[i] != NULL; i++ ) {
411 ppNewBV = (struct berval **)slapi_ch_malloc( (i+1)*sizeof(struct berval *));
412 if ( ppNewBV == NULL ) {
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 ) {
421 pNewBV->bv_val = slapi_ch_malloc(pMod->mod_bvalues[i]->bv_len+1);
422 if ( pNewBV->bv_val == NULL ) {
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);
431 } /* for each bvalue */
432 if ( rc == LDAP_SUCCESS ) {
434 (*ppNewMod)->mod_bvalues = ppNewBV;
445 * Function : ValuestoBValues
446 * Convert an array of char ptrs to an array of berval ptrs.
447 * return value : LDAP_SUCCESS
452 ValuesToBValues( char **ppValue,
453 struct berval ***pppBV )
455 int rc = LDAP_SUCCESS;
457 struct berval *pTmpBV;
458 struct berval **ppNewBV;
460 /* count the number of char ptrs. */
461 for ( i=0; ppValue != NULL && ppValue[i] != NULL; i++ ) {
468 *pppBV = ppNewBV = (struct berval **)slapi_ch_malloc( (i+1)*(sizeof(struct berval *)) );
469 if ( *pppBV == NULL ) {
472 while ( ppValue != NULL && *ppValue != NULL && rc == LDAP_SUCCESS ) {
473 pTmpBV = (struct berval *)slapi_ch_malloc(sizeof(struct berval));
474 if ( pTmpBV == NULL) {
477 pTmpBV->bv_val = slapi_ch_strdup(*ppValue);
478 if ( pTmpBV->bv_val == NULL ) {
481 pTmpBV->bv_len = strlen(*ppValue);
488 /* null terminate the array of berval ptrs */
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
505 LDAPModToEntry( char *ldn,
512 struct berval **ppSaveBV;
513 struct berval **ppBV;
514 struct berval *pTmpBV;
518 AttributeDescription *ad;
522 Modifications *modlist = NULL;
523 Modifications **modtail = &modlist;
526 struct berval dn = { 0, NULL };
528 dn.ber_val = slapi_ch_strdup(ldn);
529 dn.ber_len = slapi_ch_strlen(ldn);
531 pEntry = (Entry *) ch_calloc( 1, sizeof(Entry) );
532 if ( pEntry == NULL) {
535 rc = dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );
536 if( rc != LDAP_SUCCESS ) {
538 LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
539 "LDAPModToEntry: invalid dn (%s)\n", dn.bv_val ));
541 Debug( LDAP_DEBUG_ANY, "LDAPModToEntry: invalid dn (%s)\n", dn.bv_val, 0, 0 );
543 rc = LDAP_INVALID_DN_SYNTAX;
546 if ( rc == LDAP_SUCCESS ) {
547 for ( i=0, pMod=mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod=mods[++i]) {
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;
557 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
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;
566 modtail = &mod->sml_next;
569 /* attr values are in string format, need to be converted */
570 /* to an array of bervals */
571 if ( pMod->mod_values == NULL ) {
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;
581 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
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;
590 modtail = &mod->sml_next;
593 if ( ppBV != NULL ) {
594 ber_bvecfree( ppBV );
598 } /* for each LDAPMod */
601 if( e->e_nname.bv_len == 0 )
602 rc = LDAP_ALREADY_EXISTS;
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 */
609 if ( rc == LDAP_SUCCESS ) {
610 be = select_backend(&bv, manageDsaIt, 0);
611 if ( be == NULL ) rc = LDAP_PARTIAL_RESULTS;
614 if ( rc == LDAP_SUCCESS ) {
615 rc = backend_check_restrictions( be, conn, op, NULL, &text ) ;
618 if ( rc == LDAP_SUCCESS ) {
619 rc = backend_check_referrals( be, conn, op, &pdn, &ndn );
623 if ( rc != LDAP_SUCCESS ) {
624 if ( pEntry != NULL ) {
625 slapi_entry_free( pEntry );
632 /*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
635 slapi_add_entry_internal( Slapi_Entry *e,
636 LDAPControl **controls,
639 int rc=LDAP_SUCCESS, i;
641 Connection *pConn=NULL;
643 Slapi_PBlock *pPB=NULL, *pSavePB=NULL;
645 int manageDsaIt = 0; /* referral is on */
649 /* check if ManageDsaIt control is set */
650 if (slapi_control_present( controls, LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical)) {
651 manageDsaIt = 1; /* turn off referral */
654 pConn = fakeConnection(NULL, LDAP_REQ_ADD);
655 if ( pConn == NULL ) {
658 pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
660 rc = LDAP_OPERATIONS_ERROR;
662 if ( rc == LDAP_SUCCESS ) {
663 be = select_backend(&e->e_nname, manageDsaIt, 0);
665 rc = LDAP_PARTIAL_RESULTS;
666 } else if ( be->be_add == NULL) {
667 rc = LDAP_UNWILLING_TO_PERFORM;
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);
675 Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
681 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
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);
704 slapi_add_internal( char *dn,
706 LDAPControl **controls,
710 Slapi_PBlock *pb=NULL;
712 int i, rc=LDAP_SUCCESS;
715 if(mods == NULL || *mods == NULL || dn == NULL || *dn == NULL)
716 rc = LDAP_OPERATIONS_ERROR ;
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) {
727 if ( rc == LDAP_SUCCESS ) {
728 if((pEntry = LDAPModToEntry( dn, mods )) == NULL) {
733 if(rc != LDAP_SUCCESS) {
734 pb = slapi_pblock_new();
735 slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
737 pb = slapi_add_entry_internal(pEntry, controls, log_changes);
741 slapi_entry_free(pEntry);
747 /*dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd*/
748 /* Function : slapi_modify_internal
750 * Description : Plugin functions call this routine to modify an entry in the backend directly
751 * Return values : LDAP_SUCCESS
752 * LDAP_OPERAITONS_ERROR
755 * LDAP_UNWILLING_TO_PERFORM
758 slapi_modify_internal( char *dn, LDAPMod **mods, LDAPControl **controls, int log_change)
767 LDAPMod *pModList=NULL;
769 Slapi_PBlock *pPB=NULL;
770 Slapi_PBlock *pSavePB=NULL;
771 Connection *pConn=NULL;
777 AttributeDescription *ad;
780 Modifications *modlist = NULL;
781 Modifications **modtail = &modlist;
782 struct berval pdn = { 0, NULL };
783 struct berval ndn = { 0, NULL };
787 pConn = fakeConnection( NULL, LDAP_REQ_MODIFY );
788 if ( pConn == NULL ) {
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;
796 if ( rc == LDAP_SUCCESS ) {
799 Debug(LDAP_DEBUG_TRACE,"slapi modifying object %s.\n", dn, 0, 0);
800 rc = dn_check(dn, &dnBadChar);
801 if ( rc == LDAP_SUCCESS ) {
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.
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 */
813 bv.bv_val = strdup(dn);
814 bv.bv_len = strlen(dn);
815 be = select_backend(&bv, manageDsaIt, 0);
817 rc = LDAP_PARTIAL_RESULTS;
818 } else if ( be->be_modify == NULL ) {
819 rc = LDAP_UNWILLING_TO_PERFORM;
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 );
829 pNewMod = (LDAPMod *)slapi_ch_malloc(sizeof(LDAPMod));
830 if ( pNewMod == NULL ) {
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 ) {
839 if ( (pMod->mod_op & ~LDAP_MOD_BVALUES) == LDAP_MOD_DELETE ) {
840 rc = ValuesToBValues( pMod->mod_values, &(pNewMod->mod_bvalues) );
842 if ( pMod->mod_values == NULL ) {
843 Debug(LDAP_DEBUG_TRACE,
844 "slapi_modify_internal:mod_values is null\n",0, 0, 0);
847 rc = ValuesToBValues( pMod->mod_values,
848 &(pNewMod->mod_bvalues) );
854 if ( rc == LDAP_SUCCESS ) {
855 /* add the new mod to the end of mod list */
856 if ( pModList == NULL ) {
860 while ( pTmpMod != NULL ) {
862 pTmpMod = pTmpMod->mod_next;
864 pSaveMod->mod_next = pNewMod;
867 } /* for each LDAPMod */
870 if ( rc == LDAP_SUCCESS ) {
871 /* convert LDAPModList to Modification list */
873 while (pTmpMod != NULL) {
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;
880 rc = bvptr2obj(pTmpMod->mod_bvalues, &pbv);
881 mod->sml_bvalues = pbv;
883 rc = slap_str2ad(pTmpMod->mod_type, &ad, &text );
886 modtail = &mod->sml_next;
887 pTmpMod = pTmpMod->mod_next;
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);
904 Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
907 rc = LDAP_OPERATIONS_ERROR;
911 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
913 if (pModList != NULL) {
914 freeModList( pModList );
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 );
932 /* Function : slapi_modrdn_internal
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
940 * LDAP_UNWILLING_TO_PERFORM
943 slapi_modrdn_internal( char *olddn,
946 LDAPControl **controls,
954 Slapi_PBlock *pPB=NULL;
955 Slapi_PBlock *pSavePB=NULL;
956 Connection *pConn=NULL;
960 struct berval bv = { 0, NULL };
963 struct berval dn = { 0, NULL };
964 struct berval ndn = { 0, NULL };
965 struct berval pdn = { 0, NULL };
967 struct berval newrdnO = { 0, NULL };
968 struct berval nnewrdnO = { 0, NULL };
969 struct berval pnewrdnO = { 0, NULL };
971 struct berval *nnewS = NULL;
972 struct berval *pnewS = NULL;
975 dn.bv_val = ch_strdup(olddn);
976 if (dn.bv_val == NULL) {
979 dn.bv_len = strlen(olddn);
982 if (rc == LDAP_SUCCESS) {
983 newrdnO.bv_val = ch_strdup(newrdn);
984 if (newrdnO.bv_val == NULL) {
987 newrdnO.bv_len = strlen(newrdn);
991 if (rc == LDAP_SUCCESS) {
992 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
995 if (rc == LDAP_SUCCESS) {
996 rc = dnPrettyNormal( NULL, &newrdnO, &pnewrdnO, &nnewrdnO );
999 if ( rc == LDAP_SUCCESS ) {
1000 pConn = fakeConnection(NULL, LDAP_REQ_MODRDN );
1003 if ( pConn == NULL ) {
1004 rc = LDAP_NO_MEMORY;
1006 pPB = (Slapi_PBlock *)pConn->c_pending_ops.stqh_first->o_pb;
1007 if ( olddn == NULL || newrdn == NULL ) {
1008 rc = LDAP_OPERATIONS_ERROR;
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);
1016 if ( rc == LDAP_SUCCESS ) {
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. */
1022 op = (Operation *)pConn->c_pending_ops.stqh_first;
1023 op->o_ctrls = controls;
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 */
1030 be = select_backend(&bv, manageDsaIt, 0);
1032 rc = LDAP_PARTIAL_RESULTS;
1036 if ( rc == LDAP_SUCCESS ) {
1037 if ( be->be_modrdn == NULL ) {
1038 rc = LDAP_UNWILLING_TO_PERFORM;
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);
1046 Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
1053 ch_free(pdn.bv_val);
1055 ch_free(ndn.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);
1063 if ( pPB != NULL ) {
1064 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
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 );
1082 slapi_search_internal( char *base, int scope, char *filStr,
1083 LDAPControl **controls, char **attrs, int attrsonly )
1085 return slapi_search_internal_bind(NULL,base,scope,filStr,controls, attrs,attrsonly);
1089 slapi_search_internal_bind( char *bindDN, char *b, int scope, char *filStr,
1090 LDAPControl **controls, char **attrs, int attrsonly )
1095 Filter *filter=NULL;
1096 int i, deref=0, sizelimit=-1, timelimit=-1, rc, dnCheckJunk=0;
1097 int manageDsaIt = 0;
1102 struct berval base = { 0, NULL };
1103 struct berval pbase = { 0, NULL };
1104 struct berval nbase = { 0, NULL };
1107 struct berval fstr = { 0, NULL };
1111 c=fakeConnection(bindDN,LDAP_REQ_SEARCH);
1114 rc = LDAP_NO_MEMORY;
1116 ptr = (Slapi_PBlock *)c->c_pending_ops.stqh_first->o_pb;
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 */
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);
1131 rc=dn_check(b, &dnCheckJunk);
1132 if(rc != LDAP_SUCCESS) {
1133 slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)rc);
1137 if ( attrs != NULL ) {
1138 for ( i = 0; attrs[i] != NULL; i++ )
1139 attr_normalize( attrs[i] );
1141 if((filter=slapi_str2filter(filStr)) == NULL) {
1142 slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PROTOCOL_ERROR);
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 */
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);
1157 slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_PARTIAL_RESULTS);
1160 } else if ( be->be_search == NULL ) {
1161 slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)LDAP_UNWILLING_TO_PERFORM);
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);
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 );
1179 slapi_pblock_set(ptr,SLAPI_PLUGIN_INTOP_RESULT,(void *)rc);
1180 if ( c->c_pending_ops.stqh_first ){
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 );
1189 slapi_ch_free((void **)c);
1191 slapi_filter_free(filter,1);
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.
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.
1206 **slapi_get_supported_extended_ops(void)
1209 ExtendedOp *pTmpExtOp;
1212 char **ppExtOpOID = NULL;
1214 if ( pGExtendedOps != NULL ) {
1215 pTmpExtOp = pGExtendedOps;
1216 while ( pTmpExtOp != NULL ) {
1218 pTmpExtOp = pTmpExtOp->ext_next;
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;
1228 pTmpExtOp = pTmpExtOp->ext_next;
1230 ppExtOpOID[i] = NULL;
1235 return( ppExtOpOID );
1239 slapi_simple_bind_internal( char *d, struct berval *cred, int method, int version)
1242 int rc=LDAP_SUCCESS;
1243 Connection *pConn=NULL;
1245 Slapi_PBlock *pPB=NULL;
1250 struct berval dn = { 0, NULL };
1251 struct berval pdn = { 0, NULL };
1252 struct berval ndn = { 0, NULL };
1256 pConn = fakeConnection(NULL, LDAP_REQ_BIND );
1258 if ( pConn == NULL ) {
1259 rc = LDAP_NO_MEMORY;
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;
1267 rc = LDAP_OPERATIONS_ERROR;
1269 dn.bv_val = ch_strdup (d);
1270 dn.bv_len = strlen(d);
1271 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
1274 if ( rc == LDAP_SUCCESS ) {
1275 be = select_backend(&ndn, 0, 0 );
1277 rc = LDAP_PARTIAL_RESULTS;
1278 } else if ( be->be_bind == NULL ) {
1279 rc = LDAP_UNWILLING_TO_PERFORM;
1283 rc = (*be->be_bind)( be, pConn, op,
1284 &pdn, &ndn, method, cred, NULL );
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);
1294 Debug (LDAP_DEBUG_TRACE, " backend routine NOT successful \n", 0, 0, 0);
1298 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );