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 #ifndef 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 #ifndef CELL_IN_PRINCIPAL
100 int cell_in_principal
= 1;
102 int cell_in_principal
= 0;
105 /* this is used to turn off pag generation for the backround worker child during startup */
106 int pag_for_children
= 1;
116 char *default_principal
;
117 char *default_keytab
;
126 struct ktc_token token
;
127 char clientprincipal
[MAXNAMELEN
];
128 krb5_context kcontext
;
130 struct ktc_principal server
;
131 struct ktc_principal client
;
133 } waklog_child_config
;
135 waklog_child_config child
;
137 struct tokencache_ent
{
138 char clientprincipal
[MAXNAMELEN
];
139 struct ktc_token token
;
140 struct ktc_principal client
;
141 struct ktc_principal server
;
146 #define SHARED_TABLE_SIZE 512
148 struct sharedspace_s
{
150 struct tokencache_ent sharedtokens
[SHARED_TABLE_SIZE
];
153 struct sharedspace_s
*sharedspace
= NULL
;
162 pthread_rwlock_t
*sharedlock
= NULL
;
164 rwlock_t
*sharedlock
= NULL
;
167 struct renew_ent renewtable
[SHARED_TABLE_SIZE
];
171 module waklog_module
;
174 #define getModConfig(P, X) P = (waklog_config *) ap_get_module_config( (X)->module_config, &waklog_module );
179 #include <sys/ioccom.h>
182 #include <afs/venus.h>
183 #include <afs/auth.h>
184 #include <afs/dirpath.h>
185 #include <afs/ptuser.h>
186 #include <rx/rxkad.h>
188 #define AFS_CELL "someplace.edu"
190 /* If there's an error, retry more aggressively */
191 #define ERR_SLEEP_TIME 5*60
194 #define K5PATH "FILE:/tmp/waklog.creds.k5"
197 log_error (const char *file
, int line
, int level
, int status
,
198 const server_rec
* s
, const char *fmt
, ...)
204 vsnprintf (errstr
, 1024, fmt
, ap
);
208 ap_log_error (file
, line
, level
| APLOG_NOERRNO
, status
, s
, "(%d) %s", getpid(), errstr
);
210 ap_log_error (file
, line
, level
| APLOG_NOERRNO
, s
, "(%d) %s", getpid(), errstr
);
215 waklog_config
*retrieve_config(request_rec
*r
) {
220 if ( r
&& r
->main
) {
228 if ( my
&& ( cfg
= (waklog_config
*) ap_get_module_config(my
->per_dir_config
, &waklog_module
) ) ) {
231 getModConfig (cfg
, r
->server
);
238 /* set_auth -- sets the tokens of the current process to this user.
239 if "self" is set, it divines the user from the current requests' environment.
240 otherwise, it's gettng it from principal/keytab */
243 set_auth ( server_rec
*s
, request_rec
*r
, int self
, char *principal
, char *keytab
, int storeonly
) {
247 krb5_error_code kerror
= 0;
248 krb5_principal kprinc
= NULL
;
249 krb5_get_init_creds_opt kopts
;
252 struct ktc_principal server
= { "afs", "", "" };
253 struct ktc_principal client
;
254 struct ktc_token token
;
255 krb5_creds
*v5credsp
= NULL
;
256 krb5_keytab krb5kt
= NULL
;
257 char buf
[MAXNAMELEN
];
261 time_t oldest_time
= 0;
267 char k5user
[MAXNAMELEN
];
270 memset((char *) &increds
, 0, sizeof(increds
));
272 /* init some stuff if it ain't already */
274 if ( ! child
.kcontext
) {
275 kerror
= krb5_init_context(&child
.kcontext
);
278 if ( ( ! child
.ccache
) && ( kerror
= krb5_cc_resolve(child
.kcontext
, "MEMORY:tmpcache", &child
.ccache
) ) ) {
279 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't initialize in-memory credentials cache %d", kerror
);
283 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: set_auth: %d, %s, %s, %d", self
, principal
? principal
: "NULL",
284 keytab
? keytab
: "NULL", storeonly
);
286 /* pull the server config record that we care about... */
289 cfg
= retrieve_config(r
);
291 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
292 "mod_waklog: set_auth using no config" );
293 getModConfig (cfg
, s
);
297 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: cfg is %d", cfg
);
302 /* pull out our principal name and stuff from the environment -- webauth better have sent
303 through. This here is also where you'd suck stuff out of KRB5CCNAME if we were
304 using something like Cosign */
306 if ( ! ( r
&& r
->connection
&& r
->user
)) {
307 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: self authentication selected, but no data available");
311 strncpy(k5user
, r
->user
, sizeof(k5user
));
313 /* the other thing we need is someone's password */
314 if ( ! ( k5secret
= (char *) MK_TABLE_GET( r
->notes
, "ATTR_PASSWORD" ) ) ) {
315 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cant do self auth without a secret");
319 /* we'll pick this up later after we've checked the cache and current state */
324 strncpy( k5user
, principal
, sizeof(k5user
));
329 /* see if we should just go ahead and ignore this call, since we already should be set to these
335 pthread_rwlock_rdlock( sharedlock
);
337 rw_rdlock( sharedlock
);
340 for ( i
= 0; i
< SHARED_TABLE_SIZE
; ++i
) {
342 /* if it's a token for the principal we're looking for, and it hasn't expired yet */
344 if ( ( !strcmp( k5user
,
345 sharedspace
->sharedtokens
[i
].clientprincipal
) ) &&
346 ( sharedspace
->sharedtokens
[i
].token
.endTime
> mytime
) ) {
348 if ( ! memcmp(&child
.token
, &sharedspace
->sharedtokens
[i
].token
, sizeof(child
.token
) ) ) {
354 /* copy the token out of the cache and into the child object */
356 strcpy(child
.clientprincipal
, sharedspace
->sharedtokens
[i
].clientprincipal
);
357 memcpy(&child
.token
, &sharedspace
->sharedtokens
[i
].token
, sizeof(child
.token
));
358 memcpy(&child
.server
, &sharedspace
->sharedtokens
[i
].server
, sizeof(child
.server
));
359 memcpy(&child
.client
, &sharedspace
->sharedtokens
[i
].client
, sizeof(child
.client
));
361 /* set our last used time thing */
362 sharedspace
->sharedtokens
[i
].lastused
= mytime
;
372 /* release the lock on the token cache */
374 pthread_rwlock_unlock( sharedlock
);
376 rw_unlock( sharedlock
);
380 /* release the lock on the token cache */
381 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
,
382 "mod_waklog: set_auth using shared token %d for %s", i
, k5user
);
386 /* if this is something that was in the cache, and it's the same as the token we already have stored,
387 and we weren't calling this just to renew it... */
389 if ( usecached
&& indentical
) {
390 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: token is identical for %s", k5user
);
396 /* if 'usecached' isn't set, we've got to get our tokens from somewhere... */
398 if (( ! usecached
) && ( k5user
)) {
400 /* clear out the creds structure */
401 memset((void *) &v5creds
, 0, sizeof(v5creds
));
403 /* create a principal out of our k5user string */
405 if ( kerror
= krb5_parse_name (child
.kcontext
, k5user
, &kprinc
) ) {
406 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_parse_name %s", (char *) error_message(kerror
) );
410 /* create the credentials options */
412 krb5_get_init_creds_opt_init ( &kopts
);
413 krb5_get_init_creds_opt_set_tkt_life ( &kopts
, TKT_LIFE
);
414 krb5_get_init_creds_opt_set_renew_life ( &kopts
, 0 );
415 krb5_get_init_creds_opt_set_forwardable ( &kopts
, 0 );
416 krb5_get_init_creds_opt_set_proxiable ( &kopts
, 0 );
420 /* if we've been passed a keytab, we're going to be getting our credentials from it */
422 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: using keytab %s", keytab
);
424 if ( kerror
= krb5_kt_resolve(child
.kcontext
, keytab
, &krb5kt
) ) {
425 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
,
426 "mod_waklog: krb5_kt_resolve %s", error_message(kerror
) );
430 if ((kerror
= krb5_get_init_creds_keytab (child
.kcontext
, &v5creds
,
431 kprinc
, krb5kt
, 0, NULL
, &kopts
) ) ) {
432 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_get_init_creds_keytab %s",
433 error_message(kerror
) );
439 /* if 'self' is set, we're going to use the credentials provided in the credential information */
440 /* if you're using CoSign, you'd actually just set the ccache to the KRB5CCNAME credentials */
441 /* and skip ahead... Our WebSSO is lame, but has a way for us to snarf the password out of */
442 /* the encrypted token for proxy-authentication stuff. We only hand out keys that allow this */
443 /* functionality to VERY special people. */
445 if ((kerror
= krb5_get_init_creds_password ( child
.kcontext
, &v5creds
,
446 kprinc
, k5secret
, NULL
, NULL
, 0, NULL
, &kopts
) ) ) {
447 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_get_init_creds_password %s",
448 error_message(kerror
) );
449 /* nuke the password so it doesn't end up in core files */
450 memset(k5secret
, 0, sizeof(k5secret
));
454 memset(k5secret
, 0, sizeof(k5secret
));
458 /* degenerate case -- we don't have enough information to do anything */
460 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: no keytab, no self?");
466 /* initialize the credentials cache and store the stuff we just got */
468 if ( kerror
= krb5_cc_initialize (child
.kcontext
, child
.ccache
, kprinc
)) {
469 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: init credentials cache %s",
470 error_message(kerror
));
474 if ( kerror
= krb5_cc_store_cred(child
.kcontext
, child
.ccache
, &v5creds
) ) {
475 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot store credentials %s",
476 error_message(kerror
));
480 krb5_free_cred_contents(child
.kcontext
, &v5creds
);
483 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: store cred %s", error_message(kerror
));
487 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: kinit ok for %s", k5user
);
489 /* now, to the 'aklog' portion of our program. */
491 strncpy( buf
, "afs", sizeof(buf
) - 1 );
493 if ( cfg
->afs_cell
&& strcmp( cfg
->afs_cell
, AFS_CELL
) ) {
494 strncat(buf
, "/", sizeof(buf
) - strlen(buf
) - 1);
495 strncat(buf
, cfg
->afs_cell
, sizeof(buf
) - strlen(buf
) - 1);
496 } else if ( cell_in_principal
) {
497 strncat(buf
, "/", sizeof(buf
) - strlen(buf
) - 1);
498 strncat(buf
, AFS_CELL
, sizeof(buf
) - strlen(buf
) - 1);
501 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: using AFS principal: %s", buf
);
503 if ((kerror
= krb5_parse_name (child
.kcontext
, buf
, &increds
.server
))) {
504 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_parse name %s", error_message(kerror
));
508 if ((kerror
= krb5_cc_get_principal(child
.kcontext
, child
.ccache
, &increds
.client
))) {
509 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_cc_get_princ %s", error_message(kerror
));
513 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: retrieved data from ccache for %s", k5user
);
515 increds
.times
.endtime
= 0;
517 increds
.keyblock
.enctype
= ENCTYPE_DES_CBC_CRC
;
519 if (kerror
= krb5_get_credentials (child
.kcontext
, 0, child
.ccache
, &increds
, &v5credsp
)) {
520 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_get_credentials: %s",
521 error_message(kerror
));
525 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: get_credentials passed for %s", k5user
);
527 if ( v5credsp
->ticket
.length
>= MAXKTCTICKETLEN
) {
528 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: ticket size (%d) too big to fake",
529 v5credsp
->ticket
.length
);
533 memset(&token
, 0, sizeof(struct ktc_token
));
535 token
.startTime
= v5credsp
->times
.starttime
? v5credsp
->times
.starttime
: v5credsp
->times
.authtime
;
536 token
.endTime
= v5credsp
->times
.endtime
;
538 memmove( &token
.sessionKey
, v5credsp
->keyblock
.contents
, v5credsp
->keyblock
.length
);
539 token
.kvno
= RXKAD_TKT_TYPE_KERBEROS_V5
;
540 token
.ticketLen
= v5credsp
->ticket
.length
;
541 memmove( token
.ticket
, v5credsp
->ticket
.data
, token
.ticketLen
);
545 memmove( buf
, v5credsp
->client
->data
[0].data
, min(v5credsp
->client
->data
[0].length
,
547 buf
[v5credsp
->client
->data
[0].length
] = '\0';
548 if ( v5credsp
->client
->length
> 1 ) {
549 strncat(buf
, ".", sizeof(buf
) - strlen(buf
) - 1);
550 buflen
= strlen(buf
);
551 memmove(buf
+ buflen
, v5credsp
->client
->data
[1].data
,
552 min(v5credsp
->client
->data
[1].length
,
553 MAXKTCNAMELEN
- strlen(buf
) - 1));
554 buf
[buflen
+ v5credsp
->client
->data
[1].length
] = '\0';
557 /* assemble the client */
558 strncpy(client
.name
, buf
, sizeof(client
.name
) - 1 );
559 strncpy(client
.instance
, "", sizeof(client
.instance
) - 1 );
560 memmove(buf
, v5credsp
->client
->realm
.data
, min(v5credsp
->client
->realm
.length
,
562 buf
[v5credsp
->client
->realm
.length
] = '\0';
563 strncpy(client
.cell
, buf
, sizeof(client
.cell
));
565 /* assemble the server's cell */
566 if ( cfg
->afs_cell
) {
567 strncpy(server
.cell
, cfg
->afs_cell
, sizeof(server
.cell
) - 1);
569 strncpy(server
.cell
, AFS_CELL
, sizeof(server
.cell
) - 1);
572 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: preparing to init PTS connection for %s", server
.cell
);
574 /* fill out the AFS ID in the client name */
575 /* we've done a pr_Initialize in the child_init -- once, per process. If you try to do it more
576 * strange things seem to happen. */
579 afs_int32 viceId
= 0;
581 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: making PTS call to look up %s", client
.name
);
583 if ( ( rc
= pr_SNameToId( client
.name
, &viceId
) ) == 0 ) {
584 snprintf( client
.name
, sizeof(client
.name
), "AFS ID %d", viceId
);
586 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: PTS call returned error %d ", rc
);
589 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: PTS call returned %s ", client
.name
);
593 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: server: name %s, instance %s, cell %s",
594 server
.name
, server
.instance
, server
.cell
);
596 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: client: name %s, instance %s, cell %s",
597 client
.name
, client
.instance
, client
.cell
);
599 /* copy the resulting stuff into the child structure */
601 strncpy(child
.clientprincipal
, k5user
, sizeof(child
.clientprincipal
));
602 memcpy(&child
.token
, &token
, sizeof(child
.token
));
603 memcpy(&child
.server
, &server
, sizeof(child
.server
));
604 memcpy(&child
.client
, &client
, sizeof(child
.client
));
606 /* stuff the resulting token-related stuff into our shared token cache */
607 /* note, that anything that was set from a keytab is "persistant", and is immune
608 * from LRU-aging. This is because nothing but the process that's running as root
609 * can update these, and it's running every hour or so and renewing these tokens.
610 * and we don't want them aged out.
613 mytime
= oldest_time
= time(0);
615 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: waiting for shared space for %s ", k5user
);
618 pthread_rwlock_wrlock(sharedlock
);
620 rw_wrlock(sharedlock
);
623 for( i
= ( SHARED_TABLE_SIZE
- 1 ); i
>= 0; i
-- ) {
624 if ( ( sharedspace
->sharedtokens
[i
].lastused
<= oldest_time
) &&
625 ( sharedspace
->sharedtokens
[i
].persist
== 0 ) ) {
627 oldest_time
= sharedspace
->sharedtokens
[i
].lastused
;
629 if ( ! strcmp ( sharedspace
->sharedtokens
[i
].clientprincipal
,
630 child
.clientprincipal
) ) {
631 memcpy(&sharedspace
->sharedtokens
[i
].token
, &child
.token
, sizeof(child
.token
) );
632 memcpy(&sharedspace
->sharedtokens
[i
].client
, &child
.client
, sizeof(child
.client
) );
633 memcpy(&sharedspace
->sharedtokens
[i
].server
, &child
.server
, sizeof(child
.server
) );
634 sharedspace
->sharedtokens
[i
].lastused
= mytime
;
635 sharedspace
->sharedtokens
[i
].persist
= keytab
? 1 : 0;
641 if ( stored
== -1 ) {
642 memcpy(&sharedspace
->sharedtokens
[oldest
].token
, &child
.token
, sizeof(child
.token
) );
643 memcpy(&sharedspace
->sharedtokens
[oldest
].client
, &child
.client
, sizeof(child
.client
) );
644 memcpy(&sharedspace
->sharedtokens
[oldest
].server
, &child
.server
, sizeof(child
.server
) );
645 strcpy(sharedspace
->sharedtokens
[oldest
].clientprincipal
, child
.clientprincipal
);
646 sharedspace
->sharedtokens
[oldest
].lastused
= mytime
;
647 sharedspace
->sharedtokens
[oldest
].persist
= keytab
? 1 : 0;
652 pthread_rwlock_unlock(sharedlock
);
654 rw_unlock(sharedlock
);
657 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: token stored in slot %d for %s", stored
,
658 child
.clientprincipal
);
660 } else if ( ! usecached
) {
661 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: set_auth divergent case");
670 /* don't ask. Something about AIX. We're leaving it here.*/
671 /* write(2, "", 0); */
673 /* we try twice, because sometimes the first one fails. Dunno why, but it always works the second time */
675 if ((rc
= ktc_SetToken(&child
.server
, &child
.token
, &child
.client
, 0))) {
676 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: settoken returned %s for %s -- trying again",
677 error_message(rc
), k5user
);
678 if ((rc
= ktc_SetToken(&child
.server
, &child
.token
, &child
.client
, 0))) {
679 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: settoken2 returned %s for %s",
680 error_message(rc
), k5user
);
687 krb5_free_cred_contents(child
.kcontext
, v5credsp
);
688 if ( increds
.client
)
689 krb5_free_principal (child
.kcontext
, increds
.client
);
690 if ( increds
.server
)
691 krb5_free_principal (child
.kcontext
, increds
.server
);
693 (void) krb5_kt_close(child
.kcontext
, krb5kt
);
695 krb5_free_principal (child
.kcontext
, kprinc
);
698 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: set_auth ending with %d", rc
);
699 } else if ( kerror
) {
700 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: set_auth ending with krb5 error %d, %s", kerror
, error_message(kerror
));
702 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: set_auth ending ok");
705 return kerror
? (int) kerror
: (int) rc
;
712 waklog_create_server_config (MK_POOL
* p
, server_rec
* s
)
716 cfg
= (waklog_config
*) ap_pcalloc (p
, sizeof (waklog_config
));
718 memset(cfg
, 0, sizeof(waklog_config
));
719 cfg
->path
= "(server)";
720 cfg
->protect
= WAKLOG_UNSET
;
721 cfg
->usertokens
= WAKLOG_UNSET
;
722 cfg
->keytab
= WAKLOG_UNSET
;
723 cfg
->principal
= WAKLOG_UNSET
;
724 cfg
->default_principal
= WAKLOG_UNSET
;
725 cfg
->default_keytab
= WAKLOG_UNSET
;
726 cfg
->afs_cell
= WAKLOG_UNSET
;
730 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
731 "mod_waklog: server config created.");
736 /* initialize with host-config information */
739 waklog_create_dir_config (MK_POOL
* p
, char *dir
)
743 cfg
= (waklog_config
*) ap_pcalloc (p
, sizeof (waklog_config
));
744 memset(cfg
, 0, sizeof(waklog_config
));
746 cfg
->path
= ap_pstrdup(p
, dir
);
747 cfg
->protect
= WAKLOG_UNSET
;
748 cfg
->usertokens
= WAKLOG_UNSET
;
749 cfg
->keytab
= WAKLOG_UNSET
;
750 cfg
->principal
= WAKLOG_UNSET
;
751 cfg
->default_principal
= WAKLOG_UNSET
;
752 cfg
->default_keytab
= WAKLOG_UNSET
;
753 cfg
->afs_cell
= WAKLOG_UNSET
;
760 static void *waklog_merge_dir_config(MK_POOL
*p
, void *parent_conf
, void *newloc_conf
) {
762 waklog_config
*merged
= ( waklog_config
* ) ap_pcalloc(p
, sizeof(waklog_config
) );
763 waklog_config
*parent
= ( waklog_config
* ) parent_conf
;
764 waklog_config
*child
= ( waklog_config
* ) newloc_conf
;
766 merged
->protect
= child
->protect
!= WAKLOG_UNSET
? child
->protect
: parent
->protect
;
768 merged
->path
= child
->path
!= WAKLOG_UNSET
? child
->path
: parent
->path
;
770 merged
->usertokens
= child
->usertokens
!= WAKLOG_UNSET
? child
->usertokens
: parent
->usertokens
;
772 merged
->principal
= child
->principal
!= WAKLOG_UNSET
? child
->principal
: parent
->principal
;
774 merged
->keytab
= child
->keytab
!= WAKLOG_UNSET
? child
->keytab
: parent
->keytab
;
776 merged
->default_keytab
= child
->default_keytab
!= WAKLOG_UNSET
? child
->default_keytab
: parent
->default_keytab
;
778 merged
->default_principal
= child
->default_principal
!= WAKLOG_UNSET
? child
->default_principal
: parent
->default_principal
;
780 merged
->afs_cell
= child
->afs_cell
!= WAKLOG_UNSET
? child
->afs_cell
: parent
->afs_cell
;
782 return (void *) merged
;
786 static void *waklog_merge_server_config(MK_POOL
*p
, void *parent_conf
, void *newloc_conf
) {
788 waklog_config
*merged
= ( waklog_config
* ) ap_pcalloc(p
, sizeof(waklog_config
) );
789 waklog_config
*pconf
= ( waklog_config
* ) parent_conf
;
790 waklog_config
*nconf
= ( waklog_config
* ) newloc_conf
;
792 merged
->protect
= nconf
->protect
== WAKLOG_UNSET
? pconf
->protect
: nconf
->protect
;
794 merged
->usertokens
= nconf
->usertokens
== WAKLOG_UNSET
? pconf
->usertokens
: nconf
->usertokens
;
796 merged
->keytab
= nconf
->keytab
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->keytab
) :
797 ( nconf
->keytab
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->keytab
) );
799 merged
->principal
= nconf
->principal
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->principal
) :
800 ( nconf
->principal
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->principal
) );
802 merged
->afs_cell
= nconf
->afs_cell
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->afs_cell
) :
803 ( nconf
->afs_cell
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->afs_cell
) );
805 merged
->default_keytab
= nconf
->default_keytab
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->default_keytab
) :
806 ( nconf
->default_keytab
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->default_keytab
) );
808 merged
->default_principal
= nconf
->default_principal
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->default_principal
) :
809 ( nconf
->default_principal
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->default_principal
) );
812 return (void *) merged
;
817 set_waklog_protect (cmd_parms
* params
, void *mconfig
, int flag
)
819 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
820 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
824 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
825 "mod_waklog: waklog_protect set on %s", cfg
->path
? cfg
->path
: "NULL");
830 /* this adds a principal/keytab pair to get their tokens renewed by the
831 child process every few centons. */
833 void add_to_renewtable(MK_POOL
*p
, char *keytab
, char *principal
) {
837 if ( renewcount
>= SHARED_TABLE_SIZE
) {
838 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, NULL
, "mod_waklog: big problem. Increase the SHARED_TABLE_SIZE or \
839 decrease your tokens.");
843 /* check to see if it's already there */
845 for ( i
= 0; i
< renewcount
; i
++ ) {
846 if ( ! strcmp(renewtable
[i
].principal
, principal
) ) {
851 renewtable
[renewcount
].keytab
= ap_pstrdup(p
, keytab
);
852 renewtable
[renewcount
].principal
= ap_pstrdup(p
, principal
);
853 renewtable
[renewcount
].lastrenewed
= 0;
859 set_waklog_principal (cmd_parms
*params
, void *mconfig
, char *principal
, char *keytab
)
861 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
862 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
864 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
865 "mod_waklog: configuring principal: %s, keytab: %s", principal
, keytab
);
867 cfg
->principal
= ap_pstrdup(params
->pool
, principal
);
868 cfg
->keytab
= ap_pstrdup (params
->pool
, keytab
);
870 add_to_renewtable(params
->pool
, keytab
, principal
);
878 set_waklog_use_afs_cell (cmd_parms
* params
, void *mconfig
, char *file
)
880 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
881 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
883 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
884 "mod_waklog: will use afs_cell: %s", file
);
886 cfg
->afs_cell
= ap_pstrdup (params
->pool
, file
);
892 set_waklog_default_principal (cmd_parms
* params
, void *mconfig
, char *principal
, char *keytab
)
894 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
895 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
897 waklog_config
*srvcfg
= ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
899 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
900 "mod_waklog: set default princ/keytab: %s, %s for %s", principal
, keytab
, cfg
->path
? cfg
->path
: "NULL");
902 cfg
->default_principal
= ap_pstrdup (params
->pool
, principal
);
903 cfg
->default_keytab
= ap_pstrdup(params
->pool
, keytab
);
905 /* this also gets set at the server level */
906 if ( mconfig
&& ( ! cfg
->path
) ) {
907 srvcfg
->default_principal
= ap_pstrdup (params
->pool
, principal
);
908 srvcfg
->default_keytab
= ap_pstrdup(params
->pool
, keytab
);
910 log_error(APLOG_MARK
, APLOG_ERR
, 0, params
->server
, "only able to set default principal on a global level!");
911 return "Unable to set DefaultPrincipal outside of top level config!";
914 add_to_renewtable( params
->pool
, keytab
, principal
);
922 set_waklog_use_usertokens (cmd_parms
* params
, void *mconfig
, int flag
)
924 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
925 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
927 cfg
->usertokens
= flag
;
931 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
932 "mod_waklog: waklog_use_user_tokens set");
938 static void waklog_child_exit( server_rec
*s
, MK_POOL
*p
) {
940 apr_status_t
waklog_child_exit( void *sr
) {
942 server_rec
*s
= (server_rec
*) sr
;
945 if ( child
.ccache
) {
946 krb5_cc_close(child
.kcontext
, child
.ccache
);
949 if ( child
.kcontext
) {
950 krb5_free_context(child
.kcontext
);
953 /* forget our tokens */
955 ktc_ForgetAllTokens ();
957 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
958 "mod_waklog: waklog_child_exit complete");
968 waklog_child_init (MK_POOL
* p
, server_rec
* s
)
970 waklog_child_init (server_rec
* s
, MK_POOL
* p
)
974 krb5_error_code code
;
979 cell
= strdup(AFS_CELL
);
981 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: child_init called for pid %d", getpid());
983 if ( !sharedspace
) {
984 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: child_init called without shared space? %d", getpid());
988 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: child_init called for pid %d", getpid());
990 memset (&child
, 0, sizeof(child
));
992 if ( code
= krb5_init_context(&child
.kcontext
) ) {
993 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't init kerberos context %d", code
);
996 if ( code
= krb5_cc_resolve(child
.kcontext
, "MEMORY:tmpcache", &child
.ccache
) ) {
997 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't initialize in-memory credentials cache %d", code
);
1000 if ( pag_for_children
) {
1004 getModConfig (cfg
, s
);
1006 if ( cfg
->default_principal
!= WAKLOG_UNSET
) {
1007 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: child_init setting default user %s, %s", cfg
->default_principal
, cfg
->default_keytab
);
1008 set_auth( s
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1011 pr_Initialize( 0, AFSDIR_CLIENT_ETC_DIR
, cell
);
1014 apr_pool_cleanup_register(p
, s
, waklog_child_exit
, apr_pool_cleanup_null
);
1017 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
1018 "mod_waklog: child_init returned");
1023 command_rec waklog_cmds
[] = {
1025 command ("WaklogProtected", set_waklog_protect
, 0, FLAG
,
1026 "enable waklog on a location or directory basis"),
1028 command ("WaklogPrincipal", set_waklog_principal
, 0, TAKE2
,
1029 "Use the supplied keytab rather than the default"),
1031 command ("WaklogUseAFSCell", set_waklog_use_afs_cell
, 0, TAKE1
,
1032 "Use the supplied AFS cell rather than the default"),
1034 command ("WaklogUseUserTokens", set_waklog_use_usertokens
, 0, FLAG
,
1035 "Use the requesting user tokens (from webauth)"),
1037 command ("WaklogDefaultPrincipal", set_waklog_default_principal
, 0, TAKE2
,
1038 "Set the default principal that the server runs as"),
1044 /* not currently using this */
1047 token_cleanup (void *data
)
1049 request_rec
*r
= (request_rec
*) data
;
1051 if (child
.token
.ticketLen
)
1053 memset (&child
.token
, 0, sizeof (struct ktc_token
));
1055 ktc_ForgetAllTokens ();
1057 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1058 "mod_waklog: ktc_ForgetAllTokens succeeded: pid: %d",
1065 waklog_child_routine (void *data
, child_info
* pinfo
)
1068 server_rec
*s
= (server_rec
*) data
;
1069 krb5_error_code code
;
1071 time_t sleep_time
= ( TKT_LIFE
/ 2 ) ;
1076 getModConfig( cfg
, s
);
1078 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: waklog_child_routine started, running as %d", getuid());
1080 memset (&child
, 0, sizeof(child
));
1082 if ( code
= krb5_init_context(&child
.kcontext
) ) {
1083 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't init kerberos context %d", code
);
1086 if ( code
= krb5_cc_resolve(child
.kcontext
, "MEMORY:tmpcache", &child
.ccache
) ) {
1087 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't initialize in-memory credentials cache %d", code
);
1090 /* need to do this so we can make PTS calls */
1091 cell
= strdup(AFS_CELL
); /* stupid */
1092 pr_Initialize( 0, AFSDIR_CLIENT_ETC_DIR
, cell
);
1096 for ( i
= 0; i
< renewcount
; ++i
) {
1097 renewtable
[i
].lastrenewed
= time(0);
1098 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: (pid %d) renewing %s / %s", getpid(), renewtable
[i
].principal
,
1099 renewtable
[i
].keytab
);
1101 set_auth( s
, NULL
, 0, renewtable
[i
].principal
, renewtable
[i
].keytab
, 1 );
1103 /* if this is our default token, we want to "stash" it in our current PAG so the parent maintains readability of
1104 things that it needs to read */
1106 if ( cfg
&& cfg
->default_principal
&& ( ! strcmp(cfg
->default_principal
, renewtable
[i
].principal
) ) ) {
1107 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: renewing/setting default tokens" );
1108 set_auth( s
, NULL
, 0, renewtable
[i
].principal
, renewtable
[i
].keytab
, 0 );
1113 sharedspace
->renewcount
++;
1122 left
-= ( time(0) - when
);
1133 waklog_init_handler (apr_pool_t
* p
, apr_pool_t
* plog
,
1134 apr_pool_t
* ptemp
, server_rec
* s
)
1137 extern char *version
;
1142 int use_existing
= 1;
1144 char cache_file
[MAXNAMELEN
];
1146 pthread_rwlockattr_t rwlock_attr
;
1150 getModConfig (cfg
, s
);
1152 /* initialize_module() will be called twice, and if it's a DSO
1153 * then all static data from the first call will be lost. Only
1154 * set up our static data on the second call.
1155 * see http://issues.apache.org/bugzilla/show_bug.cgi?id=37519 */
1156 apr_pool_userdata_get (&data
, userdata_key
, s
->process
->pool
);
1160 apr_pool_userdata_set ((const void *) 1, userdata_key
,
1161 apr_pool_cleanup_null
, s
->process
->pool
);
1165 log_error (APLOG_MARK
, APLOG_INFO
, 0, s
,
1166 "mod_waklog: version %s initialized.", version
);
1168 if ( sharedspace
) {
1169 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: shared memory already allocated." );
1172 snprintf( cache_file
, MAXNAMELEN
, "/tmp/waklog_cache.%d", getpid() );
1174 if ( ( fd
= open( cache_file
, O_RDWR
, 0600 ) ) == -1 ) {
1176 if ( errno
== ENOENT
) {
1178 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: creating shared token cache file %s", cache_file
);
1180 if ( ( fd
= open( cache_file
, O_RDWR
|O_CREAT
|O_TRUNC
, 0600 ) ) == -1 ) {
1181 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot create shared token cache file %s (%d)", cache_file
, errno
);
1185 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot open existing shared token cache file %s (%d)", cache_file
, errno
);
1189 if ( use_existing
== 0 ) {
1190 struct sharedspace_s bob
;
1191 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: sizing our cache file %d to %d", fd
, sizeof(struct sharedspace_s
) );
1192 memset( &bob
, 0, sizeof(struct sharedspace_s
));
1193 write(fd
, &bob
, sizeof(struct sharedspace_s
));
1194 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: done sizing our cache file to %d", sizeof(struct sharedspace_s
) );
1197 /* mmap the region */
1199 if ( ( sharedspace
= (struct sharedspace_s
*) mmap ( NULL
, sizeof(struct sharedspace_s
), PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, 0 ) ) != MAP_FAILED
) {
1200 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: shared mmap region ok %d", sharedspace
);
1203 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: mmap failed %d", errno
);
1209 #define locktype pthread_rwlock_t
1211 #define locktype rwlock_t
1214 if ( sharedlock
= ( locktype
* ) mmap ( NULL
, sizeof(locktype
), PROT_READ
|PROT_WRITE
, MAP_SHARED
|MAP_ANON
, -1, 0 ) ) {
1215 #ifndef use_pthreads
1216 rwlock_init(sharedlock
, USYNC_PROCESS
, NULL
);
1218 pthread_rwlockattr_init(&rwlock_attr
);
1219 pthread_rwlockattr_setpshared(&rwlock_attr
, PTHREAD_PROCESS_SHARED
);
1220 pthread_rwlock_init(sharedlock
, &rwlock_attr
);
1223 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: rwlock mmap failed %d", errno
);
1228 /* set our default tokens */
1230 oldrenewcount
= sharedspace
->renewcount
;
1232 pag_for_children
= 0;
1234 proc
= (apr_proc_t
*) ap_pcalloc (s
->process
->pool
, sizeof (apr_proc_t
));
1236 rv
= apr_proc_fork (proc
, s
->process
->pool
);
1238 if (rv
== APR_INCHILD
)
1240 waklog_child_routine (s
, NULL
);
1244 apr_pool_note_subprocess (s
->process
->pool
, proc
, APR_KILL_ALWAYS
);
1246 /* parent and child */
1247 cfg
->forked
= proc
->pid
;
1248 pag_for_children
= 1;
1250 if ( use_existing
== 0 ) {
1251 /* wait here until our child process has gone and done it's renewing thing. */
1252 while( sharedspace
->renewcount
== oldrenewcount
) {
1253 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: waiting for tokens..." );
1258 if ( cfg
->default_principal
) {
1259 set_auth( s
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1266 waklog_init (server_rec
* s
, MK_POOL
* p
)
1268 extern char *version
;
1273 int use_existing
= 1;
1275 char cache_file
[MAXNAMELEN
];
1277 pthread_rwlockattr_t rwlock_attr
;
1280 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
1281 "mod_waklog: version %s initialized.", version
);
1283 if ( sharedspace
) {
1284 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: shared memory already allocated." );
1287 snprintf( cache_file
, MAXNAMELEN
, "/tmp/waklog_cache.%d", getpid() );
1289 if ( ( fd
= open( cache_file
, O_RDWR
, 0600 ) ) == -1 ) {
1291 if ( errno
== ENOENT
) {
1293 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: creating shared token cache file %s", cache_file
);
1295 if ( ( fd
= open( cache_file
, O_RDWR
|O_CREAT
|O_TRUNC
, 0600 ) ) == -1 ) {
1296 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot create shared token cache file %s (%d)", cache_file
, errno
);
1300 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot open existing shared token cache file %s (%d)", cache_file
, errno
);
1305 if ( use_existing
== 0 ) {
1306 struct sharedspace_s bob
;
1307 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: sizing our cache file %d to %d", fd
, sizeof(struct sharedspace_s
) );
1308 memset( &bob
, 0, sizeof(struct sharedspace_s
));
1309 write(fd
, &bob
, sizeof(struct sharedspace_s
));
1310 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: done sizing our cache file to %d", sizeof(struct sharedspace_s
) );
1313 /* mmap the region */
1315 if ( ( sharedspace
= (struct sharedspace_s
*) mmap ( NULL
, sizeof(struct sharedspace_s
), PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, 0 ) ) != -1 ) {
1316 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: shared mmap region ok %d", sharedspace
);
1319 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: mmap failed %d", errno
);
1325 #define locktype pthread_rwlock_t
1327 #define locktype rwlock_t
1330 /* mmap our shared space for our lock */
1331 if ( sharedlock
= ( locktype
* ) mmap ( NULL
, sizeof(locktype
), PROT_READ
|PROT_WRITE
, MAP_SHARED
|MAP_ANON
, -1, 0 ) ) {
1332 #ifndef use_pthreads
1333 rwlock_init(sharedlock
, USYNC_PROCESS
, NULL
);
1335 pthread_rwlockattr_init(&rwlock_attr
);
1336 pthread_rwlockattr_setpshared(&rwlock_attr
, PTHREAD_PROCESS_SHARED
);
1337 pthread_rwlock_init(sharedlock
, &rwlock_attr
);
1340 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: rwlock mmap failed %d", errno
);
1345 /* set our default tokens */
1347 getModConfig (cfg
, s
);
1349 oldrenewcount
= sharedspace
->renewcount
;
1351 pag_for_children
= 0;
1353 pid
= ap_bspawn_child (p
, waklog_child_routine
, s
, kill_always
,
1356 pag_for_children
= 1;
1358 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
1359 "mod_waklog: ap_bspawn_child: %d.", pid
);
1361 if ( use_existing
== 0 ) {
1362 /* wait here until our child process has gone and done it's renewing thing. */
1363 while( sharedspace
->renewcount
== oldrenewcount
) {
1364 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: waiting for tokens..." );
1369 if ( cfg
->default_principal
) {
1370 set_auth( s
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1377 waklog_phase0 (request_rec
* r
)
1381 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1382 "mod_waklog: phase0 called");
1384 cfg
= retrieve_config(r
);
1386 if ( cfg
->protect
&& cfg
->principal
) {
1387 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase0 using user %s", cfg
->principal
);
1388 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1389 } else if ( cfg
->default_principal
) {
1390 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase0 using default user %s", cfg
->default_principal
);
1391 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1393 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase0 not doing nothin.");
1400 waklog_phase1 (request_rec
* r
)
1404 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1405 "mod_waklog: phase1 called");
1407 cfg
= retrieve_config(r
);
1409 if ( cfg
->protect
&& cfg
->principal
) {
1410 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase1 using user %s", cfg
->principal
);
1411 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1412 } else if ( cfg
->default_principal
) {
1413 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase1 using default user %s", cfg
->default_principal
);
1414 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1416 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase1 not doing nothin.");
1423 waklog_phase3 (request_rec
* r
)
1427 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1428 "mod_waklog: phase 3 called");
1430 cfg
= retrieve_config(r
);
1432 if ( cfg
->protect
&& cfg
->principal
) {
1433 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase3 using user %s", cfg
->principal
);
1434 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1435 } else if ( cfg
->default_principal
) {
1436 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase3 using default user %s", cfg
->default_principal
);
1437 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1439 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase3 not doing nothin.");
1446 waklog_phase6 (request_rec
* r
)
1450 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1451 "mod_waklog: phase6 called");
1453 cfg
= retrieve_config(r
);
1455 if ( cfg
->protect
&& cfg
->principal
) {
1456 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase6 using user %s", cfg
->principal
);
1457 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1458 } else if ( cfg
->default_principal
) {
1459 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase6 using default user %s", cfg
->default_principal
);
1460 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1462 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase6 not doing nothin.");
1469 waklog_phase7 (request_rec
* r
)
1474 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1475 "mod_waklog: phase7 called");
1477 cfg
= retrieve_config (r
);
1479 if ( cfg
->protect
&& cfg
->usertokens
) {
1480 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase7 using usertokens");
1481 rc
= set_auth( r
->server
, r
, 1, NULL
, NULL
, 0);
1482 } else if ( cfg
->protect
&& cfg
->principal
) {
1483 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase7 using user %s", cfg
->principal
);
1484 rc
= set_auth( r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1485 } else if ( cfg
->default_principal
) {
1486 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase7 using default user %s", cfg
->default_principal
);
1487 rc
= set_auth( r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1498 waklog_phase9 (request_rec
* r
)
1502 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1503 "mod_waklog: phase9 called");
1505 getModConfig (cfg
, r
->server
);
1507 if ( cfg
->default_principal
) {
1508 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase9 using default user %s", cfg
->default_principal
);
1509 set_auth( r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1522 waklog_new_connection (conn_rec
* c
1531 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, c
->base_server
,
1532 "mod_waklog: new_connection called: pid: %d", getpid ());
1534 getModConfig(cfg
, c
->base_server
);
1536 if ( cfg
->default_principal
) {
1537 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, c
->base_server
, "mod_waklog: new conn setting default user %s",
1538 cfg
->default_principal
);
1539 set_auth( c
->base_server
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1552 ** Here's a quick explaination for phase0 and phase2:
1553 ** Apache does a stat() on the path between phase0 and
1554 ** phase2, and must by ACLed rl to succeed. So, at
1555 ** phase0 we acquire credentials for umweb:servers from
1556 ** a keytab, and at phase2 we must ensure we remove them.
1558 ** Failure to "unlog" would be a security risk.
1561 waklog_phase2 (request_rec
* r
)
1564 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1565 "mod_waklog: phase2 called");
1567 if (child
.token
.ticketLen
)
1569 memset (&child
.token
, 0, sizeof (struct ktc_token
));
1571 ktc_ForgetAllTokens ();
1573 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1574 "mod_waklog: ktc_ForgetAllTokens succeeded: pid: %d",
1578 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1579 "mod_waklog: phase2 returning");
1585 module MODULE_VAR_EXPORT waklog_module
= {
1586 STANDARD_MODULE_STUFF
,
1587 waklog_init
, /* module initializer */
1588 waklog_create_dir_config
, /* create per-dir config structures */
1589 waklog_merge_dir_config
, /* merge per-dir config structures */
1590 waklog_create_server_config
, /* create per-server config structures */
1591 waklog_merge_dir_config
, /* merge per-server config structures */
1592 waklog_cmds
, /* table of config file commands */
1593 NULL
, /* [#8] MIME-typed-dispatched handlers */
1594 waklog_phase1
, /* [#1] URI to filename translation */
1595 NULL
, /* [#4] validate user id from request */
1596 NULL
, /* [#5] check if the user is ok _here_ */
1597 waklog_phase3
, /* [#3] check access by host address */
1598 waklog_phase6
, /* [#6] determine MIME type */
1599 waklog_phase7
, /* [#7] pre-run fixups */
1600 waklog_phase9
, /* [#9] log a transaction */
1601 NULL
, /* [#2] header parser */
1602 waklog_child_init
, /* child_init */
1603 waklog_child_exit
, /* child_exit */
1604 waklog_phase0
/* [#0] post read-request */
1606 , NULL
, /* EAPI: add_module */
1607 NULL
, /* EAPI: remove_module */
1608 NULL
, /* EAPI: rewrite_command */
1609 waklog_new_connection
/* EAPI: new_connection */
1614 waklog_register_hooks (apr_pool_t
* p
)
1616 ap_hook_translate_name (waklog_phase1
, NULL
, NULL
, APR_HOOK_FIRST
);
1617 ap_hook_header_parser (waklog_phase2
, NULL
, NULL
, APR_HOOK_FIRST
);
1618 ap_hook_access_checker (waklog_phase3
, NULL
, NULL
, APR_HOOK_FIRST
);
1619 ap_hook_type_checker (waklog_phase6
, NULL
, NULL
, APR_HOOK_FIRST
);
1620 ap_hook_fixups (waklog_phase7
, NULL
, NULL
, APR_HOOK_FIRST
);
1621 ap_hook_log_transaction (waklog_phase9
, NULL
, NULL
, APR_HOOK_FIRST
);
1622 ap_hook_child_init (waklog_child_init
, NULL
, NULL
, APR_HOOK_FIRST
);
1623 ap_hook_post_read_request (waklog_phase0
, NULL
, NULL
, APR_HOOK_FIRST
);
1624 ap_hook_pre_connection (waklog_new_connection
, NULL
, NULL
, APR_HOOK_FIRST
);
1625 ap_hook_post_config (waklog_init_handler
, NULL
, NULL
, APR_HOOK_MIDDLE
);
1629 module AP_MODULE_DECLARE_DATA waklog_module
= {
1630 STANDARD20_MODULE_STUFF
,
1631 waklog_create_dir_config
, /* create per-dir conf structures */
1632 waklog_merge_dir_config
, /* merge per-dir conf structures */
1633 waklog_create_server_config
, /* create per-server conf structures */
1634 waklog_merge_dir_config
, /* merge per-server conf structures */
1635 waklog_cmds
, /* table of configuration directives */
1636 waklog_register_hooks
/* register hooks */