1 #define _LARGEFILE64_SOURCE
5 #include "http_config.h"
7 #include "http_protocol.h"
8 #include "http_request.h"
16 #include <sys/types.h>
20 #error "make sure you include the right stuff here"
24 #define MAXNAMELEN 1024
27 #ifdef STANDARD20_MODULE_STUFF
31 /********************* APACHE1 ******************************************************************************/
33 #include "ap_config.h"
35 #include <sys/ioccom.h>
37 #include <http_conf_globals.h>
39 #define MK_TABLE_GET ap_table_get
40 #define MK_TABLE_SET ap_table_set
41 #define command(name, func, var, type, usage) \
44 RSRC_CONF | ACCESS_CONF , type, usage }
46 /********************* APACHE2 ******************************************************************************/
48 #include <apr_strings.h>
49 #include <apr_base64.h>
50 //#include <ap_compat.h>
51 #define ap_pcalloc apr_pcalloc
52 #define ap_pdupstr apr_pdupstr
53 #define ap_pstrdup apr_pstrdup
55 module AP_MODULE_DECLARE_DATA waklog_module
;
57 #define MK_POOL apr_pool_t
58 #define MK_TABLE_GET apr_table_get
59 #define MK_TABLE_SET apr_table_set
61 extern unixd_config_rec unixd_config
;
62 #define ap_user_id unixd_config.user_id
63 #define ap_group_id unixd_config.group_id
64 #define ap_user_name unixd_config.user_name
65 #define command(name, func, var, type, usage) \
66 AP_INIT_ ## type (name, (void*) func, \
68 RSRC_CONF | ACCESS_CONF, usage)
75 const char *userdata_key
= "waklog_init";
77 /**************************************************************************************************/
81 #include <afs/venus.h>
83 #include <afs/dirpath.h>
84 #include <afs/ptuser.h>
87 #define TKT_LIFE ( 12 * 60 * 60 )
88 #define SLEEP_TIME ( TKT_LIFE - 5*60 )
92 #define WAKLOG_UNSET 0
96 #define APLOG_DEBUG APLOG_ERR
99 /* this is used to turn off pag generation for the backround worker child during startup */
100 int pag_for_children
= 1;
108 int cell_in_principal
;
111 char *default_principal
;
112 char *default_keytab
;
121 struct ktc_token token
;
122 char clientprincipal
[MAXNAMELEN
];
123 krb5_context kcontext
;
125 struct ktc_principal server
;
126 struct ktc_principal client
;
128 } waklog_child_config
;
130 waklog_child_config child
;
132 struct tokencache_ent
{
133 char clientprincipal
[MAXNAMELEN
];
134 struct ktc_token token
;
135 struct ktc_principal client
;
136 struct ktc_principal server
;
141 #define SHARED_TABLE_SIZE 512
143 struct sharedspace_s
{
145 struct tokencache_ent sharedtokens
[SHARED_TABLE_SIZE
];
148 struct sharedspace_s
*sharedspace
= NULL
;
157 pthread_rwlock_t
*sharedlock
= NULL
;
159 rwlock_t
*sharedlock
= NULL
;
162 struct renew_ent renewtable
[SHARED_TABLE_SIZE
];
166 module waklog_module
;
169 #define getModConfig(P, X) P = (waklog_config *) ap_get_module_config( (X)->module_config, &waklog_module );
174 #include <sys/ioccom.h>
177 #include <afs/venus.h>
178 #include <afs/auth.h>
179 #include <afs/dirpath.h>
180 #include <afs/ptuser.h>
181 #include <rx/rxkad.h>
183 /* If there's an error, retry more aggressively */
184 #define ERR_SLEEP_TIME 5*60
188 log_error (const char *file
, int line
, int level
, int status
,
189 const server_rec
* s
, const char *fmt
, ...)
195 vsnprintf (errstr
, 1024, fmt
, ap
);
199 ap_log_error (file
, line
, level
| APLOG_NOERRNO
, status
, s
, "(%d) %s", getpid(), errstr
);
201 ap_log_error (file
, line
, level
| APLOG_NOERRNO
, s
, "(%d) %s", getpid(), errstr
);
206 waklog_config
*retrieve_config(request_rec
*r
) {
211 if ( r
&& r
->main
) {
219 if ( my
&& ( cfg
= (waklog_config
*) ap_get_module_config(my
->per_dir_config
, &waklog_module
) ) ) {
222 getModConfig (cfg
, r
->server
);
229 /* set_auth -- sets the tokens of the current process to this user.
230 if "self" is set, it divines the user from the current requests' environment.
231 otherwise, it's gettng it from principal/keytab */
234 set_auth ( server_rec
*s
, request_rec
*r
, int self
, char *principal
, char *keytab
, int storeonly
) {
238 krb5_error_code kerror
= 0;
239 krb5_principal kprinc
= NULL
;
240 krb5_get_init_creds_opt kopts
;
243 struct ktc_principal server
= { "afs", "", "" };
244 struct ktc_principal client
;
245 struct ktc_token token
;
246 krb5_creds
*v5credsp
= NULL
;
247 krb5_keytab krb5kt
= NULL
;
248 char buf
[MAXNAMELEN
];
252 time_t oldest_time
= 0;
257 int cell_in_principal
;
260 char k5user
[MAXNAMELEN
];
263 memset((char *) &increds
, 0, sizeof(increds
));
265 /* init some stuff if it ain't already */
267 if ( ! child
.kcontext
) {
268 kerror
= krb5_init_context(&child
.kcontext
);
271 if ( ( ! child
.ccache
) && ( kerror
= krb5_cc_resolve(child
.kcontext
, "MEMORY:tmpcache", &child
.ccache
) ) ) {
272 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't initialize in-memory credentials cache %d", kerror
);
276 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: set_auth: %d, %s, %s, %d", self
, principal
? principal
: "NULL",
277 keytab
? keytab
: "NULL", storeonly
);
279 /* pull the server config record that we care about... */
282 cfg
= retrieve_config(r
);
284 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
285 "mod_waklog: set_auth using no config" );
286 getModConfig (cfg
, s
);
290 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: cfg is %d", cfg
);
295 /* pull out our principal name and stuff from the environment -- webauth better have sent
296 through. This here is also where you'd suck stuff out of KRB5CCNAME if we were
297 using something like Cosign */
299 if ( ! ( r
&& r
->connection
&& r
->user
)) {
300 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: self authentication selected, but no data available");
304 strncpy(k5user
, r
->user
, sizeof(k5user
));
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");
312 /* we'll pick this up later after we've checked the cache and current state */
317 strncpy( k5user
, principal
, sizeof(k5user
));
322 /* see if we should just go ahead and ignore this call, since we already should be set to these
328 pthread_rwlock_rdlock( sharedlock
);
330 rw_rdlock( sharedlock
);
333 for ( i
= 0; i
< SHARED_TABLE_SIZE
; ++i
) {
335 /* if it's a token for the principal we're looking for, and it hasn't expired yet */
337 if ( ( !strcmp( k5user
,
338 sharedspace
->sharedtokens
[i
].clientprincipal
) ) &&
339 ( sharedspace
->sharedtokens
[i
].token
.endTime
> mytime
) ) {
341 if ( ! memcmp(&child
.token
, &sharedspace
->sharedtokens
[i
].token
, sizeof(child
.token
) ) ) {
347 /* copy the token out of the cache and into the child object */
349 strcpy(child
.clientprincipal
, sharedspace
->sharedtokens
[i
].clientprincipal
);
350 memcpy(&child
.token
, &sharedspace
->sharedtokens
[i
].token
, sizeof(child
.token
));
351 memcpy(&child
.server
, &sharedspace
->sharedtokens
[i
].server
, sizeof(child
.server
));
352 memcpy(&child
.client
, &sharedspace
->sharedtokens
[i
].client
, sizeof(child
.client
));
354 /* set our last used time thing */
355 sharedspace
->sharedtokens
[i
].lastused
= mytime
;
365 /* release the lock on the token cache */
367 pthread_rwlock_unlock( sharedlock
);
369 rw_unlock( sharedlock
);
373 /* release the lock on the token cache */
374 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
,
375 "mod_waklog: set_auth using shared token %d for %s", i
, k5user
);
379 /* if this is something that was in the cache, and it's the same as the token we already have stored,
380 and we weren't calling this just to renew it... */
382 if ( usecached
&& indentical
) {
383 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: token is identical for %s", k5user
);
389 /* if 'usecached' isn't set, we've got to get our tokens from somewhere... */
391 if (( ! usecached
) && ( k5user
)) {
393 /* clear out the creds structure */
394 memset((void *) &v5creds
, 0, sizeof(v5creds
));
396 /* create a principal out of our k5user string */
398 if ( kerror
= krb5_parse_name (child
.kcontext
, k5user
, &kprinc
) ) {
399 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_parse_name %s", (char *) error_message(kerror
) );
403 /* create the credentials options */
405 krb5_get_init_creds_opt_init ( &kopts
);
406 krb5_get_init_creds_opt_set_tkt_life ( &kopts
, TKT_LIFE
);
407 krb5_get_init_creds_opt_set_renew_life ( &kopts
, 0 );
408 krb5_get_init_creds_opt_set_forwardable ( &kopts
, 0 );
409 krb5_get_init_creds_opt_set_proxiable ( &kopts
, 0 );
413 /* if we've been passed a keytab, we're going to be getting our credentials from it */
415 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: using keytab %s", keytab
);
417 if ( kerror
= krb5_kt_resolve(child
.kcontext
, keytab
, &krb5kt
) ) {
418 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
,
419 "mod_waklog: krb5_kt_resolve %s", error_message(kerror
) );
423 if ((kerror
= krb5_get_init_creds_keytab (child
.kcontext
, &v5creds
,
424 kprinc
, krb5kt
, 0, NULL
, &kopts
) ) ) {
425 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_get_init_creds_keytab %s",
426 error_message(kerror
) );
432 /* if 'self' is set, we're going to use the credentials provided in the credential information */
433 /* if you're using CoSign, you'd actually just set the ccache to the KRB5CCNAME credentials */
434 /* and skip ahead... Our WebSSO is lame, but has a way for us to snarf the password out of */
435 /* the encrypted token for proxy-authentication stuff. We only hand out keys that allow this */
436 /* functionality to VERY special people. */
438 if ((kerror
= krb5_get_init_creds_password ( child
.kcontext
, &v5creds
,
439 kprinc
, k5secret
, NULL
, NULL
, 0, NULL
, &kopts
) ) ) {
440 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_get_init_creds_password %s",
441 error_message(kerror
) );
442 /* nuke the password so it doesn't end up in core files */
443 memset(k5secret
, 0, sizeof(k5secret
));
447 memset(k5secret
, 0, sizeof(k5secret
));
451 /* degenerate case -- we don't have enough information to do anything */
453 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: no keytab, no self?");
459 /* initialize the credentials cache and store the stuff we just got */
461 if ( kerror
= krb5_cc_initialize (child
.kcontext
, child
.ccache
, kprinc
)) {
462 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: init credentials cache %s",
463 error_message(kerror
));
467 if ( kerror
= krb5_cc_store_cred(child
.kcontext
, child
.ccache
, &v5creds
) ) {
468 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot store credentials %s",
469 error_message(kerror
));
473 krb5_free_cred_contents(child
.kcontext
, &v5creds
);
476 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: store cred %s", error_message(kerror
));
480 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: kinit ok for %s", k5user
);
482 /* now, to the 'aklog' portion of our program. */
484 strncpy( buf
, "afs", sizeof(buf
) - 1 );
486 /** we make two attempts here, one for afs@REALM and one for afs/cell@REALM */
487 for(attempt
= 0; attempt
<= 1; attempt
++) {
488 cell_in_principal
= (cfg
->cell_in_principal
+ attempt
) % 2;
490 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: cell_in_principal=%d", cell_in_principal
);
491 if (cell_in_principal
) {
492 strncat(buf
, "/", sizeof(buf
) - strlen(buf
) - 1);
493 strncat(buf
, cfg
->afs_cell
, sizeof(buf
) - strlen(buf
) - 1);
496 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: using AFS principal: %s", buf
);
498 if ((kerror
= krb5_parse_name (child
.kcontext
, buf
, &increds
.server
))) {
499 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_parse name %s", error_message(kerror
));
503 if ((kerror
= krb5_cc_get_principal(child
.kcontext
, child
.ccache
, &increds
.client
))) {
504 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_cc_get_princ %s", error_message(kerror
));
508 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: retrieved data from ccache for %s", k5user
);
510 increds
.times
.endtime
= 0;
512 increds
.keyblock
.enctype
= ENCTYPE_DES_CBC_CRC
;
514 if (kerror
= krb5_get_credentials (child
.kcontext
, 0, child
.ccache
, &increds
, &v5credsp
)) {
515 /* only complain once we've tried both afs@REALM and afs/cell@REALM */
517 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_get_credentials: %s",
518 error_message(kerror
));
524 cfg
->cell_in_principal
= cell_in_principal
;
528 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: get_credentials passed for %s", k5user
);
530 if ( v5credsp
->ticket
.length
>= MAXKTCTICKETLEN
) {
531 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: ticket size (%d) too big to fake",
532 v5credsp
->ticket
.length
);
536 memset(&token
, 0, sizeof(struct ktc_token
));
538 token
.startTime
= v5credsp
->times
.starttime
? v5credsp
->times
.starttime
: v5credsp
->times
.authtime
;
539 token
.endTime
= v5credsp
->times
.endtime
;
541 memmove( &token
.sessionKey
, v5credsp
->keyblock
.contents
, v5credsp
->keyblock
.length
);
542 token
.kvno
= RXKAD_TKT_TYPE_KERBEROS_V5
;
543 token
.ticketLen
= v5credsp
->ticket
.length
;
544 memmove( token
.ticket
, v5credsp
->ticket
.data
, token
.ticketLen
);
548 memmove( buf
, v5credsp
->client
->data
[0].data
, min(v5credsp
->client
->data
[0].length
,
550 buf
[v5credsp
->client
->data
[0].length
] = '\0';
551 if ( v5credsp
->client
->length
> 1 ) {
552 strncat(buf
, ".", sizeof(buf
) - strlen(buf
) - 1);
553 buflen
= strlen(buf
);
554 memmove(buf
+ buflen
, v5credsp
->client
->data
[1].data
,
555 min(v5credsp
->client
->data
[1].length
,
556 MAXKTCNAMELEN
- strlen(buf
) - 1));
557 buf
[buflen
+ v5credsp
->client
->data
[1].length
] = '\0';
560 /* assemble the client */
561 strncpy(client
.name
, buf
, sizeof(client
.name
) - 1 );
562 strncpy(client
.instance
, "", sizeof(client
.instance
) - 1 );
563 memmove(buf
, v5credsp
->client
->realm
.data
, min(v5credsp
->client
->realm
.length
,
565 buf
[v5credsp
->client
->realm
.length
] = '\0';
566 strncpy(client
.cell
, buf
, sizeof(client
.cell
));
568 /* assemble the server's cell */
569 strncpy(server
.cell
, cfg
->afs_cell
, sizeof(server
.cell
) - 1);
571 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: preparing to init PTS connection for %s", server
.cell
);
573 /* fill out the AFS ID in the client name */
574 /* we've done a pr_Initialize in the child_init -- once, per process. If you try to do it more
575 * strange things seem to happen. */
578 afs_int32 viceId
= 0;
580 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: making PTS call to look up %s", client
.name
);
582 if ( ( rc
= pr_SNameToId( client
.name
, &viceId
) ) == 0 ) {
583 snprintf( client
.name
, sizeof(client
.name
), "AFS ID %d", viceId
);
585 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: PTS call returned error %d ", rc
);
588 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: PTS call returned %s ", client
.name
);
592 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: server: name %s, instance %s, cell %s",
593 server
.name
, server
.instance
, server
.cell
);
595 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: client: name %s, instance %s, cell %s",
596 client
.name
, client
.instance
, client
.cell
);
598 /* copy the resulting stuff into the child structure */
600 strncpy(child
.clientprincipal
, k5user
, sizeof(child
.clientprincipal
));
601 memcpy(&child
.token
, &token
, sizeof(child
.token
));
602 memcpy(&child
.server
, &server
, sizeof(child
.server
));
603 memcpy(&child
.client
, &client
, sizeof(child
.client
));
605 /* stuff the resulting token-related stuff into our shared token cache */
606 /* note, that anything that was set from a keytab is "persistant", and is immune
607 * from LRU-aging. This is because nothing but the process that's running as root
608 * can update these, and it's running every hour or so and renewing these tokens.
609 * and we don't want them aged out.
612 mytime
= oldest_time
= time(0);
614 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: waiting for shared space for %s ", k5user
);
617 pthread_rwlock_wrlock(sharedlock
);
619 rw_wrlock(sharedlock
);
622 for( i
= ( SHARED_TABLE_SIZE
- 1 ); i
>= 0; i
-- ) {
623 if ( ( sharedspace
->sharedtokens
[i
].lastused
<= oldest_time
) &&
624 ( sharedspace
->sharedtokens
[i
].persist
== 0 ) ) {
626 oldest_time
= sharedspace
->sharedtokens
[i
].lastused
;
628 if ( ! strcmp ( sharedspace
->sharedtokens
[i
].clientprincipal
,
629 child
.clientprincipal
) ) {
630 memcpy(&sharedspace
->sharedtokens
[i
].token
, &child
.token
, sizeof(child
.token
) );
631 memcpy(&sharedspace
->sharedtokens
[i
].client
, &child
.client
, sizeof(child
.client
) );
632 memcpy(&sharedspace
->sharedtokens
[i
].server
, &child
.server
, sizeof(child
.server
) );
633 sharedspace
->sharedtokens
[i
].lastused
= mytime
;
634 sharedspace
->sharedtokens
[i
].persist
= keytab
? 1 : 0;
640 if ( stored
== -1 ) {
641 memcpy(&sharedspace
->sharedtokens
[oldest
].token
, &child
.token
, sizeof(child
.token
) );
642 memcpy(&sharedspace
->sharedtokens
[oldest
].client
, &child
.client
, sizeof(child
.client
) );
643 memcpy(&sharedspace
->sharedtokens
[oldest
].server
, &child
.server
, sizeof(child
.server
) );
644 strcpy(sharedspace
->sharedtokens
[oldest
].clientprincipal
, child
.clientprincipal
);
645 sharedspace
->sharedtokens
[oldest
].lastused
= mytime
;
646 sharedspace
->sharedtokens
[oldest
].persist
= keytab
? 1 : 0;
651 pthread_rwlock_unlock(sharedlock
);
653 rw_unlock(sharedlock
);
656 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: token stored in slot %d for %s", stored
,
657 child
.clientprincipal
);
659 } else if ( ! usecached
) {
660 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: set_auth divergent case");
669 /* don't ask. Something about AIX. We're leaving it here.*/
670 /* write(2, "", 0); */
672 /* we try twice, because sometimes the first one fails. Dunno why, but it always works the second time */
674 if ((rc
= ktc_SetToken(&child
.server
, &child
.token
, &child
.client
, 0))) {
675 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: settoken returned %s for %s -- trying again",
676 error_message(rc
), k5user
);
677 if ((rc
= ktc_SetToken(&child
.server
, &child
.token
, &child
.client
, 0))) {
678 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: settoken2 returned %s for %s",
679 error_message(rc
), k5user
);
686 krb5_free_cred_contents(child
.kcontext
, v5credsp
);
687 if ( increds
.client
)
688 krb5_free_principal (child
.kcontext
, increds
.client
);
689 if ( increds
.server
)
690 krb5_free_principal (child
.kcontext
, increds
.server
);
692 (void) krb5_kt_close(child
.kcontext
, krb5kt
);
694 krb5_free_principal (child
.kcontext
, kprinc
);
697 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: set_auth ending with %d", rc
);
698 } else if ( kerror
) {
699 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: set_auth ending with krb5 error %d, %s", kerror
, error_message(kerror
));
701 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: set_auth ending ok");
704 return kerror
? (int) kerror
: (int) rc
;
711 waklog_create_server_config (MK_POOL
* p
, server_rec
* s
)
715 cfg
= (waklog_config
*) ap_pcalloc (p
, sizeof (waklog_config
));
717 memset(cfg
, 0, sizeof(waklog_config
));
718 cfg
->path
= "(server)";
719 cfg
->protect
= WAKLOG_UNSET
;
720 cfg
->usertokens
= WAKLOG_UNSET
;
721 cfg
->keytab
= WAKLOG_UNSET
;
722 cfg
->principal
= WAKLOG_UNSET
;
723 cfg
->default_principal
= WAKLOG_UNSET
;
724 cfg
->default_keytab
= WAKLOG_UNSET
;
725 cfg
->afs_cell
= WAKLOG_UNSET
;
729 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
730 "mod_waklog: server config created.");
735 /* initialize with host-config information */
738 waklog_create_dir_config (MK_POOL
* p
, char *dir
)
742 cfg
= (waklog_config
*) ap_pcalloc (p
, sizeof (waklog_config
));
743 memset(cfg
, 0, sizeof(waklog_config
));
745 cfg
->path
= ap_pstrdup(p
, dir
);
746 cfg
->protect
= WAKLOG_UNSET
;
747 cfg
->usertokens
= WAKLOG_UNSET
;
748 cfg
->keytab
= WAKLOG_UNSET
;
749 cfg
->principal
= WAKLOG_UNSET
;
750 cfg
->default_principal
= WAKLOG_UNSET
;
751 cfg
->default_keytab
= WAKLOG_UNSET
;
752 cfg
->afs_cell
= WAKLOG_UNSET
;
759 static void *waklog_merge_dir_config(MK_POOL
*p
, void *parent_conf
, void *newloc_conf
) {
761 waklog_config
*merged
= ( waklog_config
* ) ap_pcalloc(p
, sizeof(waklog_config
) );
762 waklog_config
*parent
= ( waklog_config
* ) parent_conf
;
763 waklog_config
*child
= ( waklog_config
* ) newloc_conf
;
765 merged
->protect
= child
->protect
!= WAKLOG_UNSET
? child
->protect
: parent
->protect
;
767 merged
->path
= child
->path
!= WAKLOG_UNSET
? child
->path
: parent
->path
;
769 merged
->usertokens
= child
->usertokens
!= WAKLOG_UNSET
? child
->usertokens
: parent
->usertokens
;
771 merged
->principal
= child
->principal
!= WAKLOG_UNSET
? child
->principal
: parent
->principal
;
773 merged
->keytab
= child
->keytab
!= WAKLOG_UNSET
? child
->keytab
: parent
->keytab
;
775 merged
->default_keytab
= child
->default_keytab
!= WAKLOG_UNSET
? child
->default_keytab
: parent
->default_keytab
;
777 merged
->default_principal
= child
->default_principal
!= WAKLOG_UNSET
? child
->default_principal
: parent
->default_principal
;
779 merged
->afs_cell
= child
->afs_cell
!= WAKLOG_UNSET
? child
->afs_cell
: parent
->afs_cell
;
781 return (void *) merged
;
785 static void *waklog_merge_server_config(MK_POOL
*p
, void *parent_conf
, void *newloc_conf
) {
787 waklog_config
*merged
= ( waklog_config
* ) ap_pcalloc(p
, sizeof(waklog_config
) );
788 waklog_config
*pconf
= ( waklog_config
* ) parent_conf
;
789 waklog_config
*nconf
= ( waklog_config
* ) newloc_conf
;
791 merged
->protect
= nconf
->protect
== WAKLOG_UNSET
? pconf
->protect
: nconf
->protect
;
793 merged
->usertokens
= nconf
->usertokens
== WAKLOG_UNSET
? pconf
->usertokens
: nconf
->usertokens
;
795 merged
->keytab
= nconf
->keytab
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->keytab
) :
796 ( nconf
->keytab
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->keytab
) );
798 merged
->principal
= nconf
->principal
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->principal
) :
799 ( nconf
->principal
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->principal
) );
801 merged
->afs_cell
= nconf
->afs_cell
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->afs_cell
) :
802 ( nconf
->afs_cell
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->afs_cell
) );
804 merged
->default_keytab
= nconf
->default_keytab
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->default_keytab
) :
805 ( nconf
->default_keytab
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->default_keytab
) );
807 merged
->default_principal
= nconf
->default_principal
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->default_principal
) :
808 ( nconf
->default_principal
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->default_principal
) );
811 return (void *) merged
;
816 set_waklog_protect (cmd_parms
* params
, void *mconfig
, int flag
)
818 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
819 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
823 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
824 "mod_waklog: waklog_protect set on %s", cfg
->path
? cfg
->path
: "NULL");
829 /* this adds a principal/keytab pair to get their tokens renewed by the
830 child process every few centons. */
832 void add_to_renewtable(MK_POOL
*p
, char *keytab
, char *principal
) {
836 if ( renewcount
>= SHARED_TABLE_SIZE
) {
837 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, NULL
, "mod_waklog: big problem. Increase the SHARED_TABLE_SIZE or \
838 decrease your tokens.");
842 /* check to see if it's already there */
844 for ( i
= 0; i
< renewcount
; i
++ ) {
845 if ( ! strcmp(renewtable
[i
].principal
, principal
) ) {
850 renewtable
[renewcount
].keytab
= ap_pstrdup(p
, keytab
);
851 renewtable
[renewcount
].principal
= ap_pstrdup(p
, principal
);
852 renewtable
[renewcount
].lastrenewed
= 0;
858 set_waklog_principal (cmd_parms
*params
, void *mconfig
, char *principal
, char *keytab
)
860 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
861 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
863 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
864 "mod_waklog: configuring principal: %s, keytab: %s", principal
, keytab
);
866 cfg
->principal
= ap_pstrdup(params
->pool
, principal
);
867 cfg
->keytab
= ap_pstrdup (params
->pool
, keytab
);
869 add_to_renewtable(params
->pool
, keytab
, principal
);
877 set_waklog_use_afs_cell (cmd_parms
* params
, void *mconfig
, char *file
)
879 waklog_config
*waklog_mconfig
= ( waklog_config
* ) mconfig
;
880 waklog_config
*waklog_srvconfig
=
881 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
883 log_error (APLOG_MARK
, APLOG_INFO
, 0, params
->server
,
884 "mod_waklog: will use afs_cell: %s", file
);
886 waklog_srvconfig
->cell_in_principal
= 0;
887 waklog_srvconfig
->afs_cell
= ap_pstrdup (params
->pool
, file
);
888 waklog_srvconfig
->configured
= 1;
890 if (waklog_mconfig
!= NULL
) {
891 waklog_mconfig
->cell_in_principal
= waklog_srvconfig
->cell_in_principal
;
892 waklog_mconfig
->afs_cell
= ap_pstrdup (params
->pool
, file
);
893 waklog_mconfig
->configured
= 1;
899 set_waklog_default_principal (cmd_parms
* params
, void *mconfig
, char *principal
, char *keytab
)
901 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
902 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
904 waklog_config
*srvcfg
= ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
906 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
907 "mod_waklog: set default princ/keytab: %s, %s for %s", principal
, keytab
, cfg
->path
? cfg
->path
: "NULL");
909 cfg
->default_principal
= ap_pstrdup (params
->pool
, principal
);
910 cfg
->default_keytab
= ap_pstrdup(params
->pool
, keytab
);
912 /* this also gets set at the server level */
913 if ( mconfig
&& ( ! cfg
->path
) ) {
914 srvcfg
->default_principal
= ap_pstrdup (params
->pool
, principal
);
915 srvcfg
->default_keytab
= ap_pstrdup(params
->pool
, keytab
);
917 log_error(APLOG_MARK
, APLOG_ERR
, 0, params
->server
, "only able to set default principal on a global level!");
918 return "Unable to set DefaultPrincipal outside of top level config!";
921 add_to_renewtable( params
->pool
, keytab
, principal
);
929 set_waklog_use_usertokens (cmd_parms
* params
, void *mconfig
, int flag
)
931 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
932 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
934 cfg
->usertokens
= flag
;
938 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
939 "mod_waklog: waklog_use_user_tokens set");
945 static void waklog_child_exit( server_rec
*s
, MK_POOL
*p
) {
947 apr_status_t
waklog_child_exit( void *sr
) {
949 server_rec
*s
= (server_rec
*) sr
;
952 if ( child
.ccache
) {
953 krb5_cc_close(child
.kcontext
, child
.ccache
);
956 if ( child
.kcontext
) {
957 krb5_free_context(child
.kcontext
);
960 /* forget our tokens */
962 ktc_ForgetAllTokens ();
964 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
965 "mod_waklog: waklog_child_exit complete");
975 waklog_child_init (MK_POOL
* p
, server_rec
* s
)
977 waklog_child_init (server_rec
* s
, MK_POOL
* p
)
981 krb5_error_code code
;
986 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: child_init called for pid %d", getpid());
988 if ( !sharedspace
) {
989 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: child_init called without shared space? %d", getpid());
993 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: child_init called for pid %d", getpid());
995 memset (&child
, 0, sizeof(child
));
997 if ( code
= krb5_init_context(&child
.kcontext
) ) {
998 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't init kerberos context %d", code
);
1001 if ( code
= krb5_cc_resolve(child
.kcontext
, "MEMORY:tmpcache", &child
.ccache
) ) {
1002 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't initialize in-memory credentials cache %d", code
);
1005 if ( pag_for_children
) {
1009 getModConfig (cfg
, s
);
1011 if ( cfg
->default_principal
!= WAKLOG_UNSET
) {
1012 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: child_init setting default user %s, %s", cfg
->default_principal
, cfg
->default_keytab
);
1013 set_auth( s
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1016 cell
= strdup(cfg
->afs_cell
);
1017 pr_Initialize( 0, AFSDIR_CLIENT_ETC_DIR
, cell
);
1020 apr_pool_cleanup_register(p
, s
, waklog_child_exit
, apr_pool_cleanup_null
);
1023 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
1024 "mod_waklog: child_init returned");
1029 command_rec waklog_cmds
[] = {
1031 command ("WaklogProtected", set_waklog_protect
, 0, FLAG
,
1032 "enable waklog on a location or directory basis"),
1034 command ("WaklogPrincipal", set_waklog_principal
, 0, TAKE2
,
1035 "Use the supplied keytab rather than the default"),
1037 command ("WaklogUseAFSCell", set_waklog_use_afs_cell
, 0, TAKE1
,
1038 "Use the supplied AFS cell rather than the default"),
1040 command ("WaklogUseUserTokens", set_waklog_use_usertokens
, 0, FLAG
,
1041 "Use the requesting user tokens (from webauth)"),
1043 command ("WaklogDefaultPrincipal", set_waklog_default_principal
, 0, TAKE2
,
1044 "Set the default principal that the server runs as"),
1050 /* not currently using this */
1053 token_cleanup (void *data
)
1055 request_rec
*r
= (request_rec
*) data
;
1057 if (child
.token
.ticketLen
)
1059 memset (&child
.token
, 0, sizeof (struct ktc_token
));
1061 ktc_ForgetAllTokens ();
1063 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1064 "mod_waklog: ktc_ForgetAllTokens succeeded: pid: %d",
1071 waklog_child_routine (void *data
, child_info
* pinfo
)
1074 server_rec
*s
= (server_rec
*) data
;
1075 krb5_error_code code
;
1077 time_t sleep_time
= ( TKT_LIFE
/ 2 ) ;
1082 getModConfig( cfg
, s
);
1084 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: waklog_child_routine started, running as %d", getuid());
1086 memset (&child
, 0, sizeof(child
));
1088 if ( code
= krb5_init_context(&child
.kcontext
) ) {
1089 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't init kerberos context %d", code
);
1092 if ( code
= krb5_cc_resolve(child
.kcontext
, "MEMORY:tmpcache", &child
.ccache
) ) {
1093 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't initialize in-memory credentials cache %d", code
);
1096 /* need to do this so we can make PTS calls */
1097 cell
= strdup(cfg
->afs_cell
); /* stupid */
1098 pr_Initialize( 0, AFSDIR_CLIENT_ETC_DIR
, cell
);
1102 for ( i
= 0; i
< renewcount
; ++i
) {
1103 renewtable
[i
].lastrenewed
= time(0);
1104 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: (pid %d) renewing %s / %s", getpid(), renewtable
[i
].principal
,
1105 renewtable
[i
].keytab
);
1107 set_auth( s
, NULL
, 0, renewtable
[i
].principal
, renewtable
[i
].keytab
, 1 );
1109 /* if this is our default token, we want to "stash" it in our current PAG so the parent maintains readability of
1110 things that it needs to read */
1112 if ( cfg
&& cfg
->default_principal
&& ( ! strcmp(cfg
->default_principal
, renewtable
[i
].principal
) ) ) {
1113 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: renewing/setting default tokens" );
1114 set_auth( s
, NULL
, 0, renewtable
[i
].principal
, renewtable
[i
].keytab
, 0 );
1119 sharedspace
->renewcount
++;
1128 left
-= ( time(0) - when
);
1139 waklog_init_handler (apr_pool_t
* p
, apr_pool_t
* plog
,
1140 apr_pool_t
* ptemp
, server_rec
* s
)
1143 extern char *version
;
1148 int use_existing
= 1;
1150 char cache_file
[MAXNAMELEN
];
1152 pthread_rwlockattr_t rwlock_attr
;
1156 getModConfig (cfg
, s
);
1158 /* initialize_module() will be called twice, and if it's a DSO
1159 * then all static data from the first call will be lost. Only
1160 * set up our static data on the second call.
1161 * see http://issues.apache.org/bugzilla/show_bug.cgi?id=37519 */
1162 apr_pool_userdata_get (&data
, userdata_key
, s
->process
->pool
);
1165 if (cfg
->afs_cell
==NULL
) {
1166 log_error (APLOG_MARK
, APLOG_ERR
, 0, s
,
1167 "mod_waklog: afs_cell==NULL; please provide the WaklogUseAFSCell directive");
1168 /** clobber apache */
1174 apr_pool_userdata_set ((const void *) 1, userdata_key
,
1175 apr_pool_cleanup_null
, s
->process
->pool
);
1179 log_error (APLOG_MARK
, APLOG_INFO
, 0, s
,
1180 "mod_waklog: version %s initialized for cell %s", version
, cfg
->afs_cell
);
1182 if ( sharedspace
) {
1183 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: shared memory already allocated." );
1186 snprintf( cache_file
, MAXNAMELEN
, "/tmp/waklog_cache.%d", getpid() );
1188 if ( ( fd
= open( cache_file
, O_RDWR
, 0600 ) ) == -1 ) {
1190 if ( errno
== ENOENT
) {
1192 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: creating shared token cache file %s", cache_file
);
1194 if ( ( fd
= open( cache_file
, O_RDWR
|O_CREAT
|O_TRUNC
, 0600 ) ) == -1 ) {
1195 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot create shared token cache file %s (%d)", cache_file
, errno
);
1199 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot open existing shared token cache file %s (%d)", cache_file
, errno
);
1203 if ( use_existing
== 0 ) {
1204 struct sharedspace_s bob
;
1205 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: sizing our cache file %d to %d", fd
, sizeof(struct sharedspace_s
) );
1206 memset( &bob
, 0, sizeof(struct sharedspace_s
));
1207 write(fd
, &bob
, sizeof(struct sharedspace_s
));
1208 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: done sizing our cache file to %d", sizeof(struct sharedspace_s
) );
1211 /* mmap the region */
1213 if ( ( sharedspace
= (struct sharedspace_s
*) mmap ( NULL
, sizeof(struct sharedspace_s
), PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, 0 ) ) != MAP_FAILED
) {
1214 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: shared mmap region ok %d", sharedspace
);
1217 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: mmap failed %d", errno
);
1223 #define locktype pthread_rwlock_t
1225 #define locktype rwlock_t
1228 if ( sharedlock
= ( locktype
* ) mmap ( NULL
, sizeof(locktype
), PROT_READ
|PROT_WRITE
, MAP_SHARED
|MAP_ANON
, -1, 0 ) ) {
1229 #ifndef use_pthreads
1230 rwlock_init(sharedlock
, USYNC_PROCESS
, NULL
);
1232 pthread_rwlockattr_init(&rwlock_attr
);
1233 pthread_rwlockattr_setpshared(&rwlock_attr
, PTHREAD_PROCESS_SHARED
);
1234 pthread_rwlock_init(sharedlock
, &rwlock_attr
);
1237 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: rwlock mmap failed %d", errno
);
1242 /* set our default tokens */
1244 oldrenewcount
= sharedspace
->renewcount
;
1246 pag_for_children
= 0;
1248 proc
= (apr_proc_t
*) ap_pcalloc (s
->process
->pool
, sizeof (apr_proc_t
));
1250 rv
= apr_proc_fork (proc
, s
->process
->pool
);
1252 if (rv
== APR_INCHILD
)
1254 waklog_child_routine (s
, NULL
);
1258 apr_pool_note_subprocess (s
->process
->pool
, proc
, APR_KILL_ALWAYS
);
1260 /* parent and child */
1261 cfg
->forked
= proc
->pid
;
1262 pag_for_children
= 1;
1264 if ( use_existing
== 0 ) {
1265 /* wait here until our child process has gone and done it's renewing thing. */
1266 while( sharedspace
->renewcount
== oldrenewcount
) {
1267 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: waiting for tokens..." );
1272 if ( cfg
->default_principal
) {
1273 set_auth( s
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1280 waklog_init (server_rec
* s
, MK_POOL
* p
)
1282 extern char *version
;
1287 int use_existing
= 1;
1289 char cache_file
[MAXNAMELEN
];
1291 pthread_rwlockattr_t rwlock_attr
;
1294 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
1295 "mod_waklog: version %s initialized.", version
);
1297 if ( sharedspace
) {
1298 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: shared memory already allocated." );
1301 snprintf( cache_file
, MAXNAMELEN
, "/tmp/waklog_cache.%d", getpid() );
1303 if ( ( fd
= open( cache_file
, O_RDWR
, 0600 ) ) == -1 ) {
1305 if ( errno
== ENOENT
) {
1307 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: creating shared token cache file %s", cache_file
);
1309 if ( ( fd
= open( cache_file
, O_RDWR
|O_CREAT
|O_TRUNC
, 0600 ) ) == -1 ) {
1310 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot create shared token cache file %s (%d)", cache_file
, errno
);
1314 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot open existing shared token cache file %s (%d)", cache_file
, errno
);
1319 if ( use_existing
== 0 ) {
1320 struct sharedspace_s bob
;
1321 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: sizing our cache file %d to %d", fd
, sizeof(struct sharedspace_s
) );
1322 memset( &bob
, 0, sizeof(struct sharedspace_s
));
1323 write(fd
, &bob
, sizeof(struct sharedspace_s
));
1324 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: done sizing our cache file to %d", sizeof(struct sharedspace_s
) );
1327 /* mmap the region */
1329 if ( ( sharedspace
= (struct sharedspace_s
*) mmap ( NULL
, sizeof(struct sharedspace_s
), PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, 0 ) ) != -1 ) {
1330 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: shared mmap region ok %d", sharedspace
);
1333 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: mmap failed %d", errno
);
1339 #define locktype pthread_rwlock_t
1341 #define locktype rwlock_t
1344 /* mmap our shared space for our lock */
1345 if ( sharedlock
= ( locktype
* ) mmap ( NULL
, sizeof(locktype
), PROT_READ
|PROT_WRITE
, MAP_SHARED
|MAP_ANON
, -1, 0 ) ) {
1346 #ifndef use_pthreads
1347 rwlock_init(sharedlock
, USYNC_PROCESS
, NULL
);
1349 pthread_rwlockattr_init(&rwlock_attr
);
1350 pthread_rwlockattr_setpshared(&rwlock_attr
, PTHREAD_PROCESS_SHARED
);
1351 pthread_rwlock_init(sharedlock
, &rwlock_attr
);
1354 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: rwlock mmap failed %d", errno
);
1359 /* set our default tokens */
1361 getModConfig (cfg
, s
);
1363 oldrenewcount
= sharedspace
->renewcount
;
1365 pag_for_children
= 0;
1367 pid
= ap_bspawn_child (p
, waklog_child_routine
, s
, kill_always
,
1370 pag_for_children
= 1;
1372 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
1373 "mod_waklog: ap_bspawn_child: %d.", pid
);
1375 if ( use_existing
== 0 ) {
1376 /* wait here until our child process has gone and done it's renewing thing. */
1377 while( sharedspace
->renewcount
== oldrenewcount
) {
1378 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: waiting for tokens..." );
1383 if ( cfg
->default_principal
) {
1384 set_auth( s
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1391 waklog_phase0 (request_rec
* r
)
1395 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1396 "mod_waklog: phase0 called");
1398 cfg
= retrieve_config(r
);
1400 if ( cfg
->protect
&& cfg
->principal
) {
1401 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase0 using user %s", cfg
->principal
);
1402 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1403 } else if ( cfg
->default_principal
) {
1404 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase0 using default user %s", cfg
->default_principal
);
1405 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1407 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase0 not doing nothin.");
1414 waklog_phase1 (request_rec
* r
)
1418 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1419 "mod_waklog: phase1 called");
1421 cfg
= retrieve_config(r
);
1423 if ( cfg
->protect
&& cfg
->principal
) {
1424 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase1 using user %s", cfg
->principal
);
1425 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1426 } else if ( cfg
->default_principal
) {
1427 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase1 using default user %s", cfg
->default_principal
);
1428 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1430 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase1 not doing nothin.");
1437 waklog_phase3 (request_rec
* r
)
1441 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1442 "mod_waklog: phase 3 called");
1444 cfg
= retrieve_config(r
);
1446 if ( cfg
->protect
&& cfg
->principal
) {
1447 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase3 using user %s", cfg
->principal
);
1448 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1449 } else if ( cfg
->default_principal
) {
1450 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase3 using default user %s", cfg
->default_principal
);
1451 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1453 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase3 not doing nothin.");
1460 waklog_phase6 (request_rec
* r
)
1464 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1465 "mod_waklog: phase6 called");
1467 cfg
= retrieve_config(r
);
1469 if ( cfg
->protect
&& cfg
->principal
) {
1470 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase6 using user %s", cfg
->principal
);
1471 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1472 } else if ( cfg
->default_principal
) {
1473 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase6 using default user %s", cfg
->default_principal
);
1474 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1476 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase6 not doing nothin.");
1483 waklog_phase7 (request_rec
* r
)
1488 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1489 "mod_waklog: phase7 called");
1491 cfg
= retrieve_config (r
);
1493 if ( cfg
->protect
&& cfg
->usertokens
) {
1494 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase7 using usertokens");
1495 rc
= set_auth( r
->server
, r
, 1, NULL
, NULL
, 0);
1496 } else if ( cfg
->protect
&& cfg
->principal
) {
1497 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase7 using user %s", cfg
->principal
);
1498 rc
= set_auth( r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1499 } else if ( cfg
->default_principal
) {
1500 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase7 using default user %s", cfg
->default_principal
);
1501 rc
= set_auth( r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1512 waklog_phase9 (request_rec
* r
)
1516 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1517 "mod_waklog: phase9 called");
1519 getModConfig (cfg
, r
->server
);
1521 if ( cfg
->default_principal
) {
1522 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase9 using default user %s", cfg
->default_principal
);
1523 set_auth( r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1536 waklog_new_connection (conn_rec
* c
1545 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, c
->base_server
,
1546 "mod_waklog: new_connection called: pid: %d", getpid ());
1548 getModConfig(cfg
, c
->base_server
);
1550 if ( cfg
->default_principal
) {
1551 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, c
->base_server
, "mod_waklog: new conn setting default user %s",
1552 cfg
->default_principal
);
1553 set_auth( c
->base_server
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1566 ** Here's a quick explaination for phase0 and phase2:
1567 ** Apache does a stat() on the path between phase0 and
1568 ** phase2, and must by ACLed rl to succeed. So, at
1569 ** phase0 we acquire credentials for umweb:servers from
1570 ** a keytab, and at phase2 we must ensure we remove them.
1572 ** Failure to "unlog" would be a security risk.
1575 waklog_phase2 (request_rec
* r
)
1578 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1579 "mod_waklog: phase2 called");
1581 if (child
.token
.ticketLen
)
1583 memset (&child
.token
, 0, sizeof (struct ktc_token
));
1585 ktc_ForgetAllTokens ();
1587 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1588 "mod_waklog: ktc_ForgetAllTokens succeeded: pid: %d",
1592 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1593 "mod_waklog: phase2 returning");
1599 module MODULE_VAR_EXPORT waklog_module
= {
1600 STANDARD_MODULE_STUFF
,
1601 waklog_init
, /* module initializer */
1602 waklog_create_dir_config
, /* create per-dir config structures */
1603 waklog_merge_dir_config
, /* merge per-dir config structures */
1604 waklog_create_server_config
, /* create per-server config structures */
1605 waklog_merge_dir_config
, /* merge per-server config structures */
1606 waklog_cmds
, /* table of config file commands */
1607 NULL
, /* [#8] MIME-typed-dispatched handlers */
1608 waklog_phase1
, /* [#1] URI to filename translation */
1609 NULL
, /* [#4] validate user id from request */
1610 NULL
, /* [#5] check if the user is ok _here_ */
1611 waklog_phase3
, /* [#3] check access by host address */
1612 waklog_phase6
, /* [#6] determine MIME type */
1613 waklog_phase7
, /* [#7] pre-run fixups */
1614 waklog_phase9
, /* [#9] log a transaction */
1615 NULL
, /* [#2] header parser */
1616 waklog_child_init
, /* child_init */
1617 waklog_child_exit
, /* child_exit */
1618 waklog_phase0
/* [#0] post read-request */
1620 , NULL
, /* EAPI: add_module */
1621 NULL
, /* EAPI: remove_module */
1622 NULL
, /* EAPI: rewrite_command */
1623 waklog_new_connection
/* EAPI: new_connection */
1628 waklog_register_hooks (apr_pool_t
* p
)
1630 ap_hook_translate_name (waklog_phase1
, NULL
, NULL
, APR_HOOK_FIRST
);
1631 ap_hook_header_parser (waklog_phase2
, NULL
, NULL
, APR_HOOK_FIRST
);
1632 ap_hook_access_checker (waklog_phase3
, NULL
, NULL
, APR_HOOK_FIRST
);
1633 ap_hook_type_checker (waklog_phase6
, NULL
, NULL
, APR_HOOK_FIRST
);
1634 ap_hook_fixups (waklog_phase7
, NULL
, NULL
, APR_HOOK_FIRST
);
1635 ap_hook_log_transaction (waklog_phase9
, NULL
, NULL
, APR_HOOK_FIRST
);
1636 ap_hook_child_init (waklog_child_init
, NULL
, NULL
, APR_HOOK_FIRST
);
1637 ap_hook_post_read_request (waklog_phase0
, NULL
, NULL
, APR_HOOK_FIRST
);
1638 ap_hook_pre_connection (waklog_new_connection
, NULL
, NULL
, APR_HOOK_FIRST
);
1639 ap_hook_post_config (waklog_init_handler
, NULL
, NULL
, APR_HOOK_MIDDLE
);
1643 module AP_MODULE_DECLARE_DATA waklog_module
= {
1644 STANDARD20_MODULE_STUFF
,
1645 waklog_create_dir_config
, /* create per-dir conf structures */
1646 waklog_merge_dir_config
, /* merge per-dir conf structures */
1647 waklog_create_server_config
, /* create per-server conf structures */
1648 waklog_merge_dir_config
, /* merge per-server conf structures */
1649 waklog_cmds
, /* table of configuration directives */
1650 waklog_register_hooks
/* register hooks */