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 | |
d9898ee8 |
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 | |