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 #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 /* If there's an error, retry more aggressively */
189 #define ERR_SLEEP_TIME 5*60
192 #define K5PATH "FILE:/tmp/waklog.creds.k5"
195 log_error (const char *file
, int line
, int level
, int status
,
196 const server_rec
* s
, const char *fmt
, ...)
202 vsnprintf (errstr
, 1024, fmt
, ap
);
206 ap_log_error (file
, line
, level
| APLOG_NOERRNO
, status
, s
, "(%d) %s", getpid(), errstr
);
208 ap_log_error (file
, line
, level
| APLOG_NOERRNO
, s
, "(%d) %s", getpid(), errstr
);
213 waklog_config
*retrieve_config(request_rec
*r
) {
218 if ( r
&& r
->main
) {
226 if ( my
&& ( cfg
= (waklog_config
*) ap_get_module_config(my
->per_dir_config
, &waklog_module
) ) ) {
229 getModConfig (cfg
, r
->server
);
236 /* set_auth -- sets the tokens of the current process to this user.
237 if "self" is set, it divines the user from the current requests' environment.
238 otherwise, it's gettng it from principal/keytab */
241 set_auth ( server_rec
*s
, request_rec
*r
, int self
, char *principal
, char *keytab
, int storeonly
) {
245 krb5_error_code kerror
= 0;
246 krb5_principal kprinc
= NULL
;
247 krb5_get_init_creds_opt kopts
;
250 struct ktc_principal server
= { "afs", "", "" };
251 struct ktc_principal client
;
252 struct ktc_token token
;
253 krb5_creds
*v5credsp
= NULL
;
254 krb5_keytab krb5kt
= NULL
;
255 char buf
[MAXNAMELEN
];
259 time_t oldest_time
= 0;
265 char k5user
[MAXNAMELEN
];
268 memset((char *) &increds
, 0, sizeof(increds
));
270 /* init some stuff if it ain't already */
272 if ( ! child
.kcontext
) {
273 kerror
= krb5_init_context(&child
.kcontext
);
276 if ( ( ! child
.ccache
) && ( kerror
= krb5_cc_resolve(child
.kcontext
, "MEMORY:tmpcache", &child
.ccache
) ) ) {
277 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't initialize in-memory credentials cache %d", kerror
);
281 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: set_auth: %d, %s, %s, %d", self
, principal
? principal
: "NULL",
282 keytab
? keytab
: "NULL", storeonly
);
284 /* pull the server config record that we care about... */
287 cfg
= retrieve_config(r
);
289 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
290 "mod_waklog: set_auth using no config" );
291 getModConfig (cfg
, s
);
295 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: cfg is %d", cfg
);
300 /* pull out our principal name and stuff from the environment -- webauth better have sent
301 through. This here is also where you'd suck stuff out of KRB5CCNAME if we were
302 using something like Cosign */
304 if ( ! ( r
&& r
->connection
&& r
->user
)) {
305 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: self authentication selected, but no data available");
309 strncpy(k5user
, r
->user
, sizeof(k5user
));
311 /* the other thing we need is someone's password */
312 if ( ! ( k5secret
= (char *) MK_TABLE_GET( r
->notes
, "ATTR_PASSWORD" ) ) ) {
313 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cant do self auth without a secret");
317 /* we'll pick this up later after we've checked the cache and current state */
322 strncpy( k5user
, principal
, sizeof(k5user
));
327 /* see if we should just go ahead and ignore this call, since we already should be set to these
333 pthread_rwlock_rdlock( sharedlock
);
335 rw_rdlock( sharedlock
);
338 for ( i
= 0; i
< SHARED_TABLE_SIZE
; ++i
) {
340 /* if it's a token for the principal we're looking for, and it hasn't expired yet */
342 if ( ( !strcmp( k5user
,
343 sharedspace
->sharedtokens
[i
].clientprincipal
) ) &&
344 ( sharedspace
->sharedtokens
[i
].token
.endTime
> mytime
) ) {
346 if ( ! memcmp(&child
.token
, &sharedspace
->sharedtokens
[i
].token
, sizeof(child
.token
) ) ) {
352 /* copy the token out of the cache and into the child object */
354 strcpy(child
.clientprincipal
, sharedspace
->sharedtokens
[i
].clientprincipal
);
355 memcpy(&child
.token
, &sharedspace
->sharedtokens
[i
].token
, sizeof(child
.token
));
356 memcpy(&child
.server
, &sharedspace
->sharedtokens
[i
].server
, sizeof(child
.server
));
357 memcpy(&child
.client
, &sharedspace
->sharedtokens
[i
].client
, sizeof(child
.client
));
359 /* set our last used time thing */
360 sharedspace
->sharedtokens
[i
].lastused
= mytime
;
370 /* release the lock on the token cache */
372 pthread_rwlock_unlock( sharedlock
);
374 rw_unlock( sharedlock
);
378 /* release the lock on the token cache */
379 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
,
380 "mod_waklog: set_auth using shared token %d for %s", i
, k5user
);
384 /* if this is something that was in the cache, and it's the same as the token we already have stored,
385 and we weren't calling this just to renew it... */
387 if ( usecached
&& indentical
) {
388 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: token is identical for %s", k5user
);
394 /* if 'usecached' isn't set, we've got to get our tokens from somewhere... */
396 if (( ! usecached
) && ( k5user
)) {
398 /* clear out the creds structure */
399 memset((void *) &v5creds
, 0, sizeof(v5creds
));
401 /* create a principal out of our k5user string */
403 if ( kerror
= krb5_parse_name (child
.kcontext
, k5user
, &kprinc
) ) {
404 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_parse_name %s", (char *) error_message(kerror
) );
408 /* create the credentials options */
410 krb5_get_init_creds_opt_init ( &kopts
);
411 krb5_get_init_creds_opt_set_tkt_life ( &kopts
, TKT_LIFE
);
412 krb5_get_init_creds_opt_set_renew_life ( &kopts
, 0 );
413 krb5_get_init_creds_opt_set_forwardable ( &kopts
, 0 );
414 krb5_get_init_creds_opt_set_proxiable ( &kopts
, 0 );
418 /* if we've been passed a keytab, we're going to be getting our credentials from it */
420 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: using keytab %s", keytab
);
422 if ( kerror
= krb5_kt_resolve(child
.kcontext
, keytab
, &krb5kt
) ) {
423 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
,
424 "mod_waklog: krb5_kt_resolve %s", error_message(kerror
) );
428 if ((kerror
= krb5_get_init_creds_keytab (child
.kcontext
, &v5creds
,
429 kprinc
, krb5kt
, 0, NULL
, &kopts
) ) ) {
430 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_get_init_creds_keytab %s",
431 error_message(kerror
) );
437 /* if 'self' is set, we're going to use the credentials provided in the credential information */
438 /* if you're using CoSign, you'd actually just set the ccache to the KRB5CCNAME credentials */
439 /* and skip ahead... Our WebSSO is lame, but has a way for us to snarf the password out of */
440 /* the encrypted token for proxy-authentication stuff. We only hand out keys that allow this */
441 /* functionality to VERY special people. */
443 if ((kerror
= krb5_get_init_creds_password ( child
.kcontext
, &v5creds
,
444 kprinc
, k5secret
, NULL
, NULL
, 0, NULL
, &kopts
) ) ) {
445 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_get_init_creds_password %s",
446 error_message(kerror
) );
447 /* nuke the password so it doesn't end up in core files */
448 memset(k5secret
, 0, sizeof(k5secret
));
452 memset(k5secret
, 0, sizeof(k5secret
));
456 /* degenerate case -- we don't have enough information to do anything */
458 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: no keytab, no self?");
464 /* initialize the credentials cache and store the stuff we just got */
466 if ( kerror
= krb5_cc_initialize (child
.kcontext
, child
.ccache
, kprinc
)) {
467 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: init credentials cache %s",
468 error_message(kerror
));
472 if ( kerror
= krb5_cc_store_cred(child
.kcontext
, child
.ccache
, &v5creds
) ) {
473 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot store credentials %s",
474 error_message(kerror
));
478 krb5_free_cred_contents(child
.kcontext
, &v5creds
);
481 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: store cred %s", error_message(kerror
));
485 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: kinit ok for %s", k5user
);
487 /* now, to the 'aklog' portion of our program. */
489 strncpy( buf
, "afs", sizeof(buf
) - 1 );
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 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_get_credentials: %s",
516 error_message(kerror
));
520 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: get_credentials passed for %s", k5user
);
522 if ( v5credsp
->ticket
.length
>= MAXKTCTICKETLEN
) {
523 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: ticket size (%d) too big to fake",
524 v5credsp
->ticket
.length
);
528 memset(&token
, 0, sizeof(struct ktc_token
));
530 token
.startTime
= v5credsp
->times
.starttime
? v5credsp
->times
.starttime
: v5credsp
->times
.authtime
;
531 token
.endTime
= v5credsp
->times
.endtime
;
533 memmove( &token
.sessionKey
, v5credsp
->keyblock
.contents
, v5credsp
->keyblock
.length
);
534 token
.kvno
= RXKAD_TKT_TYPE_KERBEROS_V5
;
535 token
.ticketLen
= v5credsp
->ticket
.length
;
536 memmove( token
.ticket
, v5credsp
->ticket
.data
, token
.ticketLen
);
540 memmove( buf
, v5credsp
->client
->data
[0].data
, min(v5credsp
->client
->data
[0].length
,
542 buf
[v5credsp
->client
->data
[0].length
] = '\0';
543 if ( v5credsp
->client
->length
> 1 ) {
544 strncat(buf
, ".", sizeof(buf
) - strlen(buf
) - 1);
545 buflen
= strlen(buf
);
546 memmove(buf
+ buflen
, v5credsp
->client
->data
[1].data
,
547 min(v5credsp
->client
->data
[1].length
,
548 MAXKTCNAMELEN
- strlen(buf
) - 1));
549 buf
[buflen
+ v5credsp
->client
->data
[1].length
] = '\0';
552 /* assemble the client */
553 strncpy(client
.name
, buf
, sizeof(client
.name
) - 1 );
554 strncpy(client
.instance
, "", sizeof(client
.instance
) - 1 );
555 memmove(buf
, v5credsp
->client
->realm
.data
, min(v5credsp
->client
->realm
.length
,
557 buf
[v5credsp
->client
->realm
.length
] = '\0';
558 strncpy(client
.cell
, buf
, sizeof(client
.cell
));
560 /* assemble the server's cell */
561 strncpy(server
.cell
, cfg
->afs_cell
, sizeof(server
.cell
) - 1);
563 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: preparing to init PTS connection for %s", server
.cell
);
565 /* fill out the AFS ID in the client name */
566 /* we've done a pr_Initialize in the child_init -- once, per process. If you try to do it more
567 * strange things seem to happen. */
570 afs_int32 viceId
= 0;
572 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: making PTS call to look up %s", client
.name
);
574 if ( ( rc
= pr_SNameToId( client
.name
, &viceId
) ) == 0 ) {
575 snprintf( client
.name
, sizeof(client
.name
), "AFS ID %d", viceId
);
577 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: PTS call returned error %d ", rc
);
580 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: PTS call returned %s ", client
.name
);
584 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: server: name %s, instance %s, cell %s",
585 server
.name
, server
.instance
, server
.cell
);
587 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: client: name %s, instance %s, cell %s",
588 client
.name
, client
.instance
, client
.cell
);
590 /* copy the resulting stuff into the child structure */
592 strncpy(child
.clientprincipal
, k5user
, sizeof(child
.clientprincipal
));
593 memcpy(&child
.token
, &token
, sizeof(child
.token
));
594 memcpy(&child
.server
, &server
, sizeof(child
.server
));
595 memcpy(&child
.client
, &client
, sizeof(child
.client
));
597 /* stuff the resulting token-related stuff into our shared token cache */
598 /* note, that anything that was set from a keytab is "persistant", and is immune
599 * from LRU-aging. This is because nothing but the process that's running as root
600 * can update these, and it's running every hour or so and renewing these tokens.
601 * and we don't want them aged out.
604 mytime
= oldest_time
= time(0);
606 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: waiting for shared space for %s ", k5user
);
609 pthread_rwlock_wrlock(sharedlock
);
611 rw_wrlock(sharedlock
);
614 for( i
= ( SHARED_TABLE_SIZE
- 1 ); i
>= 0; i
-- ) {
615 if ( ( sharedspace
->sharedtokens
[i
].lastused
<= oldest_time
) &&
616 ( sharedspace
->sharedtokens
[i
].persist
== 0 ) ) {
618 oldest_time
= sharedspace
->sharedtokens
[i
].lastused
;
620 if ( ! strcmp ( sharedspace
->sharedtokens
[i
].clientprincipal
,
621 child
.clientprincipal
) ) {
622 memcpy(&sharedspace
->sharedtokens
[i
].token
, &child
.token
, sizeof(child
.token
) );
623 memcpy(&sharedspace
->sharedtokens
[i
].client
, &child
.client
, sizeof(child
.client
) );
624 memcpy(&sharedspace
->sharedtokens
[i
].server
, &child
.server
, sizeof(child
.server
) );
625 sharedspace
->sharedtokens
[i
].lastused
= mytime
;
626 sharedspace
->sharedtokens
[i
].persist
= keytab
? 1 : 0;
632 if ( stored
== -1 ) {
633 memcpy(&sharedspace
->sharedtokens
[oldest
].token
, &child
.token
, sizeof(child
.token
) );
634 memcpy(&sharedspace
->sharedtokens
[oldest
].client
, &child
.client
, sizeof(child
.client
) );
635 memcpy(&sharedspace
->sharedtokens
[oldest
].server
, &child
.server
, sizeof(child
.server
) );
636 strcpy(sharedspace
->sharedtokens
[oldest
].clientprincipal
, child
.clientprincipal
);
637 sharedspace
->sharedtokens
[oldest
].lastused
= mytime
;
638 sharedspace
->sharedtokens
[oldest
].persist
= keytab
? 1 : 0;
643 pthread_rwlock_unlock(sharedlock
);
645 rw_unlock(sharedlock
);
648 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: token stored in slot %d for %s", stored
,
649 child
.clientprincipal
);
651 } else if ( ! usecached
) {
652 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: set_auth divergent case");
661 /* don't ask. Something about AIX. We're leaving it here.*/
662 /* write(2, "", 0); */
664 /* we try twice, because sometimes the first one fails. Dunno why, but it always works the second time */
666 if ((rc
= ktc_SetToken(&child
.server
, &child
.token
, &child
.client
, 0))) {
667 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: settoken returned %s for %s -- trying again",
668 error_message(rc
), k5user
);
669 if ((rc
= ktc_SetToken(&child
.server
, &child
.token
, &child
.client
, 0))) {
670 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: settoken2 returned %s for %s",
671 error_message(rc
), k5user
);
678 krb5_free_cred_contents(child
.kcontext
, v5credsp
);
679 if ( increds
.client
)
680 krb5_free_principal (child
.kcontext
, increds
.client
);
681 if ( increds
.server
)
682 krb5_free_principal (child
.kcontext
, increds
.server
);
684 (void) krb5_kt_close(child
.kcontext
, krb5kt
);
686 krb5_free_principal (child
.kcontext
, kprinc
);
689 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: set_auth ending with %d", rc
);
690 } else if ( kerror
) {
691 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: set_auth ending with krb5 error %d, %s", kerror
, error_message(kerror
));
693 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: set_auth ending ok");
696 return kerror
? (int) kerror
: (int) rc
;
703 waklog_create_server_config (MK_POOL
* p
, server_rec
* s
)
707 cfg
= (waklog_config
*) ap_pcalloc (p
, sizeof (waklog_config
));
709 memset(cfg
, 0, sizeof(waklog_config
));
710 cfg
->path
= "(server)";
711 cfg
->protect
= WAKLOG_UNSET
;
712 cfg
->usertokens
= WAKLOG_UNSET
;
713 cfg
->keytab
= WAKLOG_UNSET
;
714 cfg
->principal
= WAKLOG_UNSET
;
715 cfg
->default_principal
= WAKLOG_UNSET
;
716 cfg
->default_keytab
= WAKLOG_UNSET
;
717 cfg
->afs_cell
= WAKLOG_UNSET
;
721 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
722 "mod_waklog: server config created.");
727 /* initialize with host-config information */
730 waklog_create_dir_config (MK_POOL
* p
, char *dir
)
734 cfg
= (waklog_config
*) ap_pcalloc (p
, sizeof (waklog_config
));
735 memset(cfg
, 0, sizeof(waklog_config
));
737 cfg
->path
= ap_pstrdup(p
, dir
);
738 cfg
->protect
= WAKLOG_UNSET
;
739 cfg
->usertokens
= WAKLOG_UNSET
;
740 cfg
->keytab
= WAKLOG_UNSET
;
741 cfg
->principal
= WAKLOG_UNSET
;
742 cfg
->default_principal
= WAKLOG_UNSET
;
743 cfg
->default_keytab
= WAKLOG_UNSET
;
744 cfg
->afs_cell
= WAKLOG_UNSET
;
751 static void *waklog_merge_dir_config(MK_POOL
*p
, void *parent_conf
, void *newloc_conf
) {
753 waklog_config
*merged
= ( waklog_config
* ) ap_pcalloc(p
, sizeof(waklog_config
) );
754 waklog_config
*parent
= ( waklog_config
* ) parent_conf
;
755 waklog_config
*child
= ( waklog_config
* ) newloc_conf
;
757 merged
->protect
= child
->protect
!= WAKLOG_UNSET
? child
->protect
: parent
->protect
;
759 merged
->path
= child
->path
!= WAKLOG_UNSET
? child
->path
: parent
->path
;
761 merged
->usertokens
= child
->usertokens
!= WAKLOG_UNSET
? child
->usertokens
: parent
->usertokens
;
763 merged
->principal
= child
->principal
!= WAKLOG_UNSET
? child
->principal
: parent
->principal
;
765 merged
->keytab
= child
->keytab
!= WAKLOG_UNSET
? child
->keytab
: parent
->keytab
;
767 merged
->default_keytab
= child
->default_keytab
!= WAKLOG_UNSET
? child
->default_keytab
: parent
->default_keytab
;
769 merged
->default_principal
= child
->default_principal
!= WAKLOG_UNSET
? child
->default_principal
: parent
->default_principal
;
771 merged
->afs_cell
= child
->afs_cell
!= WAKLOG_UNSET
? child
->afs_cell
: parent
->afs_cell
;
773 return (void *) merged
;
777 static void *waklog_merge_server_config(MK_POOL
*p
, void *parent_conf
, void *newloc_conf
) {
779 waklog_config
*merged
= ( waklog_config
* ) ap_pcalloc(p
, sizeof(waklog_config
) );
780 waklog_config
*pconf
= ( waklog_config
* ) parent_conf
;
781 waklog_config
*nconf
= ( waklog_config
* ) newloc_conf
;
783 merged
->protect
= nconf
->protect
== WAKLOG_UNSET
? pconf
->protect
: nconf
->protect
;
785 merged
->usertokens
= nconf
->usertokens
== WAKLOG_UNSET
? pconf
->usertokens
: nconf
->usertokens
;
787 merged
->keytab
= nconf
->keytab
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->keytab
) :
788 ( nconf
->keytab
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->keytab
) );
790 merged
->principal
= nconf
->principal
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->principal
) :
791 ( nconf
->principal
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->principal
) );
793 merged
->afs_cell
= nconf
->afs_cell
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->afs_cell
) :
794 ( nconf
->afs_cell
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->afs_cell
) );
796 merged
->default_keytab
= nconf
->default_keytab
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->default_keytab
) :
797 ( nconf
->default_keytab
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->default_keytab
) );
799 merged
->default_principal
= nconf
->default_principal
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->default_principal
) :
800 ( nconf
->default_principal
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->default_principal
) );
803 return (void *) merged
;
808 set_waklog_protect (cmd_parms
* params
, void *mconfig
, int flag
)
810 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
811 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
815 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
816 "mod_waklog: waklog_protect set on %s", cfg
->path
? cfg
->path
: "NULL");
821 /* this adds a principal/keytab pair to get their tokens renewed by the
822 child process every few centons. */
824 void add_to_renewtable(MK_POOL
*p
, char *keytab
, char *principal
) {
828 if ( renewcount
>= SHARED_TABLE_SIZE
) {
829 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, NULL
, "mod_waklog: big problem. Increase the SHARED_TABLE_SIZE or \
830 decrease your tokens.");
834 /* check to see if it's already there */
836 for ( i
= 0; i
< renewcount
; i
++ ) {
837 if ( ! strcmp(renewtable
[i
].principal
, principal
) ) {
842 renewtable
[renewcount
].keytab
= ap_pstrdup(p
, keytab
);
843 renewtable
[renewcount
].principal
= ap_pstrdup(p
, principal
);
844 renewtable
[renewcount
].lastrenewed
= 0;
850 set_waklog_principal (cmd_parms
*params
, void *mconfig
, char *principal
, char *keytab
)
852 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
853 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
855 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
856 "mod_waklog: configuring principal: %s, keytab: %s", principal
, keytab
);
858 cfg
->principal
= ap_pstrdup(params
->pool
, principal
);
859 cfg
->keytab
= ap_pstrdup (params
->pool
, keytab
);
861 add_to_renewtable(params
->pool
, keytab
, principal
);
869 set_waklog_use_afs_cell (cmd_parms
* params
, void *mconfig
, char *file
)
871 waklog_config
*waklog_mconfig
= ( waklog_config
* ) mconfig
;
872 waklog_config
*waklog_srvconfig
=
873 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
875 log_error (APLOG_MARK
, APLOG_INFO
, 0, params
->server
,
876 "mod_waklog: will use afs_cell: %s", file
);
878 waklog_srvconfig
->afs_cell
= ap_pstrdup (params
->pool
, file
);
879 waklog_srvconfig
->configured
= 1;
881 if (waklog_mconfig
!= NULL
) {
882 waklog_mconfig
->afs_cell
= ap_pstrdup (params
->pool
, file
);
883 waklog_mconfig
->configured
= 1;
889 set_waklog_default_principal (cmd_parms
* params
, void *mconfig
, char *principal
, char *keytab
)
891 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
892 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
894 waklog_config
*srvcfg
= ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
896 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
897 "mod_waklog: set default princ/keytab: %s, %s for %s", principal
, keytab
, cfg
->path
? cfg
->path
: "NULL");
899 cfg
->default_principal
= ap_pstrdup (params
->pool
, principal
);
900 cfg
->default_keytab
= ap_pstrdup(params
->pool
, keytab
);
902 /* this also gets set at the server level */
903 if ( mconfig
&& ( ! cfg
->path
) ) {
904 srvcfg
->default_principal
= ap_pstrdup (params
->pool
, principal
);
905 srvcfg
->default_keytab
= ap_pstrdup(params
->pool
, keytab
);
907 log_error(APLOG_MARK
, APLOG_ERR
, 0, params
->server
, "only able to set default principal on a global level!");
908 return "Unable to set DefaultPrincipal outside of top level config!";
911 add_to_renewtable( params
->pool
, keytab
, principal
);
919 set_waklog_use_usertokens (cmd_parms
* params
, void *mconfig
, int flag
)
921 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
922 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
924 cfg
->usertokens
= flag
;
928 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
929 "mod_waklog: waklog_use_user_tokens set");
935 static void waklog_child_exit( server_rec
*s
, MK_POOL
*p
) {
937 apr_status_t
waklog_child_exit( void *sr
) {
939 server_rec
*s
= (server_rec
*) sr
;
942 if ( child
.ccache
) {
943 krb5_cc_close(child
.kcontext
, child
.ccache
);
946 if ( child
.kcontext
) {
947 krb5_free_context(child
.kcontext
);
950 /* forget our tokens */
952 ktc_ForgetAllTokens ();
954 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
955 "mod_waklog: waklog_child_exit complete");
965 waklog_child_init (MK_POOL
* p
, server_rec
* s
)
967 waklog_child_init (server_rec
* s
, MK_POOL
* p
)
971 krb5_error_code code
;
976 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: child_init called for pid %d", getpid());
978 if ( !sharedspace
) {
979 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: child_init called without shared space? %d", getpid());
983 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: child_init called for pid %d", getpid());
985 memset (&child
, 0, sizeof(child
));
987 if ( code
= krb5_init_context(&child
.kcontext
) ) {
988 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't init kerberos context %d", code
);
991 if ( code
= krb5_cc_resolve(child
.kcontext
, "MEMORY:tmpcache", &child
.ccache
) ) {
992 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't initialize in-memory credentials cache %d", code
);
995 if ( pag_for_children
) {
999 getModConfig (cfg
, s
);
1001 if ( cfg
->default_principal
!= WAKLOG_UNSET
) {
1002 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: child_init setting default user %s, %s", cfg
->default_principal
, cfg
->default_keytab
);
1003 set_auth( s
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1006 cell
= strdup(cfg
->afs_cell
);
1007 pr_Initialize( 0, AFSDIR_CLIENT_ETC_DIR
, cell
);
1010 apr_pool_cleanup_register(p
, s
, waklog_child_exit
, apr_pool_cleanup_null
);
1013 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
1014 "mod_waklog: child_init returned");
1019 command_rec waklog_cmds
[] = {
1021 command ("WaklogProtected", set_waklog_protect
, 0, FLAG
,
1022 "enable waklog on a location or directory basis"),
1024 command ("WaklogPrincipal", set_waklog_principal
, 0, TAKE2
,
1025 "Use the supplied keytab rather than the default"),
1027 command ("WaklogUseAFSCell", set_waklog_use_afs_cell
, 0, TAKE1
,
1028 "Use the supplied AFS cell rather than the default"),
1030 command ("WaklogUseUserTokens", set_waklog_use_usertokens
, 0, FLAG
,
1031 "Use the requesting user tokens (from webauth)"),
1033 command ("WaklogDefaultPrincipal", set_waklog_default_principal
, 0, TAKE2
,
1034 "Set the default principal that the server runs as"),
1040 /* not currently using this */
1043 token_cleanup (void *data
)
1045 request_rec
*r
= (request_rec
*) data
;
1047 if (child
.token
.ticketLen
)
1049 memset (&child
.token
, 0, sizeof (struct ktc_token
));
1051 ktc_ForgetAllTokens ();
1053 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1054 "mod_waklog: ktc_ForgetAllTokens succeeded: pid: %d",
1061 waklog_child_routine (void *data
, child_info
* pinfo
)
1064 server_rec
*s
= (server_rec
*) data
;
1065 krb5_error_code code
;
1067 time_t sleep_time
= ( TKT_LIFE
/ 2 ) ;
1072 getModConfig( cfg
, s
);
1074 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: waklog_child_routine started, running as %d", getuid());
1076 memset (&child
, 0, sizeof(child
));
1078 if ( code
= krb5_init_context(&child
.kcontext
) ) {
1079 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't init kerberos context %d", code
);
1082 if ( code
= krb5_cc_resolve(child
.kcontext
, "MEMORY:tmpcache", &child
.ccache
) ) {
1083 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't initialize in-memory credentials cache %d", code
);
1086 /* need to do this so we can make PTS calls */
1087 cell
= strdup(cfg
->afs_cell
); /* stupid */
1088 pr_Initialize( 0, AFSDIR_CLIENT_ETC_DIR
, cell
);
1092 for ( i
= 0; i
< renewcount
; ++i
) {
1093 renewtable
[i
].lastrenewed
= time(0);
1094 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: (pid %d) renewing %s / %s", getpid(), renewtable
[i
].principal
,
1095 renewtable
[i
].keytab
);
1097 set_auth( s
, NULL
, 0, renewtable
[i
].principal
, renewtable
[i
].keytab
, 1 );
1099 /* if this is our default token, we want to "stash" it in our current PAG so the parent maintains readability of
1100 things that it needs to read */
1102 if ( cfg
&& cfg
->default_principal
&& ( ! strcmp(cfg
->default_principal
, renewtable
[i
].principal
) ) ) {
1103 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: renewing/setting default tokens" );
1104 set_auth( s
, NULL
, 0, renewtable
[i
].principal
, renewtable
[i
].keytab
, 0 );
1109 sharedspace
->renewcount
++;
1118 left
-= ( time(0) - when
);
1129 waklog_init_handler (apr_pool_t
* p
, apr_pool_t
* plog
,
1130 apr_pool_t
* ptemp
, server_rec
* s
)
1133 extern char *version
;
1138 int use_existing
= 1;
1140 char cache_file
[MAXNAMELEN
];
1142 pthread_rwlockattr_t rwlock_attr
;
1146 getModConfig (cfg
, s
);
1148 /* initialize_module() will be called twice, and if it's a DSO
1149 * then all static data from the first call will be lost. Only
1150 * set up our static data on the second call.
1151 * see http://issues.apache.org/bugzilla/show_bug.cgi?id=37519 */
1152 apr_pool_userdata_get (&data
, userdata_key
, s
->process
->pool
);
1155 if (cfg
->afs_cell
==NULL
) {
1156 log_error (APLOG_MARK
, APLOG_ERR
, 0, s
,
1157 "mod_waklog: afs_cell==NULL; please provide the WaklogUseAFSCell directive");
1158 /** clobber apache */
1164 apr_pool_userdata_set ((const void *) 1, userdata_key
,
1165 apr_pool_cleanup_null
, s
->process
->pool
);
1169 log_error (APLOG_MARK
, APLOG_INFO
, 0, s
,
1170 "mod_waklog: version %s initialized for cell %s", version
, cfg
->afs_cell
);
1172 if ( sharedspace
) {
1173 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: shared memory already allocated." );
1176 snprintf( cache_file
, MAXNAMELEN
, "/tmp/waklog_cache.%d", getpid() );
1178 if ( ( fd
= open( cache_file
, O_RDWR
, 0600 ) ) == -1 ) {
1180 if ( errno
== ENOENT
) {
1182 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: creating shared token cache file %s", cache_file
);
1184 if ( ( fd
= open( cache_file
, O_RDWR
|O_CREAT
|O_TRUNC
, 0600 ) ) == -1 ) {
1185 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot create shared token cache file %s (%d)", cache_file
, errno
);
1189 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot open existing shared token cache file %s (%d)", cache_file
, errno
);
1193 if ( use_existing
== 0 ) {
1194 struct sharedspace_s bob
;
1195 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: sizing our cache file %d to %d", fd
, sizeof(struct sharedspace_s
) );
1196 memset( &bob
, 0, sizeof(struct sharedspace_s
));
1197 write(fd
, &bob
, sizeof(struct sharedspace_s
));
1198 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: done sizing our cache file to %d", sizeof(struct sharedspace_s
) );
1201 /* mmap the region */
1203 if ( ( sharedspace
= (struct sharedspace_s
*) mmap ( NULL
, sizeof(struct sharedspace_s
), PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, 0 ) ) != MAP_FAILED
) {
1204 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: shared mmap region ok %d", sharedspace
);
1207 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: mmap failed %d", errno
);
1213 #define locktype pthread_rwlock_t
1215 #define locktype rwlock_t
1218 if ( sharedlock
= ( locktype
* ) mmap ( NULL
, sizeof(locktype
), PROT_READ
|PROT_WRITE
, MAP_SHARED
|MAP_ANON
, -1, 0 ) ) {
1219 #ifndef use_pthreads
1220 rwlock_init(sharedlock
, USYNC_PROCESS
, NULL
);
1222 pthread_rwlockattr_init(&rwlock_attr
);
1223 pthread_rwlockattr_setpshared(&rwlock_attr
, PTHREAD_PROCESS_SHARED
);
1224 pthread_rwlock_init(sharedlock
, &rwlock_attr
);
1227 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: rwlock mmap failed %d", errno
);
1232 /* set our default tokens */
1234 oldrenewcount
= sharedspace
->renewcount
;
1236 pag_for_children
= 0;
1238 proc
= (apr_proc_t
*) ap_pcalloc (s
->process
->pool
, sizeof (apr_proc_t
));
1240 rv
= apr_proc_fork (proc
, s
->process
->pool
);
1242 if (rv
== APR_INCHILD
)
1244 waklog_child_routine (s
, NULL
);
1248 apr_pool_note_subprocess (s
->process
->pool
, proc
, APR_KILL_ALWAYS
);
1250 /* parent and child */
1251 cfg
->forked
= proc
->pid
;
1252 pag_for_children
= 1;
1254 if ( use_existing
== 0 ) {
1255 /* wait here until our child process has gone and done it's renewing thing. */
1256 while( sharedspace
->renewcount
== oldrenewcount
) {
1257 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: waiting for tokens..." );
1262 if ( cfg
->default_principal
) {
1263 set_auth( s
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1270 waklog_init (server_rec
* s
, MK_POOL
* p
)
1272 extern char *version
;
1277 int use_existing
= 1;
1279 char cache_file
[MAXNAMELEN
];
1281 pthread_rwlockattr_t rwlock_attr
;
1284 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
1285 "mod_waklog: version %s initialized.", version
);
1287 if ( sharedspace
) {
1288 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: shared memory already allocated." );
1291 snprintf( cache_file
, MAXNAMELEN
, "/tmp/waklog_cache.%d", getpid() );
1293 if ( ( fd
= open( cache_file
, O_RDWR
, 0600 ) ) == -1 ) {
1295 if ( errno
== ENOENT
) {
1297 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: creating shared token cache file %s", cache_file
);
1299 if ( ( fd
= open( cache_file
, O_RDWR
|O_CREAT
|O_TRUNC
, 0600 ) ) == -1 ) {
1300 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot create shared token cache file %s (%d)", cache_file
, errno
);
1304 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot open existing shared token cache file %s (%d)", cache_file
, errno
);
1309 if ( use_existing
== 0 ) {
1310 struct sharedspace_s bob
;
1311 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: sizing our cache file %d to %d", fd
, sizeof(struct sharedspace_s
) );
1312 memset( &bob
, 0, sizeof(struct sharedspace_s
));
1313 write(fd
, &bob
, sizeof(struct sharedspace_s
));
1314 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: done sizing our cache file to %d", sizeof(struct sharedspace_s
) );
1317 /* mmap the region */
1319 if ( ( sharedspace
= (struct sharedspace_s
*) mmap ( NULL
, sizeof(struct sharedspace_s
), PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, 0 ) ) != -1 ) {
1320 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: shared mmap region ok %d", sharedspace
);
1323 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: mmap failed %d", errno
);
1329 #define locktype pthread_rwlock_t
1331 #define locktype rwlock_t
1334 /* mmap our shared space for our lock */
1335 if ( sharedlock
= ( locktype
* ) mmap ( NULL
, sizeof(locktype
), PROT_READ
|PROT_WRITE
, MAP_SHARED
|MAP_ANON
, -1, 0 ) ) {
1336 #ifndef use_pthreads
1337 rwlock_init(sharedlock
, USYNC_PROCESS
, NULL
);
1339 pthread_rwlockattr_init(&rwlock_attr
);
1340 pthread_rwlockattr_setpshared(&rwlock_attr
, PTHREAD_PROCESS_SHARED
);
1341 pthread_rwlock_init(sharedlock
, &rwlock_attr
);
1344 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: rwlock mmap failed %d", errno
);
1349 /* set our default tokens */
1351 getModConfig (cfg
, s
);
1353 oldrenewcount
= sharedspace
->renewcount
;
1355 pag_for_children
= 0;
1357 pid
= ap_bspawn_child (p
, waklog_child_routine
, s
, kill_always
,
1360 pag_for_children
= 1;
1362 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
1363 "mod_waklog: ap_bspawn_child: %d.", pid
);
1365 if ( use_existing
== 0 ) {
1366 /* wait here until our child process has gone and done it's renewing thing. */
1367 while( sharedspace
->renewcount
== oldrenewcount
) {
1368 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: waiting for tokens..." );
1373 if ( cfg
->default_principal
) {
1374 set_auth( s
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1381 waklog_phase0 (request_rec
* r
)
1385 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1386 "mod_waklog: phase0 called");
1388 cfg
= retrieve_config(r
);
1390 if ( cfg
->protect
&& cfg
->principal
) {
1391 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase0 using user %s", cfg
->principal
);
1392 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1393 } else if ( cfg
->default_principal
) {
1394 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase0 using default user %s", cfg
->default_principal
);
1395 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1397 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase0 not doing nothin.");
1404 waklog_phase1 (request_rec
* r
)
1408 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1409 "mod_waklog: phase1 called");
1411 cfg
= retrieve_config(r
);
1413 if ( cfg
->protect
&& cfg
->principal
) {
1414 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase1 using user %s", cfg
->principal
);
1415 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1416 } else if ( cfg
->default_principal
) {
1417 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase1 using default user %s", cfg
->default_principal
);
1418 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1420 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase1 not doing nothin.");
1427 waklog_phase3 (request_rec
* r
)
1431 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1432 "mod_waklog: phase 3 called");
1434 cfg
= retrieve_config(r
);
1436 if ( cfg
->protect
&& cfg
->principal
) {
1437 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase3 using user %s", cfg
->principal
);
1438 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1439 } else if ( cfg
->default_principal
) {
1440 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase3 using default user %s", cfg
->default_principal
);
1441 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1443 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase3 not doing nothin.");
1450 waklog_phase6 (request_rec
* r
)
1454 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1455 "mod_waklog: phase6 called");
1457 cfg
= retrieve_config(r
);
1459 if ( cfg
->protect
&& cfg
->principal
) {
1460 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase6 using user %s", cfg
->principal
);
1461 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1462 } else if ( cfg
->default_principal
) {
1463 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase6 using default user %s", cfg
->default_principal
);
1464 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1466 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase6 not doing nothin.");
1473 waklog_phase7 (request_rec
* r
)
1478 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1479 "mod_waklog: phase7 called");
1481 cfg
= retrieve_config (r
);
1483 if ( cfg
->protect
&& cfg
->usertokens
) {
1484 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase7 using usertokens");
1485 rc
= set_auth( r
->server
, r
, 1, NULL
, NULL
, 0);
1486 } else if ( cfg
->protect
&& cfg
->principal
) {
1487 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase7 using user %s", cfg
->principal
);
1488 rc
= set_auth( r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1489 } else if ( cfg
->default_principal
) {
1490 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase7 using default user %s", cfg
->default_principal
);
1491 rc
= set_auth( r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1502 waklog_phase9 (request_rec
* r
)
1506 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1507 "mod_waklog: phase9 called");
1509 getModConfig (cfg
, r
->server
);
1511 if ( cfg
->default_principal
) {
1512 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase9 using default user %s", cfg
->default_principal
);
1513 set_auth( r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1526 waklog_new_connection (conn_rec
* c
1535 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, c
->base_server
,
1536 "mod_waklog: new_connection called: pid: %d", getpid ());
1538 getModConfig(cfg
, c
->base_server
);
1540 if ( cfg
->default_principal
) {
1541 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, c
->base_server
, "mod_waklog: new conn setting default user %s",
1542 cfg
->default_principal
);
1543 set_auth( c
->base_server
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1556 ** Here's a quick explaination for phase0 and phase2:
1557 ** Apache does a stat() on the path between phase0 and
1558 ** phase2, and must by ACLed rl to succeed. So, at
1559 ** phase0 we acquire credentials for umweb:servers from
1560 ** a keytab, and at phase2 we must ensure we remove them.
1562 ** Failure to "unlog" would be a security risk.
1565 waklog_phase2 (request_rec
* r
)
1568 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1569 "mod_waklog: phase2 called");
1571 if (child
.token
.ticketLen
)
1573 memset (&child
.token
, 0, sizeof (struct ktc_token
));
1575 ktc_ForgetAllTokens ();
1577 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1578 "mod_waklog: ktc_ForgetAllTokens succeeded: pid: %d",
1582 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1583 "mod_waklog: phase2 returning");
1589 module MODULE_VAR_EXPORT waklog_module
= {
1590 STANDARD_MODULE_STUFF
,
1591 waklog_init
, /* module initializer */
1592 waklog_create_dir_config
, /* create per-dir config structures */
1593 waklog_merge_dir_config
, /* merge per-dir config structures */
1594 waklog_create_server_config
, /* create per-server config structures */
1595 waklog_merge_dir_config
, /* merge per-server config structures */
1596 waklog_cmds
, /* table of config file commands */
1597 NULL
, /* [#8] MIME-typed-dispatched handlers */
1598 waklog_phase1
, /* [#1] URI to filename translation */
1599 NULL
, /* [#4] validate user id from request */
1600 NULL
, /* [#5] check if the user is ok _here_ */
1601 waklog_phase3
, /* [#3] check access by host address */
1602 waklog_phase6
, /* [#6] determine MIME type */
1603 waklog_phase7
, /* [#7] pre-run fixups */
1604 waklog_phase9
, /* [#9] log a transaction */
1605 NULL
, /* [#2] header parser */
1606 waklog_child_init
, /* child_init */
1607 waklog_child_exit
, /* child_exit */
1608 waklog_phase0
/* [#0] post read-request */
1610 , NULL
, /* EAPI: add_module */
1611 NULL
, /* EAPI: remove_module */
1612 NULL
, /* EAPI: rewrite_command */
1613 waklog_new_connection
/* EAPI: new_connection */
1618 waklog_register_hooks (apr_pool_t
* p
)
1620 ap_hook_translate_name (waklog_phase1
, NULL
, NULL
, APR_HOOK_FIRST
);
1621 ap_hook_header_parser (waklog_phase2
, NULL
, NULL
, APR_HOOK_FIRST
);
1622 ap_hook_access_checker (waklog_phase3
, NULL
, NULL
, APR_HOOK_FIRST
);
1623 ap_hook_type_checker (waklog_phase6
, NULL
, NULL
, APR_HOOK_FIRST
);
1624 ap_hook_fixups (waklog_phase7
, NULL
, NULL
, APR_HOOK_FIRST
);
1625 ap_hook_log_transaction (waklog_phase9
, NULL
, NULL
, APR_HOOK_FIRST
);
1626 ap_hook_child_init (waklog_child_init
, NULL
, NULL
, APR_HOOK_FIRST
);
1627 ap_hook_post_read_request (waklog_phase0
, NULL
, NULL
, APR_HOOK_FIRST
);
1628 ap_hook_pre_connection (waklog_new_connection
, NULL
, NULL
, APR_HOOK_FIRST
);
1629 ap_hook_post_config (waklog_init_handler
, NULL
, NULL
, APR_HOOK_MIDDLE
);
1633 module AP_MODULE_DECLARE_DATA waklog_module
= {
1634 STANDARD20_MODULE_STUFF
,
1635 waklog_create_dir_config
, /* create per-dir conf structures */
1636 waklog_merge_dir_config
, /* merge per-dir conf structures */
1637 waklog_create_server_config
, /* create per-server conf structures */
1638 waklog_merge_dir_config
, /* merge per-server conf structures */
1639 waklog_cmds
, /* table of configuration directives */
1640 waklog_register_hooks
/* register hooks */