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 );
42 /* XXX needs review after internal API change */
43 /* rs->sr_nentries appears to always be 0 */
44 if (op->o_tag == LDAP_REQ_SEARCH)
45 slapi_pblock_set( (Slapi_PBlock *)op->o_pb,
46 SLAPI_NENTRIES, (void *)rs->sr_nentries );
53 internal_search_entry(
58 int nentries = 0, len = 0, i = 0;
59 Slapi_Entry **head = NULL, **tp;
61 ent2str = slapi_entry2str( rs->sr_entry, &len );
62 if ( ent2str == NULL ) {
66 slapi_pblock_get( (Slapi_PBlock *)op->o_pb,
67 SLAPI_NENTRIES, &nentries );
68 slapi_pblock_get( (Slapi_PBlock *)op->o_pb,
69 SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head );
72 if ( nentries == 0 ) {
73 tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) );
78 tp[ 0 ] = (Slapi_Entry *)str2entry( ent2str );
79 if ( tp[ 0 ] == NULL ) {
84 tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head,
85 sizeof(Slapi_Entry *) * ( i + 1 ) );
89 tp[ i - 1 ] = (Slapi_Entry *)str2entry( ent2str );
90 if ( tp[ i - 1 ] == NULL ) {
96 slapi_pblock_set( (Slapi_PBlock *)op->o_pb,
97 SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, (void *)tp );
98 slapi_pblock_set( (Slapi_PBlock *)op->o_pb,
99 SLAPI_NENTRIES, (void *)i );
113 internal_search_reference(
125 Connection *pConn, *c;
126 ber_len_t max = sockbuf_max_incoming;
128 pConn = (Connection *) slapi_ch_calloc(1, sizeof(Connection));
130 return (Connection *)NULL;
133 LDAP_STAILQ_INIT( &pConn->c_pending_ops );
135 pConn->c_pending_ops.stqh_first =
136 (Operation *) slapi_ch_calloc( 1, sizeof(Operation) );
137 if ( pConn->c_pending_ops.stqh_first == NULL ) {
138 slapi_ch_free( (void **)&pConn );
139 return (Connection *)NULL;
142 pConn->c_pending_ops.stqh_first->o_pb =
143 (Slapi_PBlock *) slapi_pblock_new();
144 if ( pConn->c_pending_ops.stqh_first->o_pb == NULL ) {
145 slapi_ch_free( (void **)&pConn->c_pending_ops.stqh_first );
146 slapi_ch_free( (void **)&pConn );
147 return (Connection *)NULL;
152 /* operation object */
153 c->c_pending_ops.stqh_first->o_tag = OpType;
154 c->c_pending_ops.stqh_first->o_protocol = LDAP_VERSION3;
155 c->c_pending_ops.stqh_first->o_authmech.bv_val = NULL;
156 c->c_pending_ops.stqh_first->o_authmech.bv_len = 0;
157 c->c_pending_ops.stqh_first->o_time = slap_get_time();
158 c->c_pending_ops.stqh_first->o_do_not_cache = 1;
159 c->c_pending_ops.stqh_first->o_threadctx = ldap_pvt_thread_pool_context();
160 c->c_pending_ops.stqh_first->o_tmpmemctx = NULL;
161 c->c_pending_ops.stqh_first->o_tmpmfuncs = &ch_mfuncs;
162 c->c_pending_ops.stqh_first->o_conn = c;
164 /* connection object */
165 c->c_authmech.bv_val = NULL;
166 c->c_authmech.bv_len = 0;
167 c->c_dn.bv_val = NULL;
169 c->c_ndn.bv_val = NULL;
173 c->c_listener = &slap_unknown_listener;
174 ber_dupbv( &c->c_peer_domain, (struct berval *)&slap_unknown_bv );
175 ber_dupbv( &c->c_peer_name, (struct berval *)&slap_unknown_bv );
177 LDAP_STAILQ_INIT( &c->c_ops );
179 c->c_sasl_bind_mech.bv_val = NULL;
180 c->c_sasl_bind_mech.bv_len = 0;
181 c->c_sasl_authctx = NULL;
182 c->c_sasl_sockctx = NULL;
183 c->c_sasl_extra = NULL;
185 c->c_sb = ber_sockbuf_alloc( );
187 ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
189 c->c_currentber = NULL;
191 /* should check status of thread calls */
192 ldap_pvt_thread_mutex_init( &c->c_mutex );
193 ldap_pvt_thread_mutex_init( &c->c_write_mutex );
194 ldap_pvt_thread_cond_init( &c->c_write_cv );
196 c->c_n_ops_received = 0;
197 c->c_n_ops_executing = 0;
198 c->c_n_ops_pending = 0;
199 c->c_n_ops_completed = 0;
205 c->c_protocol = LDAP_VERSION3;
207 c->c_activitytime = c->c_starttime = slap_get_time();
211 c->c_conn_state = 0x01; /* SLAP_C_ACTIVE */
212 c->c_struct_state = 0x02; /* SLAP_C_USED */
214 c->c_ssf = c->c_transport_ssf = 0;
217 backend_connection_init( c );
219 pConn->c_send_ldap_result = internal_result_v3;
220 pConn->c_send_search_entry = internal_search_entry;
221 pConn->c_send_ldap_extended = internal_result_ext;
222 pConn->c_send_search_reference = internal_search_reference;
227 static void slapiConnectionDestroy( Connection **pConn )
229 Connection *conn = *pConn;
232 if ( pConn == NULL ) {
236 op = (Operation *)conn->c_pending_ops.stqh_first;
238 if ( op->o_req_dn.bv_val != NULL ) {
239 slapi_ch_free( (void **)&op->o_req_dn.bv_val );
241 if ( op->o_req_ndn.bv_val != NULL ) {
242 slapi_ch_free( (void **)&op->o_req_ndn.bv_val );
245 if ( conn->c_sb != NULL ) {
246 ber_sockbuf_free( conn->c_sb );
249 slapi_ch_free( (void **)&op );
251 slapi_ch_free( (void **)pConn );
255 * Function : values2obj
256 * Convert an array of strings into a BerVarray.
267 if ( ppValue == NULL ) {
272 for ( i = 0; ppValue[i] != NULL; i++ )
275 tmpberval = (BerVarray)slapi_ch_malloc( (i+1) * (sizeof(struct berval)) );
276 if ( tmpberval == NULL ) {
277 return LDAP_NO_MEMORY;
279 for ( i = 0; ppValue[i] != NULL; i++ ) {
280 tmpberval[i].bv_val = ppValue[i];
281 tmpberval[i].bv_len = strlen( ppValue[i] );
283 tmpberval[i].bv_val = NULL;
284 tmpberval[i].bv_len = 0;
292 freeMods( Modifications *ml )
295 * Free a modification list whose values have been
296 * set with bvptr2obj() or values2obj() (ie. they
297 * do not own the pointer to the underlying values)
301 for ( ; ml != NULL; ml = next ) {
304 slapi_ch_free( (void **)&ml->sml_bvalues );
305 slapi_ch_free( (void **)&ml->sml_nvalues );
306 slapi_ch_free( (void **)&ml );
311 * Function : LDAPModToEntry
312 * convert a dn plus an array of LDAPMod struct ptrs to an entry structure
313 * with a link list of the correspondent attributes.
314 * Return value : LDAP_SUCCESS
323 struct berval dn = { 0, NULL };
329 Modifications *modlist = NULL;
330 Modifications **modtail = &modlist;
333 int rc = LDAP_SUCCESS;
336 const char *text = NULL;
339 op = (Operation *) slapi_ch_calloc(1, sizeof(Operation));
340 if ( pEntry == NULL) {
344 op->o_tag = LDAP_REQ_ADD;
346 pEntry = (Entry *) ch_calloc( 1, sizeof(Entry) );
347 if ( pEntry == NULL) {
352 dn.bv_val = slapi_ch_strdup(ldn);
353 dn.bv_len = strlen(ldn);
355 rc = dnPrettyNormal( NULL, &dn, &pEntry->e_name, &pEntry->e_nname, NULL );
356 if ( rc != LDAP_SUCCESS )
359 if ( rc == LDAP_SUCCESS ) {
360 for ( i=0, pMod=mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod=mods[++i]) {
362 if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
363 /* attr values are in berval format */
364 /* convert an array of pointers to bervals to an array of bervals */
365 rc = bvptr2obj(pMod->mod_bvalues, &bv);
366 if (rc != LDAP_SUCCESS) goto cleanup;
367 tmp.sml_type.bv_val = pMod->mod_type;
368 tmp.sml_type.bv_len = strlen( pMod->mod_type );
369 tmp.sml_bvalues = bv;
370 tmp.sml_nvalues = NULL;
372 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
374 mod->sml_op = LDAP_MOD_ADD;
375 mod->sml_next = NULL;
376 mod->sml_desc = NULL;
377 mod->sml_type = tmp.sml_type;
378 mod->sml_bvalues = tmp.sml_bvalues;
379 mod->sml_nvalues = tmp.sml_nvalues;
382 modtail = &mod->sml_next;
385 /* attr values are in string format, need to be converted */
386 /* to an array of bervals */
387 if ( pMod->mod_values == NULL ) {
390 rc = values2obj( pMod->mod_values, &bv );
391 if (rc != LDAP_SUCCESS) goto cleanup;
392 tmp.sml_type.bv_val = pMod->mod_type;
393 tmp.sml_type.bv_len = strlen( pMod->mod_type );
394 tmp.sml_bvalues = bv;
395 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;
404 mod->sml_nvalues = tmp.sml_nvalues;
407 modtail = &mod->sml_next;
410 } /* for each LDAPMod */
413 op->o_bd = select_backend( &pEntry->e_nname, 0, 0 );
414 if ( op->o_bd == NULL ) {
415 rc = LDAP_PARTIAL_RESULTS;
417 int repl_user = be_isupdate( op->o_bd, &op->o_bd->be_rootdn );
418 if ( !op->o_bd->be_update_ndn.bv_len || repl_user ) {
419 int update = op->o_bd->be_update_ndn.bv_len;
420 char textbuf[SLAP_TEXT_BUFLEN];
421 size_t textlen = sizeof textbuf;
423 rc = slap_mods_check( modlist, update, &text,
424 textbuf, textlen, NULL );
425 if ( rc != LDAP_SUCCESS) {
430 rc = slap_mods_opattrs( op,
431 modlist, modtail, &text,
433 if ( rc != LDAP_SUCCESS) {
439 * FIXME: slap_mods2entry is declared static
440 * in servers/slapd/add.c
442 rc = slap_mods2entry( modlist, &pEntry, repl_user,
443 &text, textbuf, textlen );
444 if (rc != LDAP_SUCCESS) {
456 slapi_ch_free( (void **)&dn.bv_val );
458 slapi_ch_free( (void **)&op );
459 if ( modlist != NULL )
461 if ( rc != LDAP_SUCCESS ) {
462 if ( pEntry != NULL ) {
463 slapi_entry_free( pEntry );
471 /* Function : slapi_delete_internal
473 * Description : Plugin functions call this routine to delete an entry
474 * in the backend directly
475 * Return values : LDAP_SUCCESS
479 * LDAP_UNWILLING_TO_PERFORM
482 slapi_delete_internal(
484 LDAPControl **controls,
488 Connection *pConn = NULL;
489 Operation *op = NULL;
490 Slapi_PBlock *pPB = NULL;
491 Slapi_PBlock *pSavePB = NULL;
492 SlapReply rs = { REP_RESULT };
493 struct berval dn = { 0, NULL };
499 rs.sr_err = LDAP_PARAM_ERROR;
503 pConn = slapiConnectionInit( NULL, LDAP_REQ_DELETE );
505 rs.sr_err = LDAP_NO_MEMORY;
509 op = (Operation *)pConn->c_pending_ops.stqh_first;
510 pPB = (Slapi_PBlock *)op->o_pb;
511 op->o_ctrls = controls;
513 dn.bv_val = slapi_ch_strdup(ldn);
514 dn.bv_len = strlen(ldn);
515 rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn, NULL );
516 if ( rs.sr_err != LDAP_SUCCESS )
519 if ( slapi_control_present( controls,
520 SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical) ) {
524 op->o_bd = select_backend( &op->o_req_ndn, manageDsaIt, 0 );
525 if ( op->o_bd == NULL ) {
526 rs.sr_err = LDAP_PARTIAL_RESULTS;
530 op->o_dn = pConn->c_dn = op->o_bd->be_rootdn;
531 op->o_ndn = pConn->c_ndn = op->o_bd->be_rootndn;
533 if ( op->o_bd->be_delete ) {
534 int repl_user = be_isupdate( op->o_bd, &op->o_ndn );
535 if ( !op->o_bd->be_update_ndn.bv_len || repl_user ) {
536 if ( (*op->o_bd->be_delete)( op, &rs ) == 0 ) {
541 rs.sr_err = LDAP_OTHER;
544 rs.sr_err = LDAP_REFERRAL;
547 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
552 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
555 slapi_ch_free( (void **)&dn.bv_val );
557 if ( pConn != NULL ) {
561 slapiConnectionDestroy( &pConn );
566 #endif /* LDAP_SLAPI */
570 slapi_add_entry_internal(
572 LDAPControl **controls,
576 Connection *pConn = NULL;
577 Operation *op = NULL;
578 Slapi_PBlock *pPB = NULL, *pSavePB = NULL;
582 SlapReply rs = { REP_RESULT };
585 rs.sr_err = LDAP_PARAM_ERROR;
589 pConn = slapiConnectionInit( NULL, LDAP_REQ_ADD );
590 if ( pConn == NULL ) {
591 rs.sr_err = LDAP_NO_MEMORY;
595 if ( slapi_control_present( controls, LDAP_CONTROL_MANAGEDSAIT,
596 NULL, &isCritical ) ) {
600 op = (Operation *)pConn->c_pending_ops.stqh_first;
601 pPB = (Slapi_PBlock *)op->o_pb;
602 op->o_ctrls = controls;
604 op->o_bd = select_backend( &e->e_nname, manageDsaIt, 0 );
605 if ( op->o_bd == NULL ) {
606 rs.sr_err = LDAP_PARTIAL_RESULTS;
610 op->o_dn = pConn->c_dn = op->o_bd->be_rootdn;
611 op->o_ndn = pConn->c_ndn = op->o_bd->be_rootndn;
614 if ( op->o_bd->be_add ) {
615 int repl_user = be_isupdate( op->o_bd, &op->o_ndn );
616 if ( !op->o_bd->be_update_ndn.bv_len || repl_user ){
617 if ( (*op->o_bd->be_add)( op, &rs ) == 0 ) {
623 rs.sr_err = LDAP_REFERRAL;
626 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
632 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
635 if ( pConn != NULL ) {
639 slapiConnectionDestroy( &pConn );
644 #endif /* LDAP_SLAPI */
652 LDAPControl **controls,
656 LDAPMod *pMod = NULL;
657 Slapi_PBlock *pb = NULL;
658 Entry *pEntry = NULL;
659 int i, rc = LDAP_SUCCESS;
661 if ( mods == NULL || *mods == NULL || dn == NULL || *dn == '\0' ) {
662 rc = LDAP_PARAM_ERROR ;
665 if ( rc == LDAP_SUCCESS ) {
666 for ( i = 0, pMod = mods[0]; pMod != NULL; pMod = mods[++i] ) {
667 if ( (pMod->mod_op & ~LDAP_MOD_BVALUES) != LDAP_MOD_ADD ) {
674 if ( rc == LDAP_SUCCESS ) {
675 if((pEntry = LDAPModToEntry( dn, mods )) == NULL) {
680 if ( rc != LDAP_SUCCESS ) {
681 pb = slapi_pblock_new();
682 slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
684 pb = slapi_add_entry_internal( pEntry, controls, log_changes );
688 slapi_entry_free(pEntry);
694 #endif /* LDAP_SLAPI */
697 /* Function : slapi_modrdn_internal
699 * Description : Plugin functions call this routine to modify the rdn
700 * of an entry in the backend directly
701 * Return values : LDAP_SUCCESS
705 * LDAP_UNWILLING_TO_PERFORM
707 * NOTE: This function does not support the "newSuperior" option from LDAP V3.
710 slapi_modrdn_internal(
714 LDAPControl **controls,
718 struct berval dn = { 0, NULL };
719 struct berval newrdn = { 0, NULL };
720 Connection *pConn = NULL;
721 Operation *op = NULL;
722 Slapi_PBlock *pPB = NULL;
723 Slapi_PBlock *pSavePB = NULL;
726 SlapReply rs = { REP_RESULT };
728 pConn = slapiConnectionInit( NULL, LDAP_REQ_MODRDN);
729 if ( pConn == NULL) {
730 rs.sr_err = LDAP_NO_MEMORY;
734 op = (Operation *)pConn->c_pending_ops.stqh_first;
735 pPB = (Slapi_PBlock *)op->o_pb;
736 op->o_ctrls = controls;
738 if ( slapi_control_present( controls,
739 SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {
743 op->o_bd = select_backend( &op->o_req_ndn, manageDsaIt, 0 );
744 if ( op->o_bd == NULL ) {
745 rs.sr_err = LDAP_PARTIAL_RESULTS;
749 op->o_dn = pConn->c_dn = op->o_bd->be_rootdn;
750 op->o_ndn = pConn->c_ndn = op->o_bd->be_rootndn;
752 dn.bv_val = slapi_ch_strdup( olddn );
753 dn.bv_len = strlen( olddn );
755 rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn, NULL );
756 if ( rs.sr_err != LDAP_SUCCESS ) {
760 if ( op->o_req_dn.bv_len == 0 ) {
761 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
765 newrdn.bv_val = slapi_ch_strdup( lnewrdn );
766 newrdn.bv_len = strlen( lnewrdn );
768 rs.sr_err = dnPrettyNormal( NULL, &newrdn, &op->oq_modrdn.rs_newrdn, &op->oq_modrdn.rs_nnewrdn, NULL );
769 if ( rs.sr_err != LDAP_SUCCESS ) {
773 if ( rdnValidate( &op->oq_modrdn.rs_nnewrdn ) != LDAP_SUCCESS ) {
777 op->oq_modrdn.rs_newSup = NULL;
778 op->oq_modrdn.rs_nnewSup = NULL;
779 op->oq_modrdn.rs_deleteoldrdn = deloldrdn;
781 if ( op->o_bd->be_modrdn ) {
782 int repl_user = be_isupdate( op->o_bd, &op->o_ndn );
783 if ( !op->o_bd->be_update_ndn.bv_len || repl_user ) {
784 if ( (*op->o_bd->be_modrdn)( op, &rs ) == 0 ) {
789 rs.sr_err = LDAP_OTHER;
792 rs.sr_err = LDAP_REFERRAL;
795 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
801 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
805 slapi_ch_free( (void **)&dn.bv_val );
808 slapi_ch_free( (void **)&newrdn.bv_val );
809 if ( op->oq_modrdn.rs_newrdn.bv_val )
810 slapi_ch_free( (void **)&op->oq_modrdn.rs_newrdn.bv_val );
811 if ( op->oq_modrdn.rs_nnewrdn.bv_val )
812 slapi_ch_free( (void **)&op->oq_modrdn.rs_nnewrdn.bv_val );
814 if ( pConn != NULL ) {
818 slapiConnectionDestroy( &pConn );
823 #endif /* LDAP_SLAPI */
826 /* Function : slapi_modify_internal
828 * Description: Plugin functions call this routine to modify an entry
829 * in the backend directly
830 * Return values : LDAP_SUCCESS
834 * LDAP_UNWILLING_TO_PERFORM
837 slapi_modify_internal(
840 LDAPControl **controls,
845 Connection *pConn = NULL;
846 Operation *op = NULL;
847 Slapi_PBlock *pPB = NULL;
848 Slapi_PBlock *pSavePB = NULL;
850 struct berval dn = { 0, NULL };
857 Modifications *modlist = NULL;
858 Modifications **modtail = &modlist;
861 SlapReply rs = { REP_RESULT };
863 if ( mods == NULL || *mods == NULL || ldn == NULL ) {
864 rs.sr_err = LDAP_PARAM_ERROR ;
868 pConn = slapiConnectionInit( NULL, LDAP_REQ_MODIFY );
869 if ( pConn == NULL ) {
870 rs.sr_err = LDAP_NO_MEMORY;
874 op = (Operation *)pConn->c_pending_ops.stqh_first;
875 pPB = (Slapi_PBlock *)op->o_pb;
876 op->o_ctrls = controls;
878 dn.bv_val = slapi_ch_strdup( ldn );
879 dn.bv_len = strlen( ldn );
880 rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn, NULL );
881 if ( rs.sr_err != LDAP_SUCCESS ) {
885 if ( slapi_control_present( controls,
886 SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {
890 op->o_bd = select_backend( &op->o_req_ndn, manageDsaIt, 0 );
891 if ( op->o_bd == NULL ) {
892 rs.sr_err = LDAP_PARTIAL_RESULTS;
896 op->o_dn = pConn->c_dn = op->o_bd->be_rootdn;
897 op->o_ndn = pConn->c_ndn = op->o_bd->be_rootndn;
899 for ( i = 0, pMod = mods[0];
900 rs.sr_err == LDAP_SUCCESS && pMod != NULL;
905 if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
907 * attr values are in berval format
908 * convert an array of pointers to bervals
909 * to an array of bervals
911 rs.sr_err = bvptr2obj( pMod->mod_bvalues, &bv );
912 if ( rs.sr_err != LDAP_SUCCESS )
914 tmp.sml_type.bv_val = pMod->mod_type;
915 tmp.sml_type.bv_len = strlen( pMod->mod_type );
916 tmp.sml_bvalues = bv;
917 tmp.sml_nvalues = NULL;
919 mod = (Modifications *)ch_malloc( sizeof(Modifications) );
921 mod->sml_op = pMod->mod_op;
922 mod->sml_next = NULL;
923 mod->sml_desc = NULL;
924 mod->sml_type = tmp.sml_type;
925 mod->sml_bvalues = tmp.sml_bvalues;
926 mod->sml_nvalues = tmp.sml_nvalues;
928 rs.sr_err = values2obj( pMod->mod_values, &bv );
929 if ( rs.sr_err != LDAP_SUCCESS )
931 tmp.sml_type.bv_val = pMod->mod_type;
932 tmp.sml_type.bv_len = strlen( pMod->mod_type );
933 tmp.sml_bvalues = bv;
934 tmp.sml_nvalues = NULL;
936 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
938 mod->sml_op = pMod->mod_op;
939 mod->sml_next = NULL;
940 mod->sml_desc = NULL;
941 mod->sml_type = tmp.sml_type;
942 mod->sml_bvalues = tmp.sml_bvalues;
943 mod->sml_nvalues = tmp.sml_nvalues;
946 modtail = &mod->sml_next;
948 switch( pMod->mod_op ) {
950 if ( mod->sml_bvalues == NULL ) {
951 rs.sr_err = LDAP_PROTOCOL_ERROR;
956 case LDAP_MOD_DELETE:
957 case LDAP_MOD_REPLACE:
961 rs.sr_err = LDAP_PROTOCOL_ERROR;
967 if ( op->o_req_ndn.bv_len == 0 ) {
968 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
972 op->oq_modify.rs_modlist = modlist;
974 if ( op->o_bd->be_modify ) {
975 int repl_user = be_isupdate( op->o_bd, &op->o_ndn );
976 if ( !op->o_bd->be_update_ndn.bv_len || repl_user ) {
977 int update = op->o_bd->be_update_ndn.bv_len;
978 const char *text = NULL;
979 char textbuf[SLAP_TEXT_BUFLEN];
980 size_t textlen = sizeof( textbuf );
982 rs.sr_err = slap_mods_check( modlist, update,
983 &text, textbuf, textlen, NULL );
984 if ( rs.sr_err != LDAP_SUCCESS ) {
989 rs.sr_err = slap_mods_opattrs( op, modlist,
990 modtail, &text, textbuf,
992 if ( rs.sr_err != LDAP_SUCCESS ) {
996 if ( (*op->o_bd->be_modify)( op, &rs ) == 0 ) {
1001 rs.sr_err = LDAP_OTHER;
1004 rs.sr_err = LDAP_REFERRAL;
1007 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
1013 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
1016 slapi_ch_free( (void **)&dn.bv_val );
1018 if ( modlist != NULL )
1019 freeMods( modlist );
1021 if ( pConn != NULL ) {
1025 slapiConnectionDestroy( &pConn );
1030 #endif /* LDAP_SLAPI */
1034 slapi_search_internal_bind(
1039 LDAPControl **controls,
1045 Operation *op = NULL;
1046 Slapi_PBlock *ptr = NULL;
1047 Slapi_PBlock *pSavePB = NULL;
1048 struct berval dn = { 0, NULL };
1049 Filter *filter=NULL;
1050 struct berval fstr = { 0, NULL };
1051 AttributeName *an = NULL;
1052 const char *text = NULL;
1054 int manageDsaIt = 0;
1058 SlapReply rs = { REP_RESULT };
1060 c = slapiConnectionInit( NULL, LDAP_REQ_SEARCH );
1062 rs.sr_err = LDAP_NO_MEMORY;
1066 op = (Operation *)c->c_pending_ops.stqh_first;
1067 ptr = (Slapi_PBlock *)op->o_pb;
1068 op->o_ctrls = controls;
1070 if ( ldn != NULL ) {
1071 dn.bv_val = slapi_ch_strdup(ldn);
1072 dn.bv_len = strlen(ldn);
1075 rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn, NULL );
1076 if ( rs.sr_err != LDAP_SUCCESS ) {
1080 if ( scope != LDAP_SCOPE_BASE &&
1081 scope != LDAP_SCOPE_ONELEVEL &&
1082 scope != LDAP_SCOPE_SUBTREE ) {
1083 rs.sr_err = LDAP_PROTOCOL_ERROR;
1087 filter = slapi_str2filter(filStr);
1088 if ( filter == NULL ) {
1089 rs.sr_err = LDAP_PROTOCOL_ERROR;
1093 filter2bv( filter, &fstr );
1095 for ( i = 0; attrs != NULL && attrs[i] != NULL; i++ ) {
1096 ; /* count the number of attributes */
1100 an = (AttributeName *)slapi_ch_calloc( (i + 1), sizeof(AttributeName) );
1101 for (i = 0; attrs[i] != 0; i++) {
1102 an[i].an_desc = NULL;
1104 an[i].an_name.bv_val = slapi_ch_strdup(attrs[i]);
1105 an[i].an_name.bv_len = strlen(attrs[i]);
1106 slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text );
1108 an[i].an_name.bv_val = NULL;
1111 memset( &rs, 0, sizeof(rs) );
1112 rs.sr_type = REP_RESULT;
1113 rs.sr_err = LDAP_SUCCESS;
1114 rs.sr_entry = NULL; /* paranoia */
1116 if ( scope == LDAP_SCOPE_BASE ) {
1119 if ( op->o_req_ndn.bv_len == 0 ) {
1120 rs.sr_err = root_dse_info( c, &rs.sr_entry, &rs.sr_text );
1123 if( rs.sr_err != LDAP_SUCCESS ) {
1124 send_ldap_result( op, &rs );
1126 } else if ( rs.sr_entry != NULL ) {
1127 rs.sr_err = test_filter( op, rs.sr_entry, filter );
1129 if ( rs.sr_err == LDAP_COMPARE_TRUE ) {
1130 rs.sr_type = REP_SEARCH;
1131 rs.sr_err = LDAP_SUCCESS;
1134 send_search_entry( op, &rs );
1137 entry_free( rs.sr_entry );
1139 rs.sr_type = REP_RESULT;
1140 rs.sr_err = LDAP_SUCCESS;
1142 send_ldap_result( op, &rs );
1148 if ( !op->o_req_ndn.bv_len && default_search_nbase.bv_len ) {
1149 slapi_ch_free( (void **)&op->o_req_dn.bv_val );
1150 slapi_ch_free( (void **)&op->o_req_ndn.bv_val );
1152 ber_dupbv( &op->o_req_dn, &default_search_base );
1153 ber_dupbv( &op->o_req_ndn, &default_search_nbase );
1156 if ( slapi_control_present( controls,
1157 LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
1161 op->o_bd = select_backend( &op->o_req_ndn, manageDsaIt, 0 );
1162 if ( op->o_bd == NULL ) {
1163 if ( manageDsaIt == 1 ) {
1164 rs.sr_err = LDAP_NO_SUCH_OBJECT;
1166 rs.sr_err = LDAP_PARTIAL_RESULTS;
1171 op->o_dn = c->c_dn = op->o_bd->be_rootdn;
1172 op->o_ndn = c->c_ndn = op->o_bd->be_rootndn;
1174 op->oq_search.rs_scope = scope;
1175 op->oq_search.rs_deref = 0;
1176 op->oq_search.rs_slimit = LDAP_NO_LIMIT;
1177 op->oq_search.rs_tlimit = LDAP_NO_LIMIT;
1178 op->oq_search.rs_attrsonly = attrsonly;
1179 op->oq_search.rs_attrs = an;
1180 op->oq_search.rs_filter = filter;
1181 op->oq_search.rs_filterstr = fstr;
1183 if ( op->o_bd->be_search ) {
1184 if ( (*op->o_bd->be_search)( op, &rs ) != 0 ) {
1185 rs.sr_err = LDAP_OTHER;
1188 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
1194 slapi_pblock_set( ptr, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
1197 slapi_ch_free( (void **)&dn.bv_val );
1199 slapi_filter_free( filter, 1 );
1201 slapi_ch_free( (void **)&fstr.bv_val );
1203 slapi_ch_free( (void **)&an );
1209 slapiConnectionDestroy( &c );
1214 #endif /* LDAP_SLAPI */
1218 slapi_search_internal(
1222 LDAPControl **controls,
1227 return slapi_search_internal_bind( NULL, base, scope, filStr,
1228 controls, attrs, attrsonly );
1231 #endif /* LDAP_SLAPI */