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 );
45 internal_search_entry(
50 int nentries = 0, len = 0, i = 0;
51 Slapi_Entry **head = NULL, **tp;
53 ent2str = slapi_entry2str( rs->sr_entry, &len );
54 if ( ent2str == NULL ) {
58 slapi_pblock_get( (Slapi_PBlock *)op->o_pb,
59 SLAPI_NENTRIES, &nentries );
60 slapi_pblock_get( (Slapi_PBlock *)op->o_pb,
61 SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &head );
64 if ( nentries == 0 ) {
65 tp = (Slapi_Entry **)slapi_ch_malloc( 2 * sizeof(Slapi_Entry *) );
70 tp[ 0 ] = (Slapi_Entry *)str2entry( ent2str );
71 if ( tp[ 0 ] == NULL ) {
76 tp = (Slapi_Entry **)slapi_ch_realloc( (char *)head,
77 sizeof(Slapi_Entry *) * ( i + 1 ) );
81 tp[ i - 1 ] = (Slapi_Entry *)str2entry( ent2str );
82 if ( tp[ i - 1 ] == NULL ) {
88 slapi_pblock_set( (Slapi_PBlock *)op->o_pb,
89 SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, (void *)tp );
90 slapi_pblock_set( (Slapi_PBlock *)op->o_pb,
91 SLAPI_NENTRIES, (void *)i );
97 internal_search_result(
101 slapi_pblock_set( (Slapi_PBlock *)op->o_pb,
102 SLAPI_NENTRIES, (void *)sr->sr_nentries );
116 internal_search_reference(
128 Connection *pConn, *c;
129 ber_len_t max = sockbuf_max_incoming;
131 pConn = (Connection *) slapi_ch_calloc(1, sizeof(Connection));
133 return (Connection *)NULL;
136 LDAP_STAILQ_INIT( &pConn->c_pending_ops );
138 pConn->c_pending_ops.stqh_first =
139 (Operation *) slapi_ch_calloc( 1, sizeof(Operation) );
140 if ( pConn->c_pending_ops.stqh_first == NULL ) {
141 slapi_ch_free( (void **)&pConn );
142 return (Connection *)NULL;
145 pConn->c_pending_ops.stqh_first->o_pb =
146 (Slapi_PBlock *) slapi_pblock_new();
147 if ( pConn->c_pending_ops.stqh_first->o_pb == NULL ) {
148 slapi_ch_free( (void **)&pConn->c_pending_ops.stqh_first );
149 slapi_ch_free( (void **)&pConn );
150 return (Connection *)NULL;
155 /* operation object */
156 c->c_pending_ops.stqh_first->o_tag = OpType;
157 c->c_pending_ops.stqh_first->o_protocol = LDAP_VERSION3;
158 c->c_pending_ops.stqh_first->o_authmech.bv_val = NULL;
159 c->c_pending_ops.stqh_first->o_authmech.bv_len = 0;
160 c->c_pending_ops.stqh_first->o_time = slap_get_time();
161 c->c_pending_ops.stqh_first->o_do_not_cache = 1;
162 c->c_pending_ops.stqh_first->o_threadctx = ldap_pvt_thread_pool_context( &connection_pool );
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_context = NULL;
182 c->c_sasl_extra = NULL;
184 c->c_sb = ber_sockbuf_alloc( );
186 ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
188 c->c_currentber = NULL;
190 /* should check status of thread calls */
191 ldap_pvt_thread_mutex_init( &c->c_mutex );
192 ldap_pvt_thread_mutex_init( &c->c_write_mutex );
193 ldap_pvt_thread_cond_init( &c->c_write_cv );
195 c->c_n_ops_received = 0;
196 c->c_n_ops_executing = 0;
197 c->c_n_ops_pending = 0;
198 c->c_n_ops_completed = 0;
204 c->c_protocol = LDAP_VERSION3;
206 c->c_activitytime = c->c_starttime = slap_get_time();
210 c->c_conn_state = 0x01; /* SLAP_C_ACTIVE */
211 c->c_struct_state = 0x02; /* SLAP_C_USED */
213 c->c_ssf = c->c_transport_ssf = 0;
216 backend_connection_init( c );
218 pConn->c_send_ldap_result = internal_result_v3;
219 pConn->c_send_search_entry = internal_search_entry;
220 pConn->c_send_search_result = internal_search_result;
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 );
306 slapi_ch_free( (void **)&ml->sml_nvalues );
308 slapi_ch_free( (void **)&ml );
313 * Function : LDAPModToEntry
314 * convert a dn plus an array of LDAPMod struct ptrs to an entry structure
315 * with a link list of the correspondent attributes.
316 * Return value : LDAP_SUCCESS
325 struct berval dn = { 0, NULL };
332 Modifications *modlist = NULL;
333 Modifications **modtail = &modlist;
336 int rc = LDAP_SUCCESS;
339 const char *text = NULL;
342 op = (Operation *) slapi_ch_calloc(1, sizeof(Operation));
343 if ( pEntry == NULL) {
347 op->o_tag = LDAP_REQ_ADD;
349 pEntry = (Entry *) ch_calloc( 1, sizeof(Entry) );
350 if ( pEntry == NULL) {
355 dn.bv_val = slapi_ch_strdup(ldn);
356 dn.bv_len = strlen(ldn);
358 rc = dnPrettyNormal( NULL, &dn, &pEntry->e_name, &pEntry->e_nname );
359 if ( rc != LDAP_SUCCESS )
362 if ( rc == LDAP_SUCCESS ) {
363 for ( i=0, pMod=mods[0]; rc == LDAP_SUCCESS && pMod != NULL; pMod=mods[++i]) {
365 if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
366 /* attr values are in berval format */
367 /* convert an array of pointers to bervals to an array of bervals */
368 rc = bvptr2obj(pMod->mod_bvalues, &bv);
369 if (rc != LDAP_SUCCESS) goto cleanup;
370 tmp.sml_type.bv_val = pMod->mod_type;
371 tmp.sml_type.bv_len = strlen( pMod->mod_type );
372 tmp.sml_bvalues = bv;
374 tmp.sml_nvalues = NULL;
377 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
379 mod->sml_op = LDAP_MOD_ADD;
380 mod->sml_next = NULL;
381 mod->sml_desc = NULL;
382 mod->sml_type = tmp.sml_type;
383 mod->sml_bvalues = tmp.sml_bvalues;
385 mod->sml_nvalues = tmp.sml_nvalues;
389 modtail = &mod->sml_next;
392 /* attr values are in string format, need to be converted */
393 /* to an array of bervals */
394 if ( pMod->mod_values == NULL ) {
397 rc = values2obj( pMod->mod_values, &bv );
398 if (rc != LDAP_SUCCESS) goto cleanup;
399 tmp.sml_type.bv_val = pMod->mod_type;
400 tmp.sml_type.bv_len = strlen( pMod->mod_type );
401 tmp.sml_bvalues = bv;
403 tmp.sml_nvalues = NULL;
406 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
408 mod->sml_op = LDAP_MOD_ADD;
409 mod->sml_next = NULL;
410 mod->sml_desc = NULL;
411 mod->sml_type = tmp.sml_type;
412 mod->sml_bvalues = tmp.sml_bvalues;
414 mod->sml_nvalues = tmp.sml_nvalues;
418 modtail = &mod->sml_next;
421 } /* for each LDAPMod */
424 be = select_backend(&pEntry->e_nname, 0, 0);
426 rc = LDAP_PARTIAL_RESULTS;
431 int repl_user = be_isupdate(be, &be->be_rootdn );
432 if ( !be->be_update_ndn.bv_len || repl_user ) {
433 int update = be->be_update_ndn.bv_len;
434 char textbuf[SLAP_TEXT_BUFLEN];
435 size_t textlen = sizeof textbuf;
437 rc = slap_mods_check( modlist, update, &text,
439 if ( rc != LDAP_SUCCESS) {
444 rc = slap_mods_opattrs( op,
445 modlist, modtail, &text,
447 if ( rc != LDAP_SUCCESS) {
453 * FIXME: slap_mods2entry is declared static
454 * in servers/slapd/add.c
456 rc = slap_mods2entry( modlist, &pEntry, repl_user,
457 &text, textbuf, textlen );
458 if (rc != LDAP_SUCCESS) {
466 rc = LDAP_UNWILLING_TO_PERFORM;
472 slapi_ch_free( (void **)&dn.bv_val );
474 slapi_ch_free( (void **)&op );
475 if ( modlist != NULL )
477 if ( rc != LDAP_SUCCESS ) {
478 if ( pEntry != NULL ) {
479 slapi_entry_free( pEntry );
487 /* Function : slapi_delete_internal
489 * Description : Plugin functions call this routine to delete an entry
490 * in the backend directly
491 * Return values : LDAP_SUCCESS
495 * LDAP_UNWILLING_TO_PERFORM
498 slapi_delete_internal(
500 LDAPControl **controls,
505 Connection *pConn = NULL;
506 Operation *op = NULL;
507 Slapi_PBlock *pPB = NULL;
508 Slapi_PBlock *pSavePB = NULL;
509 SlapReply rs = { REP_RESULT };
510 struct berval dn = { 0, NULL };
516 rs.sr_err = LDAP_PARAM_ERROR;
520 pConn = slapiConnectionInit( NULL, LDAP_REQ_DELETE );
522 rs.sr_err = LDAP_NO_MEMORY;
526 op = (Operation *)pConn->c_pending_ops.stqh_first;
527 pPB = (Slapi_PBlock *)op->o_pb;
528 op->o_ctrls = controls;
530 dn.bv_val = slapi_ch_strdup(ldn);
531 dn.bv_len = strlen(ldn);
532 rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn );
533 if ( rs.sr_err != LDAP_SUCCESS )
536 if ( slapi_control_present( controls,
537 SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical) ) {
541 be = select_backend( &op->o_req_ndn, manageDsaIt, 0 );
543 rs.sr_err = LDAP_PARTIAL_RESULTS;
547 op->o_dn = pConn->c_dn = be->be_rootdn;
548 op->o_ndn = pConn->c_ndn = be->be_rootndn;
550 if ( be->be_delete ) {
551 int repl_user = be_isupdate( be, &op->o_ndn );
552 if ( !be->be_update_ndn.bv_len || repl_user ) {
553 if ( (*be->be_delete)( op, &rs ) == 0 ) {
558 rs.sr_err = LDAP_OTHER;
561 rs.sr_err = LDAP_REFERRAL;
564 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
569 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
572 slapi_ch_free( (void **)&dn.bv_val );
574 if ( pConn != NULL ) {
578 slapiConnectionDestroy( &pConn );
583 #endif /* LDAP_SLAPI */
587 slapi_add_entry_internal(
589 LDAPControl **controls,
593 Connection *pConn = NULL;
594 Operation *op = NULL;
595 Slapi_PBlock *pPB = NULL, *pSavePB = NULL;
600 SlapReply rs = { REP_RESULT };
603 rs.sr_err = LDAP_PARAM_ERROR;
607 pConn = slapiConnectionInit( NULL, LDAP_REQ_ADD );
608 if ( pConn == NULL ) {
609 rs.sr_err = LDAP_NO_MEMORY;
613 if ( slapi_control_present( controls, LDAP_CONTROL_MANAGEDSAIT,
614 NULL, &isCritical ) ) {
618 op = (Operation *)pConn->c_pending_ops.stqh_first;
619 pPB = (Slapi_PBlock *)op->o_pb;
620 op->o_ctrls = controls;
622 be = select_backend( &e->e_nname, manageDsaIt, 0 );
624 rs.sr_err = LDAP_PARTIAL_RESULTS;
628 op->o_dn = pConn->c_dn = be->be_rootdn;
629 op->o_ndn = pConn->c_ndn = be->be_rootndn;
633 int repl_user = be_isupdate( be, &op->o_ndn );
634 if ( !be->be_update_ndn.bv_len || repl_user ){
635 if ( (*be->be_add)( op, &rs ) == 0 ) {
641 rs.sr_err = LDAP_REFERRAL;
644 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
650 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
653 if ( pConn != NULL ) {
657 slapiConnectionDestroy( &pConn );
662 #endif /* LDAP_SLAPI */
670 LDAPControl **controls,
674 LDAPMod *pMod = NULL;
675 Slapi_PBlock *pb = NULL;
676 Entry *pEntry = NULL;
677 int i, rc = LDAP_SUCCESS;
679 if ( mods == NULL || *mods == NULL || dn == NULL || *dn == '\0' ) {
680 rc = LDAP_PARAM_ERROR ;
683 if ( rc == LDAP_SUCCESS ) {
684 for ( i = 0, pMod = mods[0]; pMod != NULL; pMod = mods[++i] ) {
685 if ( (pMod->mod_op & ~LDAP_MOD_BVALUES) != LDAP_MOD_ADD ) {
692 if ( rc == LDAP_SUCCESS ) {
693 if((pEntry = LDAPModToEntry( dn, mods )) == NULL) {
698 if ( rc != LDAP_SUCCESS ) {
699 pb = slapi_pblock_new();
700 slapi_pblock_set( pb, SLAPI_PLUGIN_INTOP_RESULT, (void *)rc );
702 pb = slapi_add_entry_internal( pEntry, controls, log_changes );
706 slapi_entry_free(pEntry);
712 #endif /* LDAP_SLAPI */
715 /* Function : slapi_modrdn_internal
717 * Description : Plugin functions call this routine to modify the rdn
718 * of an entry in the backend directly
719 * Return values : LDAP_SUCCESS
723 * LDAP_UNWILLING_TO_PERFORM
725 * NOTE: This function does not support the "newSuperior" option from LDAP V3.
728 slapi_modrdn_internal(
732 LDAPControl **controls,
736 struct berval dn = { 0, NULL };
737 struct berval newrdn = { 0, NULL };
738 Connection *pConn = NULL;
739 Operation *op = NULL;
740 Slapi_PBlock *pPB = NULL;
741 Slapi_PBlock *pSavePB = NULL;
745 SlapReply rs = { REP_RESULT };
747 pConn = slapiConnectionInit( NULL, LDAP_REQ_MODRDN);
748 if ( pConn == NULL) {
749 rs.sr_err = LDAP_NO_MEMORY;
753 op = (Operation *)pConn->c_pending_ops.stqh_first;
754 pPB = (Slapi_PBlock *)op->o_pb;
755 op->o_ctrls = controls;
757 if ( slapi_control_present( controls,
758 SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {
762 be = select_backend( &op->o_req_ndn, manageDsaIt, 0 );
764 rs.sr_err = LDAP_PARTIAL_RESULTS;
768 op->o_dn = pConn->c_dn = be->be_rootdn;
769 op->o_ndn = pConn->c_ndn = be->be_rootndn;
771 dn.bv_val = slapi_ch_strdup( olddn );
772 dn.bv_len = strlen( olddn );
774 rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn );
775 if ( rs.sr_err != LDAP_SUCCESS ) {
779 if ( op->o_req_dn.bv_len == 0 ) {
780 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
784 newrdn.bv_val = slapi_ch_strdup( lnewrdn );
785 newrdn.bv_len = strlen( lnewrdn );
787 rs.sr_err = dnPrettyNormal( NULL, &newrdn, &op->oq_modrdn.rs_newrdn, &op->oq_modrdn.rs_nnewrdn );
788 if ( rs.sr_err != LDAP_SUCCESS ) {
792 if ( rdnValidate( &op->oq_modrdn.rs_nnewrdn ) != LDAP_SUCCESS ) {
796 op->oq_modrdn.rs_newSup = NULL;
797 op->oq_modrdn.rs_nnewSup = NULL;
798 op->oq_modrdn.rs_deleteoldrdn = deloldrdn;
800 if ( be->be_modrdn ) {
801 int repl_user = be_isupdate( be, &op->o_ndn );
802 if ( !be->be_update_ndn.bv_len || repl_user ) {
803 if ( (*be->be_modrdn)( op, &rs ) == 0 ) {
808 rs.sr_err = LDAP_OTHER;
811 rs.sr_err = LDAP_REFERRAL;
814 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
820 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
824 slapi_ch_free( (void **)&dn.bv_val );
827 slapi_ch_free( (void **)&newrdn.bv_val );
828 if ( op->oq_modrdn.rs_newrdn.bv_val )
829 slapi_ch_free( (void **)&op->oq_modrdn.rs_newrdn.bv_val );
830 if ( op->oq_modrdn.rs_nnewrdn.bv_val )
831 slapi_ch_free( (void **)&op->oq_modrdn.rs_nnewrdn.bv_val );
833 if ( pConn != NULL ) {
837 slapiConnectionDestroy( &pConn );
842 #endif /* LDAP_SLAPI */
845 /* Function : slapi_modify_internal
847 * Description: Plugin functions call this routine to modify an entry
848 * in the backend directly
849 * Return values : LDAP_SUCCESS
853 * LDAP_UNWILLING_TO_PERFORM
856 slapi_modify_internal(
859 LDAPControl **controls,
864 Connection *pConn = NULL;
865 Operation *op = NULL;
866 Slapi_PBlock *pPB = NULL;
867 Slapi_PBlock *pSavePB = NULL;
869 struct berval dn = { 0, NULL };
877 Modifications *modlist = NULL;
878 Modifications **modtail = &modlist;
881 SlapReply rs = { REP_RESULT };
883 if ( mods == NULL || *mods == NULL || ldn == NULL ) {
884 rs.sr_err = LDAP_PARAM_ERROR ;
888 pConn = slapiConnectionInit( NULL, LDAP_REQ_MODIFY );
889 if ( pConn == NULL ) {
890 rs.sr_err = LDAP_NO_MEMORY;
894 op = (Operation *)pConn->c_pending_ops.stqh_first;
895 pPB = (Slapi_PBlock *)op->o_pb;
896 op->o_ctrls = controls;
898 dn.bv_val = slapi_ch_strdup( ldn );
899 dn.bv_len = strlen( ldn );
900 rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn );
901 if ( rs.sr_err != LDAP_SUCCESS ) {
905 if ( slapi_control_present( controls,
906 SLAPI_CONTROL_MANAGEDSAIT_OID, NULL, &isCritical ) ) {
910 be = select_backend( &op->o_req_ndn, manageDsaIt, 0 );
912 rs.sr_err = LDAP_PARTIAL_RESULTS;
916 op->o_dn = pConn->c_dn = be->be_rootdn;
917 op->o_ndn = pConn->c_ndn = be->be_rootndn;
919 for ( i = 0, pMod = mods[0];
920 rs.sr_err == LDAP_SUCCESS && pMod != NULL;
925 if ( (pMod->mod_op & LDAP_MOD_BVALUES) != 0 ) {
927 * attr values are in berval format
928 * convert an array of pointers to bervals
929 * to an array of bervals
931 rs.sr_err = bvptr2obj( pMod->mod_bvalues, &bv );
932 if ( rs.sr_err != LDAP_SUCCESS )
934 tmp.sml_type.bv_val = pMod->mod_type;
935 tmp.sml_type.bv_len = strlen( pMod->mod_type );
936 tmp.sml_bvalues = bv;
938 tmp.sml_nvalues = NULL;
941 mod = (Modifications *)ch_malloc( sizeof(Modifications) );
943 mod->sml_op = pMod->mod_op;
944 mod->sml_next = NULL;
945 mod->sml_desc = NULL;
946 mod->sml_type = tmp.sml_type;
947 mod->sml_bvalues = tmp.sml_bvalues;
949 mod->sml_nvalues = tmp.sml_nvalues;
952 rs.sr_err = values2obj( pMod->mod_values, &bv );
953 if ( rs.sr_err != LDAP_SUCCESS )
955 tmp.sml_type.bv_val = pMod->mod_type;
956 tmp.sml_type.bv_len = strlen( pMod->mod_type );
957 tmp.sml_bvalues = bv;
959 tmp.sml_nvalues = NULL;
962 mod = (Modifications *) ch_malloc( sizeof(Modifications) );
964 mod->sml_op = pMod->mod_op;
965 mod->sml_next = NULL;
966 mod->sml_desc = NULL;
967 mod->sml_type = tmp.sml_type;
968 mod->sml_bvalues = tmp.sml_bvalues;
970 mod->sml_nvalues = tmp.sml_nvalues;
974 modtail = &mod->sml_next;
976 switch( pMod->mod_op ) {
978 if ( mod->sml_bvalues == NULL ) {
979 rs.sr_err = LDAP_PROTOCOL_ERROR;
984 case LDAP_MOD_DELETE:
985 case LDAP_MOD_REPLACE:
989 rs.sr_err = LDAP_PROTOCOL_ERROR;
995 if ( op->o_req_ndn.bv_len == 0 ) {
996 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
1000 op->oq_modify.rs_modlist = modlist;
1002 if ( be->be_modify ) {
1003 int repl_user = be_isupdate( be, &op->o_ndn );
1004 if ( !be->be_update_ndn.bv_len || repl_user ) {
1005 int update = be->be_update_ndn.bv_len;
1006 const char *text = NULL;
1007 char textbuf[SLAP_TEXT_BUFLEN];
1008 size_t textlen = sizeof( textbuf );
1010 rs.sr_err = slap_mods_check( modlist, update,
1011 &text, textbuf, textlen );
1012 if ( rs.sr_err != LDAP_SUCCESS ) {
1017 rs.sr_err = slap_mods_opattrs( op, modlist,
1018 modtail, &text, textbuf,
1020 if ( rs.sr_err != LDAP_SUCCESS ) {
1024 if ( (*be->be_modify)( op, &rs ) == 0 ) {
1029 rs.sr_err = LDAP_OTHER;
1032 rs.sr_err = LDAP_REFERRAL;
1035 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
1041 slapi_pblock_set( pPB, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
1044 slapi_ch_free( (void **)&dn.bv_val );
1046 if ( modlist != NULL )
1047 freeMods( modlist );
1049 if ( pConn != NULL ) {
1053 slapiConnectionDestroy( &pConn );
1058 #endif /* LDAP_SLAPI */
1062 slapi_search_internal_bind(
1067 LDAPControl **controls,
1074 Operation *op = NULL;
1075 Slapi_PBlock *ptr = NULL;
1076 Slapi_PBlock *pSavePB = NULL;
1077 struct berval dn = { 0, NULL };
1078 Filter *filter=NULL;
1079 struct berval fstr = { 0, NULL };
1080 AttributeName *an = NULL;
1081 const char *text = NULL;
1083 int manageDsaIt = 0;
1087 SlapReply rs = { REP_RESULT };
1089 c = slapiConnectionInit( NULL, LDAP_REQ_SEARCH );
1091 rs.sr_err = LDAP_NO_MEMORY;
1095 op = (Operation *)c->c_pending_ops.stqh_first;
1096 ptr = (Slapi_PBlock *)op->o_pb;
1097 op->o_ctrls = controls;
1099 dn.bv_val = slapi_ch_strdup(ldn);
1100 dn.bv_len = strlen(ldn);
1102 rs.sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn );
1103 if ( rs.sr_err != LDAP_SUCCESS ) {
1107 if ( scope != LDAP_SCOPE_BASE &&
1108 scope != LDAP_SCOPE_ONELEVEL &&
1109 scope != LDAP_SCOPE_SUBTREE ) {
1110 rs.sr_err = LDAP_PROTOCOL_ERROR;
1114 filter = slapi_str2filter(filStr);
1115 if ( filter == NULL ) {
1116 rs.sr_err = LDAP_PROTOCOL_ERROR;
1120 filter2bv( filter, &fstr );
1122 for ( i = 0; attrs != NULL && attrs[i] != NULL; i++ ) {
1123 ; /* count the number of attributes */
1127 an = (AttributeName *)slapi_ch_calloc( (i + 1), sizeof(AttributeName) );
1128 for (i = 0; attrs[i] != 0; i++) {
1129 an[i].an_desc = NULL;
1131 an[i].an_name.bv_val = slapi_ch_strdup(attrs[i]);
1132 an[i].an_name.bv_len = strlen(attrs[i]);
1133 slap_bv2ad( &an[i].an_name, &an[i].an_desc, &text );
1135 an[i].an_name.bv_val = NULL;
1138 memset( &rs, 0, sizeof(rs) );
1139 rs.sr_type = REP_RESULT;
1140 rs.sr_err = LDAP_SUCCESS;
1141 rs.sr_entry = NULL; /* paranoia */
1143 if ( scope == LDAP_SCOPE_BASE ) {
1146 if ( op->o_req_ndn.bv_len == 0 ) {
1147 rs.sr_err = root_dse_info( c, &rs.sr_entry, &rs.sr_text );
1150 if( rs.sr_err != LDAP_SUCCESS ) {
1151 send_ldap_result( op, &rs );
1153 } else if ( rs.sr_entry != NULL ) {
1154 rs.sr_err = test_filter( op, rs.sr_entry, filter );
1156 if ( rs.sr_err == LDAP_COMPARE_TRUE ) {
1157 rs.sr_type = REP_SEARCH;
1158 rs.sr_err = LDAP_SUCCESS;
1161 send_search_entry( op, &rs );
1164 entry_free( rs.sr_entry );
1166 rs.sr_type = REP_RESULT;
1167 rs.sr_err = LDAP_SUCCESS;
1169 send_ldap_result( op, &rs );
1175 if ( !op->o_req_ndn.bv_len && default_search_nbase.bv_len ) {
1176 slapi_ch_free( (void **)op->o_req_dn.bv_val );
1177 slapi_ch_free( (void **)op->o_req_ndn.bv_val );
1179 ber_dupbv( &op->o_req_dn, &default_search_base );
1180 ber_dupbv( &op->o_req_ndn, &default_search_nbase );
1183 if ( slapi_control_present( controls,
1184 LDAP_CONTROL_MANAGEDSAIT, NULL, &isCritical ) ) {
1188 be = select_backend( &op->o_req_ndn, manageDsaIt, 0 );
1190 if ( manageDsaIt == 1 ) {
1191 rs.sr_err = LDAP_NO_SUCH_OBJECT;
1193 rs.sr_err = LDAP_PARTIAL_RESULTS;
1198 op->o_dn = c->c_dn = be->be_rootdn;
1199 op->o_ndn = c->c_ndn = be->be_rootndn;
1201 op->oq_search.rs_scope = scope;
1202 op->oq_search.rs_deref = 0;
1203 op->oq_search.rs_slimit = LDAP_NO_LIMIT;
1204 op->oq_search.rs_tlimit = LDAP_NO_LIMIT;
1205 op->oq_search.rs_attrsonly = attrsonly;
1206 op->oq_search.rs_attrs = an;
1207 op->oq_search.rs_filter = filter;
1208 op->oq_search.rs_filterstr = fstr;
1210 if ( be->be_search ) {
1211 if ( (*be->be_search)( op, &rs ) != 0 ) {
1212 rs.sr_err = LDAP_OTHER;
1215 rs.sr_err = LDAP_UNWILLING_TO_PERFORM;
1221 slapi_pblock_set( ptr, SLAPI_PLUGIN_INTOP_RESULT, (void *)rs.sr_err );
1224 slapi_ch_free( (void **)&dn.bv_val );
1226 slapi_filter_free( filter, 1 );
1228 slapi_ch_free( (void **)&fstr.bv_val );
1230 slapi_ch_free( (void **)&an );
1236 slapiConnectionDestroy( &c );
1241 #endif /* LDAP_SLAPI */
1245 slapi_search_internal(
1249 LDAPControl **controls,
1254 return slapi_search_internal_bind( NULL, base, scope, filStr,
1255 controls, attrs, attrsonly );
1258 #endif /* LDAP_SLAPI */