38
38
OpRequest o_request;
42
rwm_db_destroy( BackendDB *be, ConfigReply *cr );
44
41
typedef struct rwm_op_cb {
47
rwm_db_destroy( BackendDB *be, ConfigReply *cr );
50
rwm_send_entry( Operation *op, SlapReply *rs );
53
rwm_op_rollback( Operation *op, SlapReply *rs, rwm_op_state *ros )
55
if ( !BER_BVISNULL( &ros->ro_dn ) ) {
56
op->o_req_dn = ros->ro_dn;
58
if ( !BER_BVISNULL( &ros->ro_ndn ) ) {
59
op->o_req_ndn = ros->ro_ndn;
62
if ( !BER_BVISNULL( &ros->r_dn )
63
&& ros->r_dn.bv_val != ros->ro_dn.bv_val )
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 );
70
if ( !BER_BVISNULL( &ros->r_ndn )
71
&& ros->r_ndn.bv_val != ros->ro_ndn.bv_val )
73
ch_free( ros->r_ndn.bv_val );
74
BER_BVZERO( &ros->r_ndn );
77
BER_BVZERO( &ros->ro_dn );
78
BER_BVZERO( &ros->ro_ndn );
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;
87
slap_mods_free( op->orm_modlist, 1 );
88
op->orm_modlist = ros->orm_modlist;
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;
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;
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;
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;
121
if ( rs->sr_err == LDAP_SUCCESS ) {
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,
130
ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
50
139
rwm_op_cleanup( Operation *op, SlapReply *rs )
52
141
slap_callback *cb = op->o_callback;
53
142
rwm_op_state *ros = cb->sc_private;
55
144
if ( rs->sr_type == REP_RESULT || rs->sr_type == REP_EXTENDED ||
56
op->o_abandon || rs->sr_err == SLAPD_ABANDON ) {
58
op->o_req_dn = ros->ro_dn;
59
op->o_req_ndn = ros->ro_ndn;
61
if ( !BER_BVISNULL( &ros->r_dn )
62
&& ros->r_dn.bv_val != ros->r_ndn.bv_val )
64
ch_free( ros->r_dn.bv_val );
65
BER_BVZERO( &ros->r_dn );
68
if ( !BER_BVISNULL( &ros->r_ndn ) ) {
69
ch_free( ros->r_ndn.bv_val );
70
BER_BVZERO( &ros->r_ndn );
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;
80
slap_mods_free( op->orm_modlist, 1 );
81
op->orm_modlist = ros->orm_modlist;
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;
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;
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;
145
op->o_abandon || rs->sr_err == SLAPD_ABANDON )
147
rwm_op_rollback( op, rs, ros );
109
149
op->o_callback = op->o_callback->sc_next;
110
150
op->o_tmpfree( cb, op->o_tmpmemctx );
728
* Rewrite the newRDN, if needed
731
struct berval newrdn = BER_BVNULL;
732
struct berval nnewrdn = BER_BVNULL;
735
dc.conn = op->o_conn;
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" );
747
if ( op->orr_newrdn.bv_val != newrdn.bv_val ) {
748
op->orr_newrdn = newrdn;
749
op->orr_nnewrdn = nnewrdn;
686
754
* Rewrite the dn, if needed
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" );
763
op->o_callback = &roc->cb;
765
rc = SLAP_CB_CONTINUE;
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 );
725
803
return SLAP_CB_CONTINUE;
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.
816
rwm_entry_release_rw( Operation *op, Entry *e, int rw )
818
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
821
if ( ((BackendInfo *)on->on_info->oi_orig)->bi_entry_get_rw == NULL ) {
822
return SLAP_CB_CONTINUE;
825
/* just free entry if (probably) ours */
826
if ( e->e_private == NULL ) {
831
return SLAP_CB_CONTINUE;
835
rwm_entry_get_rw( Operation *op, struct berval *ndn,
836
ObjectClass *oc, AttributeDescription *at, int rw, Entry **ep )
838
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
839
struct ldaprwmap *rwmap =
840
(struct ldaprwmap *)on->on_bi.bi_private;
847
SlapReply rs = { REP_SEARCH };
849
rwm_op_state ros = { 0 };
851
if ( ((BackendInfo *)on->on_info->oi_orig)->bi_entry_get_rw == NULL ) {
852
return SLAP_CB_CONTINUE;
856
op2.o_tag = LDAP_REQ_SEARCH;
859
op2.o_req_ndn = *ndn;
860
rc = rwm_op_dn_massage( &op2, &rs, "searchDN", &ros );
861
if ( rc != LDAP_SUCCESS ) {
865
/* map attribute & objectClass */
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 ) {
881
/* duplicate & release */
882
op2.o_bd->bd_info = (BackendInfo *)on;
883
rc = rwm_send_entry( &op2, &rs );
884
if ( rc == SLAP_CB_CONTINUE ) {
890
if ( ros.r_ndn.bv_val != ndn->bv_val ) {
891
op->o_tmpfree( ros.r_ndn.bv_val, op->o_tmpmemctx );
729
898
rwm_op_search( Operation *op, SlapReply *rs )
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 )
1060
last = (*ap)->a_numvals;
1228
if ((rwmap->rwm_flags & RWM_F_NORMALIZE_MAPPED_ATTRS))
1063
(*ap)->a_nvals = ch_malloc( (last+1) * sizeof(struct berval) );
1065
for ( i = 0; !BER_BVISNULL( &(*ap)->a_vals[i]); i++ ) {
1068
* check that each value is valid per syntax
1069
* and pretty if appropriate
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],
1078
if ( rc != LDAP_SUCCESS ) {
1079
BER_BVZERO( &(*ap)->a_nvals[i] );
1232
last = (*ap)->a_numvals;
1235
(*ap)->a_nvals = ch_malloc( (last+1) * sizeof(struct berval) );
1237
for ( i = 0; !BER_BVISNULL( &(*ap)->a_vals[i]); i++ ) {
1240
* check that each value is valid per syntax
1241
* and pretty if appropriate
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],
1250
if ( rc != LDAP_SUCCESS ) {
1251
BER_BVZERO( &(*ap)->a_nvals[i] );
1254
BER_BVZERO( &(*ap)->a_nvals[i] );
1082
BER_BVZERO( &(*ap)->a_nvals[i] );
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 );
1951
rwm_bva_rewrite_add(
1952
struct ldaprwmap *rwmap,
1954
const char *argv[] )
1959
line = ldap_charray2str( argv, "\" \"" );
1960
if ( line != NULL ) {
1961
int len = strlen( argv[ 0 ] );
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 ] = '"';
1969
ber_bvarray_add( &rwmap->rwm_bva_rewrite, &bv );
1972
rwmap->rwm_bva_rewrite[ idx ] = bv;
1980
rwm_info_init( struct rewrite_info ** rwm_rw )
1984
*rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
1985
if ( *rwm_rw == NULL ) {
1989
/* this rewriteContext by default must be null;
1990
* rules can be added if required */
1991
rargv[ 0 ] = "rewriteContext";
1992
rargv[ 1 ] = "searchFilter";
1994
rewrite_parse( *rwm_rw, "<suffix massage>", 1, 2, rargv );
1996
rargv[ 0 ] = "rewriteContext";
1997
rargv[ 1 ] = "default";
1999
rewrite_parse( *rwm_rw, "<suffix massage>", 2, 2, rargv );
1770
2005
rwm_cf_gen( ConfigArgs *c )
1772
2007
slap_overinst *on = (slap_overinst *)c->bi;
1832
2068
switch ( c->type ) {
1833
2069
case RWM_CF_REWRITE:
1834
2070
if ( c->valx >= 0 ) {
1835
/* single modification is not allowed */
2071
ConfigArgs ca = { 0 };
2074
for ( i = 0; !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ i ] ); i++ )
2077
if ( i >= c->valx ) {
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++ )
2085
rwmap->rwm_bva_rewrite[ i ] = rwmap->rwm_bva_rewrite[ i + 1 ];
2087
BER_BVZERO( &rwmap->rwm_bva_rewrite[ i ] );
2089
rewrite_info_delete( &rwmap->rwm_rw );
2090
assert( rwmap->rwm_rw == NULL );
2092
rc = rwm_info_init( &rwmap->rwm_rw );
2094
for ( i = 0; !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ i ] ); i++ )
2096
ca.line = rwmap->rwm_bva_rewrite[ i ].bv_val;
2098
config_fp_parse_line( &ca );
2100
if ( strcasecmp( ca.argv[ 0 ], "suffixmassage" ) == 0 ) {
2101
rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
2105
rc = rwm_rw_config( &db, c->fname, c->lineno,
2109
ch_free( ca.tline );
1838
2114
} else if ( rwmap->rwm_rw != NULL ) {
1839
2115
rewrite_info_delete( &rwmap->rwm_rw );
2160
if ( strncasecmp( c->argv[ 0 ], "olcRwm", STRLENOF( "olcRwm" ) ) == 0 ) {
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;
1895
line = ldap_charray2str( c->argv, "\" \"" );
1896
if ( line != NULL ) {
1897
int len = strlen( c->argv[ 0 ] );
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 );
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;
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 */
1925
line = ldap_charray2str( c->argv, "\" \"" );
1926
if ( line != NULL ) {
1927
int len = strlen( c->argv[ 0 ] );
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 );
2166
if ( c->valx >= 0 ) {
2167
struct rewrite_info *rwm_rw = rwmap->rwm_rw;
2168
ConfigArgs ca = { 0 };
2171
for ( last = 0; !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ last ] ); last++ )
2174
if ( c->valx > last ) {
2178
rwmap->rwm_rw = NULL;
2179
rc = rwm_info_init( &rwmap->rwm_rw );
2181
for ( i = 0; i < c->valx; i++ ) {
2182
ca.line = rwmap->rwm_bva_rewrite[ i ].bv_val;
2184
config_fp_parse_line( &ca );
2186
argv0 = ca.argv[ 0 ];
2187
ca.argv[ 0 ] += STRLENOF( "rwm-" );
2189
if ( strcasecmp( ca.argv[ 0 ], "suffixmassage" ) == 0 ) {
2190
rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
2194
rc = rwm_rw_config( &db, c->fname, c->lineno,
2198
ca.argv[ 0 ] = argv0;
2200
ch_free( ca.tline );
2205
argv0 = c->argv[ idx0 ];
2206
if ( strncasecmp( argv0, "rwm-", STRLENOF( "rwm-" ) ) != 0 ) {
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 ] );
2215
rc = rwm_rw_config( &db, c->fname, c->lineno,
2216
c->argc - idx0, &c->argv[ idx0 ] );
2218
c->argv[ idx0 ] = argv0;
2220
rewrite_info_delete( &rwmap->rwm_rw );
2221
assert( rwmap->rwm_rw == NULL );
2223
rwmap->rwm_rw = rwm_rw;
2227
for ( i = c->valx; !BER_BVISNULL( &rwmap->rwm_bva_rewrite[ i ] ); i++ )
2229
ca.line = rwmap->rwm_bva_rewrite[ i ].bv_val;
2231
config_fp_parse_line( &ca );
2233
argv0 = ca.argv[ 0 ];
2234
ca.argv[ 0 ] += STRLENOF( "rwm-" );
2236
if ( strcasecmp( ca.argv[ 0 ], "suffixmassage" ) == 0 ) {
2237
rc = rwm_suffixmassage_config( &db, c->fname, c->lineno,
2241
rc = rwm_rw_config( &db, c->fname, c->lineno,
2245
ca.argv[ 0 ] = argv0;
2247
ch_free( ca.tline );
2252
rwmap->rwm_bva_rewrite = ch_realloc( rwmap->rwm_bva_rewrite,
2253
( last + 2 )*sizeof( struct berval ) );
2255
for ( i = last - 1; i >= c->valx; i-- )
2257
rwmap->rwm_bva_rewrite[ i + 1 ] = rwmap->rwm_bva_rewrite[ i ];
2260
rwm_bva_rewrite_add( rwmap, c->valx, &c->argv[ idx0 ] );
2262
rewrite_info_delete( &rwm_rw );
2263
assert( rwm_rw == NULL );
2268
argv0 = c->argv[ idx0 ];
2269
if ( strncasecmp( argv0, "rwm-", STRLENOF( "rwm-" ) ) != 0 ) {
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 ] );
2278
rc = rwm_rw_config( &db, c->fname, c->lineno,
2279
c->argc - idx0, &c->argv[ idx0 ] );
2281
c->argv[ idx0 ] = argv0;
2286
rwm_bva_rewrite_add( rwmap, -1, &c->argv[ idx0 ] );
1990
2346
slap_overinst *on = (slap_overinst *) be->bd_info;
1991
2347
struct ldaprwmap *rwmap;
1995
2350
rwmap = (struct ldaprwmap *)ch_calloc( 1, sizeof( struct ldaprwmap ) );
1997
rwmap->rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
1998
if ( rwmap->rwm_rw == NULL ) {
2003
/* this rewriteContext by default must be null;
2004
* rules can be added if required */
2005
rargv[ 0 ] = "rewriteContext";
2006
rargv[ 1 ] = "searchFilter";
2008
rewrite_parse( rwmap->rwm_rw, "<suffix massage>", 1, 2, rargv );
2010
rargv[ 0 ] = "rewriteContext";
2011
rargv[ 1 ] = "default";
2013
rewrite_parse( rwmap->rwm_rw, "<suffix massage>", 2, 2, rargv );
2352
rc = rwm_info_init( &rwmap->rwm_rw );
2016
2355
on->on_bi.bi_private = (void *)rwmap;