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