Merge branch 'debian'
[hcoop/debian/courier-authlib.git] / debug.c
1 /*
2 ** Copyright 2002 Double Precision, Inc. See COPYING for
3 ** distribution information.
4 */
5
6 #include "auth.h"
7 #include "courierauthdebug.h"
8 #include <ctype.h>
9 #include <stdarg.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14
15 /* for internal use */
16
17 static int courier_authdebug( const char *ofmt, const char *fmt, va_list ap );
18
19 /*
20 ** 0 - dont debug
21 ** 1 - debug auth
22 ** 2 - debug auth + write out passwords
23 */
24
25 int courier_authdebug_login_level = 0;
26
27 /*
28 ** purpose: initialize debugging
29 ** function: read environment variable DEBUG_LOGIN
30 ** and set up debugging according to it
31 ** args: none
32 */
33
34 void courier_authdebug_login_init( void )
35 {
36 const char *p=getenv(DEBUG_LOGIN_ENV);
37
38 courier_authdebug_login_level = atoi( p ? p:"0" );
39 }
40
41 /*
42 ** purpose: print debug message to logger
43 ** does nothing if debug level is zero
44 ** adds prefix "DEBUG: " and suffix "\n"
45 ** Since we have a return value, we can use the convenient production
46 ** courier_authdebug_login_level && courier_authdebug_printf(...)
47 ** (as a macro, saves function calls when debugging is disabled)
48 */
49
50 int courier_authdebug_printf( const char *fmt, ... ) {
51
52 va_list ap;
53 int rc;
54
55 if (courier_authdebug_login_level == 0) return 0;
56 va_start( ap, fmt );
57 rc = courier_authdebug( "DEBUG: %s\n", fmt, ap );
58 va_end( ap );
59 return rc;
60 }
61
62 /*
63 * Print a string to stderr, replacing any control characters with dot and
64 * limiting the total message size, followed by a newline
65 */
66
67 int courier_safe_printf(const char *fmt, ...)
68 {
69 va_list ap;
70 int rc;
71
72 va_start( ap, fmt );
73 rc = courier_authdebug( "%s\n", fmt, ap );
74 va_end( ap );
75 return rc;
76 }
77
78 /** Print error log message **/
79
80 int courier_auth_err( const char *fmt, ... ) {
81
82 va_list ap;
83 int rc;
84
85 va_start( ap, fmt );
86 rc = courier_authdebug( "ERR: %s\n", fmt, ap );
87 va_end( ap );
88 return rc;
89 }
90
91 /*
92 ** purpose: print debug messages to logger - handy use
93 ** function: take message with logging level and drop
94 ** messages with too high level.
95 ** also include into the message the IP address
96 ** args:
97 ** * level - level to be compared with DEBUG_LOGIN env var.
98 ** * fmt - message format as like in printf().
99 ** * ... - and "arguments" for fmt
100 */
101
102 void courier_authdebug_login( int level, const char *fmt, ... ) {
103
104 va_list ap;
105 char ofmt[128];
106
107 /* logging severity */
108
109 if( level > courier_authdebug_login_level )
110 return;
111
112 snprintf( ofmt, sizeof ofmt, "DEBUG: LOGIN: ip=[%s], %%s\n", getenv("TCPREMOTEIP") );
113 va_start( ap, fmt );
114 courier_authdebug( ofmt, fmt, ap );
115 va_end( ap );
116 }
117
118 /*
119 ** purpose: print debug messages to logger - general use
120 ** function: read format string and arguments
121 ** and convert them to suitable form for output.
122 ** args:
123 ** ofmt- printf() format string for output, where %s = the assembled text
124 ** fmt - printf() format string for arguments
125 ** ... - variable arguments
126 */
127
128 static int courier_authdebug( const char *ofmt, const char *fmt, va_list ap )
129 {
130
131 char buf[DEBUG_MESSAGE_SIZE];
132 int i;
133 int len;
134
135 /* print into buffer to be able to replace control and other unwanted chars. */
136 vsnprintf( buf, DEBUG_MESSAGE_SIZE, fmt, ap );
137 len = strlen( buf );
138
139 /* replace nonprintable chars by dot */
140 for( i=0 ; i<len ; i++ )
141 if( !isprint(buf[i]) )
142 buf[i] = '.';
143
144 /* emit it */
145
146 return fprintf( stderr, ofmt , buf );
147 }
148
149 /*
150 * Print the information retrieved from the database into struct authinfo.
151 *
152 * The structure members 'clearpasswd' and 'passwd' are not always set at
153 * the point where this function is called, so we take separate values
154 * for these
155 */
156
157 int courier_authdebug_authinfo(const char *pfx, const struct authinfo *auth,
158 const char *clearpasswd, const char *passwd)
159 {
160 char uidstr[32] = "<null>";
161
162 if (!courier_authdebug_login_level) return 0;
163
164 if (auth->sysuserid)
165 snprintf(uidstr, sizeof uidstr, "%ld", (long)*auth->sysuserid);
166 fprintf(stderr, "%ssysusername=%s, sysuserid=%s, "
167 "sysgroupid=%ld, homedir=%s, address=%s, fullname=%s, "
168 "maildir=%s, quota=%s, options=%s\n", pfx,
169 auth->sysusername ? auth->sysusername : "<null>",
170 uidstr, (long)auth->sysgroupid,
171 auth->homedir ? auth->homedir : "<null>",
172 auth->address ? auth->address : "<null>",
173 auth->fullname ? auth->fullname : "<null>",
174 auth->maildir ? auth->maildir : "<null>",
175 auth->quota ? auth->quota : "<null>",
176 auth->options ? auth->options : "<null>");
177 if (courier_authdebug_login_level >= 2)
178 fprintf(stderr, "%sclearpasswd=%s, passwd=%s\n", pfx,
179 clearpasswd ? clearpasswd : "<null>",
180 passwd ? passwd : "<null>");
181 return 0;
182 }
183