add WaklogAFSCellRealm directive
[hcoop/zz_old/modwaklog.git] / mod_waklog.c
CommitLineData
87822447 1#define _LARGEFILE64_SOURCE
ff47641b 2#define _GNU_SOURCE
87822447 3
bed98ff9 4#include "httpd.h"
5#include "http_config.h"
bed98ff9 6#include "http_log.h"
7193eb01 7#include "http_protocol.h"
8#include "http_request.h"
9#include "http_core.h"
87822447 10
ff47641b 11#ifdef sun
12#include <synch.h>
13#elif linux
14#define use_pthreads
15#include <features.h>
16#include <sys/types.h>
17#include <sys/mman.h>
18#include <pthread.h>
19#else
20#error "make sure you include the right stuff here"
21#endif
22
23#ifndef MAXNAMELEN
24#define MAXNAMELEN 1024
25#endif
26
891fb458 27#ifdef STANDARD20_MODULE_STUFF
c9d59a9c 28#define APACHE2
29#endif
30
31/********************* APACHE1 ******************************************************************************/
32#ifndef APACHE2
ebb1f61c 33#include "ap_config.h"
34#if defined(sun)
35#include <sys/ioccom.h>
36#endif /* sun */
37#include <http_conf_globals.h>
38#define MK_POOL pool
39#define MK_TABLE_GET ap_table_get
40#define MK_TABLE_SET ap_table_set
41#define command(name, func, var, type, usage) \
42 { name, func, \
43 NULL , \
44 RSRC_CONF | ACCESS_CONF , type, usage }
21a7788b 45module waklog_module;
ebb1f61c 46
47/********************* APACHE2 ******************************************************************************/
48#else
87822447 49#include <apr_strings.h>
50#include <apr_base64.h>
ebb1f61c 51#define ap_pcalloc apr_pcalloc
52#define ap_pdupstr apr_pdupstr
53#define ap_pstrdup apr_pstrdup
87822447 54#define MK_POOL apr_pool_t
55#define MK_TABLE_GET apr_table_get
d06251b1 56#define MK_TABLE_SET apr_table_set
87822447 57#include "unixd.h"
58extern unixd_config_rec unixd_config;
59#define ap_user_id unixd_config.user_id
60#define ap_group_id unixd_config.group_id
61#define ap_user_name unixd_config.user_name
62#define command(name, func, var, type, usage) \
63 AP_INIT_ ## type (name, (void*) func, \
ebb1f61c 64 NULL, \
65 RSRC_CONF | ACCESS_CONF, usage)
21a7788b 66module AP_MODULE_DECLARE_DATA waklog_module;
67typedef struct { int dummy; } child_info;
87822447 68const char *userdata_key = "waklog_init";
21a7788b 69
c9d59a9c 70#endif /* APACHE2 */
ebb1f61c 71/**************************************************************************************************/
877d453f 72
73#include <krb5.h>
877d453f 74#include <stropts.h>
75#include <afs/venus.h>
76#include <afs/auth.h>
77#include <afs/dirpath.h>
78#include <afs/ptuser.h>
79#include <rx/rxkad.h>
80
81#define TKT_LIFE ( 12 * 60 * 60 )
42d78dfb 82#define SLEEP_TIME ( TKT_LIFE - 5*60 )
877d453f 83
84#define WAKLOG_ON 1
85#define WAKLOG_OFF 2
86#define WAKLOG_UNSET 0
87
88#ifdef WAKLOG_DEBUG
89#undef APLOG_DEBUG
90#define APLOG_DEBUG APLOG_ERR
91#endif
92
877d453f 93/* this is used to turn off pag generation for the backround worker child during startup */
94int pag_for_children = 1;
95
96typedef struct
97{
98 int forked;
99 int configured;
100 int protect;
101 int usertokens;
c8563f50 102 int cell_in_principal;
21a7788b 103 int disable_token_cache;
877d453f 104 char *keytab;
105 char *principal;
106 char *default_principal;
107 char *default_keytab;
108 char *afs_cell;
98534230 109 char *afs_cell_realm;
877d453f 110 char *path;
111 MK_POOL *p;
112}
113waklog_config;
114
115typedef struct
116{
117 struct ktc_token token;
118 char clientprincipal[MAXNAMELEN];
119 krb5_context kcontext;
120 krb5_ccache ccache;
121 struct ktc_principal server;
122 struct ktc_principal client;
123 int pr_init;
124} waklog_child_config;
125
126waklog_child_config child;
127
128struct tokencache_ent {
129 char clientprincipal[MAXNAMELEN];
130 struct ktc_token token;
131 struct ktc_principal client;
132 struct ktc_principal server;
133 time_t lastused;
134 int persist;
135};
136
137#define SHARED_TABLE_SIZE 512
138
139struct sharedspace_s {
140 int renewcount;
141 struct tokencache_ent sharedtokens[SHARED_TABLE_SIZE];
142};
143
144struct sharedspace_s *sharedspace = NULL;
145
146struct renew_ent {
147 char *keytab;
148 char *principal;
149 int lastrenewed;
150};
151
152#ifdef use_pthreads
153pthread_rwlock_t *sharedlock = NULL;
154#else
155rwlock_t *sharedlock = NULL;
156#endif
157
158struct renew_ent renewtable[SHARED_TABLE_SIZE];
159
160int renewcount = 0;
161
ebb1f61c 162
87822447 163
c69d952f 164#define getModConfig(P, X) P = (waklog_config *) ap_get_module_config( (X)->module_config, &waklog_module );
87822447 165
4e1ae1cd 166#include <krb5.h>
bed98ff9 167
7193eb01 168#if defined(sun)
bed98ff9 169#include <sys/ioccom.h>
7193eb01 170#endif /* sun */
bed98ff9 171#include <stropts.h>
bed98ff9 172#include <afs/venus.h>
7193eb01 173#include <afs/auth.h>
d06251b1 174#include <afs/dirpath.h>
175#include <afs/ptuser.h>
7193eb01 176#include <rx/rxkad.h>
177
58bbdc54 178
87822447 179static void
3f4fda20 180log_error (const char *file, int line, int level, int status,
42d78dfb 181 const server_rec * s, const char *fmt, ...)
4d47a8d9 182{
3f4fda20 183 char errstr[4096];
184 va_list ap;
4d47a8d9 185
3f4fda20 186 va_start (ap, fmt);
187 vsnprintf (errstr, 1024, fmt, ap);
188 va_end (ap);
4d47a8d9 189
c9d59a9c 190#ifdef APACHE2
3f4fda20 191 ap_log_error (file, line, level | APLOG_NOERRNO, status, s, "(%d) %s", getpid(), errstr);
87822447 192#else
3f4fda20 193 ap_log_error (file, line, level | APLOG_NOERRNO, s, "(%d) %s", getpid(), errstr);
87822447 194#endif
4d47a8d9 195
87822447 196}
4d47a8d9 197
3f4fda20 198waklog_config *retrieve_config(request_rec *r) {
199
200 request_rec *my;
201 waklog_config *cfg;
202
203 if ( r && r->main ) {
204 my = r->main;
205 } else if (r) {
206 my = r;
207 } else {
208 return NULL;
209 }
210
211 if ( my && ( cfg = (waklog_config *) ap_get_module_config(my->per_dir_config, &waklog_module ) ) ) {
212 return cfg;
213 } else {
214 getModConfig (cfg, r->server);
215 }
216
217 return cfg;
218
219}
313dde40 220
3f4fda20 221/* set_auth -- sets the tokens of the current process to this user.
222 if "self" is set, it divines the user from the current requests' environment.
223 otherwise, it's gettng it from principal/keytab */
224
225int
226set_auth ( server_rec *s, request_rec *r, int self, char *principal, char *keytab, int storeonly ) {
227
228 int i;
229 int usecached = 0;
230 krb5_error_code kerror = 0;
231 krb5_principal kprinc = NULL;
232 krb5_get_init_creds_opt kopts;
233 krb5_creds v5creds;
234 krb5_creds increds;
235 struct ktc_principal server = { "afs", "", "" };
236 struct ktc_principal client;
237 struct ktc_token token;
238 krb5_creds *v5credsp = NULL;
239 krb5_keytab krb5kt = NULL;
240 char buf[MAXNAMELEN];
241 waklog_config *cfg;
242 int rc = 0;
243 int buflen = 0;
244 time_t oldest_time = 0;
245 int oldest;
246 int stored = -1;
247 time_t mytime;
248 int indentical;
c8563f50 249 int cell_in_principal;
250 int attempt;
7c53b5d0 251 int use_client_credentials = 0;
3f4fda20 252
253 char k5user[MAXNAMELEN];
254 char *k5secret;
7c53b5d0 255 char *k5path = NULL;
3f4fda20 256
7c53b5d0 257 k5path = !r ? NULL : MK_TABLE_GET( r->subprocess_env, "KRB5CCNAME" );
258
3f4fda20 259 memset((char *) &increds, 0, sizeof(increds));
3f4fda20 260 /* init some stuff if it ain't already */
261
262 if ( ! child.kcontext ) {
263 kerror = krb5_init_context(&child.kcontext);
264 }
265
7c53b5d0 266 if (!k5path || !*k5path) {
267 k5path = "MEMORY:tmpcache";
268 }
269 if ( ( ! child.ccache ) && ( kerror = krb5_cc_resolve(child.kcontext, k5path, &child.ccache) ) ) {
270 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: can't initialize credentials cache %s err=%d",
271 k5path, kerror );
3f4fda20 272 }
273
7c53b5d0 274 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: set_auth: %d, %s, %s, %d, KRB5CC=%s",
275 self, principal ? principal : "NULL",
276 keytab ? keytab : "NULL", storeonly, k5path ? k5path : "NULL");
3f4fda20 277
278 /* pull the server config record that we care about... */
279
280 if ( r ) {
281 cfg = retrieve_config(r);
282 } else {
283 log_error (APLOG_MARK, APLOG_DEBUG, 0, s,
42d78dfb 284 "mod_waklog: set_auth using no config" );
3f4fda20 285 getModConfig (cfg, s);
286 }
287
288 if ( ! cfg ) {
289 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: cfg is %d", cfg );
290 }
291
c9d59a9c 292#ifdef APACHE2
3f4fda20 293 if ( self ) {
294 /* pull out our principal name and stuff from the environment -- webauth better have sent
295 through. This here is also where you'd suck stuff out of KRB5CCNAME if we were
296 using something like Cosign */
297
298 if ( ! ( r && r->connection && r->user )) {
299 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: self authentication selected, but no data available");
7c53b5d0 300 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: r->user=%s", (r->user==NULL ? "null" : r->user==NULL));
3f4fda20 301 return -1;
302 }
303
304 strncpy(k5user, r->user, sizeof(k5user));
305
306 /* the other thing we need is someone's password */
307 if ( ! ( k5secret = (char *) MK_TABLE_GET( r->notes, "ATTR_PASSWORD" ) ) ) {
308 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: cant do self auth without a secret");
309 return -1;
310 }
311
312 /* we'll pick this up later after we've checked the cache and current state */
313
314 } else
7c53b5d0 315 if (r && r->user) {
316 strncpy(k5user, r->user, sizeof(k5user));
317 keytab = NULL;
98534230 318 } else
319#endif
320 if ( principal ) {
3f4fda20 321 strncpy( k5user, principal, sizeof(k5user));
322 }
323
7c53b5d0 324 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: set_auth: k5user=%s", k5user ? k5user : "NULL");
3f4fda20 325 mytime = time(0);
326
327 /* see if we should just go ahead and ignore this call, since we already should be set to these
328 credentials */
313dde40 329
3f4fda20 330 if ( ! storeonly ) {
313dde40 331
3f4fda20 332#ifdef use_pthreads
333 pthread_rwlock_rdlock( sharedlock );
334#else
335 rw_rdlock( sharedlock );
336#endif
313dde40 337
3f4fda20 338 for ( i = 0; i < SHARED_TABLE_SIZE; ++i ) {
339
340 /* if it's a token for the principal we're looking for, and it hasn't expired yet */
341
342 if ( ( !strcmp( k5user,
343 sharedspace->sharedtokens[i].clientprincipal ) ) &&
344 ( sharedspace->sharedtokens[i].token.endTime > mytime ) ) {
345
346 if ( ! memcmp(&child.token, &sharedspace->sharedtokens[i].token, sizeof(child.token) ) ) {
347 indentical = 1;
348 } else {
349 indentical = 0;
350 }
351
352 /* copy the token out of the cache and into the child object */
353
354 strcpy(child.clientprincipal, sharedspace->sharedtokens[i].clientprincipal );
355 memcpy(&child.token, &sharedspace->sharedtokens[i].token, sizeof(child.token));
356 memcpy(&child.server, &sharedspace->sharedtokens[i].server, sizeof(child.server));
357 memcpy(&child.client, &sharedspace->sharedtokens[i].client, sizeof(child.client));
358
359 /* set our last used time thing */
360 sharedspace->sharedtokens[i].lastused = mytime;
361
362 usecached = 1;
363
364 break;
365
366 }
367
368 }
369
370 /* release the lock on the token cache */
371#ifdef use_pthreads
372 pthread_rwlock_unlock( sharedlock );
373#else
374 rw_unlock( sharedlock );
375#endif
313dde40 376
3f4fda20 377 if ( usecached ) {
378 /* release the lock on the token cache */
379 log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
380 "mod_waklog: set_auth using shared token %d for %s", i, k5user );
381
382 }
383
384 /* if this is something that was in the cache, and it's the same as the token we already have stored,
385 and we weren't calling this just to renew it... */
386
387 if ( usecached && indentical ) {
388 log_error (APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: token is identical for %s", k5user );
389 return 0;
390 }
391
392 }
7c53b5d0 393
3f4fda20 394 /* if 'usecached' isn't set, we've got to get our tokens from somewhere... */
3f4fda20 395 if (( ! usecached ) && ( k5user )) {
313dde40 396
3f4fda20 397 /* clear out the creds structure */
398 memset((void *) &v5creds, 0, sizeof(v5creds));
399
400 /* create a principal out of our k5user string */
401
402 if ( kerror = krb5_parse_name (child.kcontext, k5user, &kprinc ) ) {
403 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_parse_name %s", (char *) error_message(kerror) );
404 goto cleanup;
405 }
406
407 /* create the credentials options */
408
409 krb5_get_init_creds_opt_init ( &kopts );
410 krb5_get_init_creds_opt_set_tkt_life ( &kopts, TKT_LIFE );
411 krb5_get_init_creds_opt_set_renew_life ( &kopts, 0 );
412 krb5_get_init_creds_opt_set_forwardable ( &kopts, 0 );
413 krb5_get_init_creds_opt_set_proxiable ( &kopts, 0 );
414
415 if ( keytab ) {
416
417 /* if we've been passed a keytab, we're going to be getting our credentials from it */
418
419 log_error( APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: using keytab %s", keytab);
420
421 if ( kerror = krb5_kt_resolve(child.kcontext, keytab, &krb5kt ) ) {
422 log_error( APLOG_MARK, APLOG_ERR, 0, s,
423 "mod_waklog: krb5_kt_resolve %s", error_message(kerror) );
424 goto cleanup;
425 }
426
427 if ((kerror = krb5_get_init_creds_keytab (child.kcontext, &v5creds,
428 kprinc, krb5kt, 0, NULL, &kopts ) ) ) {
429 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_get_init_creds_keytab %s",
430 error_message(kerror) );
431 goto cleanup;
432 }
433
434 } else if ( self ) {
435
436 /* if 'self' is set, we're going to use the credentials provided in the credential information */
437 /* if you're using CoSign, you'd actually just set the ccache to the KRB5CCNAME credentials */
438 /* and skip ahead... Our WebSSO is lame, but has a way for us to snarf the password out of */
439 /* the encrypted token for proxy-authentication stuff. We only hand out keys that allow this */
440 /* functionality to VERY special people. */
441
442 if ((kerror = krb5_get_init_creds_password ( child.kcontext, &v5creds,
443 kprinc, k5secret, NULL, NULL, 0, NULL, &kopts ) ) ) {
444 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_get_init_creds_password %s",
445 error_message(kerror) );
446 /* nuke the password so it doesn't end up in core files */
447 memset(k5secret, 0, sizeof(k5secret));
448 goto cleanup;
449 }
450
451 memset(k5secret, 0, sizeof(k5secret));
452
453 } else {
7c53b5d0 454 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: no keytab, no self; assuming mod_auth_kerb or similar");
455 use_client_credentials = 1;
3f4fda20 456 }
457
458 /* initialize the credentials cache and store the stuff we just got */
7c53b5d0 459 if (!use_client_credentials) {
460 if ( kerror = krb5_cc_initialize (child.kcontext, child.ccache, kprinc)) {
461 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: init credentials cache %s",
462 error_message(kerror));
463 goto cleanup;
464 }
3f4fda20 465
7c53b5d0 466 if ( kerror = krb5_cc_store_cred(child.kcontext, child.ccache, &v5creds) ) {
467 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: cannot store credentials %s",
468 error_message(kerror));
469 goto cleanup;
470 }
3f4fda20 471 }
472
473 krb5_free_cred_contents(child.kcontext, &v5creds);
474
475 if ( kerror ) {
476 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: store cred %s", error_message(kerror));
477 goto cleanup;
478 }
479
480 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: kinit ok for %s", k5user );
481
482 /* now, to the 'aklog' portion of our program. */
483
c8563f50 484 /** we make two attempts here, one for afs@REALM and one for afs/cell@REALM */
485 for(attempt = 0; attempt <= 1; attempt++) {
98534230 486 strncpy( buf, "afs", sizeof(buf) - 1 );
c8563f50 487 cell_in_principal = (cfg->cell_in_principal + attempt) % 2;
488
489 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: cell_in_principal=%d", cell_in_principal );
490 if (cell_in_principal) {
98534230 491 strncat(buf, "/", sizeof(buf) - strlen(buf) - 1);
c8563f50 492 strncat(buf, cfg->afs_cell, sizeof(buf) - strlen(buf) - 1);
493 }
98534230 494 if (cfg->afs_cell_realm != WAKLOG_UNSET) {
495 strncat(buf, "@", sizeof(buf) - strlen(buf) - 1);
496 strncat(buf, cfg->afs_cell_realm, sizeof(buf) - strlen(buf) - 1);
497 }
c8563f50 498
499 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: using AFS principal: %s", buf);
500
501 if ((kerror = krb5_parse_name (child.kcontext, buf, &increds.server))) {
502 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_parse name %s", error_message(kerror));
503 goto cleanup;
504 }
7c53b5d0 505
506 if (use_client_credentials) {
507 if (( kerror = krb5_cc_resolve( child.kcontext, k5path, &child.ccache)) != 0 ) {
508 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_cc_resolve %s", error_message(kerror));
509 goto cleanup;
510 }
511 }
c8563f50 512
513 if ((kerror = krb5_cc_get_principal(child.kcontext, child.ccache, &increds.client))) {
514 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_cc_get_princ %s", error_message(kerror));
515 goto cleanup;
516 }
517
518 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: retrieved data from ccache for %s", k5user);
519
520 increds.times.endtime = 0;
521
522 increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
523
524 if (kerror = krb5_get_credentials (child.kcontext, 0, child.ccache, &increds, &v5credsp )) {
525 /* only complain once we've tried both afs@REALM and afs/cell@REALM */
526 if (attempt>=1) {
527 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_get_credentials: %s",
528 error_message(kerror));
529 goto cleanup;
530 } else {
531 continue;
532 }
533 }
534 cfg->cell_in_principal = cell_in_principal;
535 break;
3f4fda20 536 }
c8563f50 537
3f4fda20 538 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: get_credentials passed for %s", k5user);
539
540 if ( v5credsp->ticket.length >= MAXKTCTICKETLEN ) {
541 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: ticket size (%d) too big to fake",
542 v5credsp->ticket.length);
543 goto cleanup;
544 }
313dde40 545
3f4fda20 546 memset(&token, 0, sizeof(struct ktc_token));
547
548 token.startTime = v5credsp->times.starttime ? v5credsp->times.starttime : v5credsp->times.authtime;
549 token.endTime = v5credsp->times.endtime;
550
551 memmove( &token.sessionKey, v5credsp->keyblock.contents, v5credsp->keyblock.length);
552 token.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
553 token.ticketLen = v5credsp->ticket.length;
554 memmove( token.ticket, v5credsp->ticket.data, token.ticketLen);
555
556 /* build the name */
557
558 memmove( buf, v5credsp->client->data[0].data, min(v5credsp->client->data[0].length,
559 MAXKTCNAMELEN -1 ));
560 buf[v5credsp->client->data[0].length] = '\0';
561 if ( v5credsp->client->length > 1 ) {
562 strncat(buf, ".", sizeof(buf) - strlen(buf) - 1);
563 buflen = strlen(buf);
564 memmove(buf + buflen, v5credsp->client->data[1].data,
565 min(v5credsp->client->data[1].length,
566 MAXKTCNAMELEN - strlen(buf) - 1));
567 buf[buflen + v5credsp->client->data[1].length] = '\0';
568 }
569
570 /* assemble the client */
571 strncpy(client.name, buf, sizeof(client.name) - 1 );
572 strncpy(client.instance, "", sizeof(client.instance) - 1 );
573 memmove(buf, v5credsp->client->realm.data, min(v5credsp->client->realm.length,
574 MAXKTCNAMELEN - 1));
575 buf[v5credsp->client->realm.length] = '\0';
576 strncpy(client.cell, buf, sizeof(client.cell));
577
578 /* assemble the server's cell */
891fb458 579 strncpy(server.cell, cfg->afs_cell, sizeof(server.cell) - 1);
3f4fda20 580
581 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: preparing to init PTS connection for %s", server.cell);
582
583 /* fill out the AFS ID in the client name */
584 /* we've done a pr_Initialize in the child_init -- once, per process. If you try to do it more
585 * strange things seem to happen. */
586
587 {
588 afs_int32 viceId = 0;
589
590 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: making PTS call to look up %s", client.name);
591
592 if ( ( rc = pr_SNameToId( client.name, &viceId ) ) == 0 ) {
593 snprintf( client.name, sizeof(client.name), "AFS ID %d", viceId );
594 } else {
595 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: PTS call returned error %d ", rc);
596 }
597
598 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: PTS call returned %s ", client.name);
599
600 }
601
602 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: server: name %s, instance %s, cell %s",
603 server.name, server.instance, server.cell );
604
605 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: client: name %s, instance %s, cell %s",
606 client.name, client.instance, client.cell );
607
608 /* copy the resulting stuff into the child structure */
609
610 strncpy(child.clientprincipal, k5user, sizeof(child.clientprincipal));
611 memcpy(&child.token, &token, sizeof(child.token));
612 memcpy(&child.server, &server, sizeof(child.server));
613 memcpy(&child.client, &client, sizeof(child.client));
614
615 /* stuff the resulting token-related stuff into our shared token cache */
616 /* note, that anything that was set from a keytab is "persistant", and is immune
617 * from LRU-aging. This is because nothing but the process that's running as root
618 * can update these, and it's running every hour or so and renewing these tokens.
619 * and we don't want them aged out.
620 */
621
622 mytime = oldest_time = time(0);
623
624 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: waiting for shared space for %s ", k5user);
4e1ae1cd 625
3f4fda20 626#ifdef use_pthreads
627 pthread_rwlock_wrlock(sharedlock);
628#else
629 rw_wrlock(sharedlock);
630#endif
4e1ae1cd 631
3f4fda20 632 for( i = ( SHARED_TABLE_SIZE - 1 ); i >= 0; i-- ) {
633 if ( ( sharedspace->sharedtokens[i].lastused <= oldest_time) &&
634 ( sharedspace->sharedtokens[i].persist == 0 ) ) {
635 oldest = i;
636 oldest_time = sharedspace->sharedtokens[i].lastused;
637 }
638 if ( ! strcmp ( sharedspace->sharedtokens[i].clientprincipal,
639 child.clientprincipal ) ) {
640 memcpy(&sharedspace->sharedtokens[i].token, &child.token, sizeof(child.token) );
641 memcpy(&sharedspace->sharedtokens[i].client, &child.client, sizeof(child.client) );
642 memcpy(&sharedspace->sharedtokens[i].server, &child.server, sizeof(child.server) );
643 sharedspace->sharedtokens[i].lastused = mytime;
644 sharedspace->sharedtokens[i].persist = keytab ? 1 : 0;
645 stored = i;
646 break;
647 }
648 }
649
650 if ( stored == -1 ) {
651 memcpy(&sharedspace->sharedtokens[oldest].token, &child.token, sizeof(child.token) );
652 memcpy(&sharedspace->sharedtokens[oldest].client, &child.client, sizeof(child.client) );
653 memcpy(&sharedspace->sharedtokens[oldest].server, &child.server, sizeof(child.server) );
654 strcpy(sharedspace->sharedtokens[oldest].clientprincipal, child.clientprincipal );
655 sharedspace->sharedtokens[oldest].lastused = mytime;
656 sharedspace->sharedtokens[oldest].persist = keytab ? 1 : 0;
657 stored = oldest;
658 }
3ed1e28a 659
3f4fda20 660#ifdef use_pthreads
661 pthread_rwlock_unlock(sharedlock);
662#else
663 rw_unlock(sharedlock);
664#endif
665
666 log_error( APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: token stored in slot %d for %s", stored,
667 child.clientprincipal );
668
669 } else if ( ! usecached ) {
670 log_error( APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: set_auth divergent case");
671 }
672
673 if ( storeonly ) {
674 goto cleanup;
675 }
676
677 usecachedtoken:
678
679 /* don't ask. Something about AIX. We're leaving it here.*/
680 /* write(2, "", 0); */
681
682 /* we try twice, because sometimes the first one fails. Dunno why, but it always works the second time */
683
684 if ((rc = ktc_SetToken(&child.server, &child.token, &child.client, 0))) {
685 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: settoken returned %s for %s -- trying again",
686 error_message(rc), k5user);
687 if ((rc = ktc_SetToken(&child.server, &child.token, &child.client, 0))) {
688 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: settoken2 returned %s for %s",
689 error_message(rc), k5user);
690 goto cleanup;
691 }
692 }
693
694 cleanup:
695 if ( v5credsp )
696 krb5_free_cred_contents(child.kcontext, v5credsp);
697 if ( increds.client )
698 krb5_free_principal (child.kcontext, increds.client);
699 if ( increds.server )
700 krb5_free_principal (child.kcontext, increds.server);
701 if ( krb5kt )
702 (void) krb5_kt_close(child.kcontext, krb5kt);
703 if ( kprinc )
704 krb5_free_principal (child.kcontext, kprinc);
705
706 if ( rc ) {
707 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: set_auth ending with %d", rc );
708 } else if ( kerror ) {
709 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: set_auth ending with krb5 error %d, %s", kerror, error_message(kerror));
710 } else {
711 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: set_auth ending ok");
712 }
713
714 return kerror ? (int) kerror : (int) rc;
715
4e1ae1cd 716}
717
718
7193eb01 719
3f4fda20 720static void *
721waklog_create_server_config (MK_POOL * p, server_rec * s)
722{
723 waklog_config *cfg;
724
725 cfg = (waklog_config *) ap_pcalloc (p, sizeof (waklog_config));
726 cfg->p = p;
727 memset(cfg, 0, sizeof(waklog_config));
728 cfg->path = "(server)";
729 cfg->protect = WAKLOG_UNSET;
730 cfg->usertokens = WAKLOG_UNSET;
21a7788b 731 cfg->disable_token_cache = WAKLOG_UNSET;
3f4fda20 732 cfg->keytab = WAKLOG_UNSET;
733 cfg->principal = WAKLOG_UNSET;
734 cfg->default_principal = WAKLOG_UNSET;
735 cfg->default_keytab = WAKLOG_UNSET;
736 cfg->afs_cell = WAKLOG_UNSET;
98534230 737 cfg->afs_cell_realm = WAKLOG_UNSET;
3f4fda20 738 cfg->forked = 0;
739 cfg->configured = 0;
740
741 log_error (APLOG_MARK, APLOG_DEBUG, 0, s,
42d78dfb 742 "mod_waklog: server config created.");
3f4fda20 743
744 return (cfg);
745}
7193eb01 746
3f4fda20 747/* initialize with host-config information */
58bbdc54 748
3f4fda20 749static void *
750waklog_create_dir_config (MK_POOL * p, char *dir)
751{
752 waklog_config *cfg;
753
754 cfg = (waklog_config *) ap_pcalloc (p, sizeof (waklog_config));
755 memset(cfg, 0, sizeof(waklog_config));
756 cfg->p = p;
757 cfg->path = ap_pstrdup(p, dir );
758 cfg->protect = WAKLOG_UNSET;
759 cfg->usertokens = WAKLOG_UNSET;
21a7788b 760 cfg->disable_token_cache = WAKLOG_UNSET;
3f4fda20 761 cfg->keytab = WAKLOG_UNSET;
762 cfg->principal = WAKLOG_UNSET;
763 cfg->default_principal = WAKLOG_UNSET;
764 cfg->default_keytab = WAKLOG_UNSET;
765 cfg->afs_cell = WAKLOG_UNSET;
98534230 766 cfg->afs_cell_realm = WAKLOG_UNSET;
3f4fda20 767 cfg->forked = 0;
768 cfg->configured = 0;
769
770 return (cfg);
58bbdc54 771}
772
3f4fda20 773static void *waklog_merge_dir_config(MK_POOL *p, void *parent_conf, void *newloc_conf) {
58bbdc54 774
3f4fda20 775 waklog_config *merged = ( waklog_config * ) ap_pcalloc(p, sizeof(waklog_config ) );
776 waklog_config *parent = ( waklog_config * ) parent_conf;
777 waklog_config *child = ( waklog_config * ) newloc_conf;
778
779 merged->protect = child->protect != WAKLOG_UNSET ? child->protect : parent->protect;
780
781 merged->path = child->path != WAKLOG_UNSET ? child->path : parent->path;
782
783 merged->usertokens = child->usertokens != WAKLOG_UNSET ? child->usertokens : parent->usertokens;
21a7788b 784
785 merged->disable_token_cache = child->disable_token_cache != WAKLOG_UNSET ? child->disable_token_cache : parent->disable_token_cache;
3f4fda20 786
787 merged->principal = child->principal != WAKLOG_UNSET ? child->principal : parent->principal;
788
789 merged->keytab = child->keytab != WAKLOG_UNSET ? child->keytab : parent->keytab;
790
791 merged->default_keytab = child->default_keytab != WAKLOG_UNSET ? child->default_keytab : parent->default_keytab;
792
793 merged->default_principal = child->default_principal != WAKLOG_UNSET ? child->default_principal : parent->default_principal;
794
795 merged->afs_cell = child->afs_cell != WAKLOG_UNSET ? child->afs_cell : parent->afs_cell;
98534230 796
797 merged->afs_cell_realm = child->afs_cell_realm != WAKLOG_UNSET ? child->afs_cell_realm : parent->afs_cell_realm;
3f4fda20 798
799 return (void *) merged;
800
801}
58bbdc54 802
3f4fda20 803static void *waklog_merge_server_config(MK_POOL *p, void *parent_conf, void *newloc_conf) {
58bbdc54 804
3f4fda20 805 waklog_config *merged = ( waklog_config * ) ap_pcalloc(p, sizeof(waklog_config ) );
806 waklog_config *pconf = ( waklog_config * ) parent_conf;
807 waklog_config *nconf = ( waklog_config * ) newloc_conf;
808
809 merged->protect = nconf->protect == WAKLOG_UNSET ? pconf->protect : nconf->protect;
58bbdc54 810
3f4fda20 811 merged->usertokens = nconf->usertokens == WAKLOG_UNSET ? pconf->usertokens : nconf->usertokens;
58bbdc54 812
bce7d4d9 813 merged->disable_token_cache = nconf->disable_token_cache == WAKLOG_UNSET ? pconf->disable_token_cache : nconf->disable_token_cache;
21a7788b 814
3f4fda20 815 merged->keytab = nconf->keytab == WAKLOG_UNSET ? ap_pstrdup(p, pconf->keytab) :
816 ( nconf->keytab == WAKLOG_UNSET ? WAKLOG_UNSET : ap_pstrdup(p, pconf->keytab) );
817
818 merged->principal = nconf->principal == WAKLOG_UNSET ? ap_pstrdup(p, pconf->principal) :
819 ( nconf->principal == WAKLOG_UNSET ? WAKLOG_UNSET : ap_pstrdup(p, pconf->principal) );
820
821 merged->afs_cell = nconf->afs_cell == WAKLOG_UNSET ? ap_pstrdup(p, pconf->afs_cell) :
822 ( nconf->afs_cell == WAKLOG_UNSET ? WAKLOG_UNSET : ap_pstrdup(p, pconf->afs_cell) );
823
98534230 824 merged->afs_cell_realm = nconf->afs_cell_realm == WAKLOG_UNSET ? ap_pstrdup(p, pconf->afs_cell_realm) :
825 ( nconf->afs_cell_realm == WAKLOG_UNSET ? WAKLOG_UNSET : ap_pstrdup(p, pconf->afs_cell_realm) );
826
3f4fda20 827 merged->default_keytab = nconf->default_keytab == WAKLOG_UNSET ? ap_pstrdup(p, pconf->default_keytab) :
828 ( nconf->default_keytab == WAKLOG_UNSET ? WAKLOG_UNSET : ap_pstrdup(p, pconf->default_keytab) );
58bbdc54 829
3f4fda20 830 merged->default_principal = nconf->default_principal == WAKLOG_UNSET ? ap_pstrdup(p, pconf->default_principal) :
831 ( nconf->default_principal == WAKLOG_UNSET ? WAKLOG_UNSET : ap_pstrdup(p, pconf->default_principal) );
832
833
834 return (void *) merged;
835
836}
837
838static const char *
21a7788b 839set_waklog_enabled (cmd_parms * params, void *mconfig, int flag)
58bbdc54 840{
3f4fda20 841 waklog_config *cfg = mconfig ? ( waklog_config * ) mconfig :
842 ( waklog_config * ) ap_get_module_config(params->server->module_config, &waklog_module );
843
844 cfg->protect = flag;
845 cfg->configured = 1;
846 log_error (APLOG_MARK, APLOG_DEBUG, 0, params->server,
21a7788b 847 "mod_waklog: waklog_enabled set on %s", cfg->path ? cfg->path : "NULL");
3f4fda20 848 return (NULL);
849}
58bbdc54 850
7193eb01 851
3f4fda20 852/* this adds a principal/keytab pair to get their tokens renewed by the
853 child process every few centons. */
7193eb01 854
3f4fda20 855void add_to_renewtable(MK_POOL *p, char *keytab, char *principal) {
87822447 856
3f4fda20 857 int i;
858
859 if ( renewcount >= SHARED_TABLE_SIZE ) {
860 log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "mod_waklog: big problem. Increase the SHARED_TABLE_SIZE or \
861 decrease your tokens.");
b74fad73 862 return;
3f4fda20 863 }
864
865 /* check to see if it's already there */
866
867 for ( i = 0; i < renewcount; i++ ) {
868 if ( ! strcmp(renewtable[i].principal, principal ) ) {
869 return;
870 }
871 }
872
873 renewtable[renewcount].keytab = ap_pstrdup(p, keytab);
874 renewtable[renewcount].principal = ap_pstrdup(p, principal);
875 renewtable[renewcount].lastrenewed = 0;
876 ++renewcount;
877
b74fad73 878}
879
3f4fda20 880static const char *
21a7788b 881set_waklog_location_principal (cmd_parms *params, void *mconfig, char *principal, char *keytab)
3f4fda20 882{
883 waklog_config *cfg = mconfig ? ( waklog_config * ) mconfig :
884 ( waklog_config * ) ap_get_module_config(params->server->module_config, &waklog_module );
885
886 log_error (APLOG_MARK, APLOG_DEBUG, 0, params->server,
42d78dfb 887 "mod_waklog: configuring principal: %s, keytab: %s", principal, keytab);
888
889 cfg->principal = ap_pstrdup(params->pool, principal);
3f4fda20 890 cfg->keytab = ap_pstrdup (params->pool, keytab);
891
892 add_to_renewtable(params->pool, keytab, principal);
893
894 cfg->configured = 1;
895
896 return (NULL);
897}
b74fad73 898
3f4fda20 899static const char *
21a7788b 900set_waklog_afs_cell (cmd_parms * params, void *mconfig, char *file)
313dde40 901{
891fb458 902 waklog_config *waklog_mconfig = ( waklog_config * ) mconfig;
903 waklog_config *waklog_srvconfig =
3f4fda20 904 ( waklog_config * ) ap_get_module_config(params->server->module_config, &waklog_module );
905
891fb458 906 log_error (APLOG_MARK, APLOG_INFO, 0, params->server,
42d78dfb 907 "mod_waklog: will use afs_cell: %s", file);
313dde40 908
c8563f50 909 waklog_srvconfig->cell_in_principal = 0;
891fb458 910 waklog_srvconfig->afs_cell = ap_pstrdup (params->pool, file);
911 waklog_srvconfig->configured = 1;
912
913 if (waklog_mconfig != NULL) {
c8563f50 914 waklog_mconfig->cell_in_principal = waklog_srvconfig->cell_in_principal;
891fb458 915 waklog_mconfig->afs_cell = ap_pstrdup (params->pool, file);
916 waklog_mconfig->configured = 1;
917 }
3f4fda20 918 return (NULL);
919}
58bbdc54 920
98534230 921static const char *
922set_waklog_afs_cell_realm (cmd_parms * params, void *mconfig, char *file)
923{
924 waklog_config *waklog_mconfig = ( waklog_config * ) mconfig;
925 waklog_config *waklog_srvconfig =
926 ( waklog_config * ) ap_get_module_config(params->server->module_config, &waklog_module );
927
928 log_error (APLOG_MARK, APLOG_INFO, 0, params->server,
929 "mod_waklog: will use afs_cell_realm: %s", file);
930
931 waklog_srvconfig->afs_cell_realm = ap_pstrdup (params->pool, file);
932
933 if (waklog_mconfig != NULL) {
934 waklog_mconfig->afs_cell_realm = ap_pstrdup (params->pool, file);
935 }
936 return (NULL);
937}
938
3f4fda20 939static const char *
940set_waklog_default_principal (cmd_parms * params, void *mconfig, char *principal, char *keytab)
941{
942 waklog_config *cfg = mconfig ? ( waklog_config * ) mconfig :
943 ( waklog_config * ) ap_get_module_config(params->server->module_config, &waklog_module );
58bbdc54 944
3f4fda20 945 waklog_config *srvcfg = ( waklog_config * ) ap_get_module_config(params->server->module_config, &waklog_module );
4e1ae1cd 946
3f4fda20 947 log_error (APLOG_MARK, APLOG_DEBUG, 0, params->server,
42d78dfb 948 "mod_waklog: set default princ/keytab: %s, %s for %s", principal, keytab, cfg->path ? cfg->path : "NULL");
313dde40 949
3f4fda20 950 cfg->default_principal = ap_pstrdup (params->pool, principal);
951 cfg->default_keytab = ap_pstrdup(params->pool, keytab );
952
953 /* this also gets set at the server level */
954 if ( mconfig && ( ! cfg->path ) ) {
955 srvcfg->default_principal = ap_pstrdup (params->pool, principal);
956 srvcfg->default_keytab = ap_pstrdup(params->pool, keytab );
957 } else {
958 log_error(APLOG_MARK, APLOG_ERR, 0, params->server, "only able to set default principal on a global level!");
959 return "Unable to set DefaultPrincipal outside of top level config!";
960 }
961
962 add_to_renewtable( params->pool, keytab, principal );
963
964 cfg->configured = 1;
965
966 return (NULL);
967}
313dde40 968
3f4fda20 969static const char *
970set_waklog_use_usertokens (cmd_parms * params, void *mconfig, int flag)
bed98ff9 971{
3f4fda20 972 waklog_config *cfg = mconfig ? ( waklog_config * ) mconfig :
973 ( waklog_config * ) ap_get_module_config(params->server->module_config, &waklog_module );
bed98ff9 974
3f4fda20 975 cfg->usertokens = flag;
bed98ff9 976
3f4fda20 977 cfg->configured = 1;
bed98ff9 978
3f4fda20 979 log_error (APLOG_MARK, APLOG_DEBUG, 0, params->server,
42d78dfb 980 "mod_waklog: waklog_use_user_tokens set");
3f4fda20 981 return (NULL);
bed98ff9 982}
983
984
21a7788b 985static const char *
986set_waklog_disable_token_cache (cmd_parms * params, void *mconfig, int flag)
987{
988 waklog_config *cfg = mconfig ? ( waklog_config * ) mconfig :
989 ( waklog_config * ) ap_get_module_config(params->server->module_config, &waklog_module );
990
991 cfg->disable_token_cache = flag;
992
993 cfg->configured = 1;
994
995 log_error (APLOG_MARK, APLOG_DEBUG, 0, params->server,
996 "mod_waklog: waklog_disable_token_cache set");
997 return (NULL);
998}
999
1000
c9d59a9c 1001#ifndef APACHE2
3f4fda20 1002static void waklog_child_exit( server_rec *s, MK_POOL *p ) {
1003#else
1004apr_status_t waklog_child_exit( void *sr ) {
4e1ae1cd 1005
3f4fda20 1006 server_rec *s = (server_rec *) sr;
1007#endif
1008
1009 if ( child.ccache ) {
1010 krb5_cc_close(child.kcontext, child.ccache);
1011 }
1012
1013 if ( child.kcontext ) {
1014 krb5_free_context(child.kcontext);
1015 }
1016
1017 /* forget our tokens */
1018
1019 ktc_ForgetAllTokens ();
1020
1021 log_error (APLOG_MARK, APLOG_DEBUG, 0, s,
42d78dfb 1022 "mod_waklog: waklog_child_exit complete");
4e1ae1cd 1023
c9d59a9c 1024#ifdef APACHE2
3f4fda20 1025 return APR_SUCCESS;
1026#endif
1027
1028}
4e1ae1cd 1029
3f4fda20 1030static void
c9d59a9c 1031#ifdef APACHE2
3f4fda20 1032waklog_child_init (MK_POOL * p, server_rec * s)
1033#else
1034waklog_child_init (server_rec * s, MK_POOL * p)
1035#endif
1036{
b52ccbb1 1037
3f4fda20 1038 krb5_error_code code;
1039 waklog_config *cfg;
1040
1041 char *cell;
1042
3f4fda20 1043 log_error (APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: child_init called for pid %d", getpid());
1044
1045 if ( !sharedspace ) {
1046 log_error( APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: child_init called without shared space? %d", getpid());
1047 return;
1048 }
1049
1050 log_error (APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: child_init called for pid %d", getpid());
7193eb01 1051
3f4fda20 1052 memset (&child, 0, sizeof(child));
1053
1054 if ( code = krb5_init_context(&child.kcontext) ) {
1055 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: can't init kerberos context %d", code );
1056 }
1057
1058 if ( code = krb5_cc_resolve(child.kcontext, "MEMORY:tmpcache", &child.ccache) ) {
1059 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: can't initialize in-memory credentials cache %d", code );
1060 }
1061
1062 if ( pag_for_children ) {
1063 setpag ();
1064 }
7193eb01 1065
3f4fda20 1066 getModConfig (cfg, s);
7193eb01 1067
3f4fda20 1068 if ( cfg->default_principal != WAKLOG_UNSET ) {
1069 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: child_init setting default user %s, %s", cfg->default_principal, cfg->default_keytab);
1070 set_auth( s, NULL, 0, cfg->default_principal, cfg->default_keytab, 0);
1071 }
7193eb01 1072
891fb458 1073 cell = strdup(cfg->afs_cell);
3f4fda20 1074 pr_Initialize( 0, AFSDIR_CLIENT_ETC_DIR, cell );
7193eb01 1075
c9d59a9c 1076#ifdef APACHE2
3f4fda20 1077 apr_pool_cleanup_register(p, s, waklog_child_exit, apr_pool_cleanup_null);
1078#endif
7193eb01 1079
3f4fda20 1080 log_error (APLOG_MARK, APLOG_DEBUG, 0, s,
42d78dfb 1081 "mod_waklog: child_init returned");
7193eb01 1082
3f4fda20 1083 return;
1084}
b52ccbb1 1085
3f4fda20 1086command_rec waklog_cmds[] = {
1087
21a7788b 1088 command ("WaklogAFSCell", set_waklog_afs_cell, 0, TAKE1,
1089 "Use the supplied AFS cell (required)"),
7193eb01 1090
98534230 1091 command ("WaklogAFSCellRealm", set_waklog_afs_cell_realm, 0, TAKE1,
1092 "Assume that the AFS cell belongs to the specified Kerberos realm (optional)"),
1093
21a7788b 1094 command ("WaklogEnabled", set_waklog_enabled, 0, FLAG,
1095 "enable waklog on a server, location, or directory basis"),
7193eb01 1096
21a7788b 1097 command ("WaklogDefaultPrincipal", set_waklog_default_principal, 0, TAKE2,
1098 "Set the default principal that the server runs as"),
7193eb01 1099
21a7788b 1100 command ("WaklogLocationPrincipal", set_waklog_location_principal, 0, TAKE2,
1101 "Set the principal on a <Location>-specific basis"),
7193eb01 1102
21a7788b 1103 command ("WaklogDisableTokenCache", set_waklog_disable_token_cache, 0, FLAG,
1104 "Ignore the token cache (location-specific); useful for scripts that need kerberos tickets."),
1105
1106 command ("WaklogUseUserTokens", set_waklog_use_usertokens, 0, FLAG,
1107 "Use the requesting user tokens (from webauth)"),
1108
3f4fda20 1109 {NULL}
1110};
7193eb01 1111
7193eb01 1112
3f4fda20 1113/* not currently using this */
7193eb01 1114
3f4fda20 1115static int
1116token_cleanup (void *data)
1117{
1118 request_rec *r = (request_rec *) data;
e2df6441 1119
3f4fda20 1120 if (child.token.ticketLen)
1121 {
1122 memset (&child.token, 0, sizeof (struct ktc_token));
e21f34f0 1123
3f4fda20 1124 ktc_ForgetAllTokens ();
7193eb01 1125
3f4fda20 1126 log_error (APLOG_MARK, APLOG_DEBUG, 0, r->server,
42d78dfb 1127 "mod_waklog: ktc_ForgetAllTokens succeeded: pid: %d",
1128 getpid ());
3f4fda20 1129 }
1130 return 0;
7193eb01 1131}
1132
3f4fda20 1133static int
1134waklog_child_routine (void *data, child_info * pinfo)
7193eb01 1135{
3f4fda20 1136 int i;
1137 server_rec *s = (server_rec *) data;
1138 krb5_error_code code;
1139 char *cell;
1140 time_t sleep_time = ( TKT_LIFE / 2 ) ;
1141 time_t when;
1142 time_t left;
1143 waklog_config *cfg;
1144
1145 getModConfig( cfg, s );
1146
1147 log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: waklog_child_routine started, running as %d", getuid());
1148
1149 memset (&child, 0, sizeof(child));
1150
1151 if ( code = krb5_init_context(&child.kcontext) ) {
1152 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: can't init kerberos context %d", code );
1153 }
1154
1155 if ( code = krb5_cc_resolve(child.kcontext, "MEMORY:tmpcache", &child.ccache) ) {
1156 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: can't initialize in-memory credentials cache %d", code );
1157 }
1158
1159 /* need to do this so we can make PTS calls */
891fb458 1160 cell = strdup(cfg->afs_cell); /* stupid */
3f4fda20 1161 pr_Initialize( 0, AFSDIR_CLIENT_ETC_DIR, cell );
1162
1163 while(1) {
1164
1165 for ( i = 0; i < renewcount; ++i ) {
1166 renewtable[i].lastrenewed = time(0);
1167 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: (pid %d) renewing %s / %s", getpid(), renewtable[i].principal,
1168 renewtable[i].keytab);
1169
1170 set_auth( s, NULL, 0, renewtable[i].principal, renewtable[i].keytab, 1 );
1171
1172 /* if this is our default token, we want to "stash" it in our current PAG so the parent maintains readability of
1173 things that it needs to read */
1174
1175 if ( cfg && cfg->default_principal && ( ! strcmp(cfg->default_principal, renewtable[i].principal ) ) ) {
1176 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: renewing/setting default tokens" );
1177 set_auth( s, NULL, 0, renewtable[i].principal, renewtable[i].keytab, 0 );
1178 }
1179
4e1ae1cd 1180 }
1181
3f4fda20 1182 sharedspace->renewcount++;
1183
1184 left = sleep_time;
1185
1186 while( left > 5 ) {
1187 when = time(0);
1188
1189 sleep(left);
1190
1191 left -= ( time(0) - when );
4e1ae1cd 1192 }
3f4fda20 1193
1194 }
4e1ae1cd 1195
3f4fda20 1196 pr_End();
403921ef 1197
3f4fda20 1198}
4e1ae1cd 1199
c9d59a9c 1200#ifdef APACHE2
3f4fda20 1201static int
1202waklog_init_handler (apr_pool_t * p, apr_pool_t * plog,
42d78dfb 1203 apr_pool_t * ptemp, server_rec * s)
3f4fda20 1204{
1205 int rv;
1206 extern char *version;
1207 apr_proc_t *proc;
1208 waklog_config *cfg;
1209 void *data;
1210 int fd = -1;
1211 int use_existing = 1;
1212 int oldrenewcount;
1213 char cache_file[MAXNAMELEN];
1214#ifdef use_pthreads
1215 pthread_rwlockattr_t rwlock_attr;
1216#endif
4e1ae1cd 1217
1218
3f4fda20 1219 getModConfig (cfg, s);
4e1ae1cd 1220
3f4fda20 1221 /* initialize_module() will be called twice, and if it's a DSO
1222 * then all static data from the first call will be lost. Only
1223 * set up our static data on the second call.
1224 * see http://issues.apache.org/bugzilla/show_bug.cgi?id=37519 */
1225 apr_pool_userdata_get (&data, userdata_key, s->process->pool);
7193eb01 1226
891fb458 1227
1228 if (cfg->afs_cell==NULL) {
1229 log_error (APLOG_MARK, APLOG_ERR, 0, s,
21a7788b 1230 "mod_waklog: afs_cell==NULL; please provide the WaklogAFSCell directive");
891fb458 1231 /** clobber apache */
1232 exit(-1);
1233 }
1234
3f4fda20 1235 if (!data)
1236 {
1237 apr_pool_userdata_set ((const void *) 1, userdata_key,
42d78dfb 1238 apr_pool_cleanup_null, s->process->pool);
4e1ae1cd 1239 }
3f4fda20 1240 else
1241 {
1242 log_error (APLOG_MARK, APLOG_INFO, 0, s,
891fb458 1243 "mod_waklog: version %s initialized for cell %s", version, cfg->afs_cell);
3f4fda20 1244
1245 if ( sharedspace ) {
1246 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: shared memory already allocated." );
1247 } else {
1248
1249 snprintf( cache_file, MAXNAMELEN, "/tmp/waklog_cache.%d", getpid() );
1250
1251 if ( ( fd = open( cache_file, O_RDWR, 0600 ) ) == -1 ) {
1252
1253 if ( errno == ENOENT ) {
1254
1255 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: creating shared token cache file %s", cache_file );
1256 use_existing = 0;
1257 if ( ( fd = open( cache_file, O_RDWR|O_CREAT|O_TRUNC, 0600 ) ) == -1 ) {
1258 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: cannot create shared token cache file %s (%d)", cache_file, errno );
1259 exit(errno);
1260 }
1261 } else {
1262 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: cannot open existing shared token cache file %s (%d)", cache_file, errno );
1263 }
1264 }
1265
1266 if ( use_existing == 0 ) {
1267 struct sharedspace_s bob;
1268 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: sizing our cache file %d to %d", fd, sizeof(struct sharedspace_s) );
1269 memset( &bob, 0, sizeof(struct sharedspace_s));
1270 write(fd, &bob, sizeof(struct sharedspace_s));
1271 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: done sizing our cache file to %d", sizeof(struct sharedspace_s) );
1272 }
1273
1274 /* mmap the region */
1275
1276 if ( ( sharedspace = (struct sharedspace_s *) mmap ( NULL, sizeof(struct sharedspace_s), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0 ) ) != MAP_FAILED ) {
1277 log_error( APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: shared mmap region ok %d", sharedspace );
1278 close(fd);
1279 } else {
1280 log_error( APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: mmap failed %d", errno );
1281 exit(errno);
1282 }
1283 }
4e1ae1cd 1284
3f4fda20 1285#ifdef use_pthreads
1286#define locktype pthread_rwlock_t
1287#else
1288#define locktype rwlock_t
1289#endif
4e1ae1cd 1290
3f4fda20 1291 if ( sharedlock = ( locktype * ) mmap ( NULL, sizeof(locktype), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0 ) ) {
1292#ifndef use_pthreads
1293 rwlock_init(sharedlock, USYNC_PROCESS, NULL );
1294#else
1295 pthread_rwlockattr_init(&rwlock_attr);
1296 pthread_rwlockattr_setpshared(&rwlock_attr, PTHREAD_PROCESS_SHARED);
1297 pthread_rwlock_init(sharedlock, &rwlock_attr );
1298#endif
1299 } else {
1300 log_error( APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: rwlock mmap failed %d", errno );
1301 }
58bbdc54 1302
3f4fda20 1303#undef locktype
7193eb01 1304
3f4fda20 1305 /* set our default tokens */
403921ef 1306
3f4fda20 1307 oldrenewcount = sharedspace->renewcount;
7193eb01 1308
3f4fda20 1309 pag_for_children = 0;
7193eb01 1310
3f4fda20 1311 proc = (apr_proc_t *) ap_pcalloc (s->process->pool, sizeof (apr_proc_t));
7193eb01 1312
3f4fda20 1313 rv = apr_proc_fork (proc, s->process->pool);
7193eb01 1314
3f4fda20 1315 if (rv == APR_INCHILD)
42d78dfb 1316 {
1317 waklog_child_routine (s, NULL);
1318 }
3f4fda20 1319 else
42d78dfb 1320 {
1321 apr_pool_note_subprocess (s->process->pool, proc, APR_KILL_ALWAYS);
1322 }
3f4fda20 1323 /* parent and child */
1324 cfg->forked = proc->pid;
1325 pag_for_children = 1;
1326
1327 if ( use_existing == 0 ) {
1328 /* wait here until our child process has gone and done it's renewing thing. */
1329 while( sharedspace->renewcount == oldrenewcount ) {
1330 log_error( APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: waiting for tokens..." );
1331 sleep(2);
1332 }
1333 }
1334
1335 if ( cfg->default_principal ) {
1336 set_auth( s, NULL, 0, cfg->default_principal, cfg->default_keytab, 0);
1337 }
1338 }
1339 return 0;
1340}
ebb1f61c 1341#else
3f4fda20 1342static void
1343waklog_init (server_rec * s, MK_POOL * p)
1344{
1345 extern char *version;
1346 int pid;
1347 waklog_config *cfg;
1348 char *cell;
1349 int fd = -1;
1350 int use_existing = 1;
1351 int oldrenewcount;
1352 char cache_file[MAXNAMELEN];
1353#ifdef use_pthreads
1354 pthread_rwlockattr_t rwlock_attr;
ebb1f61c 1355#endif
7193eb01 1356
3f4fda20 1357 log_error (APLOG_MARK, APLOG_DEBUG, 0, s,
42d78dfb 1358 "mod_waklog: version %s initialized.", version);
7193eb01 1359
3f4fda20 1360 if ( sharedspace ) {
1361 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: shared memory already allocated." );
1362 } else {
1363
1364 snprintf( cache_file, MAXNAMELEN, "/tmp/waklog_cache.%d", getpid() );
1365
1366 if ( ( fd = open( cache_file, O_RDWR, 0600 ) ) == -1 ) {
1367
1368 if ( errno == ENOENT ) {
1369
1370 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: creating shared token cache file %s", cache_file );
1371 use_existing = 0;
1372 if ( ( fd = open( cache_file, O_RDWR|O_CREAT|O_TRUNC, 0600 ) ) == -1 ) {
1373 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: cannot create shared token cache file %s (%d)", cache_file, errno );
1374 exit(errno);
1375 }
1376 } else {
1377 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: cannot open existing shared token cache file %s (%d)", cache_file, errno );
1378 }
1379
1380 }
1381
1382 if ( use_existing == 0 ) {
1383 struct sharedspace_s bob;
1384 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: sizing our cache file %d to %d", fd, sizeof(struct sharedspace_s) );
1385 memset( &bob, 0, sizeof(struct sharedspace_s));
1386 write(fd, &bob, sizeof(struct sharedspace_s));
1387 log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: done sizing our cache file to %d", sizeof(struct sharedspace_s) );
1388 }
4e1ae1cd 1389
3f4fda20 1390 /* mmap the region */
1391
1392 if ( ( sharedspace = (struct sharedspace_s *) mmap ( NULL, sizeof(struct sharedspace_s), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0 ) ) != -1 ) {
1393 log_error( APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: shared mmap region ok %d", sharedspace );
1394 close(fd);
1395 } else {
1396 log_error( APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: mmap failed %d", errno );
1397 exit(errno);
1398 }
1399 }
e21f34f0 1400
3f4fda20 1401#ifdef use_pthreads
1402#define locktype pthread_rwlock_t
1403#else
1404#define locktype rwlock_t
ea3e8708 1405#endif
e21f34f0 1406
3f4fda20 1407 /* mmap our shared space for our lock */
1408 if ( sharedlock = ( locktype * ) mmap ( NULL, sizeof(locktype), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0 ) ) {
1409#ifndef use_pthreads
1410 rwlock_init(sharedlock, USYNC_PROCESS, NULL );
1411#else
1412 pthread_rwlockattr_init(&rwlock_attr);
1413 pthread_rwlockattr_setpshared(&rwlock_attr, PTHREAD_PROCESS_SHARED);
1414 pthread_rwlock_init(sharedlock, &rwlock_attr );
1415#endif
1416 } else {
1417 log_error( APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: rwlock mmap failed %d", errno );
1418 }
e21f34f0 1419
3f4fda20 1420#undef locktype
e21f34f0 1421
3f4fda20 1422 /* set our default tokens */
1423
1424 getModConfig (cfg, s);
42d78dfb 1425
1426 oldrenewcount = sharedspace->renewcount;
1427
1428 pag_for_children = 0;
1429
1430 pid = ap_bspawn_child (p, waklog_child_routine, s, kill_always,
1431 NULL, NULL, NULL);
1432
1433 pag_for_children = 1;
1434
3f4fda20 1435 log_error (APLOG_MARK, APLOG_DEBUG, 0, s,
42d78dfb 1436 "mod_waklog: ap_bspawn_child: %d.", pid);
3f4fda20 1437
1438 if ( use_existing == 0 ) {
1439 /* wait here until our child process has gone and done it's renewing thing. */
1440 while( sharedspace->renewcount == oldrenewcount ) {
1441 log_error( APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: waiting for tokens..." );
1442 sleep(2);
87822447 1443 }
3f4fda20 1444 }
1445
1446 if ( cfg->default_principal ) {
1447 set_auth( s, NULL, 0, cfg->default_principal, cfg->default_keytab, 0);
1448 }
1449
87822447 1450}
3f4fda20 1451#endif
1452
1453static int
1454waklog_phase0 (request_rec * r)
e21f34f0 1455{
3f4fda20 1456 waklog_config *cfg;
e21f34f0 1457
3f4fda20 1458 log_error (APLOG_MARK, APLOG_DEBUG, 0, r->server,
42d78dfb 1459 "mod_waklog: phase0 called");
3f4fda20 1460
1461 cfg = retrieve_config(r);
e21f34f0 1462
3f4fda20 1463 if ( cfg->protect && cfg->principal ) {
1464 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase0 using user %s", cfg->principal);
1465 set_auth(r->server, r, 0, cfg->principal, cfg->keytab, 0);
1466 } else if ( cfg->default_principal ) {
1467 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase0 using default user %s", cfg->default_principal);
1468 set_auth(r->server, r, 0, cfg->default_principal, cfg->default_keytab, 0);
1469 } else {
1470 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase0 not doing nothin.");
1471 }
e21f34f0 1472
3f4fda20 1473 return DECLINED;
e21f34f0 1474}
4e1ae1cd 1475
3f4fda20 1476static int
1477waklog_phase1 (request_rec * r)
bed98ff9 1478{
3f4fda20 1479 waklog_config *cfg;
313dde40 1480
3f4fda20 1481 log_error (APLOG_MARK, APLOG_DEBUG, 0, r->server,
42d78dfb 1482 "mod_waklog: phase1 called");
7193eb01 1483
3f4fda20 1484 cfg = retrieve_config(r);
313dde40 1485
3f4fda20 1486 if ( cfg->protect && cfg->principal ) {
1487 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase1 using user %s", cfg->principal);
1488 set_auth(r->server, r, 0, cfg->principal, cfg->keytab, 0);
1489 } else if ( cfg->default_principal ) {
1490 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase1 using default user %s", cfg->default_principal);
1491 set_auth(r->server, r, 0, cfg->default_principal, cfg->default_keytab, 0);
1492 } else {
1493 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase1 not doing nothin.");
1494 }
4e1ae1cd 1495
3f4fda20 1496 return DECLINED;
7193eb01 1497}
4e1ae1cd 1498
3f4fda20 1499static int
1500waklog_phase3 (request_rec * r)
7193eb01 1501{
3f4fda20 1502 waklog_config *cfg;
1e18ef7d 1503
3f4fda20 1504 log_error (APLOG_MARK, APLOG_DEBUG, 0, r->server,
42d78dfb 1505 "mod_waklog: phase 3 called");
1e18ef7d 1506
3f4fda20 1507 cfg = retrieve_config(r);
1508
1509 if ( cfg->protect && cfg->principal ) {
1510 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase3 using user %s", cfg->principal);
1511 set_auth(r->server, r, 0, cfg->principal, cfg->keytab, 0);
1512 } else if ( cfg->default_principal ) {
1513 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase3 using default user %s", cfg->default_principal);
1514 set_auth(r->server, r, 0, cfg->default_principal, cfg->default_keytab, 0);
1515 } else {
1516 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase3 not doing nothin.");
1517 }
1518
1519 return DECLINED;
1520}
bed98ff9 1521
3f4fda20 1522static int
1523waklog_phase6 (request_rec * r)
1524{
1525 waklog_config *cfg;
1526
1527 log_error (APLOG_MARK, APLOG_DEBUG, 0, r->server,
42d78dfb 1528 "mod_waklog: phase6 called");
3f4fda20 1529
1530 cfg = retrieve_config(r);
1531
1532 if ( cfg->protect && cfg->principal ) {
1533 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase6 using user %s", cfg->principal);
1534 set_auth(r->server, r, 0, cfg->principal, cfg->keytab, 0);
1535 } else if ( cfg->default_principal ) {
1536 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase6 using default user %s", cfg->default_principal);
1537 set_auth(r->server, r, 0, cfg->default_principal, cfg->default_keytab, 0);
1538 } else {
1539 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase6 not doing nothin.");
1540 }
1541
1542 return DECLINED;
1543}
bed98ff9 1544
3f4fda20 1545static int
1546waklog_phase7 (request_rec * r)
1547{
1548 waklog_config *cfg;
1549 int rc = 0;
1550
1551 log_error (APLOG_MARK, APLOG_DEBUG, 0, r->server,
42d78dfb 1552 "mod_waklog: phase7 called");
3f4fda20 1553
1554 cfg = retrieve_config (r);
1555
1556 if ( cfg->protect && cfg->usertokens ) {
1557 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase7 using usertokens");
1558 rc = set_auth( r->server, r, 1, NULL, NULL, 0);
1559 } else if ( cfg->protect && cfg->principal ) {
1560 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase7 using user %s", cfg->principal);
1561 rc = set_auth( r->server, r, 0, cfg->principal, cfg->keytab, 0);
1562 } else if ( cfg->default_principal ) {
1563 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase7 using default user %s", cfg->default_principal);
1564 rc = set_auth( r->server, r, 0, cfg->default_principal, cfg->default_keytab, 0);
1565 }
1566
1567 if ( rc ) {
1568 return 400;
1569 }
1570
1571 return DECLINED;
1572}
87822447 1573
3f4fda20 1574static int
1575waklog_phase9 (request_rec * r)
1576{
1577 waklog_config *cfg;
bed98ff9 1578
3f4fda20 1579 log_error (APLOG_MARK, APLOG_DEBUG, 0, r->server,
42d78dfb 1580 "mod_waklog: phase9 called");
bed98ff9 1581
3f4fda20 1582 getModConfig (cfg, r->server);
1583
1584 if ( cfg->default_principal ) {
1585 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "mod_waklog: phase9 using default user %s", cfg->default_principal);
1586 set_auth( r->server, r, 0, cfg->default_principal, cfg->default_keytab, 0);
1587 }
1588
1589 return DECLINED;
bed98ff9 1590}
1591
ff47641b 1592
87822447 1593static
c9d59a9c 1594#ifdef APACHE2
ff47641b 1595 int
87822447 1596#else
ff47641b 1597 void
87822447 1598#endif
ff47641b 1599waklog_new_connection (conn_rec * c
c9d59a9c 1600#ifdef APACHE2
42d78dfb 1601 , void *dummy
87822447 1602#endif
ff47641b 1603 )
1604{
1605
3f4fda20 1606 waklog_config *cfg;
ff47641b 1607
1608 log_error (APLOG_MARK, APLOG_DEBUG, 0, c->base_server,
42d78dfb 1609 "mod_waklog: new_connection called: pid: %d", getpid ());
1610
1611 getModConfig(cfg, c->base_server);
1612
1613 if ( cfg->default_principal ) {
1614 log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "mod_waklog: new conn setting default user %s",
1615 cfg->default_principal);
1616 set_auth( c->base_server, NULL, 0, cfg->default_principal, cfg->default_keytab, 0);
1617 }
1618
1619
3f4fda20 1620 return
c9d59a9c 1621#ifdef APACHE2
3f4fda20 1622 0
87822447 1623#endif
3f4fda20 1624 ;
7193eb01 1625}
bed98ff9 1626
c4ad0387 1627
1196adfe 1628/*
1629** Here's a quick explaination for phase0 and phase2:
1630** Apache does a stat() on the path between phase0 and
1631** phase2, and must by ACLed rl to succeed. So, at
1632** phase0 we acquire credentials for umweb:servers from
1633** a keytab, and at phase2 we must ensure we remove them.
1634**
1635** Failure to "unlog" would be a security risk.
1636*/
ff47641b 1637static int
1638waklog_phase2 (request_rec * r)
c4ad0387 1639{
161ffd84 1640
ff47641b 1641 log_error (APLOG_MARK, APLOG_DEBUG, 0, r->server,
42d78dfb 1642 "mod_waklog: phase2 called");
1196adfe 1643
ff47641b 1644 if (child.token.ticketLen)
1645 {
1646 memset (&child.token, 0, sizeof (struct ktc_token));
c4ad0387 1647
ff47641b 1648 ktc_ForgetAllTokens ();
c4ad0387 1649
ff47641b 1650 log_error (APLOG_MARK, APLOG_DEBUG, 0, r->server,
42d78dfb 1651 "mod_waklog: ktc_ForgetAllTokens succeeded: pid: %d",
1652 getpid ());
c4ad0387 1653 }
1196adfe 1654
ff47641b 1655 log_error (APLOG_MARK, APLOG_DEBUG, 0, r->server,
42d78dfb 1656 "mod_waklog: phase2 returning");
1196adfe 1657
3f4fda20 1658 return DECLINED;
c4ad0387 1659}
1660
c9d59a9c 1661#ifndef APACHE2
313dde40 1662module MODULE_VAR_EXPORT waklog_module = {
3f4fda20 1663 STANDARD_MODULE_STUFF,
866ccfbd 1664 waklog_init, /* module initializer */
42d78dfb 1665 waklog_create_dir_config, /* create per-dir config structures */
866ccfbd 1666 waklog_merge_dir_config, /* merge per-dir config structures */
1667 waklog_create_server_config, /* create per-server config structures */
1668 waklog_merge_dir_config, /* merge per-server config structures */
1669 waklog_cmds, /* table of config file commands */
1670 NULL, /* [#8] MIME-typed-dispatched handlers */
1671 waklog_phase1, /* [#1] URI to filename translation */
1672 NULL, /* [#4] validate user id from request */
1673 NULL, /* [#5] check if the user is ok _here_ */
1674 waklog_phase3, /* [#3] check access by host address */
1675 waklog_phase6, /* [#6] determine MIME type */
1676 waklog_phase7, /* [#7] pre-run fixups */
1677 waklog_phase9, /* [#9] log a transaction */
1678 NULL, /* [#2] header parser */
1679 waklog_child_init, /* child_init */
1680 waklog_child_exit, /* child_exit */
1681 waklog_phase0 /* [#0] post read-request */
bed98ff9 1682#ifdef EAPI
866ccfbd 1683 , NULL, /* EAPI: add_module */
1684 NULL, /* EAPI: remove_module */
1685 NULL, /* EAPI: rewrite_command */
1686 waklog_new_connection /* EAPI: new_connection */
bed98ff9 1687#endif
1688};
87822447 1689#else
1690static void
ff47641b 1691waklog_register_hooks (apr_pool_t * p)
87822447 1692{
3f4fda20 1693 ap_hook_translate_name (waklog_phase1, NULL, NULL, APR_HOOK_FIRST);
ff47641b 1694 ap_hook_header_parser (waklog_phase2, NULL, NULL, APR_HOOK_FIRST);
3f4fda20 1695 ap_hook_access_checker (waklog_phase3, NULL, NULL, APR_HOOK_FIRST);
1696 ap_hook_type_checker (waklog_phase6, NULL, NULL, APR_HOOK_FIRST);
ff47641b 1697 ap_hook_fixups (waklog_phase7, NULL, NULL, APR_HOOK_FIRST);
3f4fda20 1698 ap_hook_log_transaction (waklog_phase9, NULL, NULL, APR_HOOK_FIRST);
ff47641b 1699 ap_hook_child_init (waklog_child_init, NULL, NULL, APR_HOOK_FIRST);
1700 ap_hook_post_read_request (waklog_phase0, NULL, NULL, APR_HOOK_FIRST);
1701 ap_hook_pre_connection (waklog_new_connection, NULL, NULL, APR_HOOK_FIRST);
1702 ap_hook_post_config (waklog_init_handler, NULL, NULL, APR_HOOK_MIDDLE);
87822447 1703}
1704
1705
3f4fda20 1706module AP_MODULE_DECLARE_DATA waklog_module = {
1707 STANDARD20_MODULE_STUFF,
42d78dfb 1708 waklog_create_dir_config, /* create per-dir conf structures */
1709 waklog_merge_dir_config, /* merge per-dir conf structures */
1710 waklog_create_server_config, /* create per-server conf structures */
1711 waklog_merge_dir_config, /* merge per-server conf structures */
1712 waklog_cmds, /* table of configuration directives */
1713 waklog_register_hooks /* register hooks */
87822447 1714};
1715#endif