📄 translucent.c
字号:
static int translucent_compare(Operation *op, SlapReply *rs) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; overlay_stack *ov = on->on_bi.bi_private; void *private = op->o_bd->be_private; AttributeAssertion *ava = op->orc_ava; Entry *e; int rc; Debug(LDAP_DEBUG_TRACE, "==> translucent_compare: <%s> %s:%s\n", op->o_req_dn.bv_val, ava->aa_desc->ad_cname.bv_val, ava->aa_value.bv_val);/*** if the local backend has an entry for this attribute:** CONTINUE and let it do the compare;***/ op->o_bd->bd_info = (BackendInfo *) on->on_info; rc = be_entry_get_rw(op, &op->o_req_ndn, NULL, ava->aa_desc, 0, &e); if(e && rc == LDAP_SUCCESS) { be_entry_release_r(op, e); op->o_bd->bd_info = (BackendInfo *) on; return(SLAP_CB_CONTINUE); }/*** call compare() in the captive backend;** return the result;***/ op->o_bd->be_private = ov->private; rc = ov->info->bi_op_compare(op, rs); op->o_bd->be_private = private; op->o_bd->bd_info = (BackendInfo *) on; return(rc);}/*** translucent_search_cb()** merge local data with the search result***/static int translucent_search_cb(Operation *op, SlapReply *rs) { slap_overinst *on; Entry *e, *re = NULL; Attribute *a, *ax, *an, *as = NULL; void *private; int rc; if(!op || !rs || rs->sr_type != REP_SEARCH || !rs->sr_entry) return(SLAP_CB_CONTINUE); Debug(LDAP_DEBUG_TRACE, "==> tranclucent_search_cb: %s\n", rs->sr_entry->e_name.bv_val, 0, 0); on = (slap_overinst *) op->o_bd->bd_info; op->o_bd->bd_info = (BackendInfo *) on->on_info; private = op->o_bd->be_private; op->o_bd->be_private = op->o_callback->sc_private; rc = be_entry_get_rw(op, &rs->sr_entry->e_nname, NULL, NULL, 0, &e);/*** if we got an entry from local backend:** make a copy of this search result;** foreach local attr:** foreach search result attr:** if match, result attr with local attr;** if new local, add to list;** append new local attrs to search result;***/ if(e && rc == LDAP_SUCCESS) { re = entry_dup(rs->sr_entry); for(ax = e->e_attrs; ax; ax = ax->a_next) {#if 0 if(is_at_operational(ax->a_desc->ad_type)) continue;#endif for(a = re->e_attrs; a; a = a->a_next) { if(a->a_desc == ax->a_desc) { if(a->a_vals != a->a_nvals) ber_bvarray_free(a->a_nvals); ber_bvarray_free(a->a_vals); a->a_vals = dup_bervarray(ax->a_vals); a->a_nvals = (ax->a_vals == ax->a_nvals) ? a->a_vals : dup_bervarray(ax->a_nvals); break; } } if(a) continue; an = attr_dup(ax); an->a_next = as; as = an; } be_entry_release_r(op, e); /* literally append, so locals are always last */ if(as) { if(re->e_attrs) { for(ax = re->e_attrs; ax->a_next; ax = ax->a_next); ax->a_next = as; } else { re->e_attrs = as; } } rs->sr_entry = re; rs->sr_flags |= REP_ENTRY_MUSTBEFREED; } op->o_bd->be_private = private; op->o_bd->bd_info = (BackendInfo *) on; return(SLAP_CB_CONTINUE);}/*** translucent_search()** search via captive backend;** override results with any local data;***/static int translucent_search(Operation *op, SlapReply *rs) { Operation nop = *op; slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; slap_callback cb = { NULL, NULL, NULL, NULL }; overlay_stack *ov = on->on_bi.bi_private; void *private = op->o_bd->be_private; int rc; Debug(LDAP_DEBUG_TRACE, "==> translucent_search: <%s> %s\n", op->o_req_dn.bv_val, op->ors_filterstr.bv_val, 0); cb.sc_response = (slap_response *) translucent_search_cb; cb.sc_private = private; cb.sc_next = nop.o_callback; nop.o_callback = &cb; op->o_bd->be_private = ov->private; rc = ov->info->bi_op_search(&nop, rs); op->o_bd->be_private = private; return(rs->sr_err);}/*** translucent_bind()** pass bind request to captive backend;***/static int translucent_bind(Operation *op, SlapReply *rs) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; overlay_stack *ov = on->on_bi.bi_private; void *private = op->o_bd->be_private; int rc = 0; Debug(LDAP_DEBUG_TRACE, "translucent_bind: <%s> method %d\n", op->o_req_dn.bv_val, op->orb_method, 0); op->o_bd->be_private = ov->private; rc = ov->info->bi_op_bind(op, rs); op->o_bd->be_private = private; return(rc);}/*** translucent_connection_destroy()** pass disconnect notification to captive backend;***/static int translucent_connection_destroy(BackendDB *be, Connection *conn) { slap_overinst *on = (slap_overinst *) be->bd_info; overlay_stack *ov = on->on_bi.bi_private; void *private = be->be_private; int rc = 0; Debug(LDAP_DEBUG_TRACE, "translucent_connection_destroy\n", 0, 0, 0); be->be_private = ov->private; rc = ov->info->bi_connection_destroy(be, conn); be->be_private = private; return(rc);}/*** translucent_db_config()** pass config directives to captive backend;** parse unrecognized directives ourselves;***/static int translucent_db_config( BackendDB *be, const char *fname, int lineno, int argc, char **argv){ slap_overinst *on = (slap_overinst *) be->bd_info; overlay_stack *ov = on->on_bi.bi_private; void *private = be->be_private; void *be_cf_ocs = be->be_cf_ocs; int rc; /* "this should never happen" */ if(!ov->info) { fprintf(stderr, "fatal: captive backend not initialized"); return(1); } be->be_private = ov->private; be->be_cf_ocs = ov->info->bi_cf_ocs; rc = ov->info->bi_db_config ? ov->info->bi_db_config(be, fname, lineno, argc, argv) : 0; be->be_private = private; be->be_cf_ocs = be_cf_ocs; /* pass okay or error up, SLAP_CONF_UNKNOWN might be ours */ if(rc == 0 || rc == 1) return(rc); rc = 0; if(!strcasecmp(*argv, "translucent_strict")) { ov->config->strict++; } else if(!strcasecmp(*argv, "translucent_no_add")) { ov->config->no_add++; } else if(!strcasecmp(*argv, "translucent_no_glue")) { ov->config->glue++; } else if(!strcasecmp(*argv, "translucent_debug")) { if(argc == 1) { ov->config->debug = 0xFFFF; rc = 0; } else if(argc == 2) { if ( lutil_atoi( &ov->config->debug, argv[1]) != 0 ) { fprintf(stderr, "%s: line %d: unable to parse debug \"%s\"\n", fname, lineno, argv[1]); return 1; } rc = 0; } else { fprintf(stderr, "%s: line %d: too many arguments (%d) to debug\n", fname, lineno, argc); rc = 1; } } else { fprintf(stderr, "%s: line %d: unknown keyword %s\n", fname, lineno, *argv); rc = SLAP_CONF_UNKNOWN; } return(rc);}/*** translucent_db_init()** initialize the captive backend;***/static int translucent_db_init(BackendDB *be) { slap_overinst *on = (slap_overinst *) be->bd_info; void *private = be->be_private; overlay_stack *ov; int rc; Debug(LDAP_DEBUG_TRACE, "==> translucent_init\n", 0, 0, 0); ov = ch_calloc(1, sizeof(overlay_stack)); ov->config = ch_calloc(1, sizeof(translucent_configuration)); ov->info = backend_info("ldap"); if(!ov->info) { Debug(LDAP_DEBUG_ANY, "translucent: backend_info failed!\n", 0, 0, 0); return(1); } /* forcibly disable schema checking on the local backend */ SLAP_DBFLAGS(be) |= SLAP_DBFLAG_NO_SCHEMA_CHECK; be->be_private = NULL; rc = ov->info->bi_db_init ? ov->info->bi_db_init(be) : 0; if(rc) Debug(LDAP_DEBUG_TRACE, "translucent: bi_db_init() returned error %d\n", rc, 0, 0); ov->private = be->be_private; be->be_private = private; on->on_bi.bi_private = ov; return(rc);}/*** translucent_db_open()** if the captive backend has an open() method, call it;***/static int translucent_db_open(BackendDB *be) { slap_overinst *on = (slap_overinst *) be->bd_info; overlay_stack *ov = on->on_bi.bi_private; void *private = be->be_private; int rc; /* "should never happen" */ if(!ov->info) { Debug(LDAP_DEBUG_ANY, "translucent_open() called with bad ov->info\n", 0, 0, 0); return(LDAP_OTHER); } Debug(LDAP_DEBUG_TRACE, "translucent_open\n", 0, 0, 0); be->be_private = ov->private; rc = ov->info->bi_db_open ? ov->info->bi_db_open(be) : 0; be->be_private = private; if(rc) Debug(LDAP_DEBUG_TRACE, "translucent: bi_db_open() returned error %d\n", rc, 0, 0); return(rc);}/*** translucent_db_close()** if the captive backend has a close() method, call it;** free any config data;***/static int translucent_db_close(BackendDB *be) { slap_overinst *on = (slap_overinst *) be->bd_info; overlay_stack *ov = on->on_bi.bi_private; int rc = 0; if ( ov ) { void *private = be->be_private; be->be_private = ov->private; rc = (ov->info && ov->info->bi_db_close) ? ov->info->bi_db_close(be) : 0; be->be_private = private; if(ov->config) ch_free(ov->config); ov->config = NULL; } return(rc);}/*** translucent_db_destroy()** if the captive backend has a db_destroy() method, call it***/static int translucent_db_destroy(BackendDB *be) { slap_overinst *on = (slap_overinst *) be->bd_info; overlay_stack *ov = on->on_bi.bi_private; int rc = 0; if ( ov ) { void *private = be->be_private; be->be_private = ov->private; rc = (ov->info && ov->info->bi_db_destroy) ? ov->info->bi_db_destroy(be) : 0; be->be_private = private; ch_free(ov); on->on_bi.bi_private = NULL; } return(rc);}/*** translucent_initialize()** initialize the slap_overinst with our entry points;***/int translucent_initialize() { translucent.on_bi.bi_type = "translucent"; translucent.on_bi.bi_db_init = translucent_db_init; translucent.on_bi.bi_db_config = translucent_db_config; translucent.on_bi.bi_db_open = translucent_db_open; translucent.on_bi.bi_db_close = translucent_db_close; translucent.on_bi.bi_db_destroy = translucent_db_destroy; translucent.on_bi.bi_op_bind = translucent_bind; translucent.on_bi.bi_op_add = translucent_add; translucent.on_bi.bi_op_modify = translucent_modify; translucent.on_bi.bi_op_modrdn = translucent_modrdn; translucent.on_bi.bi_op_delete = translucent_delete; translucent.on_bi.bi_op_search = translucent_search; translucent.on_bi.bi_op_compare = translucent_compare; translucent.on_bi.bi_connection_destroy = translucent_connection_destroy; return(overlay_register(&translucent));}#if SLAPD_OVER_TRANSLUCENT == SLAPD_MOD_DYNAMIC && defined(PIC)int init_module(int argc, char *argv[]) { return translucent_initialize();}#endif#endif /* SLAPD_OVER_TRANSLUCENT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -