1/* trace.c - traces overlay invocation */
2/* $OpenLDAP$ */
3/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 *
5 * Copyright 2006-2011 The OpenLDAP Foundation.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
10 * Public License.
11 *
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
15 */
16/* ACKNOWLEDGEMENTS:
17 * This work was initially developed by Pierangelo Masarati for inclusion in
18 * OpenLDAP Software.
19 */
20
21#include "portable.h"
22
23#ifdef SLAPD_OVER_TRACE
24
25#include <stdio.h>
26
27#include <ac/string.h>
28#include <ac/socket.h>
29
30#include "slap.h"
31#include "lutil.h"
32
33static int
34trace_op2str( Operation *op, char **op_strp )
35{
36	switch ( op->o_tag ) {
37	case LDAP_REQ_BIND:
38		*op_strp = "BIND";
39		break;
40
41	case LDAP_REQ_UNBIND:
42		*op_strp = "UNBIND";
43		break;
44
45	case LDAP_REQ_SEARCH:
46		*op_strp = "SEARCH";
47		break;
48
49	case LDAP_REQ_MODIFY:
50		*op_strp = "MODIFY";
51		break;
52
53	case LDAP_REQ_ADD:
54		*op_strp = "ADD";
55		break;
56
57	case LDAP_REQ_DELETE:
58		*op_strp = "DELETE";
59		break;
60
61	case LDAP_REQ_MODRDN:
62		*op_strp = "MODRDN";
63		break;
64
65	case LDAP_REQ_COMPARE:
66		*op_strp = "COMPARE";
67		break;
68
69	case LDAP_REQ_ABANDON:
70		*op_strp = "ABANDON";
71		break;
72
73	case LDAP_REQ_EXTENDED:
74		*op_strp = "EXTENDED";
75		break;
76
77	default:
78		assert( 0 );
79	}
80
81	return 0;
82}
83
84static int
85trace_op_func( Operation *op, SlapReply *rs )
86{
87	char	*op_str = NULL;
88
89	(void)trace_op2str( op, &op_str );
90
91	switch ( op->o_tag ) {
92	case LDAP_REQ_EXTENDED:
93		Log3( LDAP_DEBUG_ANY, LDAP_LEVEL_INFO,
94			"%s trace op=EXTENDED dn=\"%s\" reqoid=%s\n",
95			op->o_log_prefix,
96			BER_BVISNULL( &op->o_req_ndn ) ? "(null)" : op->o_req_ndn.bv_val,
97			BER_BVISNULL( &op->ore_reqoid ) ? "" : op->ore_reqoid.bv_val );
98		break;
99
100	default:
101		Log3( LDAP_DEBUG_ANY, LDAP_LEVEL_INFO,
102			"%s trace op=%s dn=\"%s\"\n",
103			op->o_log_prefix, op_str,
104			BER_BVISNULL( &op->o_req_ndn ) ? "(null)" : op->o_req_ndn.bv_val );
105		break;
106	}
107
108	return SLAP_CB_CONTINUE;
109}
110
111static int
112trace_response( Operation *op, SlapReply *rs )
113{
114	char	*op_str = NULL;
115
116	(void)trace_op2str( op, &op_str );
117
118	switch ( op->o_tag ) {
119	case LDAP_REQ_EXTENDED:
120		Log5( LDAP_DEBUG_ANY, LDAP_LEVEL_INFO,
121			"%s trace op=EXTENDED RESPONSE dn=\"%s\" reqoid=%s rspoid=%s err=%d\n",
122			op->o_log_prefix,
123			BER_BVISNULL( &op->o_req_ndn ) ? "(null)" : op->o_req_ndn.bv_val,
124			BER_BVISNULL( &op->ore_reqoid ) ? "" : op->ore_reqoid.bv_val,
125			rs->sr_rspoid == NULL ? "" : rs->sr_rspoid,
126			rs->sr_err );
127		break;
128
129	case LDAP_REQ_SEARCH:
130		switch ( rs->sr_type ) {
131		case REP_SEARCH:
132			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_INFO,
133				"%s trace op=SEARCH ENTRY dn=\"%s\"\n",
134				op->o_log_prefix,
135				rs->sr_entry->e_name.bv_val );
136			goto done;
137
138		case REP_SEARCHREF:
139			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_INFO,
140				"%s trace op=SEARCH REFERENCE ref=\"%s\"\n",
141				op->o_log_prefix,
142				rs->sr_ref[ 0 ].bv_val );
143			goto done;
144
145		case REP_RESULT:
146			break;
147
148		default:
149			assert( 0 );
150		}
151		/* fallthru */
152
153	default:
154		Log4( LDAP_DEBUG_ANY, LDAP_LEVEL_INFO,
155			"%s trace op=%s RESPONSE dn=\"%s\" err=%d\n",
156			op->o_log_prefix,
157			op_str,
158			BER_BVISNULL( &op->o_req_ndn ) ? "(null)" : op->o_req_ndn.bv_val,
159			rs->sr_err );
160		break;
161	}
162
163done:;
164	return SLAP_CB_CONTINUE;
165}
166
167static int
168trace_db_init(
169	BackendDB *be )
170{
171	Log0( LDAP_DEBUG_ANY, LDAP_LEVEL_INFO,
172		"trace DB_INIT\n" );
173
174	return 0;
175}
176
177static int
178trace_db_config(
179	BackendDB	*be,
180	const char	*fname,
181	int		lineno,
182	int		argc,
183	char		**argv )
184{
185	Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_INFO,
186		"trace DB_CONFIG argc=%d argv[0]=\"%s\"\n",
187		argc, argv[ 0 ] );
188
189	return 0;
190}
191
192static int
193trace_db_open(
194	BackendDB *be )
195{
196	Log0( LDAP_DEBUG_ANY, LDAP_LEVEL_INFO,
197		"trace DB_OPEN\n" );
198
199	return 0;
200}
201
202static int
203trace_db_close(
204	BackendDB *be )
205{
206	Log0( LDAP_DEBUG_ANY, LDAP_LEVEL_INFO,
207		"trace DB_CLOSE\n" );
208
209	return 0;
210}
211
212static int
213trace_db_destroy(
214	BackendDB *be )
215{
216	Log0( LDAP_DEBUG_ANY, LDAP_LEVEL_INFO,
217		"trace DB_DESTROY\n" );
218
219	return 0;
220}
221
222static slap_overinst 		trace;
223
224int
225trace_initialize()
226{
227	trace.on_bi.bi_type = "trace";
228
229	trace.on_bi.bi_db_init = trace_db_init;
230	trace.on_bi.bi_db_open = trace_db_open;
231	trace.on_bi.bi_db_config = trace_db_config;
232	trace.on_bi.bi_db_close = trace_db_close;
233	trace.on_bi.bi_db_destroy = trace_db_destroy;
234
235	trace.on_bi.bi_op_add = trace_op_func;
236	trace.on_bi.bi_op_bind = trace_op_func;
237	trace.on_bi.bi_op_unbind = trace_op_func;
238	trace.on_bi.bi_op_compare = trace_op_func;
239	trace.on_bi.bi_op_delete = trace_op_func;
240	trace.on_bi.bi_op_modify = trace_op_func;
241	trace.on_bi.bi_op_modrdn = trace_op_func;
242	trace.on_bi.bi_op_search = trace_op_func;
243	trace.on_bi.bi_op_abandon = trace_op_func;
244	trace.on_bi.bi_extended = trace_op_func;
245
246	trace.on_response = trace_response;
247
248	return overlay_register( &trace );
249}
250
251#if SLAPD_OVER_TRACE == SLAPD_MOD_DYNAMIC
252int
253init_module( int argc, char *argv[] )
254{
255	return trace_initialize();
256}
257#endif /* SLAPD_OVER_TRACE == SLAPD_MOD_DYNAMIC */
258
259#endif /* defined(SLAPD_OVER_TRACE) */
260