~ubuntu-branches/ubuntu/maverick/openldap/maverick-proposed

« back to all changes in this revision

Viewing changes to servers/slapd/overlays/rwm.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug, Steve Langasek, Mathias Gug
  • Date: 2009-02-18 18:44:00 UTC
  • mfrom: (1.1.2 upstream) (0.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20090218184400-zw4mjse9eywt5566
Tags: 2.4.14-0ubuntu1
[ Steve Langasek ]
* New upstream version
  - Fixes a bug with the pcache overlay not returning cached entries
    (closes: #497697)
  - Update evolution-ntlm patch to apply to current Makefiles.
  - (tentatively) drop gnutls-ciphers, since this bug was reported to be
    fixed upstream in 2.4.8.  The fix applied in 2.4.8 didn't match the
    patch from the bug report, so this should be watched for regressions.
* Build against db4.7 instead of db4.2 at last!  Closes: #421946.
* Build with --disable-ndb, to avoid a misbuild when libmysqlclient is
  installed in the build environment.
* New patch, no-crlcheck-for-gnutls, to fix a build failure when using
  --with-tls=gnutls.

[ Mathias Gug ]
* Merge from debian unstable, remaining changes:
  - debian/apparmor-profile: add AppArmor profile
  - debian/slapd.postinst: Reload AA profile on configuration
  - updated debian/slapd.README.Debian for note on AppArmor
  - debian/control: Recommends apparmor >= 2.1+1075-0ubuntu6
  - debian/control: Conflicts with apparmor-profiles << 2.1+1075-0ubuntu4
    to make sure that if earlier version of apparmour-profiles gets
    installed it won't overwrite our profile.
  - Modify Maintainer value to match the DebianMaintainerField
    speficication.
  - follow ApparmorProfileMigration and force apparmor compalin mode on 
    some upgrades (LP: #203529)
  - debian/slapd.dirs: add etc/apparmor.d/force-complain
  - debian/slapd.preinst: create symlink for force-complain on pre-feisty
    upgrades, upgrades where apparmor-profiles profile is unchanged (ie
    non-enforcing) and upgrades where apparmor profile does not exist.
  - debian/slapd.postrm: remove symlink in force-complain/ on purge
  - debian/patches/fix-ucred-libc due to changes how newer glibc handle
    the ucred struct now.
  - debian/control:
    - Build-depend on libltdl7-dev rather then libltdl3-dev.
  - debian/patches/autogen.sh:
    - Call libtoolize with the --install option to install config.{guess,sub}
      files.
  - Don't use local statement in config script as it fails if /bin/sh
    points to bash (LP: #286063).
  - Disable the testsuite on hppa. Allows building of packages on this
    architecture again, once this package is in the archive.
    LP: #288908.
  - debian/slapd.postinst, debian/slapd.script-common: set correct ownership
    and permissions on /var/lib/ldap, /etc/ldap/slapd.d (group readable) and
    /var/run/slapd (world readable). (LP: #257667).
  - debian/patches/nssov-build, debian/rules: 
    Build and package the nss overlay.
    debian/schema/misc.ldif: add ldif file for the misc schema, which defines
    rfc822MailMember (required by the nss overlay).
  - debian/{control,rules}: enable PIE hardening
  - Use cn=config as the default configuration backend instead of 
    slapd.conf. Migrate slapd.conf  file to /etc/ldap/slapd.d/ on upgrade
    asking the end user to enter a new password to control the access to the
    cn=config tree.
* debian/patches/corrupt-contextCSN: The contextCSN can get corrupted at
  times. (ITS: #5947)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* rwm.c - rewrite/remap operations */
2
 
/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/rwm.c,v 1.70.2.10 2008/02/15 18:11:46 quanah Exp $ */
 
2
/* $OpenLDAP: pkg/ldap/servers/slapd/overlays/rwm.c,v 1.70.2.22 2009/02/13 03:16:59 quanah Exp $ */
3
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
4
 *
5
 
 * Copyright 2003-2008 The OpenLDAP Foundation.
 
5
 * Copyright 2003-2009 The OpenLDAP Foundation.
6
6
 * Portions Copyright 2003 Pierangelo Masarati.
7
7
 * All rights reserved.
8
8
 *
38
38
        OpRequest o_request;
39
39
} rwm_op_state;
40
40
 
41
 
static int
42
 
rwm_db_destroy( BackendDB *be, ConfigReply *cr );
43
 
 
44
41
typedef struct rwm_op_cb {
45
42
        slap_callback cb;
46
43
        rwm_op_state ros;
47
44
} rwm_op_cb;
48
45
 
49
46
static int
 
47
rwm_db_destroy( BackendDB *be, ConfigReply *cr );
 
48
 
 
49
static int
 
50
rwm_send_entry( Operation *op, SlapReply *rs );
 
51
 
 
52
static void
 
53
rwm_op_rollback( Operation *op, SlapReply *rs, rwm_op_state *ros )
 
54
{
 
55
        if ( !BER_BVISNULL( &ros->ro_dn ) ) {
 
56
                op->o_req_dn = ros->ro_dn;
 
57
        }
 
58
        if ( !BER_BVISNULL( &ros->ro_ndn ) ) {
 
59
                op->o_req_ndn = ros->ro_ndn;
 
60
        }
 
61
 
 
62
        if ( !BER_BVISNULL( &ros->r_dn )
 
63
                && ros->r_dn.bv_val != ros->ro_dn.bv_val )
 
64
        {
 
65
                assert( ros->r_dn.bv_val != ros->r_ndn.bv_val );
 
66
                ch_free( ros->r_dn.bv_val );
 
67
                BER_BVZERO( &ros->r_dn );
 
68
        }
 
69
 
 
70
        if ( !BER_BVISNULL( &ros->r_ndn )
 
71
                && ros->r_ndn.bv_val != ros->ro_ndn.bv_val )
 
72
        {
 
73
                ch_free( ros->r_ndn.bv_val );
 
74
                BER_BVZERO( &ros->r_ndn );
 
75
        }
 
76
 
 
77
        BER_BVZERO( &ros->ro_dn );
 
78
        BER_BVZERO( &ros->ro_ndn );
 
79
 
 
80
        switch( ros->r_tag ) {
 
81
        case LDAP_REQ_COMPARE:
 
82
                if ( op->orc_ava->aa_value.bv_val != ros->orc_ava->aa_value.bv_val )
 
83
                        op->o_tmpfree( op->orc_ava->aa_value.bv_val, op->o_tmpmemctx );
 
84
                op->orc_ava = ros->orc_ava;
 
85
                break;
 
86
        case LDAP_REQ_MODIFY:
 
87
                slap_mods_free( op->orm_modlist, 1 );
 
88
                op->orm_modlist = ros->orm_modlist;
 
89
                break;
 
90
        case LDAP_REQ_MODRDN:
 
91
                if ( op->orr_newSup != ros->orr_newSup ) {
 
92
                        ch_free( op->orr_newSup->bv_val );
 
93
                        ch_free( op->orr_nnewSup->bv_val );
 
94
                        op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
 
95
                        op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
 
96
                        op->orr_newSup = ros->orr_newSup;
 
97
                        op->orr_nnewSup = ros->orr_nnewSup;
 
98
                }
 
99
                if ( op->orr_newrdn.bv_val != ros->orr_newrdn.bv_val ) {
 
100
                        ch_free( op->orr_newrdn.bv_val );
 
101
                        ch_free( op->orr_nnewrdn.bv_val );
 
102
                        op->orr_newrdn = ros->orr_newrdn;
 
103
                        op->orr_nnewrdn = ros->orr_nnewrdn;
 
104
                }
 
105
                break;
 
106
        case LDAP_REQ_SEARCH:
 
107
                ch_free( ros->mapped_attrs );
 
108
                filter_free_x( op, op->ors_filter, 1 );
 
109
                ch_free( op->ors_filterstr.bv_val );
 
110
                op->ors_attrs = ros->ors_attrs;
 
111
                op->ors_filter = ros->ors_filter;
 
112
                op->ors_filterstr = ros->ors_filterstr;
 
113
                break;
 
114
        case LDAP_REQ_EXTENDED:
 
115
                if ( op->ore_reqdata != ros->ore_reqdata ) {
 
116
                        ber_bvfree( op->ore_reqdata );
 
117
                        op->ore_reqdata = ros->ore_reqdata;
 
118
                }
 
119
                break;
 
120
        case LDAP_REQ_BIND:
 
121
                if ( rs->sr_err == LDAP_SUCCESS ) {
 
122
#if 0
 
123
                        ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
 
124
                        /* too late, c_mutex released */
 
125
                        fprintf( stderr, "*** DN: \"%s\" => \"%s\"\n",
 
126
                                op->o_conn->c_ndn.bv_val,
 
127
                                op->o_req_ndn.bv_val );
 
128
                        ber_bvreplace( &op->o_conn->c_ndn,
 
129
                                &op->o_req_ndn );
 
130
                        ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
 
131
#endif
 
132
                }
 
133
                break;
 
134
        default:        break;
 
135
        }
 
136
}
 
137
 
 
138
static int
50
139
rwm_op_cleanup( Operation *op, SlapReply *rs )
51
140
{
52
141
        slap_callback   *cb = op->o_callback;
53
142
        rwm_op_state *ros = cb->sc_private;
54
143
 
55
144
        if ( rs->sr_type == REP_RESULT || rs->sr_type == REP_EXTENDED ||
56
 
                op->o_abandon || rs->sr_err == SLAPD_ABANDON ) {
57
 
 
58
 
                op->o_req_dn = ros->ro_dn;
59
 
                op->o_req_ndn = ros->ro_ndn;
60
 
 
61
 
                if ( !BER_BVISNULL( &ros->r_dn )
62
 
                        && ros->r_dn.bv_val != ros->r_ndn.bv_val )
63
 
                {
64
 
                        ch_free( ros->r_dn.bv_val );
65
 
                        BER_BVZERO( &ros->r_dn );
66
 
                }
67
 
 
68
 
                if ( !BER_BVISNULL( &ros->r_ndn ) ) {
69
 
                        ch_free( ros->r_ndn.bv_val );
70
 
                        BER_BVZERO( &ros->r_ndn );
71
 
                }
72
 
 
73
 
                switch( ros->r_tag ) {
74
 
                case LDAP_REQ_COMPARE:
75
 
                        if ( op->orc_ava->aa_value.bv_val != ros->orc_ava->aa_value.bv_val )
76
 
                                op->o_tmpfree( op->orc_ava->aa_value.bv_val, op->o_tmpmemctx );
77
 
                        op->orc_ava = ros->orc_ava;
78
 
                        break;
79
 
                case LDAP_REQ_MODIFY:
80
 
                        slap_mods_free( op->orm_modlist, 1 );
81
 
                        op->orm_modlist = ros->orm_modlist;
82
 
                        break;
83
 
                case LDAP_REQ_MODRDN:
84
 
                        if ( op->orr_newSup != ros->orr_newSup ) {
85
 
                                ch_free( op->orr_newSup->bv_val );
86
 
                                ch_free( op->orr_nnewSup->bv_val );
87
 
                                op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
88
 
                                op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
89
 
                                op->orr_newSup = ros->orr_newSup;
90
 
                                op->orr_nnewSup = ros->orr_nnewSup;
91
 
                        }
92
 
                        break;
93
 
                case LDAP_REQ_SEARCH:
94
 
                        ch_free( ros->mapped_attrs );
95
 
                        filter_free_x( op, op->ors_filter );
96
 
                        ch_free( op->ors_filterstr.bv_val );
97
 
                        op->ors_attrs = ros->ors_attrs;
98
 
                        op->ors_filter = ros->ors_filter;
99
 
                        op->ors_filterstr = ros->ors_filterstr;
100
 
                        break;
101
 
                case LDAP_REQ_EXTENDED:
102
 
                        if ( op->ore_reqdata != ros->ore_reqdata ) {
103
 
                                ber_bvfree( op->ore_reqdata );
104
 
                                op->ore_reqdata = ros->ore_reqdata;
105
 
                        }
106
 
                        break;
107
 
                default:        break;
108
 
                }
 
145
                op->o_abandon || rs->sr_err == SLAPD_ABANDON )
 
146
        {
 
147
                rwm_op_rollback( op, rs, ros );
 
148
 
109
149
                op->o_callback = op->o_callback->sc_next;
110
150
                op->o_tmpfree( cb, op->o_tmpmemctx );
111
151
        }
179
219
 
180
220
        if ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val ) {
181
221
                op->o_req_dn = dn;
 
222
                assert( BER_BVISNULL( &ros->r_dn ) );
182
223
                ros->r_dn = dn;
183
224
        } else {
184
225
                op->o_req_dn = ndn;
185
226
        }
186
227
        op->o_req_ndn = ndn;
 
228
        assert( BER_BVISNULL( &ros->r_ndn ) );
187
229
        ros->r_ndn = ndn;
188
230
 
189
231
        return LDAP_SUCCESS;
354
396
                return -1;
355
397
        }
356
398
 
357
 
        op->o_callback = &roc->cb;
 
399
        overlay_callback_after_backover( op, &roc->cb, 1 );
358
400
 
359
401
        return SLAP_CB_CONTINUE;
360
402
}
648
690
                        (struct ldaprwmap *)on->on_bi.bi_private;
649
691
        
650
692
        int                     rc;
 
693
        dncookie                dc;
651
694
 
652
695
        rwm_op_cb               *roc = rwm_callback_get( op, rs );
653
696
 
654
697
        if ( op->orr_newSup ) {
655
 
                dncookie        dc;
656
698
                struct berval   nnewSup = BER_BVNULL;
657
699
                struct berval   newSup = BER_BVNULL;
658
700
 
683
725
        }
684
726
 
685
727
        /*
 
728
         * Rewrite the newRDN, if needed
 
729
         */
 
730
        {
 
731
                struct berval   newrdn = BER_BVNULL;
 
732
                struct berval   nnewrdn = BER_BVNULL;
 
733
 
 
734
                dc.rwmap = rwmap;
 
735
                dc.conn = op->o_conn;
 
736
                dc.rs = rs;
 
737
                dc.ctx = "newRDN";
 
738
                newrdn = op->orr_newrdn;
 
739
                nnewrdn = op->orr_nnewrdn;
 
740
                rc = rwm_dn_massage_pretty_normalize( &dc, &op->orr_newrdn, &newrdn, &nnewrdn );
 
741
                if ( rc != LDAP_SUCCESS ) {
 
742
                        op->o_bd->bd_info = (BackendInfo *)on->on_info;
 
743
                        send_ldap_error( op, rs, rc, "newRDN massage error" );
 
744
                        goto err;
 
745
                }
 
746
 
 
747
                if ( op->orr_newrdn.bv_val != newrdn.bv_val ) {
 
748
                        op->orr_newrdn = newrdn;
 
749
                        op->orr_nnewrdn = nnewrdn;
 
750
                }
 
751
        }
 
752
 
 
753
        /*
686
754
         * Rewrite the dn, if needed
687
755
         */
688
756
        rc = rwm_op_dn_massage( op, rs, "renameDN", &roc->ros );
689
757
        if ( rc != LDAP_SUCCESS ) {
690
758
                op->o_bd->bd_info = (BackendInfo *)on->on_info;
691
759
                send_ldap_error( op, rs, rc, "renameDN massage error" );
 
760
                goto err;
 
761
        }
 
762
 
 
763
        op->o_callback = &roc->cb;
 
764
 
 
765
        rc = SLAP_CB_CONTINUE;
 
766
 
 
767
        if ( 0 ) {
 
768
err:;
692
769
                if ( op->orr_newSup != roc->ros.orr_newSup ) {
693
770
                        ch_free( op->orr_newSup->bv_val );
694
771
                        ch_free( op->orr_nnewSup->bv_val );
697
774
                        op->orr_newSup = roc->ros.orr_newSup;
698
775
                        op->orr_nnewSup = roc->ros.orr_nnewSup;
699
776
                }
700
 
                return -1;
 
777
 
 
778
                if ( op->orr_newrdn.bv_val != roc->ros.orr_newrdn.bv_val ) {
 
779
                        ch_free( op->orr_newrdn.bv_val );
 
780
                        ch_free( op->orr_nnewrdn.bv_val );
 
781
                        op->orr_newrdn = roc->ros.orr_newrdn;
 
782
                        op->orr_nnewrdn = roc->ros.orr_nnewrdn;
 
783
                }
701
784
        }
702
785
 
703
 
        /* TODO: rewrite newRDN, attribute types, 
704
 
         * values of DN-valued attributes ... */
705
 
 
706
 
        op->o_callback = &roc->cb;
707
 
 
708
 
        return SLAP_CB_CONTINUE;
 
786
        return rc;
709
787
}
710
788
 
711
789
 
725
803
        return SLAP_CB_CONTINUE;
726
804
}
727
805
 
 
806
/*
 
807
 * NOTE: this implementation of get/release entry is probably far from
 
808
 * optimal.  The rationale consists in intercepting the request directed
 
809
 * to the underlying database, in order to rewrite/remap the request,
 
810
 * perform it using the modified data, duplicate the resulting entry
 
811
 * and finally free it when release is called.
 
812
 * This implies that subsequent overlays are not called, as the request
 
813
 * is directly shunted to the underlying database.
 
814
 */
 
815
static int
 
816
rwm_entry_release_rw( Operation *op, Entry *e, int rw )
 
817
{
 
818
        slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
 
819
 
 
820
        /* can't be ours */
 
821
        if ( ((BackendInfo *)on->on_info->oi_orig)->bi_entry_get_rw == NULL ) {
 
822
                return SLAP_CB_CONTINUE;
 
823
        }
 
824
 
 
825
        /* just free entry if (probably) ours */
 
826
        if ( e->e_private == NULL ) {
 
827
                entry_free( e );
 
828
                return LDAP_SUCCESS;
 
829
        }
 
830
 
 
831
        return SLAP_CB_CONTINUE;
 
832
}
 
833
 
 
834
static int
 
835
rwm_entry_get_rw( Operation *op, struct berval *ndn,
 
836
        ObjectClass *oc, AttributeDescription *at, int rw, Entry **ep )
 
837
{
 
838
        slap_overinst           *on = (slap_overinst *) op->o_bd->bd_info;
 
839
        struct ldaprwmap        *rwmap = 
 
840
                        (struct ldaprwmap *)on->on_bi.bi_private;
 
841
 
 
842
        int                     rc;
 
843
        dncookie                dc;
 
844
 
 
845
        BackendDB               db;
 
846
        Operation               op2;
 
847
        SlapReply               rs = { REP_SEARCH };
 
848
 
 
849
        rwm_op_state            ros = { 0 };
 
850
 
 
851
        if ( ((BackendInfo *)on->on_info->oi_orig)->bi_entry_get_rw == NULL ) {
 
852
                return SLAP_CB_CONTINUE;
 
853
        }
 
854
 
 
855
        /* massage DN */
 
856
        op2.o_tag = LDAP_REQ_SEARCH;
 
857
        op2 = *op;
 
858
        op2.o_req_dn = *ndn;
 
859
        op2.o_req_ndn = *ndn;
 
860
        rc = rwm_op_dn_massage( &op2, &rs, "searchDN", &ros );
 
861
        if ( rc != LDAP_SUCCESS ) {
 
862
                return LDAP_OTHER;
 
863
        }
 
864
 
 
865
        /* map attribute & objectClass */
 
866
        if ( at != NULL ) {
 
867
        }
 
868
 
 
869
        if ( oc != NULL ) {
 
870
        }
 
871
 
 
872
        /* fetch entry */
 
873
        db = *op->o_bd;
 
874
        op2.o_bd = &db;
 
875
        op2.o_bd->bd_info = (BackendInfo *)on->on_info->oi_orig;
 
876
        op2.ors_attrs = slap_anlist_all_attributes;
 
877
        rc = op2.o_bd->bd_info->bi_entry_get_rw( &op2, &ros.r_ndn, oc, at, rw, ep );
 
878
        if ( rc == LDAP_SUCCESS && *ep != NULL ) {
 
879
                rs.sr_entry = *ep;
 
880
 
 
881
                /* duplicate & release */
 
882
                op2.o_bd->bd_info = (BackendInfo *)on;
 
883
                rc = rwm_send_entry( &op2, &rs );
 
884
                if ( rc == SLAP_CB_CONTINUE ) {
 
885
                        *ep = rs.sr_entry;
 
886
                        rc = LDAP_SUCCESS;
 
887
                }
 
888
        }
 
889
 
 
890
        if ( ros.r_ndn.bv_val != ndn->bv_val ) {
 
891
                op->o_tmpfree( ros.r_ndn.bv_val, op->o_tmpmemctx );
 
892
        }
 
893
 
 
894
        return rc;
 
895
}
 
896
 
728
897
static int
729
898
rwm_op_search( Operation *op, SlapReply *rs )
730
899
{
800
969
        }
801
970
 
802
971
        if ( f != NULL ) {
803
 
                filter_free_x( op, f );
 
972
                filter_free_x( op, f, 1 );
804
973
        }
805
974
 
806
975
        if ( !BER_BVISNULL( &fstr ) ) {
807
976
                ch_free( fstr.bv_val );
808
977
        }
809
978
 
 
979
        rwm_op_rollback( op, rs, &roc->ros );
810
980
        op->oq_search = roc->ros.oq_search;
 
981
        op->o_tmpfree( roc, op->o_tmpmemctx );
811
982
 
812
983
        op->o_bd->bd_info = (BackendInfo *)on->on_info;
813
984
        send_ldap_error( op, rs, rc, text );
1049
1220
 
1050
1221
                                /* try to normalize mapped Attributes if the original 
1051
1222
                                 * AttributeType was not normalized */
1052
 
                                if ((rwmap->rwm_flags & RWM_F_NORMALIZE_MAPPED_ATTRS) && 
1053
 
                                        (!(*ap)->a_desc->ad_type->sat_equality || 
 
1223
                                if ( (!(*ap)->a_desc->ad_type->sat_equality || 
1054
1224
                                        !(*ap)->a_desc->ad_type->sat_equality->smr_normalize) &&
1055
1225
                                        mapping->m_dst_ad->ad_type->sat_equality &&
1056
1226
                                        mapping->m_dst_ad->ad_type->sat_equality->smr_normalize )
1057
1227
                                {
1058
 
                                        int i = 0;
1059
 
 
1060
 
                                        last = (*ap)->a_numvals;
1061
 
                                        if ( last )
 
1228
                                        if ((rwmap->rwm_flags & RWM_F_NORMALIZE_MAPPED_ATTRS))
1062
1229
                                        {
1063
 
                                                (*ap)->a_nvals = ch_malloc( (last+1) * sizeof(struct berval) );
1064
 
 
1065
 
                                                for ( i = 0; !BER_BVISNULL( &(*ap)->a_vals[i]); i++ ) {
1066
 
                                                        int             rc;
1067
 
                                                        /*
1068
 
                                                         * check that each value is valid per syntax
1069
 
                                                         * and pretty if appropriate
1070
 
                                                         */
1071
 
                                                        rc = mapping->m_dst_ad->ad_type->sat_equality->smr_normalize(
1072
 
                                                                SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
1073
 
                                                                mapping->m_dst_ad->ad_type->sat_syntax,
1074
 
                                                                mapping->m_dst_ad->ad_type->sat_equality,
1075
 
                                                                &(*ap)->a_vals[i], &(*ap)->a_nvals[i],
1076
 
                                                                NULL );
1077
 
 
1078
 
                                                        if ( rc != LDAP_SUCCESS ) {
1079
 
                                                                BER_BVZERO( &(*ap)->a_nvals[i] );
 
1230
                                                int i = 0;
 
1231
 
 
1232
                                                last = (*ap)->a_numvals;
 
1233
                                                if ( last )
 
1234
                                                {
 
1235
                                                        (*ap)->a_nvals = ch_malloc( (last+1) * sizeof(struct berval) );
 
1236
 
 
1237
                                                        for ( i = 0; !BER_BVISNULL( &(*ap)->a_vals[i]); i++ ) {
 
1238
                                                                int             rc;
 
1239
                                                                /*
 
1240
                                                                 * check that each value is valid per syntax
 
1241
                                                                 * and pretty if appropriate
 
1242
                                                                 */
 
1243
                                                                rc = mapping->m_dst_ad->ad_type->sat_equality->smr_normalize(
 
1244
                                                                        SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
 
1245
                                                                        mapping->m_dst_ad->ad_type->sat_syntax,
 
1246
                                                                        mapping->m_dst_ad->ad_type->sat_equality,
 
1247
                                                                        &(*ap)->a_vals[i], &(*ap)->a_nvals[i],
 
1248
                                                                        NULL );
 
1249
 
 
1250
                                                                if ( rc != LDAP_SUCCESS ) {
 
1251
                                                                        BER_BVZERO( &(*ap)->a_nvals[i] );
 
1252
                                                                }
1080
1253
                                                        }
 
1254
                                                        BER_BVZERO( &(*ap)->a_nvals[i] );
1081
1255
                                                }
1082
 
                                                BER_BVZERO( &(*ap)->a_nvals[i] );
 
1256
 
 
1257
                                        } else {
 
1258
                                                assert( (*ap)->a_nvals == (*ap)->a_vals );
 
1259
                                                (*ap)->a_nvals = NULL;
 
1260
                                                ber_bvarray_dup_x( &(*ap)->a_nvals, (*ap)->a_vals, NULL );
1083
1261
                                        }
1084
1262
                                }
1085
1263
 
1135
1313
                                        last--;
1136
1314
                                        bv--;
1137
1315
 
1138
 
                                } else if ( mapped.bv_val != bv[0].bv_val ) {
 
1316
                                } else if ( mapped.bv_val != bv[0].bv_val
 
1317
                                        && ber_bvstrcasecmp( &mapped, &bv[0] ) != 0 )
 
1318
                                {
1139
1319
                                        int     i;
1140
1320
 
1141
1321
                                        for ( i = 0; !BER_BVISNULL( &(*ap)->a_vals[ i ] ); i++ ) {
1181
1361
                                || ( mapping != NULL && mapping->m_src_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )
1182
1362
                {
1183
1363
                        dc.ctx = "searchAttrDN";
1184
 
                        rc = rwm_dnattr_result_rewrite( &dc, (*ap)->a_vals );
 
1364
                        rc = rwm_dnattr_result_rewrite( &dc, (*ap)->a_vals, (*ap)->a_nvals );
1185
1365
                        if ( rc != LDAP_SUCCESS ) {
1186
1366
                                goto cleanup_attr;
1187
1367
                        }
1325
1505
        (void)rwm_attrs( op, rs, &e->e_attrs, 1 );
1326
1506
 
1327
1507
        if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
1328
 
                be_entry_release_rw( op, rs->sr_entry, 0 );
 
1508
                overlay_entry_release_ov( op, rs->sr_entry, 0, on );
1329
1509
        }
1330
1510
 
1331
1511
        rs->sr_entry = e;
1650
1830
enum {
1651
1831
        /* rewrite */
1652
1832
        RWM_CF_REWRITE = 1,
1653
 
        RWM_CF_SUFFIXMASSAGE,
1654
1833
 
1655
1834
        /* map */
1656
1835
        RWM_CF_MAP,
1661
1840
};
1662
1841
 
1663
1842
static slap_verbmasks t_f_mode[] = {
 
1843
        { BER_BVC( "true" ),            RWM_F_SUPPORT_T_F },
1664
1844
        { BER_BVC( "yes" ),             RWM_F_SUPPORT_T_F },
1665
1845
        { BER_BVC( "discover" ),        RWM_F_SUPPORT_T_F_DISCOVER },
 
1846
        { BER_BVC( "false" ),           RWM_F_NONE },
1666
1847
        { BER_BVC( "no" ),              RWM_F_NONE },
1667
1848
        { BER_BVNULL,                   0 }
1668
1849
};
1672
1853
static ConfigTable rwmcfg[] = {
1673
1854
        { "rwm-rewrite", "rewrite",
1674
1855
                2, 0, STRLENOF("rwm-rewrite"),
1675
 
                ARG_MAGIC|ARG_QUOTE|RWM_CF_REWRITE, rwm_cf_gen,
 
1856
                ARG_MAGIC|RWM_CF_REWRITE, rwm_cf_gen,
1676
1857
                "( OLcfgOvAt:16.1 NAME 'olcRwmRewrite' "
1677
1858
                        "DESC 'Rewrites strings' "
1678
1859
                        "EQUALITY caseIgnoreMatch "
1681
1862
                NULL, NULL },
1682
1863
 
1683
1864
        { "rwm-suffixmassage", "[virtual]> <real",
1684
 
                2, 3, 0, ARG_MAGIC|RWM_CF_SUFFIXMASSAGE, rwm_cf_gen,
 
1865
                2, 3, 0, ARG_MAGIC|RWM_CF_REWRITE, rwm_cf_gen,
1685
1866
                NULL, NULL, NULL },
1686
1867
                
1687
1868
        { "rwm-t-f-support", "true|false|discover",
1767
1948
}
1768
1949
 
1769
1950
static int
 
1951
rwm_bva_rewrite_add(
 
1952
        struct ldaprwmap        *rwmap,
 
1953
        int                     idx,
 
1954
        const char              *argv[] )
 
1955
{
 
1956
        char            *line;
 
1957
        struct berval   bv;
 
1958
 
 
1959
        line = ldap_charray2str( argv, "\" \"" );
 
1960
        if ( line != NULL ) {
 
1961
                int     len = strlen( argv[ 0 ] );
 
1962
 
 
1963
                ber_str2bv( line, 0, 0, &bv );
 
1964
                AC_MEMCPY( &bv.bv_val[ len ], &bv.bv_val[ len + 1 ],
 
1965
                        bv.bv_len - ( len + 1 ) );
 
1966
                bv.bv_val[ bv.bv_len - 1 ] = '"';
 
1967
 
 
1968
                if ( idx == -1 ) {
 
1969
                        ber_bvarray_add( &rwmap->rwm_bva_rewrite, &bv );
 
1970
 
 
1971
                } else {
 
1972
                        rwmap->rwm_bva_rewrite[ idx ] = bv;
 
1973
                }
 
1974
        }
 
1975
 
 
1976
        return 0;
 
1977
}
 
1978
 
 
1979
static int
 
1980
rwm_info_init( struct rewrite_info ** rwm_rw )
 
1981
{
 
1982
        char                    *rargv[ 3 ];
 
1983
 
 
1984
        *rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
 
1985
        if ( *rwm_rw == NULL ) {
 
1986
                return -1;
 
1987
        }
 
1988
 
 
1989
        /* this rewriteContext by default must be null;
 
1990
         * rules can be added if required */
 
1991
        rargv[ 0 ] = "rewriteContext";
 
1992
        rargv[ 1 ] = "searchFilter";
 
1993
        rargv[ 2 ] = NULL;
 
1994
        rewrite_parse( *rwm_rw, "<suffix massage>", 1, 2, rargv );
 
1995
 
 
1996
        rargv[ 0 ] = "rewriteContext";
 
1997
        rargv[ 1 ] = "default";
 
1998
        rargv[ 2 ] = NULL;
 
1999
        rewrite_parse( *rwm_rw, "<suffix massage>", 2, 2, rargv );
 
2000
 
 
2001
        return 0;
 
2002
}
 
2003
 
 
2004
static int
1770
2005
rwm_cf_gen( ConfigArgs *c )
1771
2006
{
1772
2007
        slap_overinst           *on = (slap_overinst *)c->bi;
1775
2010
 
1776
2011
        BackendDB               db;
1777
2012
        char                    *argv0;
 
2013
        int                     idx0 = 0;
1778
2014
        int                     rc = 0;
1779
2015
 
1780
2016
        db = *c->be;
1832
2068
                switch ( c->type ) {
1833
2069
                case RWM_CF_REWRITE:
1834
2070
                        if ( c->valx >= 0 ) {
1835
 
                                /* single modification is not allowed */
1836
 
                                rc = 1;
 
2071
                                ConfigArgs ca = { 0 };
 
2072
                                int i;
 
2073
 
 
2074
                                for ( i = 0; !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ i ] ); i++ )
 
2075
                                        /* count'em */ ;
 
2076
 
 
2077
                                if ( i >= c->valx ) {
 
2078
                                        rc = 1;
 
2079
                                        break;
 
2080
                                }
 
2081
 
 
2082
                                ber_memfree( rwmap->rwm_bva_rewrite[ c->valx ].bv_val );
 
2083
                                for ( i = c->valx; !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ i + 1 ] ); i++ )
 
2084
                                {
 
2085
                                        rwmap->rwm_bva_rewrite[ i ] = rwmap->rwm_bva_rewrite[ i + 1 ];
 
2086
                                }
 
2087
                                BER_BVZERO( &rwmap->rwm_bva_rewrite[ i ] );
 
2088
 
 
2089
                                rewrite_info_delete( &rwmap->rwm_rw );
 
2090
                                assert( rwmap->rwm_rw == NULL );
 
2091
 
 
2092
                                rc = rwm_info_init( &rwmap->rwm_rw );
 
2093
 
 
2094
                                for ( i = 0; !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ i ] ); i++ )
 
2095
                                {
 
2096
                                        ca.line = rwmap->rwm_bva_rewrite[ i ].bv_val;
 
2097
                                        ca.argc = 0;
 
2098
                                        config_fp_parse_line( &ca );
 
2099
                                        
 
2100
                                        if ( strcasecmp( ca.argv[ 0 ], "suffixmassage" ) == 0 ) {
 
2101
                                                rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
 
2102
                                                        ca.argc, ca.argv );
 
2103
 
 
2104
                                        } else {
 
2105
                                                rc = rwm_rw_config( &db, c->fname, c->lineno,
 
2106
                                                        ca.argc, ca.argv );
 
2107
                                        }
 
2108
 
 
2109
                                        ch_free( ca.tline );
 
2110
 
 
2111
                                        assert( rc == 0 );
 
2112
                                }
1837
2113
 
1838
2114
                        } else if ( rwmap->rwm_rw != NULL ) {
1839
2115
                                rewrite_info_delete( &rwmap->rwm_rw );
1841
2117
 
1842
2118
                                ber_bvarray_free( rwmap->rwm_bva_rewrite );
1843
2119
                                rwmap->rwm_bva_rewrite = NULL;
 
2120
 
 
2121
                                rc = rwm_info_init( &rwmap->rwm_rw );
1844
2122
                        }
1845
2123
                        break;
1846
2124
 
1879
2157
                return rc;
1880
2158
        }
1881
2159
 
 
2160
        if ( strncasecmp( c->argv[ 0 ], "olcRwm", STRLENOF( "olcRwm" ) ) == 0 ) {
 
2161
                idx0 = 1;
 
2162
        }
 
2163
 
1882
2164
        switch ( c->type ) {
1883
2165
        case RWM_CF_REWRITE:
1884
 
                argv0 = c->argv[ 0 ];
1885
 
                c->argv[ 0 ] += STRLENOF( "rwm-" );
1886
 
                rc = rwm_rw_config( &db, c->fname, c->lineno, c->argc, c->argv );
1887
 
                c->argv[ 0 ] = argv0;
1888
 
                if ( rc ) {
1889
 
                        return 1;
1890
 
 
1891
 
                } else {
1892
 
                        char            *line;
1893
 
                        struct berval   bv;
1894
 
 
1895
 
                        line = ldap_charray2str( c->argv, "\" \"" );
1896
 
                        if ( line != NULL ) {
1897
 
                                int     len = strlen( c->argv[ 0 ] );
1898
 
 
1899
 
                                ber_str2bv( line, 0, 0, &bv );
1900
 
                                AC_MEMCPY( &bv.bv_val[ len ], &bv.bv_val[ len + 1 ],
1901
 
                                        bv.bv_len - ( len + 1 ) );
1902
 
                                bv.bv_val[ bv.bv_len - 1 ] = '"';
1903
 
                                ber_bvarray_add( &rwmap->rwm_bva_rewrite, &bv );
1904
 
                        }
1905
 
                }
1906
 
                break;
1907
 
 
1908
 
        case RWM_CF_SUFFIXMASSAGE:
1909
 
                argv0 = c->argv[ 0 ];
1910
 
                c->argv[ 0 ] += STRLENOF( "rwm-" );
1911
 
                rc = rwm_suffixmassage_config( &db, c->fname, c->lineno, c->argc, c->argv );
1912
 
                c->argv[ 0 ] = argv0;
1913
 
                if ( rc ) {
1914
 
                        return 1;
1915
 
 
1916
 
                } else {
1917
 
                        char            *line;
1918
 
                        struct berval   bv;
1919
 
 
1920
 
                        /* FIXME: not optimal; in fact, this keeps track
1921
 
                         * of the fact that a set of rules was added
1922
 
                         * using the rwm-suffixmassage shortcut, but the
1923
 
                         * rules are not clarified */
1924
 
 
1925
 
                        line = ldap_charray2str( c->argv, "\" \"" );
1926
 
                        if ( line != NULL ) {
1927
 
                                int     len = strlen( c->argv[ 0 ] );
1928
 
 
1929
 
                                ber_str2bv( line, 0, 0, &bv );
1930
 
                                AC_MEMCPY( &bv.bv_val[ len ], &bv.bv_val[ len + 1 ],
1931
 
                                        bv.bv_len - ( len + 1 ) );
1932
 
                                bv.bv_val[ bv.bv_len - 1 ] = '"';
1933
 
                                ber_bvarray_add( &rwmap->rwm_bva_rewrite, &bv );
1934
 
                        }
 
2166
                if ( c->valx >= 0 ) {
 
2167
                        struct rewrite_info *rwm_rw = rwmap->rwm_rw;
 
2168
                        ConfigArgs ca = { 0 };
 
2169
                        int i, last;
 
2170
 
 
2171
                        for ( last = 0; !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ last ] ); last++ )
 
2172
                                /* count'em */ ;
 
2173
 
 
2174
                        if ( c->valx > last ) {
 
2175
                                c->valx = last;
 
2176
                        }
 
2177
 
 
2178
                        rwmap->rwm_rw = NULL;
 
2179
                        rc = rwm_info_init( &rwmap->rwm_rw );
 
2180
 
 
2181
                        for ( i = 0; i < c->valx; i++ ) {
 
2182
                                ca.line = rwmap->rwm_bva_rewrite[ i ].bv_val;
 
2183
                                ca.argc = 0;
 
2184
                                config_fp_parse_line( &ca );
 
2185
 
 
2186
                                argv0 = ca.argv[ 0 ];
 
2187
                                ca.argv[ 0 ] += STRLENOF( "rwm-" );
 
2188
                                
 
2189
                                if ( strcasecmp( ca.argv[ 0 ], "suffixmassage" ) == 0 ) {
 
2190
                                        rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
 
2191
                                                ca.argc, ca.argv );
 
2192
 
 
2193
                                } else {
 
2194
                                        rc = rwm_rw_config( &db, c->fname, c->lineno,
 
2195
                                                ca.argc, ca.argv );
 
2196
                                }
 
2197
 
 
2198
                                ca.argv[ 0 ] = argv0;
 
2199
 
 
2200
                                ch_free( ca.tline );
 
2201
 
 
2202
                                assert( rc == 0 );
 
2203
                        }
 
2204
 
 
2205
                        argv0 = c->argv[ idx0 ];
 
2206
                        if ( strncasecmp( argv0, "rwm-", STRLENOF( "rwm-" ) ) != 0 ) {
 
2207
                                return 1;
 
2208
                        }
 
2209
                        c->argv[ idx0 ] += STRLENOF( "rwm-" );
 
2210
                        if ( strcasecmp( c->argv[ idx0 ], "suffixmassage" ) == 0 ) {
 
2211
                                rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
 
2212
                                        c->argc - idx0, &c->argv[ idx0 ] );
 
2213
 
 
2214
                        } else {
 
2215
                                rc = rwm_rw_config( &db, c->fname, c->lineno,
 
2216
                                        c->argc - idx0, &c->argv[ idx0 ] );
 
2217
                        }
 
2218
                        c->argv[ idx0 ] = argv0;
 
2219
                        if ( rc != 0 ) {
 
2220
                                rewrite_info_delete( &rwmap->rwm_rw );
 
2221
                                assert( rwmap->rwm_rw == NULL );
 
2222
 
 
2223
                                rwmap->rwm_rw = rwm_rw;
 
2224
                                return 1;
 
2225
                        }
 
2226
 
 
2227
                        for ( i = c->valx; !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ i ] ); i++ )
 
2228
                        {
 
2229
                                ca.line = rwmap->rwm_bva_rewrite[ i ].bv_val;
 
2230
                                ca.argc = 0;
 
2231
                                config_fp_parse_line( &ca );
 
2232
                                
 
2233
                                argv0 = ca.argv[ 0 ];
 
2234
                                ca.argv[ 0 ] += STRLENOF( "rwm-" );
 
2235
                                
 
2236
                                if ( strcasecmp( ca.argv[ 0 ], "suffixmassage" ) == 0 ) {
 
2237
                                        rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
 
2238
                                                ca.argc, ca.argv );
 
2239
 
 
2240
                                } else {
 
2241
                                        rc = rwm_rw_config( &db, c->fname, c->lineno,
 
2242
                                                ca.argc, ca.argv );
 
2243
                                }
 
2244
 
 
2245
                                ca.argv[ 0 ] = argv0;
 
2246
 
 
2247
                                ch_free( ca.tline );
 
2248
 
 
2249
                                assert( rc == 0 );
 
2250
                        }
 
2251
 
 
2252
                        rwmap->rwm_bva_rewrite = ch_realloc( rwmap->rwm_bva_rewrite,
 
2253
                                ( last + 2 )*sizeof( struct berval ) );
 
2254
 
 
2255
                        for ( i = last - 1; i >= c->valx; i-- )
 
2256
                        {
 
2257
                                rwmap->rwm_bva_rewrite[ i + 1 ] = rwmap->rwm_bva_rewrite[ i ];
 
2258
                        }
 
2259
 
 
2260
                        rwm_bva_rewrite_add( rwmap, c->valx, &c->argv[ idx0 ] );
 
2261
 
 
2262
                        rewrite_info_delete( &rwm_rw );
 
2263
                        assert( rwm_rw == NULL );
 
2264
 
 
2265
                        break;
 
2266
                }
 
2267
 
 
2268
                argv0 = c->argv[ idx0 ];
 
2269
                if ( strncasecmp( argv0, "rwm-", STRLENOF( "rwm-" ) ) != 0 ) {
 
2270
                        return 1;
 
2271
                }
 
2272
                c->argv[ idx0 ] += STRLENOF( "rwm-" );
 
2273
                if ( strcasecmp( c->argv[ idx0 ], "suffixmassage" ) == 0 ) {
 
2274
                        rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
 
2275
                                c->argc - idx0, &c->argv[ idx0 ] );
 
2276
 
 
2277
                } else {
 
2278
                        rc = rwm_rw_config( &db, c->fname, c->lineno,
 
2279
                                c->argc - idx0, &c->argv[ idx0 ] );
 
2280
                }
 
2281
                c->argv[ idx0 ] = argv0;
 
2282
                if ( rc ) {
 
2283
                        return 1;
 
2284
 
 
2285
                } else {
 
2286
                        rwm_bva_rewrite_add( rwmap, -1, &c->argv[ idx0 ] );
1935
2287
                }
1936
2288
                break;
1937
2289
 
1947
2299
                break;
1948
2300
 
1949
2301
        case RWM_CF_MAP:
 
2302
                if ( c->valx >= 0 ) {
 
2303
                        return 1;
 
2304
                }
 
2305
 
1950
2306
                argv0 = c->argv[ 0 ];
1951
2307
                c->argv[ 0 ] += STRLENOF( "rwm-" );
1952
2308
                rc = rwm_m_config( &db, c->fname, c->lineno, c->argc, c->argv );
1989
2345
{
1990
2346
        slap_overinst           *on = (slap_overinst *) be->bd_info;
1991
2347
        struct ldaprwmap        *rwmap;
1992
 
        char                    *rargv[ 3 ];
1993
2348
        int                     rc = 0;
1994
2349
 
1995
2350
        rwmap = (struct ldaprwmap *)ch_calloc( 1, sizeof( struct ldaprwmap ) );
1996
2351
 
1997
 
        rwmap->rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
1998
 
        if ( rwmap->rwm_rw == NULL ) {
1999
 
                rc = -1;
2000
 
                goto error_return;
2001
 
        }
2002
 
 
2003
 
        /* this rewriteContext by default must be null;
2004
 
         * rules can be added if required */
2005
 
        rargv[ 0 ] = "rewriteContext";
2006
 
        rargv[ 1 ] = "searchFilter";
2007
 
        rargv[ 2 ] = NULL;
2008
 
        rewrite_parse( rwmap->rwm_rw, "<suffix massage>", 1, 2, rargv );
2009
 
 
2010
 
        rargv[ 0 ] = "rewriteContext";
2011
 
        rargv[ 1 ] = "default";
2012
 
        rargv[ 2 ] = NULL;
2013
 
        rewrite_parse( rwmap->rwm_rw, "<suffix massage>", 2, 2, rargv );
 
2352
        rc = rwm_info_init( &rwmap->rwm_rw );
2014
2353
 
2015
2354
error_return:;
2016
2355
        on->on_bi.bi_private = (void *)rwmap;
2084
2423
        rwm.on_bi.bi_op_delete = rwm_op_delete;
2085
2424
        rwm.on_bi.bi_op_unbind = rwm_op_unbind;
2086
2425
        rwm.on_bi.bi_extended = rwm_extended;
 
2426
#if 1 /* TODO */
 
2427
        rwm.on_bi.bi_entry_release_rw = rwm_entry_release_rw;
 
2428
        rwm.on_bi.bi_entry_get_rw = rwm_entry_get_rw;
 
2429
#endif
2087
2430
 
2088
2431
        rwm.on_bi.bi_operational = rwm_operational;
2089
2432
        rwm.on_bi.bi_chk_referrals = 0 /* rwm_chk_referrals */ ;