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.
17 #include "../../../libraries/liblber/lber-int.h"
20 int bvptr2obj( struct berval **bvptr, struct berval **bvobj );
36 internal_search_entry(
46 int nentries = 0, len = 0, i = 0;
47 Slapi_Entry **head = NULL, **tp;
49 ent2str = slapi_entry2str( e, &len );
50 if ( ent2str == NULL ) {
54 slapi_pblock_get( (Slapi_PBlock *)op->o_pb,
55 SLAPI_NENTRIES, &nentries );
56 slapi_pblock_get( (Slapi_PBlock *)op->o_pb,
57 SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head );
60 if ( nentries == 0 ) {
61 tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) );
66 tp[ 0 ] = (Slapi_Entry *)str2entry( ent2str );
67 if ( tp[ 0 ] == NULL ) {
72 tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head,
73 sizeof(Slapi_Entry *) * ( i + 1 ) );
77 tp[ i - 1 ] = (Slapi_Entry *)str2entry( ent2str );
78 if ( tp[ i - 1 ] == NULL ) {
84 slapi_pblock_set( (Slapi_PBlock *)op->o_pb,
85 SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, (void *)tp );
86 slapi_pblock_set( (Slapi_PBlock *)op->o_pb,
87 SLAPI_NENTRIES, (void *)i );
93 internal_search_result(
103 slapi_pblock_set( (Slapi_PBlock *)op->o_pb,
104 SLAPI_NENTRIES, (void *)nentries );
118 struct berval *rspdata,
119 LDAPControl **ctrls )
125 internal_search_reference(
142 Connection *pConn, *c;
143 ber_len_t max = sockbuf_max_incoming;
145 pConn = (Connection *) slapi_ch_calloc(1, sizeof(Connection));
147 return (Connection *)NULL;
150 LDAP_STAILQ_INIT( &pConn->c_pending_ops );
152 pConn->c_pending_ops.stqh_first =
153 (Operation *) slapi_ch_calloc( 1, sizeof(Operation) );
154 if ( pConn->c_pending_ops.stqh_first == NULL ) {
155 slapi_ch_free( (void **)&pConn );
156 return (Connection *)NULL;
159 pConn->c_pending_ops.stqh_first->o_pb =
160 (Slapi_PBlock *) slapi_pblock_new();
161 if ( pConn->c_pending_ops.stqh_first->o_pb == NULL ) {
162 slapi_ch_free( (void **)&pConn->c_pending_ops.stqh_first );
163 slapi_ch_free( (void **)&pConn );
164 return (Connection *)NULL;
169 /* operation object */
170 c->c_pending_ops.stqh_first->o_tag = OpType;
171 c->c_pending_ops.stqh_first->o_protocol = LDAP_VERSION3;
172 c->c_pending_ops.stqh_first->o_authmech.bv_val = NULL;
173 c->c_pending_ops.stqh_first->o_authmech.bv_len = 0;
174 c->c_pending_ops.stqh_first->o_time = slap_get_time();
175 c->c_pending_ops.stqh_first->o_do_not_cache = 1;
176 c->c_pending_ops.stqh_first->o_threadctx = ldap_pvt_thread_pool_context( &connection_pool );
178 /* connection object */
179 c->c_authmech.bv_val = NULL;
180 c->c_authmech.bv_len = 0;
181 c->c_dn.bv_val = NULL;
183 c->c_ndn.bv_val = NULL;
187 c->c_listener = NULL;
188 c->c_peer_domain.bv_val = NULL;
189 c->c_peer_domain.bv_len = 0;
190 c->c_peer_name.bv_val = NULL;
191 c->c_peer_name.bv_len = 0;
193 LDAP_STAILQ_INIT( &c->c_ops );
195 c->c_sasl_bind_mech.bv_val = NULL;
196 c->c_sasl_bind_mech.bv_len = 0;
197 c->c_sasl_context = NULL;
198 c->c_sasl_extra = NULL;
200 c->c_sb = ber_sockbuf_alloc( );
202 ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
204 c->c_currentber = NULL;
206 /* should check status of thread calls */
207 ldap_pvt_thread_mutex_init( &c->c_mutex );
208 ldap_pvt_thread_mutex_init( &c->c_write_mutex );
209 ldap_pvt_thread_cond_init( &c->c_write_cv );
211 c->c_n_ops_received = 0;
212 c->c_n_ops_executing = 0;
213 c->c_n_ops_pending = 0;
214 c->c_n_ops_completed = 0;
220 c->c_protocol = LDAP_VERSION3;
222 c->c_activitytime = c->c_starttime = slap_get_time();
226 c->c_conn_state = 0x01; /* SLAP_C_ACTIVE */
227 c->c_struct_state = 0x02; /* SLAP_C_USED */
229 c->c_ssf = c->c_transport_ssf = 0;
232 backend_connection_init( c );
234 pConn->c_send_ldap_result = internal_result_v3;
235 pConn->c_send_search_entry = internal_search_entry;
236 pConn->c_send_search_result = internal_search_result;
237 pConn->c_send_ldap_extended = internal_result_ext;
238 pConn->c_send_search_reference = internal_search_reference;
244 * Function : values2obj
245 * Convert an array of strings into a BerVarray.
253 int rc = LDAP_SUCCESS;
257 if ( ppValue == NULL ) {
262 for ( i = 0; ppValue[i] != NULL; i++ )
265 tmpberval = (BerVarray)slapi_ch_malloc( (i+1) * (sizeof(struct berval)) );
266 if ( tmpberval == NULL ) {
267 return LDAP_NO_MEMORY;
269 for ( i = 0; ppValue[i] != NULL; i++ ) {
270 tmpberval[i].bv_val = ppValue[i];
271 tmpberval[i].bv_len = strlen( ppValue[i] );
273 tmpberval[i].bv_val = NULL;
274 tmpberval[i].bv_len = 0;
282 freeMods( Modifications *ml )
285 * Free a modification list whose values have been
286 * set with bvptr2obj() or values2obj() (ie. they
287 * do not own the pointer to the underlying values)
291 for ( ; ml != NULL; ml = next ) {
294 slapi_ch_free( (void **)&ml->sml_bvalues );
295 slapi_ch_free( (void **)&ml );
300 * Function : LDAPModToEntry
301 * convert a dn plus an array of LDAPMod struct ptrs to an entry structure
302 * with a link list of the correspondent attributes.
303 * Return value : LDAP_SUCCESS
312 struct berval dn = { 0, NULL };
319 Modifications *modlist = NULL;
320 Modifications **modtail = &modlist;
323 int rc = LDAP_SUCCESS;
326 const char *text = NULL;
329 op = (Operation *) slapi_ch_calloc(1, sizeof(Operation));
330 if ( pEntry == NULL) {
334 op->o_tag = LDAP_REQ_ADD;
336 pEntry = (Entry *) ch_calloc( 1, sizeof(Entry) );
337 if ( pEntry == NULL) {
342 dn.bv_val = slapi_ch_strdup(ldn);
343 dn.bv_len = strlen(ldn);
345 rc = dnPrettyNormal( NULL, &dn, &pEntry->e_name, &pEntry->e_nname );
346 if (rc != LDAP_SUCCESS) goto cleanup;
348 if ( rc == LDAP_SUCCESS ) {
349 for ( i=0, pMod=mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod=mods[++i]) {
351 if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
352 /* attr values are in berval format */
353 /* convert an array of pointers to bervals to an array of bervals */
354 rc = bvptr2obj(pMod->mod_bvalues, &bv);
355 if (rc != LDAP_SUCCESS) goto cleanup;
356 tmp.sml_type.bv_val = pMod->mod_type;
357 tmp.sml_type.bv_len = strlen( pMod->mod_type );
358 tmp.sml_bvalues = bv;
360 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
362 mod->sml_op = LDAP_MOD_ADD;
363 mod->sml_next = NULL;
364 mod->sml_desc = NULL;
365 mod->sml_type = tmp.sml_type;
366 mod->sml_bvalues = tmp.sml_bvalues;
369 modtail = &mod->sml_next;
372 /* attr values are in string format, need to be converted */
373 /* to an array of bervals */
374 if ( pMod->mod_values == NULL ) {
377 rc = values2obj( pMod->mod_values, &bv );
378 if (rc != LDAP_SUCCESS) goto cleanup;
379 tmp.sml_type.bv_val = pMod->mod_type;
380 tmp.sml_type.bv_len = strlen( pMod->mod_type );
381 tmp.sml_bvalues = bv;
383 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
385 mod->sml_op = LDAP_MOD_ADD;
386 mod->sml_next = NULL;
387 mod->sml_desc = NULL;
388 mod->sml_type = tmp.sml_type;
389 mod->sml_bvalues = tmp.sml_bvalues;
392 modtail = &mod->sml_next;
395 } /* for each LDAPMod */
398 be = select_backend(&pEntry->e_nname, 0, 0);
400 rc = LDAP_PARTIAL_RESULTS;
405 int repl_user = be_isupdate(be, &be->be_rootdn );
406 if ( !be->be_update_ndn.bv_len || repl_user ) {
407 int update = be->be_update_ndn.bv_len;
408 char textbuf[SLAP_TEXT_BUFLEN];
409 size_t textlen = sizeof textbuf;
411 rc = slap_mods_check( modlist, update, &text,
413 if ( rc != LDAP_SUCCESS) {
418 rc = slap_mods_opattrs( be, op,
419 modlist, modtail, &text,
421 if ( rc != LDAP_SUCCESS) {
427 * FIXME: slap_mods2entry is declared static
428 * in servers/slapd/add.c
430 rc = slap_mods2entry( modlist, &pEntry, repl_user,
431 &text, textbuf, textlen );
432 if (rc != LDAP_SUCCESS) {
440 rc = LDAP_UNWILLING_TO_PERFORM;
445 if ( dn.bv_val ) slapi_ch_free( (void **)&dn.bv_val );
446 if ( op ) slapi_ch_free( (void **)&op );
447 if ( modlist != NULL ) freeMods( modlist );
448 if ( rc != LDAP_SUCCESS ) {
449 if ( pEntry != NULL ) {
450 slapi_entry_free( pEntry );
458 /* Function : slapi_delete_internal
460 * Description : Plugin functions call this routine to delete an entry
461 * in the backend directly
462 * Return values : LDAP_SUCCESS
466 * LDAP_UNWILLING_TO_PERFORM
469 slapi_delete_internal(
471 LDAPControl **controls,
474 #if defined(LDAP_SLAPI)
476 Connection *pConn = NULL;
477 Operation *op = NULL;
478 Slapi_PBlock *pPB = NULL;
479 Slapi_PBlock *pSavePB = NULL;
481 struct berval dn = { 0, NULL };
482 struct berval pdn = { 0, NULL };
483 struct berval ndn = { 0, NULL };
490 rc = LDAP_PARAM_ERROR;
494 pConn = fakeConnection( NULL, LDAP_REQ_DELETE );
500 op = (Operation *)pConn->c_pending_ops.stqh_first;
501 pPB = (Slapi_PBlock *)op->o_pb;
502 op->o_ctrls = controls;
504 dn.bv_val = slapi_ch_strdup(ldn);
505 dn.bv_len = slapi_strlen(ldn);
506 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
507 if ( rc != LDAP_SUCCESS ) goto cleanup;
509 if ( slapi_control_present( controls,
510 SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical) ) {
514 be = select_backend( &ndn, manageDsaIt, 0 );
516 rc = LDAP_PARTIAL_RESULTS;
520 op->o_dn = pConn->c_dn = be->be_rootdn;
521 op->o_ndn = pConn->c_ndn = be->be_rootndn;
523 suffix_alias( be, &ndn );
525 if ( be->be_delete ) {
526 int repl_user = be_isupdate( be, &op->o_ndn );
527 if ( !be->be_update_ndn.bv_len || repl_user ) {
528 rc = (*be->be_delete)( be, pConn, op, &pdn, &ndn );
531 replog( be, op, &pdn, &ndn, NULL );
535 rc = LDAP_OPERATIONS_ERROR;
541 rc = LDAP_UNWILLING_TO_PERFORM;
546 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
548 if (dn.bv_val) slapi_ch_free( (void **)&dn.bv_val );
549 if (pdn.bv_val) slapi_ch_free( (void **)&pdn.bv_val );
550 if (ndn.bv_val) slapi_ch_free( (void **)&ndn.bv_val );
552 if ( pConn != NULL ) {
553 if ( pConn->c_sb != NULL ) ber_sockbuf_free( pConn->c_sb );
554 if ( op ) slapi_ch_free( (void **)&op );
560 #endif /* LDAP_SLAPI */
565 slapi_add_entry_internal(
567 LDAPControl **controls,
570 #if defined(LDAP_SLAPI)
571 Connection *pConn = NULL;
572 Operation *op = NULL;
573 Slapi_PBlock *pPB = NULL, *pSavePB = NULL;
578 int rc = LDAP_SUCCESS;
581 rc = LDAP_PARAM_ERROR;
585 pConn = fakeConnection( NULL, LDAP_REQ_ADD );
586 if ( pConn == NULL ) {
591 if ( slapi_control_present( controls, LDAP_CONTROL_MANAGEDSAIT,
592 NULL, &isCritical ) ) {
596 op = (Operation *)pConn->c_pending_ops.stqh_first;
597 pPB = (Slapi_PBlock *)op->o_pb;
598 op->o_ctrls = controls;
600 be = select_backend( &e->e_nname, manageDsaIt, 0 );
602 rc = LDAP_PARTIAL_RESULTS;
606 op->o_dn = pConn->c_dn = be->be_rootdn;
607 op->o_ndn = pConn->c_ndn = be->be_rootndn;
610 int repl_user = be_isupdate( be, &op->o_ndn );
611 if ( !be->be_update_ndn.bv_len || repl_user ){
612 if ( (*be->be_add)( be, pConn, op, e ) == 0 ) {
614 replog( be, op, &e->e_name,
623 rc = LDAP_UNWILLING_TO_PERFORM;
629 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
632 if ( pConn != NULL ) {
633 if ( pConn->c_sb != NULL ) ber_sockbuf_free( pConn->c_sb );
634 if ( op != NULL ) slapi_ch_free( (void **)&op );
639 #endif /* LDAP_SLAPI */
648 LDAPControl **controls,
651 #if defined(LDAP_SLAPI)
652 LDAPMod *pMod = NULL;
653 Slapi_PBlock *pb = NULL;
654 Entry *pEntry = NULL;
655 int i, rc=LDAP_SUCCESS;
657 if ( mods == NULL || *mods == NULL || dn == NULL || *dn == '\0' ) {
658 rc = LDAP_PARAM_ERROR ;
661 if ( rc == LDAP_SUCCESS ) {
662 for ( i = 0, pMod = mods[0]; pMod != NULL; pMod = mods[++i] ) {
663 if ( (pMod->mod_op & ~LDAP_MOD_BVALUES) != LDAP_MOD_ADD ) {
670 if ( rc == LDAP_SUCCESS ) {
671 if((pEntry = LDAPModToEntry( dn, mods )) == NULL) {
676 if ( rc != LDAP_SUCCESS ) {
677 pb = slapi_pblock_new();
678 slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
680 pb = slapi_add_entry_internal( pEntry, controls, log_changes );
684 slapi_entry_free(pEntry);
688 #endif /* LDAP_SLAPI */
692 /* Function : slapi_modrdn_internal
694 * Description : Plugin functions call this routine to modify the rdn
695 * of an entry in the backend directly
696 * Return values : LDAP_SUCCESS
698 * LDAP_OPERATIONS_ERROR
701 * LDAP_UNWILLING_TO_PERFORM
703 * NOTE: This function does not support the "newSuperior" option from LDAP V3.
706 slapi_modrdn_internal(
710 LDAPControl **controls,
713 #if defined(LDAP_SLAPI)
714 int rc = LDAP_SUCCESS;
716 struct berval dn = { 0, NULL };
717 struct berval pdn = { 0, NULL };
718 struct berval ndn = { 0, NULL };
720 struct berval newrdn = { 0, NULL };
721 struct berval pnewrdn = { 0, NULL };
722 struct berval nnewrdn = { 0, NULL };
724 #if 0 /* currently unused */
725 struct berval newSuperior = { 0, NULL };
727 struct berval pnewSuperior = { 0, NULL };
728 #if 0 /* currently unused */
729 struct berval nnewSuperior = { 0, NULL };
732 struct berval *pnewS = NULL;
733 struct berval *nnewS = NULL;
735 Connection *pConn = NULL;
736 Operation *op = NULL;
737 Slapi_PBlock *pPB = NULL;
738 Slapi_PBlock *pSavePB = NULL;
741 #if 0 /* currently unused */
742 Backend *newSuperior_be = NULL;
747 #if 0 /* currently unused */
748 const char *text = NULL;
751 dn.bv_val = slapi_ch_strdup(olddn);
752 dn.bv_len = slapi_ch_stlen(olddn);
754 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
756 if ( rc != LDAP_SUCCESS ) goto cleanup;
758 if ( ndn.bv_len == 0 ) {
759 rc = LDAP_UNWILLING_TO_PERFORM;
763 newrdn.bv_val = slapi_ch_strdup( lnewrdn );
764 newrdn.bv_len = slapi_ch_stlen( lnewrdn );
766 rc = dnPrettyNormal( NULL, &newrdn, &pnewrdn, &nnewrdn );
768 if ( rc != LDAP_SUCCESS ) goto cleanup;
770 if ( rdnValidate( &pnewrdn ) != LDAP_SUCCESS ) goto cleanup;
772 pConn = fakeConnection( NULL, LDAP_REQ_MODRDN);
773 if ( pConn == NULL) {
778 op = (Operation *)pConn->c_pending_ops.stqh_first;
779 pPB = (Slapi_PBlock *)op->o_pb;
780 op->o_ctrls = controls;
782 if ( slapi_control_present( controls,
783 SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {
787 be = select_backend( &ndn, manageDsaIt, 0 );
789 rc = LDAP_PARTIAL_RESULTS;
793 op->o_dn = pConn->c_dn = be->be_rootdn;
794 op->o_ndn = pConn->c_ndn = be->be_rootndn;
796 suffix_alias( be, &ndn );
798 if ( be->be_modrdn ) {
799 int repl_user = be_isupdate( be, &op->o_ndn );
800 if ( !be->be_update_ndn.bv_len || repl_user ) {
801 rc = (*be->be_modrdn)( be, pConn, op, &pdn, &ndn,
802 &pnewrdn, &nnewrdn, deloldrdn, pnewS,
805 struct slap_replog_moddn moddn;
806 moddn.newrdn = &pnewrdn;
807 moddn.deloldrdn = deloldrdn;
808 moddn.newsup = &pnewSuperior;
810 replog( be, op, &pdn, &ndn, &moddn );
815 rc = LDAP_OPERATIONS_ERROR;
823 rc = LDAP_UNWILLING_TO_PERFORM;
829 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
832 if ( dn.bv_val ) ch_free( dn.bv_val );
833 if ( pdn.bv_val ) ch_free( pdn.bv_val );
834 if ( ndn.bv_val ) ch_free( ndn.bv_val );
836 if ( newrdn.bv_val ) ch_free( newrdn.bv_val );
837 if ( pnewrdn.bv_val ) ch_free( newrdn.bv_val );
838 if ( nnewrdn.bv_val ) ch_free( newrdn.bv_val );
840 if ( pConn != NULL ) {
841 if ( pConn->c_sb != NULL ) ber_sockbuf_free( pConn->c_sb );
842 if ( op != NULL ) slapi_ch_free( (void **)&op );
848 #endif /* LDAP_SLAPI */
852 /* Function : slapi_modify_internal
854 * Description: Plugin functions call this routine to modify an entry
855 * in the backend directly
856 * Return values : LDAP_SUCCESS
859 * LDAP_OPERATIONS_ERROR
861 * LDAP_UNWILLING_TO_PERFORM
864 slapi_modify_internal(
867 LDAPControl **controls,
870 #if defined(LDAP_SLAPI)
871 int i, rc = LDAP_SUCCESS;
872 Connection *pConn = NULL;
873 Operation *op = NULL;
874 Slapi_PBlock *pPB = NULL;
875 Slapi_PBlock *pSavePB = NULL;
877 struct berval dn = { 0, NULL };
878 struct berval pdn = { 0, NULL };
879 struct berval ndn = { 0, NULL };
887 Modifications *modlist = NULL;
888 Modifications **modtail = &modlist;
891 if ( mods == NULL || *mods == NULL || ldn == NULL ) {
892 rc = LDAP_PARAM_ERROR ;
896 pConn = fakeConnection( NULL, LDAP_REQ_MODIFY );
897 if ( pConn == NULL ) {
902 op = (Operation *)pConn->c_pending_ops.stqh_first;
903 pPB = (Slapi_PBlock *)op->o_pb;
904 op->o_ctrls = controls;
906 dn.bv_val = slapi_ch_strdup( ldn );
907 dn.bv_len = slapi_strlen( ldn );
908 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
909 if ( rc != LDAP_SUCCESS ) goto cleanup;
911 if ( slapi_control_present( controls,
912 SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {
916 be = select_backend( &ndn, manageDsaIt, 0 );
918 rc = LDAP_PARTIAL_RESULTS;
922 op->o_dn = pConn->c_dn = be->be_rootdn;
923 op->o_ndn = pConn->c_ndn = be->be_rootndn;
925 suffix_alias( be, &ndn );
927 for ( i = 0, pMod = mods[0]; rc == LDAP_SUCCESS && pMod != NULL;
930 if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
932 * attr values are in berval format
933 * convert an array of pointers to bervals
934 * to an array of bervals
936 rc = bvptr2obj( pMod->mod_bvalues, &bv );
937 if ( rc != LDAP_SUCCESS ) goto cleanup;
938 tmp.sml_type.bv_val = pMod->mod_type;
939 tmp.sml_type.bv_len = strlen( pMod->mod_type );
940 tmp.sml_bvalues = bv;
942 mod = (Modifications *)ch_malloc( sizeof(Modifications) );
944 mod->sml_op = pMod->mod_op;
945 mod->sml_next = NULL;
946 mod->sml_desc = NULL;
947 mod->sml_type = tmp.sml_type;
948 mod->sml_bvalues = tmp.sml_bvalues;
950 rc = values2obj( pMod->mod_values, &bv );
951 if ( rc != LDAP_SUCCESS ) goto cleanup;
952 tmp.sml_type.bv_val = pMod->mod_type;
953 tmp.sml_type.bv_len = strlen( pMod->mod_type );
954 tmp.sml_bvalues = bv;
956 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
958 mod->sml_op = pMod->mod_op;
959 mod->sml_next = NULL;
960 mod->sml_desc = NULL;
961 mod->sml_type = tmp.sml_type;
962 mod->sml_bvalues = tmp.sml_bvalues;
965 modtail = &mod->sml_next;
967 switch( pMod->mod_op ) {
969 if ( mod->sml_bvalues == NULL ) {
970 rc = LDAP_PROTOCOL_ERROR;
975 case LDAP_MOD_DELETE:
976 case LDAP_MOD_REPLACE:
980 rc = LDAP_PROTOCOL_ERROR;
986 if ( ndn.bv_len == 0 ) {
987 rc = LDAP_UNWILLING_TO_PERFORM;
991 if ( be->be_modify ) {
992 int repl_user = be_isupdate( be, &op->o_ndn );
993 if ( !be->be_update_ndn.bv_len || repl_user ) {
994 int update = be->be_update_ndn.bv_len;
995 const char *text = NULL;
996 char textbuf[SLAP_TEXT_BUFLEN];
997 size_t textlen = sizeof( textbuf );
999 rc = slap_mods_check( modlist, update,
1000 &text, textbuf, textlen );
1001 if (rc != LDAP_SUCCESS) {
1006 rc = slap_mods_opattrs( be, op, modlist,
1007 modtail, &text, textbuf,
1009 if (rc != LDAP_SUCCESS) {
1013 rc = (*be->be_modify)( be, pConn, op,
1014 &pdn, &ndn, modlist );
1017 replog( be, op, &pdn, &ndn, modlist );
1021 rc = LDAP_OPERATIONS_ERROR;
1027 rc = LDAP_UNWILLING_TO_PERFORM;
1033 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
1035 if ( dn.bv_val ) ch_free( dn.bv_val );
1036 if ( pdn.bv_val ) ch_free( pdn.bv_val );
1037 if ( ndn.bv_val ) ch_free( ndn.bv_val );
1039 if ( modlist != NULL ) freeMods( modlist );
1041 if ( pConn != NULL ) {
1042 if ( pConn->c_sb != NULL ) ber_sockbuf_free( pConn->c_sb );
1043 if ( op != NULL ) slapi_ch_free( (void **)&op );
1050 #endif /* LDAP_SLAPI */
1055 slapi_search_internal_bind(
1060 LDAPControl **controls,
1064 #if defined(LDAP_SLAPI)
1067 Operation *op = NULL;
1068 Slapi_PBlock *ptr = NULL;
1069 Slapi_PBlock *pSavePB = NULL;
1070 struct berval dn = { 0, NULL };
1071 struct berval pdn = { 0, NULL };
1072 struct berval ndn = { 0, NULL };
1073 Filter *filter=NULL;
1074 struct berval fstr = { 0, NULL };
1075 AttributeName *an = NULL;
1076 const char *text = NULL;
1079 int sizelimit=-1, timelimit=-1;
1081 int manageDsaIt = 0;
1084 int i, rc = LDAP_SUCCESS;
1086 c = fakeConnection( NULL, LDAP_REQ_SEARCH );
1088 rc = LDAP_NO_MEMORY;
1092 op = (Operation *)c->c_pending_ops.stqh_first;
1093 ptr = (Slapi_PBlock *)op->o_pb;
1094 op->o_ctrls = controls;
1096 dn.bv_val = slapi_ch_strdup(ldn);
1097 dn.bv_len = slapi_strlen(ldn);
1099 rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn );
1100 if (rc != LDAP_SUCCESS) goto cleanup;
1102 if ( scope != LDAP_SCOPE_BASE &&
1103 scope != LDAP_SCOPE_ONELEVEL &&
1104 scope != LDAP_SCOPE_SUBTREE ) {
1105 rc = LDAP_PROTOCOL_ERROR;
1109 filter = slapi_str2filter(filStr);
1110 if ( filter == NULL ) {
1111 rc = LDAP_PROTOCOL_ERROR;
1115 filter2bv( filter, &fstr );
1117 for ( i = 0; attrs != NULL && attrs[i] != NULL; i++ ) {
1118 ; /* count the number of attributes */
1122 an = (AttributeName *)slapi_ch_calloc( (i + 1), sizeof(AttributeName) );
1123 for (i = 0; attrs[i] != 0; i++) {
1124 an[i].an_desc = NULL;
1126 an[i].an_name.bv_val = slapi_ch_strdup(attrs[i]);
1127 an[i].an_name.bv_len = slapi_strlen(attrs[i]);
1128 slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text );
1130 an[i].an_name.bv_val = NULL;
1133 if ( scope == LDAP_SCOPE_BASE ) {
1134 Entry *entry = NULL;
1136 if ( ndn.bv_len == 0 ) {
1137 rc = root_dse_info( c, &entry, &text );
1140 if( rc != LDAP_SUCCESS ) {
1141 send_ldap_result( c, op, rc, NULL, text, NULL, NULL );
1143 } else if ( entry != NULL ) {
1144 rc = test_filter( NULL, c, op, entry, filter );
1146 if( rc == LDAP_COMPARE_TRUE ) {
1147 send_search_entry( NULL, c, op, entry,
1148 an, attrsonly, NULL );
1151 entry_free( entry );
1153 send_ldap_result( c, op, LDAP_SUCCESS,
1154 NULL, NULL, NULL, NULL );
1162 if ( !ndn.bv_len && default_search_nbase.bv_len ) {
1163 ch_free( pdn.bv_val );
1164 ch_free( ndn.bv_val );
1166 ber_dupbv( &pdn, &default_search_base );
1167 ber_dupbv( &ndn, &default_search_nbase );
1170 if ( slapi_control_present( controls,
1171 LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
1175 be = select_backend( &ndn, manageDsaIt, 0 );
1177 if ( manageDsaIt == 1 ) {
1178 rc = LDAP_NO_SUCH_OBJECT;
1180 rc = LDAP_PARTIAL_RESULTS;
1185 op->o_dn = c->c_dn = be->be_rootdn;
1186 op->o_ndn = c->c_ndn = be->be_rootndn;
1188 if ( be->be_search ) {
1189 rc = (*be->be_search)( be, c, op, &pdn, &ndn,
1190 scope, deref, sizelimit, timelimit,
1191 filter, &fstr, an, attrsonly );
1195 rc = LDAP_OPERATIONS_ERROR;
1198 rc = LDAP_UNWILLING_TO_PERFORM;
1204 slapi_pblock_set( ptr, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
1206 if ( dn.bv_val ) free( dn.bv_val );
1207 if ( ndn.bv_val ) free( ndn.bv_val );
1208 if ( pdn.bv_val ) free( pdn.bv_val );
1210 if ( filter ) slapi_filter_free( filter, 1 );
1211 if ( fstr.bv_val ) free ( fstr.bv_val );
1213 if ( an != NULL ) free( an );
1216 if ( c->c_sb != NULL ) ber_sockbuf_free( c->c_sb );
1217 if ( op != NULL ) slapi_ch_free( (void **)&op );
1222 #endif /* LDAP_SLAPI */
1227 slapi_search_internal(
1231 LDAPControl **controls,
1235 #if defined(LDAP_SLAPI)
1236 return slapi_search_internal_bind( NULL, base, scope, filStr,
1237 controls, attrs, attrsonly );
1240 #endif /* LDAP_SLAPI */