📄 accesslog.c
字号:
} } vals[i].bv_val = NULL; vals[i].bv_len = 0; a = attr_alloc( ad_reqMod ); a->a_vals = vals; a->a_nvals = vals; last_attr->a_next = a; if ( old ) { last_attr = a; /* count all the vals */ i = 0; for ( a=old->e_attrs; a; a=a->a_next ) { if ( a->a_vals && a->a_flags ) { for (b=a->a_vals; !BER_BVISNULL( b ); b++) { i++; } } } vals = ch_malloc( (i+1) * sizeof( struct berval )); i = 0; for ( a=old->e_attrs; a; a=a->a_next ) { if ( a->a_vals && a->a_flags ) { for (b=a->a_vals; !BER_BVISNULL( b ); b++,i++) { accesslog_val2val( a->a_desc, b, 0, &vals[i] ); } } } vals[i].bv_val = NULL; vals[i].bv_len = 0; a = attr_alloc( ad_reqOld ); a->a_vals = vals; a->a_nvals = vals; last_attr->a_next = a; } break; case LOG_EN_MODRDN: attr_merge_one( e, ad_reqNewRDN, &op->orr_newrdn, &op->orr_nnewrdn ); attr_merge_one( e, ad_reqDeleteOldRDN, op->orr_deleteoldrdn ? (struct berval *)&slap_true_bv : (struct berval *)&slap_false_bv, NULL ); if ( op->orr_newSup ) { attr_merge_one( e, ad_reqNewSuperior, op->orr_newSup, op->orr_nnewSup ); } break; case LOG_EN_COMPARE: bv.bv_len = op->orc_ava->aa_desc->ad_cname.bv_len + 1 + op->orc_ava->aa_value.bv_len; bv.bv_val = op->o_tmpalloc( bv.bv_len+1, op->o_tmpmemctx ); ptr = lutil_strcopy( bv.bv_val, op->orc_ava->aa_desc->ad_cname.bv_val ); *ptr++ = '='; AC_MEMCPY( ptr, op->orc_ava->aa_value.bv_val, op->orc_ava->aa_value.bv_len ); bv.bv_val[bv.bv_len] = '\0'; attr_merge_one( e, ad_reqAssertion, &bv, NULL ); op->o_tmpfree( bv.bv_val, op->o_tmpmemctx ); break; case LOG_EN_SEARCH: attr_merge_one( e, ad_reqScope, &scopes[op->ors_scope], NULL ); attr_merge_one( e, ad_reqDerefAliases, &derefs[op->ors_deref], NULL ); attr_merge_one( e, ad_reqAttrsOnly, op->ors_attrsonly ? (struct berval *)&slap_true_bv : (struct berval *)&slap_false_bv, NULL ); if ( !BER_BVISEMPTY( &op->ors_filterstr )) attr_merge_one( e, ad_reqFilter, &op->ors_filterstr, NULL ); if ( op->ors_attrs ) { /* count them */ for (i=0; !BER_BVISNULL(&op->ors_attrs[i].an_name );i++) ; vals = op->o_tmpalloc( (i+1) * sizeof(struct berval), op->o_tmpmemctx ); for (i=0; !BER_BVISNULL(&op->ors_attrs[i].an_name );i++) vals[i] = op->ors_attrs[i].an_name; vals[i].bv_val = NULL; vals[i].bv_len = 0; attr_merge( e, ad_reqAttr, vals, NULL ); op->o_tmpfree( vals, op->o_tmpmemctx ); } bv.bv_val = timebuf; bv.bv_len = sprintf( bv.bv_val, "%d", rs->sr_nentries ); attr_merge_one( e, ad_reqEntries, &bv, NULL ); bv.bv_len = sprintf( bv.bv_val, "%d", op->ors_tlimit ); attr_merge_one( e, ad_reqTimeLimit, &bv, NULL ); bv.bv_len = sprintf( bv.bv_val, "%d", op->ors_slimit ); attr_merge_one( e, ad_reqSizeLimit, &bv, NULL ); break; case LOG_EN_BIND: bv.bv_val = timebuf; bv.bv_len = sprintf( bv.bv_val, "%d", op->o_protocol ); attr_merge_one( e, ad_reqVersion, &bv, NULL ); if ( op->orb_method == LDAP_AUTH_SIMPLE ) { attr_merge_one( e, ad_reqMethod, &simple, NULL ); } else { bv.bv_len = STRLENOF("SASL()") + op->orb_tmp_mech.bv_len; bv.bv_val = op->o_tmpalloc( bv.bv_len + 1, op->o_tmpmemctx ); ptr = lutil_strcopy( bv.bv_val, "SASL(" ); ptr = lutil_strcopy( ptr, op->orb_tmp_mech.bv_val ); *ptr++ = ')'; *ptr = '\0'; attr_merge_one( e, ad_reqMethod, &bv, NULL ); op->o_tmpfree( bv.bv_val, op->o_tmpmemctx ); } break; case LOG_EN_EXTENDED: if ( op->ore_reqdata ) { attr_merge_one( e, ad_reqData, op->ore_reqdata, NULL ); } break; case LOG_EN_UNKNOWN: /* we don't know its parameters, don't add any */ break; } op2.o_hdr = op->o_hdr; op2.o_tag = LDAP_REQ_ADD; op2.o_bd = li->li_db; op2.o_dn = li->li_db->be_rootdn; op2.o_ndn = li->li_db->be_rootndn; op2.o_req_dn = e->e_name; op2.o_req_ndn = e->e_nname; op2.ora_e = e; op2.o_callback = &nullsc; if (( lo->mask & LOG_OP_WRITES ) && !BER_BVISEMPTY( &op->o_csn )) { slap_queue_csn( &op2, &op->o_csn ); } op2.o_bd->be_add( &op2, &rs2 );done: if ( lo->mask & LOG_OP_WRITES ) ldap_pvt_thread_mutex_unlock( &li->li_log_mutex ); if ( e ) entry_free( e ); if ( old ) entry_free( old ); return SLAP_CB_CONTINUE;}/* Since Bind success is sent by the frontend, it won't normally enter * the overlay response callback. Add another callback to make sure it * gets here. */static intaccesslog_bind_resp( Operation *op, SlapReply *rs ){ BackendDB *be, db; int rc; slap_callback *sc; be = op->o_bd; db = *be; op->o_bd = &db; db.bd_info = op->o_callback->sc_private; rc = accesslog_response( op, rs ); op->o_bd = be; sc = op->o_callback; op->o_callback = sc->sc_next; op->o_tmpfree( sc, op->o_tmpmemctx ); return rc;}static intaccesslog_op_bind( Operation *op, SlapReply *rs ){ slap_callback *sc; sc = op->o_tmpcalloc( 1, sizeof(slap_callback), op->o_tmpmemctx ); sc->sc_response = accesslog_bind_resp; sc->sc_private = op->o_bd->bd_info; if ( op->o_callback ) { sc->sc_next = op->o_callback->sc_next; op->o_callback->sc_next = sc; } else { op->o_callback = sc; } return SLAP_CB_CONTINUE;}static intaccesslog_op_mod( Operation *op, SlapReply *rs ){ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; log_info *li = on->on_bi.bi_private; if ( li->li_ops & LOG_OP_WRITES ) { /* FIXME: this needs to be a recursive mutex to allow * overlays like refint to keep working. */ ldap_pvt_thread_mutex_lock( &li->li_op_mutex ); if ( li->li_oldf && ( op->o_tag == LDAP_REQ_DELETE || op->o_tag == LDAP_REQ_MODIFY )) { int rc; Entry *e; op->o_bd->bd_info = on->on_info->oi_orig; rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &e ); if ( e ) { if ( test_filter( op, e, li->li_oldf ) == LDAP_COMPARE_TRUE ) li->li_old = entry_dup( e ); be_entry_release_rw( op, e, 0 ); } op->o_bd->bd_info = (BackendInfo *)on; } } return SLAP_CB_CONTINUE;}/* unbinds are broadcast to all backends; we only log it if this * backend was used for the original bind. */static intaccesslog_unbind( Operation *op, SlapReply *rs ){ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; if ( op->o_conn->c_authz_backend == on->on_info->oi_origdb ) { log_info *li = on->on_bi.bi_private; Operation op2 = {0}; void *cids[SLAP_MAX_CIDS]; SlapReply rs2 = {REP_RESULT}; Entry *e; if ( !( li->li_ops & LOG_OP_UNBIND )) return SLAP_CB_CONTINUE; e = accesslog_entry( op, LOG_EN_UNBIND, &op2 ); op2.o_hdr = op->o_hdr; op2.o_tag = LDAP_REQ_ADD; op2.o_bd = li->li_db; op2.o_dn = li->li_db->be_rootdn; op2.o_ndn = li->li_db->be_rootndn; op2.o_req_dn = e->e_name; op2.o_req_ndn = e->e_nname; op2.ora_e = e; op2.o_callback = &nullsc; op2.o_controls = cids; memset(cids, 0, sizeof( cids )); op2.o_bd->be_add( &op2, &rs2 ); entry_free( e ); } return SLAP_CB_CONTINUE;}static intaccesslog_abandon( Operation *op, SlapReply *rs ){ slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; log_info *li = on->on_bi.bi_private; Operation op2 = {0}; void *cids[SLAP_MAX_CIDS]; SlapReply rs2 = {REP_RESULT}; Entry *e; char buf[64]; struct berval bv; if ( !op->o_time || !( li->li_ops & LOG_OP_ABANDON )) return SLAP_CB_CONTINUE; e = accesslog_entry( op, LOG_EN_ABANDON, &op2 ); bv.bv_val = buf; bv.bv_len = sprintf( buf, "%d", op->orn_msgid ); attr_merge_one( e, ad_reqId, &bv, NULL ); op2.o_hdr = op->o_hdr; op2.o_tag = LDAP_REQ_ADD; op2.o_bd = li->li_db; op2.o_dn = li->li_db->be_rootdn; op2.o_ndn = li->li_db->be_rootndn; op2.o_req_dn = e->e_name; op2.o_req_ndn = e->e_nname; op2.ora_e = e; op2.o_callback = &nullsc; op2.o_controls = cids; memset(cids, 0, sizeof( cids )); op2.o_bd->be_add( &op2, &rs2 ); entry_free( e ); return SLAP_CB_CONTINUE;}static slap_overinst accesslog;static intaccesslog_db_init( BackendDB *be){ slap_overinst *on = (slap_overinst *)be->bd_info; log_info *li = ch_calloc(1, sizeof(log_info)); on->on_bi.bi_private = li; ldap_pvt_thread_mutex_init( &li->li_op_mutex ); ldap_pvt_thread_mutex_init( &li->li_log_mutex ); return 0;}static intaccesslog_db_destroy( BackendDB *be){ slap_overinst *on = (slap_overinst *)be->bd_info; log_info *li = on->on_bi.bi_private; if ( li->li_oldf ) filter_free( li->li_oldf ); ldap_pvt_thread_mutex_destroy( &li->li_log_mutex ); ldap_pvt_thread_mutex_destroy( &li->li_op_mutex ); free( li ); return LDAP_SUCCESS;}static intaccesslog_db_open( BackendDB *be){ slap_overinst *on = (slap_overinst *)be->bd_info; log_info *li = on->on_bi.bi_private; Connection conn; OperationBuffer opbuf; Operation *op = (Operation *) &opbuf; Entry *e; int rc; void *thrctx; if ( li->li_db == NULL ) { Debug( LDAP_DEBUG_ANY, "accesslog: \"logdb <suffix>\" must be specified.\n", 0, 0, 0 ); return 1; } if ( slapMode & SLAP_TOOL_MODE ) return 0; thrctx = ldap_pvt_thread_pool_context(); connection_fake_init( &conn, op, thrctx ); op->o_bd = li->li_db; op->o_dn = li->li_db->be_rootdn; op->o_ndn = li->li_db->be_rootndn; rc = be_entry_get_rw( op, li->li_db->be_nsuffix, NULL, NULL, 0, &e ); if ( e ) { be_entry_release_rw( op, e, 0 ); } else { SlapReply rs = {REP_RESULT}; struct berval rdn, nrdn, attr; char *ptr; AttributeDescription *ad = NULL; const char *text = NULL; Entry *e_ctx; e = ch_calloc( 1, sizeof( Entry )); e->e_name = *li->li_db->be_suffix; e->e_nname = *li->li_db->be_nsuffix; attr_merge_one( e, slap_schema.si_ad_objectClass, &log_container->soc_cname, NULL ); dnRdn( &e->e_name, &rdn ); dnRdn( &e->e_nname, &nrdn ); ptr = ber_bvchr( &rdn, '=' ); assert( ptr != NULL ); attr.bv_val = rdn.bv_val; attr.bv_len = ptr - rdn.bv_val; slap_bv2ad( &attr, &ad, &text ); rdn.bv_val = ptr+1; rdn.bv_len -= attr.bv_len + 1; ptr = ber_bvchr( &nrdn, '=' ); nrdn.bv_len -= ptr - nrdn.bv_val + 1; nrdn.bv_val = ptr+1; attr_merge_one( e, ad, &rdn, &nrdn ); /* Get contextCSN from main DB */ op->o_bd = be; op->o_bd->bd_info = on->on_info->oi_orig; rc = be_entry_get_rw( op, be->be_nsuffix, NULL, slap_schema.si_ad_contextCSN, 0, &e_ctx ); if ( e_ctx ) { Attribute *a; a = attr_find( e_ctx->e_attrs, slap_schema.si_ad_contextCSN ); if ( a ) { attr_merge( e, slap_schema.si_ad_entryCSN, a->a_vals, NULL ); attr_merge( e, a->a_desc, a->a_vals, NULL ); } be_entry_release_rw( op, e_ctx, 0 ); } op->o_bd->bd_info = (BackendInfo *)on; op->o_bd = li->li_db; op->ora_e = e; op->o_req_dn = e->e_name; op->o_req_ndn = e->e_nname; op->o_callback = &nullsc; SLAP_DBFLAGS( op->o_bd ) |= SLAP_DBFLAG_NOLASTMOD; rc = op->o_bd->be_add( op, &rs ); SLAP_DBFLAGS( op->o_bd ) ^= SLAP_DBFLAG_NOLASTMOD; attrs_free( e->e_attrs ); ch_free( e ); } return rc;}int accesslog_initialize(){ int i, rc; accesslog.on_bi.bi_type = "accesslog"; accesslog.on_bi.bi_db_init = accesslog_db_init; accesslog.on_bi.bi_db_destroy = accesslog_db_destroy; accesslog.on_bi.bi_db_open = accesslog_db_open; accesslog.on_bi.bi_op_add = accesslog_op_mod; accesslog.on_bi.bi_op_bind = accesslog_op_bind; accesslog.on_bi.bi_op_delete = accesslog_op_mod; accesslog.on_bi.bi_op_modify = accesslog_op_mod; accesslog.on_bi.bi_op_modrdn = accesslog_op_mod; accesslog.on_bi.bi_op_unbind = accesslog_unbind; accesslog.on_bi.bi_op_abandon = accesslog_abandon; accesslog.on_response = accesslog_response; accesslog.on_bi.bi_cf_ocs = log_cfocs; nullsc.sc_response = slap_null_cb; rc = config_register_schema( log_cfats, log_cfocs ); if ( rc ) return rc; /* log schema integration */ for ( i=0; lattrs[i].at; i++ ) { LDAPAttributeType *lat; AttributeType *at; int code; const char *err; lat = ldap_str2attributetype( lattrs[i].at, &code, &err, LDAP_SCHEMA_ALLOW_ALL ); if ( !lat ) { Debug( LDAP_DEBUG_ANY, "accesslog_init: " "ldap_str2attributetype failed on %d: %s, %s\n", i, ldap_scherr2str(code), err ); return -1; } code = at_add( lat, 0, &at, &err ); ldap_memfree( lat ); if ( code ) { Debug( LDAP_DEBUG_ANY, "log_back_initialize: " "at_add failed on %d: %s\n", i, scherr2str(code), 0 ); return -1; } if ( slap_bv2ad( &at->sat_cname, lattrs[i].ad, &err )) { Debug( LDAP_DEBUG_ANY, "accesslog_init: " "slap_bv2ad failed on %d: %s\n", i, err, 0 ); return -1; } } for ( i=0; locs[i].ot; i++ ) { LDAPObjectClass *loc; ObjectClass *oc; int code; const char *err; loc = ldap_str2objectclass( locs[i].ot, &code, &err, LDAP_SCHEMA_ALLOW_ALL ); if ( !loc ) { Debug( LDAP_DEBUG_ANY, "accesslog_init: " "ldap_str2objectclass failed on %d: %s, %s\n", i, ldap_scherr2str(code), err ); return -1; } code = oc_add( loc, 0, &oc, &err ); ldap_memfree( loc ); if ( code ) { Debug( LDAP_DEBUG_ANY, "accesslog_init: " "oc_add failed on %d: %s\n", i, scherr2str(code), 0 ); return -1; } if ( locs[i].oc ) *locs[i].oc = oc; } return overlay_register(&accesslog);}#if SLAPD_OVER_ACCESSLOG == SLAPD_MOD_DYNAMICintinit_module( int argc, char *argv[] ){ return accesslog_initialize();}#endif#endif /* SLAPD_OVER_ACCESSLOG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -