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.
13 * Portions (C) Copyright PADL Software Pty Ltd. 2003
14 * Redistribution and use in source and binary forms are permitted
15 * provided that this notice is preserved and that due credit is
16 * given to PADL Software Pty Ltd. This software is provided ``as is''
17 * without express or implied warranty.
26 * use a fake listener when faking a connection,
27 * so it can be used in ACLs
29 static struct slap_listener slap_unknown_listener = {
30 BER_BVC("unknown"), /* FIXME: use a URI form? */
34 int bvptr2obj( struct berval **bvptr, struct berval **bvobj );
41 if (op->o_tag == LDAP_REQ_SEARCH)
42 slapi_pblock_set( (Slapi_PBlock *)op->o_pb,
43 SLAPI_NENTRIES, (void *)sr->sr_nentries );
49 internal_search_entry(
54 int nentries = 0, len = 0, i = 0;
55 Slapi_Entry **head = NULL, **tp;
57 ent2str = slapi_entry2str( rs->sr_entry, &len );
58 if ( ent2str == NULL ) {
62 slapi_pblock_get( (Slapi_PBlock *)op->o_pb,
63 SLAPI_NENTRIES, &nentries );
64 slapi_pblock_get( (Slapi_PBlock *)op->o_pb,
65 SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head );
68 if ( nentries == 0 ) {
69 tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) );
74 tp[ 0 ] = (Slapi_Entry *)str2entry( ent2str );
75 if ( tp[ 0 ] == NULL ) {
80 tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head,
81 sizeof(Slapi_Entry *) * ( i + 1 ) );
85 tp[ i - 1 ] = (Slapi_Entry *)str2entry( ent2str );
86 if ( tp[ i - 1 ] == NULL ) {
92 slapi_pblock_set( (Slapi_PBlock *)op->o_pb,
93 SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, (void *)tp );
94 slapi_pblock_set( (Slapi_PBlock *)op->o_pb,
95 SLAPI_NENTRIES, (void *)i );
109 internal_search_reference(
121 Connection *pConn, *c;
122 ber_len_t max = sockbuf_max_incoming;
124 pConn = (Connection *) slapi_ch_calloc(1, sizeof(Connection));
126 return (Connection *)NULL;
129 LDAP_STAILQ_INIT( &pConn->c_pending_ops );
131 pConn->c_pending_ops.stqh_first =
132 (Operation *) slapi_ch_calloc( 1, sizeof(Operation) );
133 if ( pConn->c_pending_ops.stqh_first == NULL ) {
134 slapi_ch_free( (void **)&pConn );
135 return (Connection *)NULL;
138 pConn->c_pending_ops.stqh_first->o_pb =
139 (Slapi_PBlock *) slapi_pblock_new();
140 if ( pConn->c_pending_ops.stqh_first->o_pb == NULL ) {
141 slapi_ch_free( (void **)&pConn->c_pending_ops.stqh_first );
142 slapi_ch_free( (void **)&pConn );
143 return (Connection *)NULL;
148 /* operation object */
149 c->c_pending_ops.stqh_first->o_tag = OpType;
150 c->c_pending_ops.stqh_first->o_protocol = LDAP_VERSION3;
151 c->c_pending_ops.stqh_first->o_authmech.bv_val = NULL;
152 c->c_pending_ops.stqh_first->o_authmech.bv_len = 0;
153 c->c_pending_ops.stqh_first->o_time = slap_get_time();
154 c->c_pending_ops.stqh_first->o_do_not_cache = 1;
155 c->c_pending_ops.stqh_first->o_threadctx = ldap_pvt_thread_pool_context( &connection_pool );
157 /* connection object */
158 c->c_authmech.bv_val = NULL;
159 c->c_authmech.bv_len = 0;
160 c->c_dn.bv_val = NULL;
162 c->c_ndn.bv_val = NULL;
166 c->c_listener = &slap_unknown_listener;
167 ber_dupbv( &c->c_peer_domain, (struct berval *)&slap_unknown_bv );
168 ber_dupbv( &c->c_peer_name, (struct berval *)&slap_unknown_bv );
170 LDAP_STAILQ_INIT( &c->c_ops );
172 c->c_sasl_bind_mech.bv_val = NULL;
173 c->c_sasl_bind_mech.bv_len = 0;
174 c->c_sasl_context = NULL;
175 c->c_sasl_extra = NULL;
177 c->c_sb = ber_sockbuf_alloc( );
179 ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
181 c->c_currentber = NULL;
183 /* should check status of thread calls */
184 ldap_pvt_thread_mutex_init( &c->c_mutex );
185 ldap_pvt_thread_mutex_init( &c->c_write_mutex );
186 ldap_pvt_thread_cond_init( &c->c_write_cv );
188 c->c_n_ops_received = 0;
189 c->c_n_ops_executing = 0;
190 c->c_n_ops_pending = 0;
191 c->c_n_ops_completed = 0;
197 c->c_protocol = LDAP_VERSION3;
199 c->c_activitytime = c->c_starttime = slap_get_time();
203 c->c_conn_state = 0x01; /* SLAP_C_ACTIVE */
204 c->c_struct_state = 0x02; /* SLAP_C_USED */
206 c->c_ssf = c->c_transport_ssf = 0;
209 backend_connection_init( c );
211 pConn->c_send_ldap_result = internal_result_v3;
212 pConn->c_send_search_entry = internal_search_entry;
213 pConn->c_send_ldap_extended = internal_result_ext;
214 pConn->c_send_search_reference = internal_search_reference;
219 static void slapiConnectionDestroy( Connection **pConn )
221 Connection *conn = *pConn;
224 if ( pConn == NULL ) {
228 op = (Operation *)conn->c_pending_ops.stqh_first;
230 if ( op->o_req_dn.bv_val != NULL ) {
231 slapi_ch_free( (void **)&op->o_req_dn.bv_val );
233 if ( op->o_req_ndn.bv_val != NULL ) {
234 slapi_ch_free( (void **)&op->o_req_ndn.bv_val );
237 if ( conn->c_sb != NULL ) {
238 ber_sockbuf_free( conn->c_sb );
241 slapi_ch_free( (void **)&op );
243 slapi_ch_free( (void **)pConn );
247 * Function : values2obj
248 * Convert an array of strings into a BerVarray.
259 if ( ppValue == NULL ) {
264 for ( i = 0; ppValue[i] != NULL; i++ )
267 tmpberval = (BerVarray)slapi_ch_malloc( (i+1) * (sizeof(struct berval)) );
268 if ( tmpberval == NULL ) {
269 return LDAP_NO_MEMORY;
271 for ( i = 0; ppValue[i] != NULL; i++ ) {
272 tmpberval[i].bv_val = ppValue[i];
273 tmpberval[i].bv_len = strlen( ppValue[i] );
275 tmpberval[i].bv_val = NULL;
276 tmpberval[i].bv_len = 0;
284 freeMods( Modifications *ml )
287 * Free a modification list whose values have been
288 * set with bvptr2obj() or values2obj() (ie. they
289 * do not own the pointer to the underlying values)
293 for ( ; ml != NULL; ml = next ) {
296 slapi_ch_free( (void **)&ml->sml_bvalues );
298 slapi_ch_free( (void **)&ml->sml_nvalues );
300 slapi_ch_free( (void **)&ml );
305 * Function : LDAPModToEntry
306 * convert a dn plus an array of LDAPMod struct ptrs to an entry structure
307 * with a link list of the correspondent attributes.
308 * Return value : LDAP_SUCCESS
317 struct berval dn = { 0, NULL };
323 Modifications *modlist = NULL;
324 Modifications **modtail = &modlist;
327 int rc = LDAP_SUCCESS;
330 const char *text = NULL;
333 op = (Operation *) slapi_ch_calloc(1, sizeof(Operation));
334 if ( pEntry == NULL) {
338 op->o_tag = LDAP_REQ_ADD;
340 pEntry = (Entry *) ch_calloc( 1, sizeof(Entry) );
341 if ( pEntry == NULL) {
346 dn.bv_val = slapi_ch_strdup(ldn);
347 dn.bv_len = strlen(ldn);
349 rc = dnPrettyNormal( NULL, &dn, &pEntry->e_name, &pEntry->e_nname );
350 if ( rc != LDAP_SUCCESS )
353 if ( rc == LDAP_SUCCESS ) {
354 for ( i=0, pMod=mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod=mods[++i]) {
356 if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
357 /* attr values are in berval format */
358 /* convert an array of pointers to bervals to an array of bervals */
359 rc = bvptr2obj(pMod->mod_bvalues, &bv);
360 if (rc != LDAP_SUCCESS) goto cleanup;
361 tmp.sml_type.bv_val = pMod->mod_type;
362 tmp.sml_type.bv_len = strlen( pMod->mod_type );
363 tmp.sml_bvalues = bv;
365 tmp.sml_nvalues = NULL;
368 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
370 mod->sml_op = LDAP_MOD_ADD;
371 mod->sml_next = NULL;
372 mod->sml_desc = NULL;
373 mod->sml_type = tmp.sml_type;
374 mod->sml_bvalues = tmp.sml_bvalues;
376 mod->sml_nvalues = tmp.sml_nvalues;
380 modtail = &mod->sml_next;
383 /* attr values are in string format, need to be converted */
384 /* to an array of bervals */
385 if ( pMod->mod_values == NULL ) {
388 rc = values2obj( pMod->mod_values, &bv );
389 if (rc != LDAP_SUCCESS) goto cleanup;
390 tmp.sml_type.bv_val = pMod->mod_type;
391 tmp.sml_type.bv_len = strlen( pMod->mod_type );
392 tmp.sml_bvalues = bv;
394 tmp.sml_nvalues = NULL;
397 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
399 mod->sml_op = LDAP_MOD_ADD;
400 mod->sml_next = NULL;
401 mod->sml_desc = NULL;
402 mod->sml_type = tmp.sml_type;
403 mod->sml_bvalues = tmp.sml_bvalues;
405 mod->sml_nvalues = tmp.sml_nvalues;
409 modtail = &mod->sml_next;
412 } /* for each LDAPMod */
415 op->o_bd = select_backend( &pEntry->e_nname, 0, 0 );
416 if ( op->o_bd == NULL ) {
417 rc = LDAP_PARTIAL_RESULTS;
419 int repl_user = be_isupdate( op->o_bd, &op->o_bd->be_rootdn );
420 if ( !op->o_bd->be_update_ndn.bv_len || repl_user ) {
421 int update = op->o_bd->be_update_ndn.bv_len;
422 char textbuf[SLAP_TEXT_BUFLEN];
423 size_t textlen = sizeof textbuf;
425 rc = slap_mods_check( modlist, update, &text,
427 if ( rc != LDAP_SUCCESS) {
432 rc = slap_mods_opattrs( op,
433 modlist, modtail, &text,
435 if ( rc != LDAP_SUCCESS) {
441 * FIXME: slap_mods2entry is declared static
442 * in servers/slapd/add.c
444 rc = slap_mods2entry( modlist, &pEntry, repl_user,
445 &text, textbuf, textlen );
446 if (rc != LDAP_SUCCESS) {
458 slapi_ch_free( (void **)&dn.bv_val );
460 slapi_ch_free( (void **)&op );
461 if ( modlist != NULL )
463 if ( rc != LDAP_SUCCESS ) {
464 if ( pEntry != NULL ) {
465 slapi_entry_free( pEntry );
473 /* Function : slapi_delete_internal
475 * Description : Plugin functions call this routine to delete an entry
476 * in the backend directly
477 * Return values : LDAP_SUCCESS
481 * LDAP_UNWILLING_TO_PERFORM
484 slapi_delete_internal(
486 LDAPControl **controls,
490 Connection *pConn = NULL;
491 Operation *op = NULL;
492 Slapi_PBlock *pPB = NULL;
493 Slapi_PBlock *pSavePB = NULL;
494 SlapReply rs = { REP_RESULT };
495 struct berval dn = { 0, NULL };
501 rs.sr_err = LDAP_PARAM_ERROR;
505 pConn = slapiConnectionInit( NULL, LDAP_REQ_DELETE );
507 rs.sr_err = LDAP_NO_MEMORY;
511 op = (Operation *)pConn->c_pending_ops.stqh_first;
512 pPB = (Slapi_PBlock *)op->o_pb;
513 op->o_ctrls = controls;
515 dn.bv_val = slapi_ch_strdup(ldn);
516 dn.bv_len = strlen(ldn);
517 rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn );
518 if ( rs.sr_err != LDAP_SUCCESS )
521 if ( slapi_control_present( controls,
522 SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical) ) {
526 op->o_bd = select_backend( &op->o_req_ndn, manageDsaIt, 0 );
527 if ( op->o_bd == NULL ) {
528 rs.sr_err = LDAP_PARTIAL_RESULTS;
532 op->o_dn = pConn->c_dn = op->o_bd->be_rootdn;
533 op->o_ndn = pConn->c_ndn = op->o_bd->be_rootndn;
535 if ( op->o_bd->be_delete ) {
536 int repl_user = be_isupdate( op->o_bd, &op->o_ndn );
537 if ( !op->o_bd->be_update_ndn.bv_len || repl_user ) {
538 if ( (*op->o_bd->be_delete)( op, &rs ) == 0 ) {
543 rs.sr_err = LDAP_OTHER;
546 rs.sr_err = LDAP_REFERRAL;
549 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
554 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
557 slapi_ch_free( (void **)&dn.bv_val );
559 if ( pConn != NULL ) {
563 slapiConnectionDestroy( &pConn );
568 #endif /* LDAP_SLAPI */
572 slapi_add_entry_internal(
574 LDAPControl **controls,
578 Connection *pConn = NULL;
579 Operation *op = NULL;
580 Slapi_PBlock *pPB = NULL, *pSavePB = NULL;
584 SlapReply rs = { REP_RESULT };
587 rs.sr_err = LDAP_PARAM_ERROR;
591 pConn = slapiConnectionInit( NULL, LDAP_REQ_ADD );
592 if ( pConn == NULL ) {
593 rs.sr_err = LDAP_NO_MEMORY;
597 if ( slapi_control_present( controls, LDAP_CONTROL_MANAGEDSAIT,
598 NULL, &isCritical ) ) {
602 op = (Operation *)pConn->c_pending_ops.stqh_first;
603 pPB = (Slapi_PBlock *)op->o_pb;
604 op->o_ctrls = controls;
606 op->o_bd = select_backend( &e->e_nname, manageDsaIt, 0 );
607 if ( op->o_bd == NULL ) {
608 rs.sr_err = LDAP_PARTIAL_RESULTS;
612 op->o_dn = pConn->c_dn = op->o_bd->be_rootdn;
613 op->o_ndn = pConn->c_ndn = op->o_bd->be_rootndn;
616 if ( op->o_bd->be_add ) {
617 int repl_user = be_isupdate( op->o_bd, &op->o_ndn );
618 if ( !op->o_bd->be_update_ndn.bv_len || repl_user ){
619 if ( (*op->o_bd->be_add)( op, &rs ) == 0 ) {
625 rs.sr_err = LDAP_REFERRAL;
628 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
634 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
637 if ( pConn != NULL ) {
641 slapiConnectionDestroy( &pConn );
646 #endif /* LDAP_SLAPI */
654 LDAPControl **controls,
658 LDAPMod *pMod = NULL;
659 Slapi_PBlock *pb = NULL;
660 Entry *pEntry = NULL;
661 int i, rc = LDAP_SUCCESS;
663 if ( mods == NULL || *mods == NULL || dn == NULL || *dn == '\0' ) {
664 rc = LDAP_PARAM_ERROR ;
667 if ( rc == LDAP_SUCCESS ) {
668 for ( i = 0, pMod = mods[0]; pMod != NULL; pMod = mods[++i] ) {
669 if ( (pMod->mod_op & ~LDAP_MOD_BVALUES) != LDAP_MOD_ADD ) {
676 if ( rc == LDAP_SUCCESS ) {
677 if((pEntry = LDAPModToEntry( dn, mods )) == NULL) {
682 if ( rc != LDAP_SUCCESS ) {
683 pb = slapi_pblock_new();
684 slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
686 pb = slapi_add_entry_internal( pEntry, controls, log_changes );
690 slapi_entry_free(pEntry);
696 #endif /* LDAP_SLAPI */
699 /* Function : slapi_modrdn_internal
701 * Description : Plugin functions call this routine to modify the rdn
702 * of an entry in the backend directly
703 * Return values : LDAP_SUCCESS
707 * LDAP_UNWILLING_TO_PERFORM
709 * NOTE: This function does not support the "newSuperior" option from LDAP V3.
712 slapi_modrdn_internal(
716 LDAPControl **controls,
720 struct berval dn = { 0, NULL };
721 struct berval newrdn = { 0, NULL };
722 Connection *pConn = NULL;
723 Operation *op = NULL;
724 Slapi_PBlock *pPB = NULL;
725 Slapi_PBlock *pSavePB = NULL;
728 SlapReply rs = { REP_RESULT };
730 pConn = slapiConnectionInit( NULL, LDAP_REQ_MODRDN);
731 if ( pConn == NULL) {
732 rs.sr_err = LDAP_NO_MEMORY;
736 op = (Operation *)pConn->c_pending_ops.stqh_first;
737 pPB = (Slapi_PBlock *)op->o_pb;
738 op->o_ctrls = controls;
740 if ( slapi_control_present( controls,
741 SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {
745 op->o_bd = select_backend( &op->o_req_ndn, manageDsaIt, 0 );
746 if ( op->o_bd == NULL ) {
747 rs.sr_err = LDAP_PARTIAL_RESULTS;
751 op->o_dn = pConn->c_dn = op->o_bd->be_rootdn;
752 op->o_ndn = pConn->c_ndn = op->o_bd->be_rootndn;
754 dn.bv_val = slapi_ch_strdup( olddn );
755 dn.bv_len = strlen( olddn );
757 rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn );
758 if ( rs.sr_err != LDAP_SUCCESS ) {
762 if ( op->o_req_dn.bv_len == 0 ) {
763 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
767 newrdn.bv_val = slapi_ch_strdup( lnewrdn );
768 newrdn.bv_len = strlen( lnewrdn );
770 rs.sr_err = dnPrettyNormal( NULL, &newrdn, &op->oq_modrdn.rs_newrdn, &op->oq_modrdn.rs_nnewrdn );
771 if ( rs.sr_err != LDAP_SUCCESS ) {
775 if ( rdnValidate( &op->oq_modrdn.rs_nnewrdn ) != LDAP_SUCCESS ) {
779 op->oq_modrdn.rs_newSup = NULL;
780 op->oq_modrdn.rs_nnewSup = NULL;
781 op->oq_modrdn.rs_deleteoldrdn = deloldrdn;
783 if ( op->o_bd->be_modrdn ) {
784 int repl_user = be_isupdate( op->o_bd, &op->o_ndn );
785 if ( !op->o_bd->be_update_ndn.bv_len || repl_user ) {
786 if ( (*op->o_bd->be_modrdn)( op, &rs ) == 0 ) {
791 rs.sr_err = LDAP_OTHER;
794 rs.sr_err = LDAP_REFERRAL;
797 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
803 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
807 slapi_ch_free( (void **)&dn.bv_val );
810 slapi_ch_free( (void **)&newrdn.bv_val );
811 if ( op->oq_modrdn.rs_newrdn.bv_val )
812 slapi_ch_free( (void **)&op->oq_modrdn.rs_newrdn.bv_val );
813 if ( op->oq_modrdn.rs_nnewrdn.bv_val )
814 slapi_ch_free( (void **)&op->oq_modrdn.rs_nnewrdn.bv_val );
816 if ( pConn != NULL ) {
820 slapiConnectionDestroy( &pConn );
825 #endif /* LDAP_SLAPI */
828 /* Function : slapi_modify_internal
830 * Description: Plugin functions call this routine to modify an entry
831 * in the backend directly
832 * Return values : LDAP_SUCCESS
836 * LDAP_UNWILLING_TO_PERFORM
839 slapi_modify_internal(
842 LDAPControl **controls,
847 Connection *pConn = NULL;
848 Operation *op = NULL;
849 Slapi_PBlock *pPB = NULL;
850 Slapi_PBlock *pSavePB = NULL;
852 struct berval dn = { 0, NULL };
859 Modifications *modlist = NULL;
860 Modifications **modtail = &modlist;
863 SlapReply rs = { REP_RESULT };
865 if ( mods == NULL || *mods == NULL || ldn == NULL ) {
866 rs.sr_err = LDAP_PARAM_ERROR ;
870 pConn = slapiConnectionInit( NULL, LDAP_REQ_MODIFY );
871 if ( pConn == NULL ) {
872 rs.sr_err = LDAP_NO_MEMORY;
876 op = (Operation *)pConn->c_pending_ops.stqh_first;
877 pPB = (Slapi_PBlock *)op->o_pb;
878 op->o_ctrls = controls;
880 dn.bv_val = slapi_ch_strdup( ldn );
881 dn.bv_len = strlen( ldn );
882 rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn );
883 if ( rs.sr_err != LDAP_SUCCESS ) {
887 if ( slapi_control_present( controls,
888 SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {
892 op->o_bd = select_backend( &op->o_req_ndn, manageDsaIt, 0 );
893 if ( op->o_bd == NULL ) {
894 rs.sr_err = LDAP_PARTIAL_RESULTS;
898 op->o_dn = pConn->c_dn = op->o_bd->be_rootdn;
899 op->o_ndn = pConn->c_ndn = op->o_bd->be_rootndn;
901 for ( i = 0, pMod = mods[0];
902 rs.sr_err == LDAP_SUCCESS && pMod != NULL;
907 if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
909 * attr values are in berval format
910 * convert an array of pointers to bervals
911 * to an array of bervals
913 rs.sr_err = bvptr2obj( pMod->mod_bvalues, &bv );
914 if ( rs.sr_err != LDAP_SUCCESS )
916 tmp.sml_type.bv_val = pMod->mod_type;
917 tmp.sml_type.bv_len = strlen( pMod->mod_type );
918 tmp.sml_bvalues = bv;
920 tmp.sml_nvalues = NULL;
923 mod = (Modifications *)ch_malloc( sizeof(Modifications) );
925 mod->sml_op = pMod->mod_op;
926 mod->sml_next = NULL;
927 mod->sml_desc = NULL;
928 mod->sml_type = tmp.sml_type;
929 mod->sml_bvalues = tmp.sml_bvalues;
931 mod->sml_nvalues = tmp.sml_nvalues;
934 rs.sr_err = values2obj( pMod->mod_values, &bv );
935 if ( rs.sr_err != LDAP_SUCCESS )
937 tmp.sml_type.bv_val = pMod->mod_type;
938 tmp.sml_type.bv_len = strlen( pMod->mod_type );
939 tmp.sml_bvalues = bv;
941 tmp.sml_nvalues = NULL;
944 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
946 mod->sml_op = pMod->mod_op;
947 mod->sml_next = NULL;
948 mod->sml_desc = NULL;
949 mod->sml_type = tmp.sml_type;
950 mod->sml_bvalues = tmp.sml_bvalues;
952 mod->sml_nvalues = tmp.sml_nvalues;
956 modtail = &mod->sml_next;
958 switch( pMod->mod_op ) {
960 if ( mod->sml_bvalues == NULL ) {
961 rs.sr_err = LDAP_PROTOCOL_ERROR;
966 case LDAP_MOD_DELETE:
967 case LDAP_MOD_REPLACE:
971 rs.sr_err = LDAP_PROTOCOL_ERROR;
977 if ( op->o_req_ndn.bv_len == 0 ) {
978 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
982 op->oq_modify.rs_modlist = modlist;
984 if ( op->o_bd->be_modify ) {
985 int repl_user = be_isupdate( op->o_bd, &op->o_ndn );
986 if ( !op->o_bd->be_update_ndn.bv_len || repl_user ) {
987 int update = op->o_bd->be_update_ndn.bv_len;
988 const char *text = NULL;
989 char textbuf[SLAP_TEXT_BUFLEN];
990 size_t textlen = sizeof( textbuf );
992 rs.sr_err = slap_mods_check( modlist, update,
993 &text, textbuf, textlen );
994 if ( rs.sr_err != LDAP_SUCCESS ) {
999 rs.sr_err = slap_mods_opattrs( op, modlist,
1000 modtail, &text, textbuf,
1002 if ( rs.sr_err != LDAP_SUCCESS ) {
1006 if ( (*op->o_bd->be_modify)( op, &rs ) == 0 ) {
1011 rs.sr_err = LDAP_OTHER;
1014 rs.sr_err = LDAP_REFERRAL;
1017 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
1023 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
1026 slapi_ch_free( (void **)&dn.bv_val );
1028 if ( modlist != NULL )
1029 freeMods( modlist );
1031 if ( pConn != NULL ) {
1035 slapiConnectionDestroy( &pConn );
1040 #endif /* LDAP_SLAPI */
1044 slapi_search_internal_bind(
1049 LDAPControl **controls,
1055 Operation *op = NULL;
1056 Slapi_PBlock *ptr = NULL;
1057 Slapi_PBlock *pSavePB = NULL;
1058 struct berval dn = { 0, NULL };
1059 Filter *filter=NULL;
1060 struct berval fstr = { 0, NULL };
1061 AttributeName *an = NULL;
1062 const char *text = NULL;
1064 int manageDsaIt = 0;
1068 SlapReply rs = { REP_RESULT };
1070 c = slapiConnectionInit( NULL, LDAP_REQ_SEARCH );
1072 rs.sr_err = LDAP_NO_MEMORY;
1076 op = (Operation *)c->c_pending_ops.stqh_first;
1077 ptr = (Slapi_PBlock *)op->o_pb;
1078 op->o_ctrls = controls;
1080 dn.bv_val = slapi_ch_strdup(ldn);
1081 dn.bv_len = strlen(ldn);
1083 rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn );
1084 if ( rs.sr_err != LDAP_SUCCESS ) {
1088 if ( scope != LDAP_SCOPE_BASE &&
1089 scope != LDAP_SCOPE_ONELEVEL &&
1090 scope != LDAP_SCOPE_SUBTREE ) {
1091 rs.sr_err = LDAP_PROTOCOL_ERROR;
1095 filter = slapi_str2filter(filStr);
1096 if ( filter == NULL ) {
1097 rs.sr_err = LDAP_PROTOCOL_ERROR;
1101 filter2bv( filter, &fstr );
1103 for ( i = 0; attrs != NULL && attrs[i] != NULL; i++ ) {
1104 ; /* count the number of attributes */
1108 an = (AttributeName *)slapi_ch_calloc( (i + 1), sizeof(AttributeName) );
1109 for (i = 0; attrs[i] != 0; i++) {
1110 an[i].an_desc = NULL;
1112 an[i].an_name.bv_val = slapi_ch_strdup(attrs[i]);
1113 an[i].an_name.bv_len = strlen(attrs[i]);
1114 slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text );
1116 an[i].an_name.bv_val = NULL;
1119 memset( &rs, 0, sizeof(rs) );
1120 rs.sr_type = REP_RESULT;
1121 rs.sr_err = LDAP_SUCCESS;
1122 rs.sr_entry = NULL; /* paranoia */
1124 if ( scope == LDAP_SCOPE_BASE ) {
1127 if ( op->o_req_ndn.bv_len == 0 ) {
1128 rs.sr_err = root_dse_info( c, &rs.sr_entry, &rs.sr_text );
1131 if( rs.sr_err != LDAP_SUCCESS ) {
1132 send_ldap_result( op, &rs );
1134 } else if ( rs.sr_entry != NULL ) {
1135 rs.sr_err = test_filter( op, rs.sr_entry, filter );
1137 if ( rs.sr_err == LDAP_COMPARE_TRUE ) {
1138 rs.sr_type = REP_SEARCH;
1139 rs.sr_err = LDAP_SUCCESS;
1142 send_search_entry( op, &rs );
1145 entry_free( rs.sr_entry );
1147 rs.sr_type = REP_RESULT;
1148 rs.sr_err = LDAP_SUCCESS;
1150 send_ldap_result( op, &rs );
1156 if ( !op->o_req_ndn.bv_len && default_search_nbase.bv_len ) {
1157 slapi_ch_free( (void **)op->o_req_dn.bv_val );
1158 slapi_ch_free( (void **)op->o_req_ndn.bv_val );
1160 ber_dupbv( &op->o_req_dn, &default_search_base );
1161 ber_dupbv( &op->o_req_ndn, &default_search_nbase );
1164 if ( slapi_control_present( controls,
1165 LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
1169 op->o_bd = select_backend( &op->o_req_ndn, manageDsaIt, 0 );
1170 if ( op->o_bd == NULL ) {
1171 if ( manageDsaIt == 1 ) {
1172 rs.sr_err = LDAP_NO_SUCH_OBJECT;
1174 rs.sr_err = LDAP_PARTIAL_RESULTS;
1179 op->o_dn = c->c_dn = op->o_bd->be_rootdn;
1180 op->o_ndn = c->c_ndn = op->o_bd->be_rootndn;
1182 op->oq_search.rs_scope = scope;
1183 op->oq_search.rs_deref = 0;
1184 op->oq_search.rs_slimit = LDAP_NO_LIMIT;
1185 op->oq_search.rs_tlimit = LDAP_NO_LIMIT;
1186 op->oq_search.rs_attrsonly = attrsonly;
1187 op->oq_search.rs_attrs = an;
1188 op->oq_search.rs_filter = filter;
1189 op->oq_search.rs_filterstr = fstr;
1191 if ( op->o_bd->be_search ) {
1192 if ( (*op->o_bd->be_search)( op, &rs ) != 0 ) {
1193 rs.sr_err = LDAP_OTHER;
1196 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
1202 slapi_pblock_set( ptr, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
1205 slapi_ch_free( (void **)&dn.bv_val );
1207 slapi_filter_free( filter, 1 );
1209 slapi_ch_free( (void **)&fstr.bv_val );
1211 slapi_ch_free( (void **)&an );
1217 slapiConnectionDestroy( &c );
1222 #endif /* LDAP_SLAPI */
1226 slapi_search_internal(
1230 LDAPControl **controls,
1235 return slapi_search_internal_bind( NULL, base, scope, filStr,
1236 controls, attrs, attrsonly );
1239 #endif /* LDAP_SLAPI */