linux-pam (1.5.3)
1 #ifndef PAM_MACROS_H
2 #define PAM_MACROS_H
3
4 /*
5 * All kind of macros used by PAM, but usable in some other
6 * programs too.
7 * Organized by Cristian Gafton <gafton@redhat.com>
8 */
9
10 #include "_pam_types.h"
11
12 /* a 'safe' version of strdup */
13
14 #include <stdlib.h>
15 #include <string.h>
16
17 #define x_strdup(s) ( (s) ? strdup(s):NULL )
18
19 /*
20 * WARNING: Do NOT use these overwrite macros, as they do not reliable
21 * override the memory.
22 */
23
24 #define _pam_overwrite(x) \
25 do { \
26 PAM_DEPRECATED register char *__xx__; \
27 if ((__xx__=(x))) \
28 while (*__xx__) \
29 *__xx__++ = '\0'; \
30 } while (0)
31
32 #define _pam_overwrite_n(x,n) \
33 do { \
34 PAM_DEPRECATED register char *__xx__; \
35 register unsigned int __i__ = 0; \
36 if ((__xx__=(x))) \
37 for (;__i__<n; __i__++) \
38 __xx__[__i__] = 0; \
39 } while (0)
40
41 /*
42 * Don't just free it, forget it too.
43 */
44
45 #define _pam_drop(X) \
46 do { \
47 if (X) { \
48 free(X); \
49 X=NULL; \
50 } \
51 } while (0)
52
53 /*
54 * WARNING: Do NOT use this macro, as it does not reliable override the memory.
55 */
56
57 #define _pam_drop_reply(/* struct pam_response * */ reply, /* int */ replies) \
58 do { \
59 PAM_DEPRECATED int reply_i; \
60 \
61 for (reply_i=0; reply_i<replies; ++reply_i) { \
62 if (reply[reply_i].resp) { \
63 _pam_overwrite(reply[reply_i].resp); \
64 free(reply[reply_i].resp); \
65 } \
66 } \
67 if (reply) \
68 free(reply); \
69 } while (0)
70
71 /* some debugging code */
72
73 #ifdef PAM_DEBUG
74
75 /*
76 * This provides the necessary function to do debugging in PAM.
77 * Cristian Gafton <gafton@redhat.com>
78 */
79
80 #include <stdio.h>
81 #include <sys/types.h>
82 #include <stdarg.h>
83 #include <errno.h>
84 #include <sys/stat.h>
85 #include <fcntl.h>
86 #include <unistd.h>
87
88 /*
89 * This is for debugging purposes ONLY. DO NOT use on live systems !!!
90 * You have been warned :-) - CG
91 *
92 * to get automated debugging to the log file, it must be created manually.
93 * _PAM_LOGFILE must exist and be writable to the programs you debug.
94 */
95
96 #ifndef _PAM_LOGFILE
97 #define _PAM_LOGFILE "/var/run/pam-debug.log"
98 #endif
99
100 static void _pam_output_debug_info(const char *file, const char *fn
101 , const int line)
102 {
103 FILE *logfile;
104 int must_close = 1, fd;
105
106 #ifdef O_NOFOLLOW
107 if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_NOFOLLOW|O_APPEND)) != -1) {
108 #else
109 if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_APPEND)) != -1) {
110 #endif
111 if (!(logfile = fdopen(fd,"a"))) {
112 logfile = stderr;
113 must_close = 0;
114 close(fd);
115 }
116 } else {
117 logfile = stderr;
118 must_close = 0;
119 }
120 fprintf(logfile,"[%s:%s(%d)] ",file, fn, line);
121 fflush(logfile);
122 if (must_close)
123 fclose(logfile);
124 }
125
126 static void _pam_output_debug(const char *format, ...)
127 {
128 va_list args;
129 FILE *logfile;
130 int must_close = 1, fd;
131
132 va_start(args, format);
133
134 #ifdef O_NOFOLLOW
135 if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_NOFOLLOW|O_APPEND)) != -1) {
136 #else
137 if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_APPEND)) != -1) {
138 #endif
139 if (!(logfile = fdopen(fd,"a"))) {
140 logfile = stderr;
141 must_close = 0;
142 close(fd);
143 }
144 } else {
145 logfile = stderr;
146 must_close = 0;
147 }
148 vfprintf(logfile, format, args);
149 fprintf(logfile, "\n");
150 fflush(logfile);
151 if (must_close)
152 fclose(logfile);
153
154 va_end(args);
155 }
156
157 #define D(x) do { \
158 _pam_output_debug_info(__FILE__, __FUNCTION__, __LINE__); \
159 _pam_output_debug x ; \
160 } while (0)
161
162 #define _pam_show_mem(X,XS) do { \
163 int i; \
164 register unsigned char *x; \
165 x = (unsigned char *)X; \
166 fprintf(stderr, " <start at %p>\n", X); \
167 for (i = 0; i < XS ; ++x, ++i) { \
168 fprintf(stderr, " %02X. <%p:%02X>\n", i, x, *x); \
169 } \
170 fprintf(stderr, " <end for %p after %d bytes>\n", X, XS); \
171 } while (0)
172
173 #define _pam_show_reply(/* struct pam_response * */reply, /* int */replies) \
174 do { \
175 int reply_i; \
176 setbuf(stderr, NULL); \
177 fprintf(stderr, "array at %p of size %d\n",reply,replies); \
178 fflush(stderr); \
179 if (reply) { \
180 for (reply_i = 0; reply_i < replies; reply_i++) { \
181 fprintf(stderr, " elem# %d at %p: resp = %p, retcode = %d\n", \
182 reply_i, reply+reply_i, reply[reply_i].resp, \
183 reply[reply_i].resp, _retcode); \
184 fflush(stderr); \
185 if (reply[reply_i].resp) { \
186 fprintf(stderr, " resp[%d] = '%s'\n", \
187 strlen(reply[reply_i].resp), reply[reply_i].resp); \
188 fflush(stderr); \
189 } \
190 } \
191 } \
192 fprintf(stderr, "done here\n"); \
193 fflush(stderr); \
194 } while (0)
195
196 #else
197
198 #define D(x) do { } while (0)
199 #define _pam_show_mem(X,XS) do { } while (0)
200 #define _pam_show_reply(reply, replies) do { } while (0)
201
202 #endif /* PAM_DEBUG */
203
204 #endif /* PAM_MACROS_H */