📄 rwm.c
字号:
/* * It is necessary to try to rewrite attributes with * dn syntax because they might be used in ACLs as * members of groups; since ACLs are applied to the * rewritten stuff, no dn-based subject clause could * be used at the ldap backend side (see * http://www.OpenLDAP.org/faq/data/cache/452.html) * The problem can be overcome by moving the dn-based * ACLs to the target directory server, and letting * everything pass thru the ldap backend. */ /* FIXME: handle distinguishedName-like syntaxes, like * nameAndOptionalUID */ } else if ( (*ap)->a_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName || ( mapping != NULL && mapping->m_src_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) ) {#ifdef ENABLE_REWRITE dc.ctx = "searchAttrDN";#endif /* ENABLE_REWRITE */ rc = rwm_dnattr_result_rewrite( &dc, (*ap)->a_vals ); if ( rc != LDAP_SUCCESS ) { goto cleanup_attr; } } else if ( (*ap)->a_desc == slap_schema.si_ad_ref ) {#ifdef ENABLE_REWRITE dc.ctx = "searchAttrDN";#endif /* ENABLE_REWRITE */ rc = rwm_referral_result_rewrite( &dc, (*ap)->a_vals ); if ( rc != LDAP_SUCCESS ) { goto cleanup_attr; } } if ( mapping != NULL ) { /* rewrite the attribute description */ assert( mapping->m_dst_ad != NULL ); (*ap)->a_desc = mapping->m_dst_ad; }next_attr:; ap = &(*ap)->a_next; continue;cleanup_attr:; a = *ap; *ap = (*ap)->a_next; attr_free( a ); } return 0;}static intrwm_send_entry( Operation *op, SlapReply *rs ){ slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; struct ldaprwmap *rwmap = (struct ldaprwmap *)on->on_bi.bi_private; Entry *e = NULL; slap_mask_t flags; struct berval dn = BER_BVNULL, ndn = BER_BVNULL; dncookie dc; int rc; assert( rs->sr_entry != NULL ); /* * Rewrite the dn of the result, if needed */ dc.rwmap = rwmap;#ifdef ENABLE_REWRITE dc.conn = op->o_conn; dc.rs = NULL; dc.ctx = "searchEntryDN";#else /* ! ENABLE_REWRITE */ dc.tofrom = 0; dc.normalized = 0;#endif /* ! ENABLE_REWRITE */ e = rs->sr_entry; flags = rs->sr_flags; if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) { /* FIXME: all we need to duplicate are: * - dn * - ndn * - attributes that are requested * - no values if attrsonly is set */ e = entry_dup( e ); if ( e == NULL ) { rc = LDAP_NO_MEMORY; goto fail; } flags &= ~REP_ENTRY_MUSTRELEASE; flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED ); } /* * Note: this may fail if the target host(s) schema differs * from the one known to the meta, and a DN with unknown * attributes is returned. */ dn = e->e_name; ndn = e->e_nname; rc = rwm_dn_massage_pretty_normalize( &dc, &e->e_name, &dn, &ndn ); if ( rc != LDAP_SUCCESS ) { rc = 1; goto fail; } if ( e->e_name.bv_val != dn.bv_val ) { ch_free( e->e_name.bv_val ); ch_free( e->e_nname.bv_val ); e->e_name = dn; e->e_nname = ndn; } /* TODO: map entry attribute types, objectclasses * and dn-valued attribute values */ /* FIXME: the entries are in the remote mapping form; * so we need to select those attributes we are willing * to return, and remap them accordingly */ (void)rwm_attrs( op, rs, &e->e_attrs, 1 ); if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { be_entry_release_rw( op, rs->sr_entry, 0 ); } rs->sr_entry = e; rs->sr_flags = flags; return SLAP_CB_CONTINUE;fail:; if ( e != NULL && e != rs->sr_entry ) { if ( e->e_name.bv_val == dn.bv_val ) { BER_BVZERO( &e->e_name ); } if ( e->e_nname.bv_val == ndn.bv_val ) { BER_BVZERO( &e->e_nname ); } entry_free( e ); } if ( !BER_BVISNULL( &dn ) ) { ch_free( dn.bv_val ); } if ( !BER_BVISNULL( &ndn ) ) { ch_free( ndn.bv_val ); } return rc;}static intrwm_operational( Operation *op, SlapReply *rs ){ /* FIXME: the entries are in the remote mapping form; * so we need to select those attributes we are willing * to return, and remap them accordingly */ if ( rs->sr_operational_attrs ) { rwm_attrs( op, rs, &rs->sr_operational_attrs, 1 ); } return SLAP_CB_CONTINUE;}#if 0/* don't use this; it cannot be reverted, and leaves op->o_req_dn * rewritten for subsequent operations; fine for plain suffixmassage, * but destroys everything else */static intrwm_chk_referrals( Operation *op, SlapReply *rs ){ slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; int rc;#ifdef ENABLE_REWRITE rc = rwm_op_dn_massage( op, rs, "referralCheckDN" );#else /* ! ENABLE_REWRITE */ rc = 1; rc = rwm_op_dn_massage( op, rs, &rc );#endif /* ! ENABLE_REWRITE */ if ( rc != LDAP_SUCCESS ) { op->o_bd->bd_info = (BackendInfo *)on->on_info; send_ldap_error( op, rs, rc, "referralCheckDN massage error" ); return -1; } return SLAP_CB_CONTINUE;}#endifstatic intrwm_rw_config( BackendDB *be, const char *fname, int lineno, int argc, char **argv ){#ifdef ENABLE_REWRITE slap_overinst *on = (slap_overinst *) be->bd_info; struct ldaprwmap *rwmap = (struct ldaprwmap *)on->on_bi.bi_private; return rewrite_parse( rwmap->rwm_rw, fname, lineno, argc, argv );#else /* !ENABLE_REWRITE */ fprintf( stderr, "%s: line %d: rewrite capabilities " "are not enabled\n", fname, lineno );#endif /* !ENABLE_REWRITE */ return 0;}static intrwm_suffixmassage_config( BackendDB *be, const char *fname, int lineno, int argc, char **argv ){ slap_overinst *on = (slap_overinst *) be->bd_info; struct ldaprwmap *rwmap = (struct ldaprwmap *)on->on_bi.bi_private; struct berval bvnc, nvnc, pvnc, brnc, nrnc, prnc; int massaged;#ifdef ENABLE_REWRITE int rc;#endif /* ENABLE_REWRITE */ /* * syntax: * * suffixmassage [<suffix>] <massaged suffix> * * the [<suffix>] field must be defined as a valid suffix * for the current database; * the <massaged suffix> shouldn't have already been * defined as a valid suffix for the current server */ if ( argc == 2 ) { if ( be->be_suffix == NULL ) { fprintf( stderr, "%s: line %d: " " \"suffixMassage [<suffix>]" " <massaged suffix>\" without " "<suffix> part requires database " "suffix be defined first.\n", fname, lineno ); return 1; } bvnc = be->be_suffix[ 0 ]; massaged = 1; } else if ( argc == 3 ) { ber_str2bv( argv[ 1 ], 0, 0, &bvnc ); massaged = 2; } else { fprintf( stderr, "%s: line %d: syntax is" " \"suffixMassage [<suffix>]" " <massaged suffix>\"\n", fname, lineno ); return 1; } if ( dnPrettyNormal( NULL, &bvnc, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) { fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n", fname, lineno, bvnc.bv_val ); return 1; } ber_str2bv( argv[ massaged ], 0, 0, &brnc ); if ( dnPrettyNormal( NULL, &brnc, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) { fprintf( stderr, "%s: line %d: suffix DN %s is invalid\n", fname, lineno, brnc.bv_val ); free( nvnc.bv_val ); free( pvnc.bv_val ); return 1; }#ifdef ENABLE_REWRITE /* * The suffix massaging is emulated * by means of the rewrite capabilities */ rc = rwm_suffix_massage_config( rwmap->rwm_rw, &pvnc, &nvnc, &prnc, &nrnc ); free( nvnc.bv_val ); free( pvnc.bv_val ); free( nrnc.bv_val ); free( prnc.bv_val ); return( rc );#else /* !ENABLE_REWRITE */ ber_bvarray_add( &rwmap->rwm_suffix_massage, &pvnc ); ber_bvarray_add( &rwmap->rwm_suffix_massage, &nvnc ); ber_bvarray_add( &rwmap->rwm_suffix_massage, &prnc ); ber_bvarray_add( &rwmap->rwm_suffix_massage, &nrnc );#endif /* !ENABLE_REWRITE */ return 0;}static intrwm_m_config( BackendDB *be, const char *fname, int lineno, int argc, char **argv ){ slap_overinst *on = (slap_overinst *) be->bd_info; struct ldaprwmap *rwmap = (struct ldaprwmap *)on->on_bi.bi_private; /* objectclass/attribute mapping */ return rwm_map_config( &rwmap->rwm_oc, &rwmap->rwm_at, fname, lineno, argc, argv );}static intrwm_response( Operation *op, SlapReply *rs ){ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; struct ldaprwmap *rwmap = (struct ldaprwmap *)on->on_bi.bi_private; int rc; if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH ) { return rwm_send_entry( op, rs ); } switch( op->o_tag ) { case LDAP_REQ_SEARCH: case LDAP_REQ_BIND: case LDAP_REQ_ADD: case LDAP_REQ_DELETE: case LDAP_REQ_MODRDN: case LDAP_REQ_MODIFY: case LDAP_REQ_COMPARE: case LDAP_REQ_EXTENDED: if ( rs->sr_ref ) { dncookie dc; /* * Rewrite the dn of the referrals, if needed */ dc.rwmap = rwmap;#ifdef ENABLE_REWRITE dc.conn = op->o_conn; dc.rs = NULL; dc.ctx = "referralDN";#else /* ! ENABLE_REWRITE */ dc.tofrom = 0; dc.normalized = 0;#endif /* ! ENABLE_REWRITE */ rc = rwm_referral_result_rewrite( &dc, rs->sr_ref ); if ( rc != LDAP_SUCCESS ) { rc = 1; break; } } rc = rwm_matched( op, rs ); break; default: rc = SLAP_CB_CONTINUE; break; } return rc;}static intrwm_db_config( BackendDB *be, const char *fname, int lineno, int argc, char **argv ){ slap_overinst *on = (slap_overinst *) be->bd_info; struct ldaprwmap *rwmap = (struct ldaprwmap *)on->on_bi.bi_private; int rc = 0; char *argv0 = NULL; if ( strncasecmp( argv[ 0 ], "rwm-", STRLENOF( "rwm-" ) ) == 0 ) { argv0 = argv[ 0 ]; argv[ 0 ] = &argv0[ STRLENOF( "rwm-" ) ]; } if ( strncasecmp( argv[0], "rewrite", STRLENOF("rewrite") ) == 0 ) { rc = rwm_rw_config( be, fname, lineno, argc, argv ); } else if ( strcasecmp( argv[0], "map" ) == 0 ) { rc = rwm_m_config( be, fname, lineno, argc, argv ); } else if ( strcasecmp( argv[0], "suffixmassage" ) == 0 ) { rc = rwm_suffixmassage_config( be, fname, lineno, argc, argv ); } else if ( strcasecmp( argv[0], "t-f-support" ) == 0 ) { if ( argc != 2 ) { fprintf( stderr, "%s: line %d: \"t-f-support {no|yes|discover}\" needs 1 argument.\n", fname, lineno ); return( 1 ); } if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) { rwmap->rwm_flags &= ~(RWM_F_SUPPORT_T_F|RWM_F_SUPPORT_T_F_DISCOVER); } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) { rwmap->rwm_flags |= RWM_F_SUPPORT_T_F; /* TODO: not implemented yet */ } else if ( strcasecmp( argv[ 1 ], "discover" ) == 0 ) { fprintf( stderr, "%s: line %d: \"discover\" not supported yet " "in \"t-f-support {no|yes|discover}\".\n", fname, lineno ); return( 1 );#if 0 rwmap->rwm_flags |= RWM_F_SUPPORT_T_F_DISCOVER;#endif } else { fprintf( stderr, "%s: line %d: unknown value \"%s\" for \"t-f-support {no|yes|discover}\".\n", fname, lineno, argv[ 1 ] ); return 1; } } else { rc = SLAP_CONF_UNKNOWN; } if ( argv0 ) { argv[ 0 ] = argv0; } return rc;}static intrwm_db_init( BackendDB *be ){ slap_overinst *on = (slap_overinst *) be->bd_info; struct ldaprwmap *rwmap;#ifdef ENABLE_REWRITE char *rargv[ 3 ];#endif /* ENABLE_REWRITE */ int rc = 0; rwmap = (struct ldaprwmap *)ch_calloc( 1, sizeof( struct ldaprwmap ) );#ifdef ENABLE_REWRITE rwmap->rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT ); if ( rwmap->rwm_rw == NULL ) { rc = -1; goto error_return; } /* this rewriteContext by default must be null; * rules can be added if required */ rargv[ 0 ] = "rewriteContext"; rargv[ 1 ] = "searchFilter"; rargv[ 2 ] = NULL; rewrite_parse( rwmap->rwm_rw, "<suffix massage>", 1, 2, rargv ); rargv[ 0 ] = "rewriteContext"; rargv[ 1 ] = "default"; rargv[ 2 ] = NULL; rewrite_parse( rwmap->rwm_rw, "<suffix massage>", 2, 2, rargv );#endif /* ENABLE_REWRITE */error_return:; on->on_bi.bi_private = (void *)rwmap; if ( rc ) { (void)rwm_db_destroy( be ); } return rc;}static intrwm_db_destroy( BackendDB *be ){ slap_overinst *on = (slap_overinst *) be->bd_info; int rc = 0; if ( on->on_bi.bi_private ) { struct ldaprwmap *rwmap = (struct ldaprwmap *)on->on_bi.bi_private;#ifdef ENABLE_REWRITE if ( rwmap->rwm_rw ) { rewrite_info_delete( &rwmap->rwm_rw ); }#else /* !ENABLE_REWRITE */ if ( rwmap->rwm_suffix_massage ) { ber_bvarray_free( rwmap->rwm_suffix_massage ); }#endif /* !ENABLE_REWRITE */ avl_free( rwmap->rwm_oc.remap, rwm_mapping_dst_free ); avl_free( rwmap->rwm_oc.map, rwm_mapping_free ); avl_free( rwmap->rwm_at.remap, rwm_mapping_dst_free ); avl_free( rwmap->rwm_at.map, rwm_mapping_free ); ch_free( rwmap ); } return rc;}static slap_overinst rwm = { { NULL } };#if SLAPD_OVER_RWM == SLAPD_MOD_DYNAMICstatic#endif /* SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC */intrwm_initialize( void ){ memset( &rwm, 0, sizeof( slap_overinst ) ); rwm.on_bi.bi_type = "rwm"; rwm.on_bi.bi_db_init = rwm_db_init; rwm.on_bi.bi_db_config = rwm_db_config; rwm.on_bi.bi_db_destroy = rwm_db_destroy; rwm.on_bi.bi_op_bind = rwm_op_bind; rwm.on_bi.bi_op_search = rwm_op_search; rwm.on_bi.bi_op_compare = rwm_op_compare; rwm.on_bi.bi_op_modify = rwm_op_modify; rwm.on_bi.bi_op_modrdn = rwm_op_modrdn; rwm.on_bi.bi_op_add = rwm_op_add; rwm.on_bi.bi_op_delete = rwm_op_delete; rwm.on_bi.bi_op_unbind = rwm_op_unbind; rwm.on_bi.bi_extended = rwm_extended; rwm.on_bi.bi_operational = rwm_operational; rwm.on_bi.bi_chk_referrals = 0 /* rwm_chk_referrals */ ;#ifdef ENABLE_REWRITE rwm.on_bi.bi_connection_init = rwm_conn_init; rwm.on_bi.bi_connection_destroy = rwm_conn_destroy;#endif /* ENABLE_REWRITE */ rwm.on_response = rwm_response; return overlay_register( &rwm );}#if SLAPD_OVER_RWM == SLAPD_MOD_DYNAMICintinit_module( int argc, char *argv[] ){ return rwm_initialize();}#endif /* SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC */#endif /* SLAPD_OVER_RWM */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -