bed98ff9 |
1 | #include "httpd.h" |
2 | #include "http_config.h" |
7193eb01 |
3 | #include "http_conf_globals.h" |
bed98ff9 |
4 | #include "http_log.h" |
7193eb01 |
5 | #include "http_protocol.h" |
6 | #include "http_request.h" |
7 | #include "http_core.h" |
bed98ff9 |
8 | #include "ap_config.h" |
4e1ae1cd |
9 | #include <krb5.h> |
bed98ff9 |
10 | |
7193eb01 |
11 | #if defined(sun) |
bed98ff9 |
12 | #include <sys/ioccom.h> |
7193eb01 |
13 | #endif /* sun */ |
bed98ff9 |
14 | #include <stropts.h> |
bed98ff9 |
15 | #include <afs/venus.h> |
7193eb01 |
16 | #include <afs/auth.h> |
17 | #include <rx/rxkad.h> |
18 | |
161ffd84 |
19 | #define KEYTAB "/etc/keytab.default" |
20 | #define KEYTAB_PRINCIPAL "defaultprinc" |
21 | #define AFS_CELL "someplace.edu" /* NB: lower case */ |
4e1ae1cd |
22 | |
58bbdc54 |
23 | #define TKT_LIFE 10*60*60 |
b52ccbb1 |
24 | #define SLEEP_TIME TKT_LIFE - 5*60 |
58bbdc54 |
25 | |
58bbdc54 |
26 | |
27 | #define K5PATH "FILE:/tmp/waklog.creds.k5" |
7193eb01 |
28 | |
313dde40 |
29 | module waklog_module; |
bed98ff9 |
30 | |
313dde40 |
31 | typedef struct { |
4e1ae1cd |
32 | int configured; |
33 | int protect; |
34 | char *keytab; |
7193eb01 |
35 | char *keytab_principal; |
403921ef |
36 | char *afs_cell; |
313dde40 |
37 | } waklog_host_config; |
38 | |
7193eb01 |
39 | typedef struct { |
40 | struct ktc_token token; |
41 | } waklog_child_config; |
58bbdc54 |
42 | waklog_child_config child; |
43 | |
b52ccbb1 |
44 | #if 0 |
4d47a8d9 |
45 | static void * |
46 | waklog_create_dir_config( pool *p, char *path ) |
47 | { |
48 | waklog_host_config *cfg; |
49 | |
50 | cfg = (waklog_host_config *)ap_pcalloc( p, sizeof( waklog_host_config )); |
51 | cfg->configured = 0; |
52 | cfg->protect = 0; |
53 | cfg->keytab = KEYTAB; |
54 | cfg->keytab_principal = KEYTAB_PRINCIPAL; |
55 | cfg->afs_cell = AFS_CELL; |
56 | |
57 | return( cfg ); |
58 | } |
b52ccbb1 |
59 | #endif /* 0 */ |
4d47a8d9 |
60 | |
61 | |
313dde40 |
62 | static void * |
63 | waklog_create_server_config( pool *p, server_rec *s ) |
64 | { |
65 | waklog_host_config *cfg; |
66 | |
67 | cfg = (waklog_host_config *)ap_pcalloc( p, sizeof( waklog_host_config )); |
68 | cfg->configured = 0; |
69 | cfg->protect = 0; |
58bbdc54 |
70 | cfg->keytab = KEYTAB; |
71 | cfg->keytab_principal = KEYTAB_PRINCIPAL; |
72 | cfg->afs_cell = AFS_CELL; |
313dde40 |
73 | |
161ffd84 |
74 | |
75 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, s, "mod_waklog: server config created" ); |
4d47a8d9 |
76 | |
313dde40 |
77 | return( cfg ); |
78 | } |
79 | |
80 | |
313dde40 |
81 | static const char * |
82 | set_waklog_protect( cmd_parms *params, void *mconfig, int flag ) |
83 | { |
84 | waklog_host_config *cfg; |
85 | |
161ffd84 |
86 | cfg = (waklog_host_config *) ap_get_module_config( |
87 | params->server->module_config, &waklog_module ); |
313dde40 |
88 | |
89 | cfg->protect = flag; |
90 | cfg->configured = 1; |
161ffd84 |
91 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, params->server, "mod_waklog: waklog_protect set" ); |
313dde40 |
92 | return( NULL ); |
93 | } |
94 | |
95 | |
4e1ae1cd |
96 | static const char * |
161ffd84 |
97 | set_waklog_keytab( cmd_parms *params, void *mconfig, char *file ) |
4e1ae1cd |
98 | { |
99 | waklog_host_config *cfg; |
100 | |
161ffd84 |
101 | cfg = (waklog_host_config *) ap_get_module_config( |
4e1ae1cd |
102 | params->server->module_config, &waklog_module ); |
4e1ae1cd |
103 | |
3ed1e28a |
104 | ap_log_error( APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, params->server, |
b52ccbb1 |
105 | "mod_waklog: will use keytab: %s", file ); |
3ed1e28a |
106 | |
b52ccbb1 |
107 | cfg->keytab = ap_pstrdup ( params->pool, file ); |
4e1ae1cd |
108 | cfg->configured = 1; |
109 | return( NULL ); |
110 | } |
111 | |
112 | |
58bbdc54 |
113 | static const char * |
114 | set_waklog_use_keytab_principal( cmd_parms *params, void *mconfig, char *file ) |
b74fad73 |
115 | { |
58bbdc54 |
116 | waklog_host_config *cfg; |
7193eb01 |
117 | |
161ffd84 |
118 | cfg = (waklog_host_config *) ap_get_module_config( |
58bbdc54 |
119 | params->server->module_config, &waklog_module ); |
7193eb01 |
120 | |
58bbdc54 |
121 | ap_log_error( APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, params->server, |
b52ccbb1 |
122 | "mod_waklog: will use keytab_principal: %s", file ); |
58bbdc54 |
123 | |
b52ccbb1 |
124 | cfg->keytab_principal = ap_pstrdup ( params->pool, file ); |
58bbdc54 |
125 | cfg->configured = 1; |
126 | return( NULL ); |
127 | } |
128 | |
129 | |
130 | static const char * |
131 | set_waklog_use_afs_cell( cmd_parms *params, void *mconfig, char *file ) |
132 | { |
133 | waklog_host_config *cfg; |
134 | |
161ffd84 |
135 | cfg = (waklog_host_config *) ap_get_module_config( |
58bbdc54 |
136 | params->server->module_config, &waklog_module ); |
58bbdc54 |
137 | |
138 | ap_log_error( APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, params->server, |
b52ccbb1 |
139 | "mod_waklog: will use afs_cell: %s", file ); |
58bbdc54 |
140 | |
b52ccbb1 |
141 | cfg->afs_cell = ap_pstrdup( params->pool, file ); |
58bbdc54 |
142 | cfg->configured = 1; |
143 | return( NULL ); |
144 | } |
145 | |
146 | |
147 | static void |
148 | waklog_child_init( server_rec *s, pool *p ) |
149 | { |
150 | |
151 | memset( &child.token, 0, sizeof( struct ktc_token ) ); |
7193eb01 |
152 | |
b74fad73 |
153 | setpag(); |
7193eb01 |
154 | |
b74fad73 |
155 | return; |
156 | } |
157 | |
158 | |
313dde40 |
159 | command_rec waklog_cmds[ ] = |
160 | { |
161 | { "WaklogProtected", set_waklog_protect, |
162 | NULL, RSRC_CONF | ACCESS_CONF, FLAG, |
163 | "enable waklog on a location or directory basis" }, |
164 | |
161ffd84 |
165 | { "WaklogKeytab", set_waklog_keytab, |
b52ccbb1 |
166 | NULL, RSRC_CONF | ACCESS_CONF, TAKE1, |
58bbdc54 |
167 | "Use the supplied keytab rather than the default" }, |
168 | |
169 | { "WaklogUseKeytabPrincipal", set_waklog_use_keytab_principal, |
b52ccbb1 |
170 | NULL, RSRC_CONF | ACCESS_CONF, TAKE1, |
58bbdc54 |
171 | "Use the supplied keytab principal rather than the default" }, |
172 | |
173 | { "WaklogUseAFSCell", set_waklog_use_afs_cell, |
b52ccbb1 |
174 | NULL, RSRC_CONF | ACCESS_CONF, TAKE1, |
58bbdc54 |
175 | "Use the supplied AFS cell rather than the default" }, |
4e1ae1cd |
176 | |
313dde40 |
177 | { NULL } |
178 | }; |
179 | |
180 | |
bed98ff9 |
181 | static void |
e2df6441 |
182 | token_cleanup( void *data ) |
bed98ff9 |
183 | { |
184 | request_rec *r = (request_rec *)data; |
bed98ff9 |
185 | |
58bbdc54 |
186 | if ( child.token.ticketLen ) { |
187 | memset( &child.token, 0, sizeof( struct ktc_token ) ); |
bed98ff9 |
188 | |
7193eb01 |
189 | ktc_ForgetAllTokens(); |
bed98ff9 |
190 | |
6b35d730 |
191 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
58bbdc54 |
192 | "mod_waklog: ktc_ForgetAllTokens succeeded: pid: %d", getpid() ); |
7193eb01 |
193 | } |
b74fad73 |
194 | return; |
bed98ff9 |
195 | } |
196 | |
197 | |
4e1ae1cd |
198 | static int |
e2df6441 |
199 | waklog_kinit( server_rec *s ) |
4e1ae1cd |
200 | { |
201 | krb5_error_code kerror; |
e2df6441 |
202 | krb5_context kcontext = NULL; |
203 | krb5_principal kprinc = NULL; |
4e1ae1cd |
204 | krb5_get_init_creds_opt kopts; |
7193eb01 |
205 | krb5_creds v5creds; |
e2df6441 |
206 | krb5_ccache kccache = NULL; |
207 | krb5_keytab keytab = NULL; |
4e1ae1cd |
208 | char ktbuf[ MAX_KEYTAB_NAME_LEN + 1 ]; |
e21f34f0 |
209 | waklog_host_config *cfg; |
b52ccbb1 |
210 | int i; |
4e1ae1cd |
211 | |
6b35d730 |
212 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, s, |
b52ccbb1 |
213 | "mod_waklog: waklog_kinit called: pid: %d", getpid() ); |
4e1ae1cd |
214 | |
58bbdc54 |
215 | cfg = (waklog_host_config *) ap_get_module_config( s->module_config, |
216 | &waklog_module ); |
217 | |
e21f34f0 |
218 | if (( kerror = krb5_init_context( &kcontext ))) { |
219 | ap_log_error( APLOG_MARK, APLOG_ERR, s, |
161ffd84 |
220 | "mod_waklog: %s", (char *)error_message( kerror )); |
4e1ae1cd |
221 | |
e2df6441 |
222 | goto cleanup; |
e21f34f0 |
223 | } |
4e1ae1cd |
224 | |
e21f34f0 |
225 | /* use the path */ |
226 | if (( kerror = krb5_cc_resolve( kcontext, K5PATH, &kccache )) != 0 ) { |
227 | ap_log_error( APLOG_MARK, APLOG_ERR, s, |
161ffd84 |
228 | "mod_waklog: %s", (char *)error_message( kerror )); |
4e1ae1cd |
229 | |
e2df6441 |
230 | goto cleanup; |
e21f34f0 |
231 | } |
4e1ae1cd |
232 | |
6b35d730 |
233 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, s, |
b52ccbb1 |
234 | "mod_waklog: keytab_principal: %s", cfg->keytab_principal ); |
235 | |
236 | if (( kerror = krb5_parse_name( kcontext, cfg->keytab_principal, &kprinc ))) { |
e21f34f0 |
237 | ap_log_error( APLOG_MARK, APLOG_ERR, s, |
161ffd84 |
238 | "mod_waklog: %s", (char *)error_message( kerror )); |
7193eb01 |
239 | |
e2df6441 |
240 | goto cleanup; |
e21f34f0 |
241 | } |
7193eb01 |
242 | |
e21f34f0 |
243 | krb5_get_init_creds_opt_init( &kopts ); |
58bbdc54 |
244 | krb5_get_init_creds_opt_set_tkt_life( &kopts, TKT_LIFE ); |
e21f34f0 |
245 | krb5_get_init_creds_opt_set_renew_life( &kopts, 0 ); |
246 | krb5_get_init_creds_opt_set_forwardable( &kopts, 1 ); |
247 | krb5_get_init_creds_opt_set_proxiable( &kopts, 0 ); |
7193eb01 |
248 | |
58bbdc54 |
249 | /* keytab from config */ |
250 | strncpy( ktbuf, cfg->keytab, sizeof( ktbuf ) - 1 ); |
7193eb01 |
251 | |
6b35d730 |
252 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, s, |
e2df6441 |
253 | "mod_waklog: waklog_kinit using: %s", ktbuf ); |
7193eb01 |
254 | |
e21f34f0 |
255 | if (( kerror = krb5_kt_resolve( kcontext, ktbuf, &keytab )) != 0 ) { |
256 | ap_log_error( APLOG_MARK, APLOG_ERR, s, |
161ffd84 |
257 | "mod_waklog:krb5_kt_resolve %s", (char *)error_message( kerror )); |
7193eb01 |
258 | |
e2df6441 |
259 | goto cleanup; |
e21f34f0 |
260 | } |
7193eb01 |
261 | |
b52ccbb1 |
262 | memset( (char *)&v5creds, 0, sizeof(v5creds)); |
263 | |
e21f34f0 |
264 | /* get the krbtgt */ |
265 | if (( kerror = krb5_get_init_creds_keytab( kcontext, &v5creds, |
403921ef |
266 | kprinc, keytab, 0, NULL, &kopts ))) { |
7193eb01 |
267 | |
e21f34f0 |
268 | ap_log_error( APLOG_MARK, APLOG_ERR, s, |
161ffd84 |
269 | "mod_waklog:krb5_get_init_creds_keytab %s", (char *)error_message( kerror )); |
7193eb01 |
270 | |
e2df6441 |
271 | goto cleanup; |
e21f34f0 |
272 | } |
7193eb01 |
273 | |
b52ccbb1 |
274 | |
7193eb01 |
275 | |
e21f34f0 |
276 | if (( kerror = krb5_cc_initialize( kcontext, kccache, kprinc )) != 0 ) { |
277 | ap_log_error( APLOG_MARK, APLOG_ERR, s, |
161ffd84 |
278 | "mod_waklog:krb5_cc_initialize %s", (char *)error_message( kerror )); |
7193eb01 |
279 | |
e2df6441 |
280 | goto cleanup; |
e21f34f0 |
281 | } |
7193eb01 |
282 | |
e2df6441 |
283 | kerror = krb5_cc_store_cred( kcontext, kccache, &v5creds ); |
284 | krb5_free_cred_contents( kcontext, &v5creds ); |
285 | if ( kerror != 0 ) { |
e21f34f0 |
286 | ap_log_error( APLOG_MARK, APLOG_ERR, s, |
161ffd84 |
287 | "mod_waklog: %s", (char *)error_message( kerror )); |
7193eb01 |
288 | |
e2df6441 |
289 | goto cleanup; |
e21f34f0 |
290 | } |
7193eb01 |
291 | |
6b35d730 |
292 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, s, |
e2df6441 |
293 | "mod_waklog: waklog_kinit success" ); |
294 | |
295 | cleanup: |
296 | if ( keytab ) |
297 | (void)krb5_kt_close( kcontext, keytab ); |
298 | if ( kprinc ) |
299 | krb5_free_principal( kcontext, kprinc ); |
300 | if ( kccache ) |
301 | krb5_cc_close( kcontext, kccache ); |
302 | if ( kcontext ) |
303 | krb5_free_context( kcontext ); |
e21f34f0 |
304 | |
6b35d730 |
305 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, s, |
e2df6441 |
306 | "mod_waklog: waklog_kinit: exiting" ); |
7193eb01 |
307 | |
308 | return( 0 ); |
309 | } |
310 | |
311 | |
312 | static void |
313 | waklog_aklog( request_rec *r ) |
314 | { |
315 | int rc; |
bd173fe7 |
316 | char buf[ MAXKTCTICKETLEN ]; |
7193eb01 |
317 | const char *k5path = NULL; |
318 | krb5_error_code kerror; |
e2df6441 |
319 | krb5_context kcontext = NULL; |
7193eb01 |
320 | krb5_creds increds; |
321 | krb5_creds *v5credsp = NULL; |
e2df6441 |
322 | krb5_ccache kccache = NULL; |
403921ef |
323 | struct ktc_principal server = { "afs", "", "" }; |
7193eb01 |
324 | struct ktc_principal client; |
325 | struct ktc_token token; |
403921ef |
326 | waklog_host_config *cfg; |
58bbdc54 |
327 | int buflen; |
7193eb01 |
328 | |
329 | k5path = ap_table_get( r->subprocess_env, "KRB5CCNAME" ); |
7193eb01 |
330 | |
161ffd84 |
331 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r->server, |
332 | "mod_waklog: waklog_aklog called: k5path: %s", k5path ); |
7193eb01 |
333 | |
161ffd84 |
334 | if ( k5path == NULL ) { |
6b35d730 |
335 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
7193eb01 |
336 | "mod_waklog: waklog_aklog giving up" ); |
e2df6441 |
337 | goto cleanup; |
4e1ae1cd |
338 | } |
339 | |
7193eb01 |
340 | /* |
341 | ** Get/build creds from file/tgs, then see if we need to SetToken |
342 | */ |
343 | |
344 | if (( kerror = krb5_init_context( &kcontext ))) { |
345 | /* Authentication Required ( kerberos error ) */ |
4e1ae1cd |
346 | ap_log_error( APLOG_MARK, APLOG_ERR, r->server, |
347 | (char *)error_message( kerror )); |
7193eb01 |
348 | |
e2df6441 |
349 | goto cleanup; |
4e1ae1cd |
350 | } |
351 | |
7193eb01 |
352 | memset( (char *)&increds, 0, sizeof(increds)); |
4e1ae1cd |
353 | |
403921ef |
354 | cfg = (waklog_host_config *) ap_get_module_config( |
355 | r->server->module_config, &waklog_module ); |
356 | |
357 | /* afs/<cell> or afs */ |
358 | strncpy( buf, "afs", sizeof( buf ) - 1 ); |
58bbdc54 |
359 | if ( strcmp( cfg->afs_cell, AFS_CELL ) ) { |
403921ef |
360 | strncat( buf, "/" , sizeof( buf ) - strlen( buf ) - 1 ); |
361 | strncat( buf, cfg->afs_cell, sizeof( buf ) - strlen( buf ) - 1 ); |
362 | } |
363 | |
7193eb01 |
364 | /* set server part */ |
403921ef |
365 | if (( kerror = krb5_parse_name( kcontext, buf, &increds.server ))) { |
4e1ae1cd |
366 | ap_log_error( APLOG_MARK, APLOG_ERR, r->server, |
367 | (char *)error_message( kerror )); |
368 | |
e2df6441 |
369 | goto cleanup; |
4e1ae1cd |
370 | } |
371 | |
7193eb01 |
372 | if (( kerror = krb5_cc_resolve( kcontext, k5path, &kccache )) != 0 ) { |
373 | ap_log_error( APLOG_MARK, APLOG_ERR, r->server, |
374 | (char *)error_message( kerror )); |
375 | |
e2df6441 |
376 | goto cleanup; |
7193eb01 |
377 | } |
4e1ae1cd |
378 | |
7193eb01 |
379 | /* set client part */ |
380 | krb5_cc_get_principal( kcontext, kccache, &increds.client ); |
4e1ae1cd |
381 | |
7193eb01 |
382 | increds.times.endtime = 0; |
383 | /* Ask for DES since that is what V4 understands */ |
384 | increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; |
385 | |
386 | /* get the V5 credentials */ |
387 | if (( kerror = krb5_get_credentials( kcontext, 0, kccache, |
388 | &increds, &v5credsp ) ) ) { |
403921ef |
389 | ap_log_error( APLOG_MARK, APLOG_ERR, r->server, |
390 | "mod_waklog: krb5_get_credentials: %s", error_message( kerror )); |
e2df6441 |
391 | goto cleanup; |
4e1ae1cd |
392 | } |
393 | |
c4ad0387 |
394 | /* don't overflow */ |
395 | if ( v5credsp->ticket.length >= MAXKTCTICKETLEN ) { /* from krb524d.c */ |
403921ef |
396 | ap_log_error( APLOG_MARK, APLOG_ERR, r->server, |
c4ad0387 |
397 | "mod_waklog: ticket size (%d) too big to fake", v5credsp->ticket.length ); |
e2df6441 |
398 | goto cleanup; |
4e1ae1cd |
399 | } |
400 | |
7193eb01 |
401 | /* assemble the token */ |
58bbdc54 |
402 | memset( &token, 0, sizeof( struct ktc_token ) ); |
403 | |
404 | token.startTime = v5credsp->times.starttime ? v5credsp->times.starttime : v5credsp->times.authtime; |
7193eb01 |
405 | token.endTime = v5credsp->times.endtime; |
58bbdc54 |
406 | memmove( &token.sessionKey, v5credsp->keyblock.contents, v5credsp->keyblock.length ); |
407 | token.kvno = RXKAD_TKT_TYPE_KERBEROS_V5; |
408 | token.ticketLen = v5credsp->ticket.length; |
409 | memmove( token.ticket, v5credsp->ticket.data, token.ticketLen ); |
7193eb01 |
410 | |
58bbdc54 |
411 | /* make sure we have to do this */ |
412 | if ( child.token.kvno != token.kvno || |
413 | child.token.ticketLen != token.ticketLen || |
414 | (memcmp( &child.token.sessionKey, &token.sessionKey, |
415 | sizeof( token.sessionKey ) )) || |
416 | (memcmp( child.token.ticket, token.ticket, token.ticketLen )) ) { |
417 | |
6b35d730 |
418 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
8258901d |
419 | "mod_waklog: client: %s", buf ); |
7193eb01 |
420 | |
421 | /* build the name */ |
bd173fe7 |
422 | memmove( buf, v5credsp->client->data[0].data, |
423 | min( v5credsp->client->data[0].length, MAXKTCNAMELEN - 1 ) ); |
58bbdc54 |
424 | buf[ v5credsp->client->data[0].length ] = '\0'; |
425 | if ( v5credsp->client->length > 1 ) { |
8258901d |
426 | strncat( buf, ".", sizeof( buf ) - strlen( buf ) - 1 ); |
58bbdc54 |
427 | buflen = strlen( buf ); |
bd173fe7 |
428 | memmove( buf + buflen, v5credsp->client->data[1].data, |
429 | min( v5credsp->client->data[1].length, MAXKTCNAMELEN - strlen( buf ) - 1 ) ); |
58bbdc54 |
430 | buf[ buflen + v5credsp->client->data[1].length ] = '\0'; |
7193eb01 |
431 | } |
432 | |
433 | /* assemble the client */ |
403921ef |
434 | strncpy( client.name, buf, sizeof( client.name ) - 1 ); |
435 | strncpy( client.instance, "", sizeof( client.instance) - 1 ); |
bd173fe7 |
436 | memmove( buf, v5credsp->client->realm.data, |
437 | min( v5credsp->client->realm.length, MAXKTCNAMELEN - 1 ) ); |
58bbdc54 |
438 | buf[ v5credsp->client->realm.length ] = '\0'; |
439 | strncpy( client.cell, buf, sizeof( client.cell ) - 1 ); |
403921ef |
440 | |
58bbdc54 |
441 | /* assemble the server's cell */ |
403921ef |
442 | strncpy( server.cell, cfg->afs_cell , sizeof( server.cell ) - 1 ); |
7193eb01 |
443 | |
6b35d730 |
444 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
7193eb01 |
445 | "mod_waklog: server: name=%s, instance=%s, cell=%s", |
446 | server.name, server.instance, server.cell ); |
447 | |
6b35d730 |
448 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
7193eb01 |
449 | "mod_waklog: client: name=%s, instance=%s, cell=%s", |
450 | client.name, client.instance, client.cell ); |
451 | |
452 | /* use the path */ |
7193eb01 |
453 | |
454 | /* rumor: we have to do this for AIX 4.1.4 with AFS 3.4+ */ |
455 | write( 2, "", 0 ); |
456 | |
457 | if ( ( rc = ktc_SetToken( &server, &token, &client, 0 ) ) ) { |
58bbdc54 |
458 | ap_log_error( APLOG_MARK, APLOG_ERR, r->server, |
7193eb01 |
459 | "mod_waklog: settoken returned %d", rc ); |
58bbdc54 |
460 | goto cleanup; |
7193eb01 |
461 | } |
462 | |
463 | /* save this */ |
58bbdc54 |
464 | memmove( &child.token, &token, sizeof( struct ktc_token ) ); |
7193eb01 |
465 | |
466 | /* we'll need to unlog when this connection is done. */ |
e2df6441 |
467 | ap_register_cleanup( r->pool, (void *)r, token_cleanup, ap_null_cleanup ); |
7193eb01 |
468 | } |
469 | |
e2df6441 |
470 | cleanup: |
471 | if ( v5credsp ) |
472 | krb5_free_cred_contents( kcontext, v5credsp ); |
473 | if ( increds.client ) |
474 | krb5_free_principal( kcontext, increds.client ); |
475 | if ( increds.server ) |
476 | krb5_free_principal( kcontext, increds.server ); |
477 | if ( kccache ) |
478 | krb5_cc_close( kcontext, kccache ); |
479 | if ( kcontext ) |
480 | krb5_free_context( kcontext ); |
3ed1e28a |
481 | |
6b35d730 |
482 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
7193eb01 |
483 | "mod_waklog: finished with waklog_aklog" ); |
484 | |
e2df6441 |
485 | return; |
486 | |
4e1ae1cd |
487 | } |
488 | |
e21f34f0 |
489 | static int |
490 | waklog_child_routine( void *s, child_info *pinfo ) |
491 | { |
e21f34f0 |
492 | if ( !getuid() ) { |
6b35d730 |
493 | ap_log_error( APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, s, |
e21f34f0 |
494 | "mod_waklog: waklog_child_routine called as root" ); |
495 | |
496 | /* this was causing the credential file to get owned by root */ |
497 | setgid(ap_group_id); |
498 | setuid(ap_user_id); |
499 | } |
500 | |
501 | while( 1 ) { |
e2df6441 |
502 | waklog_kinit( s ); |
58bbdc54 |
503 | sleep( SLEEP_TIME ); |
e21f34f0 |
504 | } |
505 | |
506 | } |
507 | |
508 | |
509 | static void |
510 | waklog_init( server_rec *s, pool *p ) |
511 | { |
512 | extern char *version; |
513 | int pid; |
514 | |
515 | ap_log_error( APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, s, |
516 | "mod_waklog: version %s initialized.", version ); |
517 | |
518 | pid = ap_bspawn_child( p, waklog_child_routine, s, kill_always, |
519 | NULL, NULL, NULL ); |
520 | |
6b35d730 |
521 | ap_log_error( APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, s, |
e21f34f0 |
522 | "mod_waklog: ap_bspawn_child: %d.", pid ); |
523 | } |
524 | |
4e1ae1cd |
525 | |
bed98ff9 |
526 | static int |
7193eb01 |
527 | waklog_phase0( request_rec *r ) |
bed98ff9 |
528 | { |
313dde40 |
529 | waklog_host_config *cfg; |
530 | |
6b35d730 |
531 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
7193eb01 |
532 | "mod_waklog: phase0 called" ); |
533 | |
7193eb01 |
534 | cfg = (waklog_host_config *)ap_get_module_config( |
535 | r->server->module_config, &waklog_module); |
313dde40 |
536 | |
7193eb01 |
537 | if ( !cfg->protect ) { |
6b35d730 |
538 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
7193eb01 |
539 | "mod_waklog: phase0 declining" ); |
540 | return( DECLINED ); |
541 | } |
4e1ae1cd |
542 | |
b52ccbb1 |
543 | /* set our environment variables */ |
544 | ap_table_set( r->subprocess_env, "KRB5CCNAME", K5PATH ); |
b52ccbb1 |
545 | |
7193eb01 |
546 | /* do this only if we are still unauthenticated */ |
58bbdc54 |
547 | if ( !child.token.ticketLen ) { |
4e1ae1cd |
548 | |
7193eb01 |
549 | /* stuff the credentials into the kernel */ |
550 | waklog_aklog( r ); |
4e1ae1cd |
551 | } |
7193eb01 |
552 | |
6b35d730 |
553 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
7193eb01 |
554 | "mod_waklog: phase0 returning" ); |
555 | return DECLINED; |
556 | } |
4e1ae1cd |
557 | |
1e18ef7d |
558 | |
7193eb01 |
559 | static int |
560 | waklog_phase7( request_rec *r ) |
561 | { |
562 | waklog_host_config *cfg; |
1e18ef7d |
563 | |
6b35d730 |
564 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
7193eb01 |
565 | "mod_waklog: phase7 called" ); |
1e18ef7d |
566 | |
7193eb01 |
567 | cfg = (waklog_host_config *)ap_get_module_config( |
568 | r->server->module_config, &waklog_module); |
bed98ff9 |
569 | |
7193eb01 |
570 | if ( !cfg->protect ) { |
571 | return( DECLINED ); |
bed98ff9 |
572 | } |
573 | |
7193eb01 |
574 | /* stuff the credentials into the kernel */ |
575 | waklog_aklog( r ); |
bed98ff9 |
576 | |
6b35d730 |
577 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
7193eb01 |
578 | "mod_waklog: phase7 returning" ); |
bed98ff9 |
579 | |
7193eb01 |
580 | return DECLINED; |
bed98ff9 |
581 | } |
582 | |
7193eb01 |
583 | static void |
584 | waklog_new_connection( conn_rec *c ) { |
6b35d730 |
585 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, c->server, |
58bbdc54 |
586 | "mod_waklog: new_connection called: pid: %d", getpid() ); |
7193eb01 |
587 | return; |
588 | } |
bed98ff9 |
589 | |
c4ad0387 |
590 | |
1196adfe |
591 | /* |
592 | ** Here's a quick explaination for phase0 and phase2: |
593 | ** Apache does a stat() on the path between phase0 and |
594 | ** phase2, and must by ACLed rl to succeed. So, at |
595 | ** phase0 we acquire credentials for umweb:servers from |
596 | ** a keytab, and at phase2 we must ensure we remove them. |
597 | ** |
598 | ** Failure to "unlog" would be a security risk. |
599 | */ |
600 | static int |
601 | waklog_phase2( request_rec *r ) |
c4ad0387 |
602 | { |
161ffd84 |
603 | |
6b35d730 |
604 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
1196adfe |
605 | "mod_waklog: phase2 called" ); |
606 | |
c4ad0387 |
607 | if ( child.token.ticketLen ) { |
608 | memset( &child.token, 0, sizeof( struct ktc_token ) ); |
609 | |
610 | ktc_ForgetAllTokens(); |
611 | |
6b35d730 |
612 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
c4ad0387 |
613 | "mod_waklog: ktc_ForgetAllTokens succeeded: pid: %d", getpid() ); |
614 | } |
1196adfe |
615 | |
6b35d730 |
616 | ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, |
1196adfe |
617 | "mod_waklog: phase2 returning" ); |
618 | |
c4ad0387 |
619 | return DECLINED; |
620 | } |
621 | |
313dde40 |
622 | module MODULE_VAR_EXPORT waklog_module = { |
bed98ff9 |
623 | STANDARD_MODULE_STUFF, |
003832b1 |
624 | waklog_init, /* module initializer */ |
b52ccbb1 |
625 | #if 0 |
4d47a8d9 |
626 | waklog_create_dir_config, /* create per-dir config structures */ |
b52ccbb1 |
627 | #else /* 0 */ |
628 | NULL, /* create per-dir config structures */ |
629 | #endif /* 0 */ |
bed98ff9 |
630 | NULL, /* merge per-dir config structures */ |
313dde40 |
631 | waklog_create_server_config, /* create per-server config structures */ |
bed98ff9 |
632 | NULL, /* merge per-server config structures */ |
313dde40 |
633 | waklog_cmds, /* table of config file commands */ |
bed98ff9 |
634 | NULL, /* [#8] MIME-typed-dispatched handlers */ |
635 | NULL, /* [#1] URI to filename translation */ |
636 | NULL, /* [#4] validate user id from request */ |
637 | NULL, /* [#5] check if the user is ok _here_ */ |
638 | NULL, /* [#3] check access by host address */ |
639 | NULL, /* [#6] determine MIME type */ |
7193eb01 |
640 | waklog_phase7, /* [#7] pre-run fixups */ |
bed98ff9 |
641 | NULL, /* [#9] log a transaction */ |
c4ad0387 |
642 | waklog_phase2, /* [#2] header parser */ |
313dde40 |
643 | waklog_child_init, /* child_init */ |
bed98ff9 |
644 | NULL, /* child_exit */ |
7193eb01 |
645 | waklog_phase0 /* [#0] post read-request */ |
bed98ff9 |
646 | #ifdef EAPI |
647 | ,NULL, /* EAPI: add_module */ |
648 | NULL, /* EAPI: remove_module */ |
649 | NULL, /* EAPI: rewrite_command */ |
7193eb01 |
650 | waklog_new_connection /* EAPI: new_connection */ |
bed98ff9 |
651 | #endif |
652 | }; |
161ffd84 |
653 | |