⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 accesslog.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* accesslog.c - log operations for audit/history purposes *//* $OpenLDAP: pkg/ldap/servers/slapd/overlays/accesslog.c,v 1.2.2.23 2007/01/25 12:42:01 hyc Exp $ *//* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 2005-2007 The OpenLDAP Foundation. * Portions copyright 2004-2005 Symas Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * Public License. * * A copy of this license is available in the file LICENSE in the * top-level directory of the distribution or, alternatively, at * <http://www.OpenLDAP.org/license.html>. *//* ACKNOWLEDGEMENTS: * This work was initially developed by Howard Chu for inclusion in * OpenLDAP Software. */#include "portable.h"#ifdef SLAPD_OVER_ACCESSLOG#include <stdio.h>#include <ac/string.h>#include <ac/ctype.h>#include "slap.h"#include "config.h"#include "lutil.h"#include "ldap_rq.h"#define LOG_OP_ADD	0x001#define LOG_OP_DELETE	0x002#define	LOG_OP_MODIFY	0x004#define LOG_OP_MODRDN	0x008#define	LOG_OP_COMPARE	0x010#define	LOG_OP_SEARCH	0x020#define LOG_OP_BIND	0x040#define LOG_OP_UNBIND	0x080#define	LOG_OP_ABANDON	0x100#define	LOG_OP_EXTENDED	0x200#define LOG_OP_UNKNOWN	0x400#define	LOG_OP_WRITES	(LOG_OP_ADD|LOG_OP_DELETE|LOG_OP_MODIFY|LOG_OP_MODRDN)#define	LOG_OP_READS	(LOG_OP_COMPARE|LOG_OP_SEARCH)#define	LOG_OP_SESSION	(LOG_OP_BIND|LOG_OP_UNBIND|LOG_OP_ABANDON)#define LOG_OP_ALL		(LOG_OP_READS|LOG_OP_WRITES|LOG_OP_SESSION| \	LOG_OP_EXTENDED|LOG_OP_UNKNOWN)typedef struct log_info {	BackendDB *li_db;	slap_mask_t li_ops;	int li_age;	int li_cycle;	struct re_s *li_task;	Filter *li_oldf;	Entry *li_old;	int li_success;	ldap_pvt_thread_mutex_t li_op_mutex;	ldap_pvt_thread_mutex_t li_log_mutex;} log_info;static ConfigDriver log_cf_gen;enum {	LOG_DB = 1,	LOG_OPS,	LOG_PURGE,	LOG_SUCCESS,	LOG_OLD};static ConfigTable log_cfats[] = {	{ "logdb", "suffix", 2, 2, 0, ARG_DN|ARG_MAGIC|LOG_DB,		log_cf_gen, "( OLcfgOvAt:4.1 NAME 'olcAccessLogDB' "			"DESC 'Suffix of database for log content' "			"SUP distinguishedName SINGLE-VALUE )", NULL, NULL },	{ "logops", "op|writes|reads|session|all", 2, 0, 0,		ARG_MAGIC|LOG_OPS,		log_cf_gen, "( OLcfgOvAt:4.2 NAME 'olcAccessLogOps' "			"DESC 'Operation types to log' "			"EQUALITY caseIgnoreMatch "			"SYNTAX OMsDirectoryString )", NULL, NULL },	{ "logpurge", "age> <interval", 3, 3, 0, ARG_MAGIC|LOG_PURGE,		log_cf_gen, "( OLcfgOvAt:4.3 NAME 'olcAccessLogPurge' "			"DESC 'Log cleanup parameters' "			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },	{ "logsuccess", NULL, 2, 2, 0, ARG_MAGIC|ARG_ON_OFF|LOG_SUCCESS,		log_cf_gen, "( OLcfgOvAt:4.4 NAME 'olcAccessLogSuccess' "			"DESC 'Log successful ops only' "			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },	{ "logold", "filter", 2, 2, 0, ARG_MAGIC|LOG_OLD,		log_cf_gen, "( OLcfgOvAt:4.5 NAME 'olcAccessLogOld' "			"DESC 'Log old values when modifying entries matching the filter' "			"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },	{ NULL }};static ConfigOCs log_cfocs[] = {	{ "( OLcfgOvOc:4.1 "		"NAME 'olcAccessLogConfig' "		"DESC 'Access log configuration' "		"SUP olcOverlayConfig "		"MUST olcAccessLogDB "		"MAY ( olcAccessLogOps $ olcAccessLogPurge $ olcAccessLogSuccess $ "			"olcAccessLogOld ) )",			Cft_Overlay, log_cfats },	{ NULL }};static slap_verbmasks logops[] = {	{ BER_BVC("all"),		LOG_OP_ALL },	{ BER_BVC("writes"),	LOG_OP_WRITES },	{ BER_BVC("session"),	LOG_OP_SESSION },	{ BER_BVC("reads"),		LOG_OP_READS },	{ BER_BVC("add"),		LOG_OP_ADD },	{ BER_BVC("delete"),	LOG_OP_DELETE },	{ BER_BVC("modify"),	LOG_OP_MODIFY },	{ BER_BVC("modrdn"),	LOG_OP_MODRDN },	{ BER_BVC("compare"),	LOG_OP_COMPARE },	{ BER_BVC("search"),	LOG_OP_SEARCH },	{ BER_BVC("bind"),		LOG_OP_BIND },	{ BER_BVC("unbind"),	LOG_OP_UNBIND },	{ BER_BVC("abandon"),	LOG_OP_ABANDON },	{ BER_BVC("extended"),	LOG_OP_EXTENDED },	{ BER_BVC("unknown"),	LOG_OP_UNKNOWN },	{ BER_BVNULL, 0 }};/* Start with "add" in logops */#define EN_OFFSET	4enum {	LOG_EN_ADD = 0,	LOG_EN_DELETE,	LOG_EN_MODIFY,	LOG_EN_MODRDN,	LOG_EN_COMPARE,	LOG_EN_SEARCH,	LOG_EN_BIND,	LOG_EN_UNBIND,	LOG_EN_ABANDON,	LOG_EN_EXTENDED,	LOG_EN_UNKNOWN,	LOG_EN__COUNT};static ObjectClass *log_ocs[LOG_EN__COUNT], *log_container;#define LOG_SCHEMA_ROOT	"1.3.6.1.4.1.4203.666.11.5"#define LOG_SCHEMA_AT LOG_SCHEMA_ROOT ".1"#define LOG_SCHEMA_OC LOG_SCHEMA_ROOT ".2"static AttributeDescription *ad_reqDN, *ad_reqStart, *ad_reqEnd, *ad_reqType,	*ad_reqSession, *ad_reqResult, *ad_reqAuthzID, *ad_reqControls,	*ad_reqRespControls, *ad_reqMethod, *ad_reqAssertion, *ad_reqNewRDN,	*ad_reqNewSuperior, *ad_reqDeleteOldRDN, *ad_reqMod,	*ad_reqScope, *ad_reqFilter, *ad_reqAttr, *ad_reqEntries,	*ad_reqSizeLimit, *ad_reqTimeLimit, *ad_reqAttrsOnly, *ad_reqData,	*ad_reqId, *ad_reqMessage, *ad_reqVersion, *ad_reqDerefAliases,	*ad_reqReferral, *ad_reqOld;static struct {	char *at;	AttributeDescription **ad;} lattrs[] = {	{ "( " LOG_SCHEMA_AT ".1 NAME 'reqDN' "		"DESC 'Target DN of request' "		"EQUALITY distinguishedNameMatch "		"SYNTAX OMsDN "		"SINGLE-VALUE )", &ad_reqDN },	{ "( " LOG_SCHEMA_AT ".2 NAME 'reqStart' "		"DESC 'Start time of request' "		"EQUALITY generalizedTimeMatch "		"ORDERING generalizedTimeOrderingMatch "		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "		"SINGLE-VALUE )", &ad_reqStart },	{ "( " LOG_SCHEMA_AT ".3 NAME 'reqEnd' "		"DESC 'End time of request' "		"EQUALITY generalizedTimeMatch "		"ORDERING generalizedTimeOrderingMatch "		"SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 "		"SINGLE-VALUE )", &ad_reqEnd },	{ "( " LOG_SCHEMA_AT ".4 NAME 'reqType' "		"DESC 'Type of request' "		"EQUALITY caseIgnoreMatch "		"SYNTAX OMsDirectoryString "		"SINGLE-VALUE )", &ad_reqType },	{ "( " LOG_SCHEMA_AT ".5 NAME 'reqSession' "		"DESC 'Session ID of request' "		"EQUALITY caseIgnoreMatch "		"SYNTAX OMsDirectoryString "		"SINGLE-VALUE )", &ad_reqSession },	{ "( " LOG_SCHEMA_AT ".6 NAME 'reqAuthzID' "		"DESC 'Authorization ID of requestor' "		"EQUALITY distinguishedNameMatch "		"SYNTAX OMsDN "		"SINGLE-VALUE )", &ad_reqAuthzID },	{ "( " LOG_SCHEMA_AT ".7 NAME 'reqResult' "		"DESC 'Result code of request' "		"EQUALITY integerMatch "		"ORDERING integerOrderingMatch "		"SYNTAX OMsInteger "		"SINGLE-VALUE )", &ad_reqResult },	{ "( " LOG_SCHEMA_AT ".8 NAME 'reqMessage' "		"DESC 'Error text of request' "		"EQUALITY caseIgnoreMatch "		"SUBSTR caseIgnoreSubstringsMatch "		"SYNTAX OMsDirectoryString "		"SINGLE-VALUE )", &ad_reqMessage },	{ "( " LOG_SCHEMA_AT ".9 NAME 'reqReferral' "		"DESC 'Referrals returned for request' "		"SUP labeledURI )", &ad_reqReferral },	{ "( " LOG_SCHEMA_AT ".10 NAME 'reqControls' "		"DESC 'Request controls' "		"SYNTAX OMsOctetString )", &ad_reqControls },	{ "( " LOG_SCHEMA_AT ".11 NAME 'reqRespControls' "		"DESC 'Response controls of request' "		"SYNTAX OMsOctetString )", &ad_reqRespControls },	{ "( " LOG_SCHEMA_AT ".12 NAME 'reqId' "		"DESC 'ID of Request to Abandon' "		"EQUALITY integerMatch "		"ORDERING integerOrderingMatch "		"SYNTAX OMsInteger "		"SINGLE-VALUE )", &ad_reqId },	{ "( " LOG_SCHEMA_AT ".13 NAME 'reqVersion' "		"DESC 'Protocol version of Bind request' "		"EQUALITY integerMatch "		"ORDERING integerOrderingMatch "		"SYNTAX OMsInteger "		"SINGLE-VALUE )", &ad_reqVersion },	{ "( " LOG_SCHEMA_AT ".14 NAME 'reqMethod' "		"DESC 'Bind method of request' "		"EQUALITY caseIgnoreMatch "		"SYNTAX OMsDirectoryString "		"SINGLE-VALUE )", &ad_reqMethod },	{ "( " LOG_SCHEMA_AT ".15 NAME 'reqAssertion' "		"DESC 'Compare Assertion of request' "		"SYNTAX OMsDirectoryString "		"SINGLE-VALUE )", &ad_reqAssertion },	{ "( " LOG_SCHEMA_AT ".16 NAME 'reqMod' "		"DESC 'Modifications of request' "		"EQUALITY octetStringMatch "		"SUBSTR octetStringSubstringsMatch "		"SYNTAX OMsOctetString )", &ad_reqMod },	{ "( " LOG_SCHEMA_AT ".17 NAME 'reqOld' "		"DESC 'Old values of entry before request completed' "		"EQUALITY octetStringMatch "		"SUBSTR octetStringSubstringsMatch "		"SYNTAX OMsOctetString )", &ad_reqOld },	{ "( " LOG_SCHEMA_AT ".18 NAME 'reqNewRDN' "		"DESC 'New RDN of request' "		"EQUALITY distinguishedNameMatch "		"SYNTAX OMsDN "		"SINGLE-VALUE )", &ad_reqNewRDN },	{ "( " LOG_SCHEMA_AT ".19 NAME 'reqDeleteOldRDN' "		"DESC 'Delete old RDN' "		"EQUALITY booleanMatch "		"SYNTAX OMsBoolean "		"SINGLE-VALUE )", &ad_reqDeleteOldRDN },	{ "( " LOG_SCHEMA_AT ".20 NAME 'reqNewSuperior' "		"DESC 'New superior DN of request' "		"EQUALITY distinguishedNameMatch "		"SYNTAX OMsDN "		"SINGLE-VALUE )", &ad_reqNewSuperior },	{ "( " LOG_SCHEMA_AT ".21 NAME 'reqScope' "		"DESC 'Scope of request' "		"EQUALITY caseIgnoreMatch "		"SYNTAX OMsDirectoryString "		"SINGLE-VALUE )", &ad_reqScope },	{ "( " LOG_SCHEMA_AT ".22 NAME 'reqDerefAliases' "		"DESC 'Disposition of Aliases in request' "		"EQUALITY caseIgnoreMatch "		"SYNTAX OMsDirectoryString "		"SINGLE-VALUE )", &ad_reqDerefAliases },	{ "( " LOG_SCHEMA_AT ".23 NAME 'reqAttrsOnly' "		"DESC 'Attributes and values of request' "		"EQUALITY booleanMatch "		"SYNTAX OMsBoolean "		"SINGLE-VALUE )", &ad_reqAttrsOnly },	{ "( " LOG_SCHEMA_AT ".24 NAME 'reqFilter' "		"DESC 'Filter of request' "		"EQUALITY caseIgnoreMatch "		"SUBSTR caseIgnoreSubstringsMatch "		"SYNTAX OMsDirectoryString "		"SINGLE-VALUE )", &ad_reqFilter },	{ "( " LOG_SCHEMA_AT ".25 NAME 'reqAttr' "		"DESC 'Attributes of request' "		"EQUALITY caseIgnoreMatch "		"SYNTAX OMsDirectoryString )", &ad_reqAttr },	{ "( " LOG_SCHEMA_AT ".26 NAME 'reqSizeLimit' "		"DESC 'Size limit of request' "		"EQUALITY integerMatch "		"ORDERING integerOrderingMatch "		"SYNTAX OMsInteger "		"SINGLE-VALUE )", &ad_reqSizeLimit },	{ "( " LOG_SCHEMA_AT ".27 NAME 'reqTimeLimit' "		"DESC 'Time limit of request' "		"EQUALITY integerMatch "		"ORDERING integerOrderingMatch "		"SYNTAX OMsInteger "		"SINGLE-VALUE )", &ad_reqTimeLimit },	{ "( " LOG_SCHEMA_AT ".28 NAME 'reqEntries' "		"DESC 'Number of entries returned' "		"EQUALITY integerMatch "		"ORDERING integerOrderingMatch "		"SYNTAX OMsInteger "		"SINGLE-VALUE )", &ad_reqEntries },	{ "( " LOG_SCHEMA_AT ".29 NAME 'reqData' "		"DESC 'Data of extended request' "		"EQUALITY octetStringMatch "		"SUBSTR octetStringSubstringsMatch "		"SYNTAX OMsOctetString "		"SINGLE-VALUE )", &ad_reqData },	{ NULL, NULL }};static struct {	char *ot;	ObjectClass **oc;} locs[] = {	{ "( " LOG_SCHEMA_OC ".0 NAME 'auditContainer' "		"DESC 'AuditLog container' "		"SUP top STRUCTURAL "		"MAY ( cn $ reqStart $ reqEnd ) )", &log_container },	{ "( " LOG_SCHEMA_OC ".1 NAME 'auditObject' "		"DESC 'OpenLDAP request auditing' "		"SUP top STRUCTURAL "		"MUST ( reqStart $ reqType $ reqSession ) "		"MAY ( reqDN $ reqAuthzID $ reqControls $ reqRespControls $ reqEnd $ "			"reqResult $ reqMessage $ reqReferral ) )",				&log_ocs[LOG_EN_UNBIND] },	{ "( " LOG_SCHEMA_OC ".2 NAME 'auditReadObject' "		"DESC 'OpenLDAP read request record' "		"SUP auditObject STRUCTURAL )", NULL },	{ "( " LOG_SCHEMA_OC ".3 NAME 'auditWriteObject' "		"DESC 'OpenLDAP write request record' "		"SUP auditObject STRUCTURAL )", NULL },	{ "( " LOG_SCHEMA_OC ".4 NAME 'auditAbandon' "		"DESC 'Abandon operation' "		"SUP auditObject STRUCTURAL "		"MUST reqId )", &log_ocs[LOG_EN_ABANDON] },	{ "( " LOG_SCHEMA_OC ".5 NAME 'auditAdd' "		"DESC 'Add operation' "		"SUP auditWriteObject STRUCTURAL "		"MUST reqMod )", &log_ocs[LOG_EN_ADD] },	{ "( " LOG_SCHEMA_OC ".6 NAME 'auditBind' "		"DESC 'Bind operation' "		"SUP auditObject STRUCTURAL "		"MUST ( reqVersion $ reqMethod ) )", &log_ocs[LOG_EN_BIND] },	{ "( " LOG_SCHEMA_OC ".7 NAME 'auditCompare' "		"DESC 'Compare operation' "		"SUP auditReadObject STRUCTURAL "		"MUST reqAssertion )", &log_ocs[LOG_EN_COMPARE] },	{ "( " LOG_SCHEMA_OC ".8 NAME 'auditDelete' "		"DESC 'Delete operation' "		"SUP auditWriteObject STRUCTURAL "		"MAY reqOld )", &log_ocs[LOG_EN_DELETE] },	{ "( " LOG_SCHEMA_OC ".9 NAME 'auditModify' "		"DESC 'Modify operation' "		"SUP auditWriteObject STRUCTURAL "		"MAY reqOld MUST reqMod )", &log_ocs[LOG_EN_MODIFY] },	{ "( " LOG_SCHEMA_OC ".10 NAME 'auditModRDN' "		"DESC 'ModRDN operation' "		"SUP auditWriteObject STRUCTURAL "		"MUST ( reqNewRDN $ reqDeleteOldRDN ) "		"MAY reqNewSuperior )", &log_ocs[LOG_EN_MODRDN] },	{ "( " LOG_SCHEMA_OC ".11 NAME 'auditSearch' "		"DESC 'Search operation' "		"SUP auditReadObject STRUCTURAL "		"MUST ( reqScope $ reqDerefAliases $ reqAttrsonly ) "		"MAY ( reqFilter $ reqAttr $ reqEntries $ reqSizeLimit $ "			"reqTimeLimit ) )", &log_ocs[LOG_EN_SEARCH] },	{ "( " LOG_SCHEMA_OC ".12 NAME 'auditExtended' "		"DESC 'Extended operation' "		"SUP auditObject STRUCTURAL "		"MAY reqData )", &log_ocs[LOG_EN_EXTENDED] },	{ NULL, NULL }};#define	RDNEQ	"reqStart="/* Our time intervals are of the form [ddd+]hh:mm[:ss] * If a field is present, it must be two digits. (Except for * days, which can be arbitrary width.) */static intlog_age_parse(char *agestr){	int t1, t2;	int gotdays = 0;	char *endptr;	t1 = strtol( agestr, &endptr, 10 );	/* Is there a days delimiter? */	if ( *endptr == '+' ) {		/* 32 bit time only covers about 68 years */		if ( t1 < 0 || t1 > 25000 )			return -1;		t1 *= 24;		gotdays = 1;		agestr = endptr + 1;	} else {		if ( agestr[2] != ':' ) {			/* No valid delimiter found, fail */			return -1;		}		t1 *= 60;		agestr += 3;	}	t2 = atoi( agestr );	t1 += t2;	if ( agestr[2] ) {		/* if there's a delimiter, it can only be a colon */		if ( agestr[2] != ':' )			return -1;	} else {		/* If we're at the end of the string, and we started with days,		 * fail because we expected to find minutes too.		 */		return gotdays ? -1 : t1 * 60;	}	agestr += 3;	t2 = atoi( agestr );	/* last field can only be seconds */	if ( agestr[2] && ( agestr[2] != ':' || !gotdays ))		return -1;	t1 *= 60;	t1 += t2;	if ( agestr[2] ) {		agestr += 3;		if ( agestr[2] )			return -1;		t1 *= 60;		t1 += atoi( agestr );	} else if ( gotdays ) {		/* only got days+hh:mm */		t1 *= 60;	}	return t1;}static voidlog_age_unparse( int age, struct berval *agebv ){	int dd, hh, mm, ss;	char *ptr;	ss = age % 60;	age /= 60;	mm = age % 60;	age /= 60;	hh = age % 24;	age /= 24;	dd = age;	ptr = agebv->bv_val;	if ( dd ) 		ptr += sprintf( ptr, "%d+", dd );	ptr += sprintf( ptr, "%02d:%02d", hh, mm );	if ( ss )		ptr += sprintf( ptr, ":%02d", ss );	agebv->bv_len = ptr - agebv->bv_val;}static slap_callback nullsc = { NULL, NULL, NULL, NULL };#define PURGE_INCREMENT	100typedef struct purge_data {	int slots;	int used;	BerVarray dn;	BerVarray ndn;	struct berval csn;	/* an arbitrary old CSN */} purge_data;static intlog_old_lookup( Operation *op, SlapReply *rs ){	purge_data *pd = op->o_callback->sc_private;	if ( rs->sr_type != REP_SEARCH) return 0;	if ( slapd_shutdown ) return 0;	/* Remember old CSN */	if ( pd->csn.bv_val[0] == '\0' ) {		Attribute *a = attr_find( rs->sr_entry->e_attrs,			slap_schema.si_ad_entryCSN );		if ( a ) {			int len = a->a_vals[0].bv_len;			if ( len > pd->csn.bv_len )				len = pd->csn.bv_len;			AC_MEMCPY( pd->csn.bv_val, a->a_vals[0].bv_val, len );			pd->csn.bv_len = len;		}	}	if ( pd->used >= pd->slots ) {		pd->slots += PURGE_INCREMENT;		pd->dn = ch_realloc( pd->dn, pd->slots * sizeof( struct berval ));		pd->ndn = ch_realloc( pd->ndn, pd->slots * sizeof( struct berval ));	}	ber_dupbv( &pd->dn[pd->used], &rs->sr_entry->e_name );	ber_dupbv( &pd->ndn[pd->used], &rs->sr_entry->e_nname );	pd->used++;	return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -