📄 refint.c
字号:
static intrefint_modrdn_cb( Operation *op, SlapReply *rs){ Attribute *a; BerVarray b = NULL; refint_data *dd = op->o_callback->sc_private; refint_attrs *ia, *da = dd->attrs; dependent_data *ip = NULL; Modifications *mp; int i, fix; Debug(LDAP_DEBUG_TRACE, "refint_modrdn_cb <%s>\n", rs->sr_entry ? rs->sr_entry->e_name.bv_val : "NOTHING", 0, 0); if (rs->sr_type != REP_SEARCH || !rs->sr_entry) return(0); dd->message = "_modrdn_cb"; /* ** foreach configured attribute type: ** if this attr exists in the search result, ** and it has a value matching the target: ** allocate a pair of Modifications; ** make it MOD_ADD the new value and MOD_DELETE the old; ** allocate its array of BerValues; ** foreach value in the search result: ** if it matches our target value, replace it; ** otherwise, copy from the search result; ** terminate the array of BerValues; ** add these mods to the list of mods; ** */ for(ia = da; ia; ia = ia->next) { if((a = attr_find(rs->sr_entry->e_attrs, ia->attr))) { for(fix = 0, i = 0, b = a->a_nvals; b[i].bv_val; i++) if(bvmatch(&dd->dn, &b[i])) { fix++; break; } if(fix) { if (!ip) { ip = ch_malloc(sizeof(dependent_data)); ip->next = NULL; ip->mm = NULL; ber_dupbv(&ip->dn, &rs->sr_entry->e_nname); } mp = ch_malloc(sizeof(Modifications)); mp->sml_op = LDAP_MOD_ADD; mp->sml_flags = 0; mp->sml_desc = ia->attr; /* XXX */ mp->sml_type = ia->attr->ad_cname; mp->sml_values = ch_malloc(2 * sizeof(BerValue)); mp->sml_nvalues = ch_malloc(2 * sizeof(BerValue)); ber_dupbv(&mp->sml_values[0], &dd->newdn); ber_dupbv(&mp->sml_nvalues[0], &dd->nnewdn); mp->sml_values[1].bv_len = mp->sml_nvalues[1].bv_len = 0; mp->sml_values[1].bv_val = mp->sml_nvalues[1].bv_val = NULL; mp->sml_next = ip->mm; ip->mm = mp; mp = ch_malloc(sizeof(Modifications)); mp->sml_op = LDAP_MOD_DELETE; mp->sml_flags = 0; mp->sml_desc = ia->attr; /* XXX */ mp->sml_type = ia->attr->ad_cname; mp->sml_values = ch_malloc(2 * sizeof(BerValue)); mp->sml_nvalues = ch_malloc(2 * sizeof(BerValue)); ber_dupbv(&mp->sml_values[0], &dd->dn); ber_dupbv(&mp->sml_nvalues[0], &dd->dn); mp->sml_values[1].bv_len = mp->sml_nvalues[1].bv_len = 0; mp->sml_values[1].bv_val = mp->sml_nvalues[1].bv_val = NULL; mp->sml_next = ip->mm; ip->mm = mp; Debug(LDAP_DEBUG_TRACE, "refint_modrdn_cb: %s: %s\n", a->a_desc->ad_cname.bv_val, dd->dn.bv_val, 0); } } } if (ip) { ip->next = dd->mods; dd->mods = ip; } return(0);}/*** refint_response** search for matching records and modify them*/static intrefint_response( Operation *op, SlapReply *rs){ Operation nop = *op; SlapReply nrs = { REP_RESULT }; slap_callback cb = { NULL, NULL, NULL, NULL }; slap_callback cb2 = { NULL, slap_replog_cb, NULL, NULL }; slap_callback *cbo, *cbp; slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; refint_data *id = on->on_bi.bi_private; refint_data dd = *id; refint_attrs *ip; dependent_data *dp; BerValue pdn; int rc, ac; Filter ftop, *fptr; id->message = "_refint_response"; /* If the main op failed or is not a Delete or ModRdn, ignore it */ if (( op->o_tag != LDAP_REQ_DELETE && op->o_tag != LDAP_REQ_MODRDN ) || rs->sr_err != LDAP_SUCCESS ) return SLAP_CB_CONTINUE; /* ** validate (and count) the list of attrs; ** */ for(ip = id->attrs, ac = 0; ip; ip = ip->next, ac++); if(!ac) { Debug( LDAP_DEBUG_TRACE, "refint_response called without any attributes\n", 0, 0, 0 ); return SLAP_CB_CONTINUE; } /* ** find the backend that matches our configured basedn; ** make sure it exists and has search and modify methods; ** */ nop.o_bd = select_backend(&id->dn, 0, 1); if(nop.o_bd) { if (!nop.o_bd->be_search || !nop.o_bd->be_modify) { Debug( LDAP_DEBUG_TRACE, "refint_response: backend missing search and/or modify\n", 0, 0, 0 ); return SLAP_CB_CONTINUE; } } else { Debug( LDAP_DEBUG_TRACE, "refint_response: no backend for our baseDN %s??\n", id->dn.bv_val, 0, 0 ); return SLAP_CB_CONTINUE; } cb2.sc_next = &cb; /* ** if delete: set delete callback; ** else modrdn: create a newdn, set modify callback; ** */ if(op->o_tag == LDAP_REQ_DELETE) { cb.sc_response = &refint_delete_cb; dd.newdn.bv_val = NULL; dd.nnewdn.bv_val = NULL; } else { cb.sc_response = &refint_modrdn_cb; if ( op->oq_modrdn.rs_newSup ) { pdn = *op->oq_modrdn.rs_newSup; } else { dnParent( &op->o_req_dn, &pdn ); } build_new_dn( &dd.newdn, &pdn, &op->orr_newrdn, NULL ); if ( op->oq_modrdn.rs_nnewSup ) { pdn = *op->oq_modrdn.rs_nnewSup; } else { dnParent( &op->o_req_ndn, &pdn ); } build_new_dn( &dd.nnewdn, &pdn, &op->orr_nnewrdn, NULL ); } /* ** build a search filter for all configured attributes; ** populate our Operation; ** pass our data (attr list, dn) to backend via sc_private; ** call the backend search function; ** nb: (|(one=thing)) is valid, but do smart formatting anyway; ** nb: 16 is arbitrarily a dozen or so extra bytes; ** */ ftop.f_choice = LDAP_FILTER_OR; ftop.f_next = NULL; ftop.f_or = NULL; nop.ors_filter = &ftop; for(ip = id->attrs; ip; ip = ip->next) { fptr = ch_malloc( sizeof(Filter) + sizeof(AttributeAssertion) ); fptr->f_choice = LDAP_FILTER_EQUALITY; fptr->f_ava = (AttributeAssertion *)(fptr+1); fptr->f_ava->aa_desc = ip->attr; fptr->f_ava->aa_value = op->o_req_ndn; fptr->f_next = ftop.f_or; ftop.f_or = fptr; } filter2bv( nop.ors_filter, &nop.ors_filterstr ); /* callback gets the searched dn instead */ dd.dn = op->o_req_ndn; dd.message = "_dependent_search"; dd.mods = NULL; cb.sc_private = ⅆ nop.o_callback = &cb; nop.o_tag = LDAP_REQ_SEARCH; nop.ors_scope = LDAP_SCOPE_SUBTREE; nop.ors_deref = LDAP_DEREF_NEVER; nop.ors_limit = NULL; nop.ors_slimit = SLAP_NO_LIMIT; nop.ors_tlimit = SLAP_NO_LIMIT; /* no attrs! */ nop.ors_attrs = slap_anlist_no_attrs; nop.ors_attrsonly = 1; nop.o_req_ndn = id->dn; nop.o_req_dn = id->dn; /* search */ rc = nop.o_bd->be_search(&nop, &nrs); ch_free( nop.ors_filterstr.bv_val ); while ( (fptr = ftop.f_or) != NULL ) { ftop.f_or = fptr->f_next; ch_free( fptr ); } ch_free(dd.nnewdn.bv_val); ch_free(dd.newdn.bv_val); dd.newdn.bv_val = NULL; dd.nnewdn.bv_val = NULL; if(rc != LDAP_SUCCESS) { Debug( LDAP_DEBUG_TRACE, "refint_response: search failed: %d\n", rc, 0, 0 ); goto done; } /* safety? paranoid just in case */ if(!cb.sc_private) { Debug( LDAP_DEBUG_TRACE, "refint_response: callback wiped out sc_private?!\n", 0, 0, 0 ); goto done; } /* presto! now it's a modify request with null callback */ cb.sc_response = &refint_null_cb; nop.o_tag = LDAP_REQ_MODIFY; dd.message = "_dependent_modify"; /* See if the parent operation is going into the replog */ for (cbo=op->o_callback, cbp = cbo->sc_next; cbp; cbo=cbp,cbp=cbp->sc_next) { if (cbp->sc_response == slap_replog_cb) { /* Invoke replog now, arrange for our * dependent mods to also be logged */ cbo->sc_next = cbp->sc_next; replog( op ); nop.o_callback = &cb2; break; } } /* ** [our search callback builds a list of mods] ** foreach mod: ** make sure its dn has a backend; ** connect Modification* chain to our op; ** call the backend modify function; ** pass any errors upstream; ** */ for(dp = dd.mods; dp; dp = dp->next) { nop.o_req_dn = dp->dn; nop.o_req_ndn = dp->dn; nop.o_bd = select_backend(&dp->dn, 0, 1); if(!nop.o_bd) { Debug( LDAP_DEBUG_TRACE, "refint_response: no backend for DN %s!\n", dp->dn.bv_val, 0, 0 ); goto done; } nrs.sr_type = REP_RESULT; nop.orm_modlist = dp->mm; /* callback did all the work */ nop.o_dn = refint_dn; nop.o_ndn = refint_dn; nop.o_dn = nop.o_bd->be_rootdn; nop.o_ndn = nop.o_bd->be_rootndn; if(rs->sr_err != LDAP_SUCCESS) goto done; if((rc = nop.o_bd->be_modify(&nop, &nrs)) != LDAP_SUCCESS) { Debug( LDAP_DEBUG_TRACE, "refint_response: dependent modify failed: %d\n", nrs.sr_err, 0, 0 ); goto done; } }done: for(dp = dd.mods; dp; dp = dd.mods) { dd.mods = dp->next; ch_free(dp->dn.bv_val); slap_mods_free(dp->mm, 1); } dd.mods = NULL; return(SLAP_CB_CONTINUE);}/*** init_module is last so the symbols resolve "for free" --** it expects to be called automagically during dynamic module initialization*/int refint_initialize() { /* statically declared just after the #includes at top */ refint.on_bi.bi_type = "refint"; refint.on_bi.bi_db_init = refint_db_init; refint.on_bi.bi_db_config = refint_config; refint.on_bi.bi_db_open = refint_open; refint.on_bi.bi_db_close = refint_close; refint.on_response = refint_response; return(overlay_register(&refint));}#if SLAPD_OVER_REFINT == SLAPD_MOD_DYNAMIC && defined(PIC)int init_module(int argc, char *argv[]) { return refint_initialize();}#endif#endif /* SLAPD_OVER_REFINT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -