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