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 /********************* APACHE1 ******************************************************************************/
28 #ifndef STANDARD20_MODULE_STUFF
29 #include "ap_config.h"
31 #include <sys/ioccom.h>
33 #include <http_conf_globals.h>
35 #define MK_TABLE_GET ap_table_get
36 #define MK_TABLE_SET ap_table_set
37 #define command(name, func, var, type, usage) \
40 RSRC_CONF | ACCESS_CONF , type, usage }
42 /********************* APACHE2 ******************************************************************************/
44 #include <apr_strings.h>
45 #include <apr_base64.h>
46 //#include <ap_compat.h>
47 #define ap_pcalloc apr_pcalloc
48 #define ap_pdupstr apr_pdupstr
49 #define ap_pstrdup apr_pstrdup
51 module AP_MODULE_DECLARE_DATA waklog_module
;
53 #define MK_POOL apr_pool_t
54 #define MK_TABLE_GET apr_table_get
55 #define MK_TABLE_SET apr_table_set
57 extern unixd_config_rec unixd_config
;
58 #define ap_user_id unixd_config.user_id
59 #define ap_group_id unixd_config.group_id
60 #define ap_user_name unixd_config.user_name
61 #define command(name, func, var, type, usage) \
62 AP_INIT_ ## type (name, (void*) func, \
64 RSRC_CONF | ACCESS_CONF, usage)
71 const char *userdata_key
= "waklog_init";
72 #endif /* STANDARD20_MODULE_STUFF */
73 /**************************************************************************************************/
77 #include <afs/venus.h>
79 #include <afs/dirpath.h>
80 #include <afs/ptuser.h>
83 #define TKT_LIFE ( 12 * 60 * 60 )
84 #define SLEEP_TIME ( TKT_LIFE - 5*60 )
88 #define WAKLOG_UNSET 0
92 #define APLOG_DEBUG APLOG_ERR
95 #ifndef CELL_IN_PRINCIPAL
96 int cell_in_principal
= 1;
98 int cell_in_principal
= 0;
101 /* this is used to turn off pag generation for the backround worker child during startup */
102 int pag_for_children
= 1;
112 char *default_principal
;
113 char *default_keytab
;
122 struct ktc_token token
;
123 char clientprincipal
[MAXNAMELEN
];
124 krb5_context kcontext
;
126 struct ktc_principal server
;
127 struct ktc_principal client
;
129 } waklog_child_config
;
131 waklog_child_config child
;
133 struct tokencache_ent
{
134 char clientprincipal
[MAXNAMELEN
];
135 struct ktc_token token
;
136 struct ktc_principal client
;
137 struct ktc_principal server
;
142 #define SHARED_TABLE_SIZE 512
144 struct sharedspace_s
{
146 struct tokencache_ent sharedtokens
[SHARED_TABLE_SIZE
];
149 struct sharedspace_s
*sharedspace
= NULL
;
158 pthread_rwlock_t
*sharedlock
= NULL
;
160 rwlock_t
*sharedlock
= NULL
;
163 struct renew_ent renewtable
[SHARED_TABLE_SIZE
];
167 module waklog_module
;
170 #define getModConfig(P, X) P = (waklog_config *) ap_get_module_config( (X)->module_config, &waklog_module );
175 #include <sys/ioccom.h>
178 #include <afs/venus.h>
179 #include <afs/auth.h>
180 #include <afs/dirpath.h>
181 #include <afs/ptuser.h>
182 #include <rx/rxkad.h>
184 #define KEYTAB "/etc/keytab.wwwserver"
185 #define PRINCIPAL "someplacewwwserver"
186 #define AFS_CELL "someplace.edu"
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
);
205 #ifdef STANDARD20_MODULE_STUFF
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
);
298 #ifdef STANDARD20_MODULE_STUFF
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 ( cfg
->afs_cell
&& strcmp( cfg
->afs_cell
, AFS_CELL
) ) {
492 strncat(buf
, "/", sizeof(buf
) - strlen(buf
) - 1);
493 strncat(buf
, cfg
->afs_cell
, sizeof(buf
) - strlen(buf
) - 1);
494 } else if ( cell_in_principal
) {
495 strncat(buf
, "/", sizeof(buf
) - strlen(buf
) - 1);
496 strncat(buf
, AFS_CELL
, sizeof(buf
) - strlen(buf
) - 1);
499 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: using AFS principal: %s", buf
);
501 if ((kerror
= krb5_parse_name (child
.kcontext
, buf
, &increds
.server
))) {
502 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_parse name %s", error_message(kerror
));
506 if ((kerror
= krb5_cc_get_principal(child
.kcontext
, child
.ccache
, &increds
.client
))) {
507 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_cc_get_princ %s", error_message(kerror
));
511 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: retrieved data from ccache for %s", k5user
);
513 increds
.times
.endtime
= 0;
515 increds
.keyblock
.enctype
= ENCTYPE_DES_CBC_CRC
;
517 if (kerror
= krb5_get_credentials (child
.kcontext
, 0, child
.ccache
, &increds
, &v5credsp
)) {
518 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: krb5_get_credentials: %s",
519 error_message(kerror
));
523 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: get_credentials passed for %s", k5user
);
525 if ( v5credsp
->ticket
.length
>= MAXKTCTICKETLEN
) {
526 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: ticket size (%d) too big to fake",
527 v5credsp
->ticket
.length
);
531 memset(&token
, 0, sizeof(struct ktc_token
));
533 token
.startTime
= v5credsp
->times
.starttime
? v5credsp
->times
.starttime
: v5credsp
->times
.authtime
;
534 token
.endTime
= v5credsp
->times
.endtime
;
536 memmove( &token
.sessionKey
, v5credsp
->keyblock
.contents
, v5credsp
->keyblock
.length
);
537 token
.kvno
= RXKAD_TKT_TYPE_KERBEROS_V5
;
538 token
.ticketLen
= v5credsp
->ticket
.length
;
539 memmove( token
.ticket
, v5credsp
->ticket
.data
, token
.ticketLen
);
543 memmove( buf
, v5credsp
->client
->data
[0].data
, min(v5credsp
->client
->data
[0].length
,
545 buf
[v5credsp
->client
->data
[0].length
] = '\0';
546 if ( v5credsp
->client
->length
> 1 ) {
547 strncat(buf
, ".", sizeof(buf
) - strlen(buf
) - 1);
548 buflen
= strlen(buf
);
549 memmove(buf
+ buflen
, v5credsp
->client
->data
[1].data
,
550 min(v5credsp
->client
->data
[1].length
,
551 MAXKTCNAMELEN
- strlen(buf
) - 1));
552 buf
[buflen
+ v5credsp
->client
->data
[1].length
] = '\0';
555 /* assemble the client */
556 strncpy(client
.name
, buf
, sizeof(client
.name
) - 1 );
557 strncpy(client
.instance
, "", sizeof(client
.instance
) - 1 );
558 memmove(buf
, v5credsp
->client
->realm
.data
, min(v5credsp
->client
->realm
.length
,
560 buf
[v5credsp
->client
->realm
.length
] = '\0';
561 strncpy(client
.cell
, buf
, sizeof(client
.cell
));
563 /* assemble the server's cell */
564 if ( cfg
->afs_cell
) {
565 strncpy(server
.cell
, cfg
->afs_cell
, sizeof(server
.cell
) - 1);
567 strncpy(server
.cell
, AFS_CELL
, sizeof(server
.cell
) - 1);
570 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: preparing to init PTS connection for %s", server
.cell
);
572 /* fill out the AFS ID in the client name */
573 /* we've done a pr_Initialize in the child_init -- once, per process. If you try to do it more
574 * strange things seem to happen. */
577 afs_int32 viceId
= 0;
579 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: making PTS call to look up %s", client
.name
);
581 if ( ( rc
= pr_SNameToId( client
.name
, &viceId
) ) == 0 ) {
582 snprintf( client
.name
, sizeof(client
.name
), "AFS ID %d", viceId
);
584 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: PTS call returned error %d ", rc
);
587 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: PTS call returned %s ", client
.name
);
591 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: server: name %s, instance %s, cell %s",
592 server
.name
, server
.instance
, server
.cell
);
594 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: client: name %s, instance %s, cell %s",
595 client
.name
, client
.instance
, client
.cell
);
597 /* copy the resulting stuff into the child structure */
599 strncpy(child
.clientprincipal
, k5user
, sizeof(child
.clientprincipal
));
600 memcpy(&child
.token
, &token
, sizeof(child
.token
));
601 memcpy(&child
.server
, &server
, sizeof(child
.server
));
602 memcpy(&child
.client
, &client
, sizeof(child
.client
));
604 /* stuff the resulting token-related stuff into our shared token cache */
605 /* note, that anything that was set from a keytab is "persistant", and is immune
606 * from LRU-aging. This is because nothing but the process that's running as root
607 * can update these, and it's running every hour or so and renewing these tokens.
608 * and we don't want them aged out.
611 mytime
= oldest_time
= time(0);
613 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: waiting for shared space for %s ", k5user
);
616 pthread_rwlock_wrlock(sharedlock
);
618 rw_wrlock(sharedlock
);
621 for( i
= ( SHARED_TABLE_SIZE
- 1 ); i
>= 0; i
-- ) {
622 if ( ( sharedspace
->sharedtokens
[i
].lastused
<= oldest_time
) &&
623 ( sharedspace
->sharedtokens
[i
].persist
== 0 ) ) {
625 oldest_time
= sharedspace
->sharedtokens
[i
].lastused
;
627 if ( ! strcmp ( sharedspace
->sharedtokens
[i
].clientprincipal
,
628 child
.clientprincipal
) ) {
629 memcpy(&sharedspace
->sharedtokens
[i
].token
, &child
.token
, sizeof(child
.token
) );
630 memcpy(&sharedspace
->sharedtokens
[i
].client
, &child
.client
, sizeof(child
.client
) );
631 memcpy(&sharedspace
->sharedtokens
[i
].server
, &child
.server
, sizeof(child
.server
) );
632 sharedspace
->sharedtokens
[i
].lastused
= mytime
;
633 sharedspace
->sharedtokens
[i
].persist
= keytab
? 1 : 0;
639 if ( stored
== -1 ) {
640 memcpy(&sharedspace
->sharedtokens
[oldest
].token
, &child
.token
, sizeof(child
.token
) );
641 memcpy(&sharedspace
->sharedtokens
[oldest
].client
, &child
.client
, sizeof(child
.client
) );
642 memcpy(&sharedspace
->sharedtokens
[oldest
].server
, &child
.server
, sizeof(child
.server
) );
643 strcpy(sharedspace
->sharedtokens
[oldest
].clientprincipal
, child
.clientprincipal
);
644 sharedspace
->sharedtokens
[oldest
].lastused
= mytime
;
645 sharedspace
->sharedtokens
[oldest
].persist
= keytab
? 1 : 0;
650 pthread_rwlock_unlock(sharedlock
);
652 rw_unlock(sharedlock
);
655 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: token stored in slot %d for %s", stored
,
656 child
.clientprincipal
);
658 } else if ( ! usecached
) {
659 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: set_auth divergent case");
668 /* don't ask. Something about AIX. We're leaving it here.*/
669 /* write(2, "", 0); */
671 /* we try twice, because sometimes the first one fails. Dunno why, but it always works the second time */
673 if ((rc
= ktc_SetToken(&child
.server
, &child
.token
, &child
.client
, 0))) {
674 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: settoken returned %s for %s -- trying again",
675 error_message(rc
), k5user
);
676 if ((rc
= ktc_SetToken(&child
.server
, &child
.token
, &child
.client
, 0))) {
677 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: settoken2 returned %s for %s",
678 error_message(rc
), k5user
);
685 krb5_free_cred_contents(child
.kcontext
, v5credsp
);
686 if ( increds
.client
)
687 krb5_free_principal (child
.kcontext
, increds
.client
);
688 if ( increds
.server
)
689 krb5_free_principal (child
.kcontext
, increds
.server
);
691 (void) krb5_kt_close(child
.kcontext
, krb5kt
);
693 krb5_free_principal (child
.kcontext
, kprinc
);
696 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: set_auth ending with %d", rc
);
697 } else if ( kerror
) {
698 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: set_auth ending with krb5 error %d, %s", kerror
, error_message(kerror
));
700 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: set_auth ending ok");
703 return kerror
? (int) kerror
: (int) rc
;
710 waklog_create_server_config (MK_POOL
* p
, server_rec
* s
)
714 cfg
= (waklog_config
*) ap_pcalloc (p
, sizeof (waklog_config
));
716 memset(cfg
, 0, sizeof(waklog_config
));
717 cfg
->path
= "(server)";
718 cfg
->protect
= WAKLOG_UNSET
;
719 cfg
->usertokens
= WAKLOG_UNSET
;
720 cfg
->keytab
= WAKLOG_UNSET
;
721 cfg
->principal
= WAKLOG_UNSET
;
722 cfg
->default_principal
= WAKLOG_UNSET
;
723 cfg
->default_keytab
= WAKLOG_UNSET
;
724 cfg
->afs_cell
= WAKLOG_UNSET
;
728 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
729 "mod_waklog: server config created.");
734 /* initialize with host-config information */
737 waklog_create_dir_config (MK_POOL
* p
, char *dir
)
741 cfg
= (waklog_config
*) ap_pcalloc (p
, sizeof (waklog_config
));
742 memset(cfg
, 0, sizeof(waklog_config
));
744 cfg
->path
= ap_pstrdup(p
, dir
);
745 cfg
->protect
= WAKLOG_UNSET
;
746 cfg
->usertokens
= WAKLOG_UNSET
;
747 cfg
->keytab
= WAKLOG_UNSET
;
748 cfg
->principal
= WAKLOG_UNSET
;
749 cfg
->default_principal
= WAKLOG_UNSET
;
750 cfg
->default_keytab
= WAKLOG_UNSET
;
751 cfg
->afs_cell
= WAKLOG_UNSET
;
758 static void *waklog_merge_dir_config(MK_POOL
*p
, void *parent_conf
, void *newloc_conf
) {
760 waklog_config
*merged
= ( waklog_config
* ) ap_pcalloc(p
, sizeof(waklog_config
) );
761 waklog_config
*parent
= ( waklog_config
* ) parent_conf
;
762 waklog_config
*child
= ( waklog_config
* ) newloc_conf
;
764 merged
->protect
= child
->protect
!= WAKLOG_UNSET
? child
->protect
: parent
->protect
;
766 merged
->path
= child
->path
!= WAKLOG_UNSET
? child
->path
: parent
->path
;
768 merged
->usertokens
= child
->usertokens
!= WAKLOG_UNSET
? child
->usertokens
: parent
->usertokens
;
770 merged
->principal
= child
->principal
!= WAKLOG_UNSET
? child
->principal
: parent
->principal
;
772 merged
->keytab
= child
->keytab
!= WAKLOG_UNSET
? child
->keytab
: parent
->keytab
;
774 merged
->default_keytab
= child
->default_keytab
!= WAKLOG_UNSET
? child
->default_keytab
: parent
->default_keytab
;
776 merged
->default_principal
= child
->default_principal
!= WAKLOG_UNSET
? child
->default_principal
: parent
->default_principal
;
778 merged
->afs_cell
= child
->afs_cell
!= WAKLOG_UNSET
? child
->afs_cell
: parent
->afs_cell
;
780 return (void *) merged
;
784 static void *waklog_merge_server_config(MK_POOL
*p
, void *parent_conf
, void *newloc_conf
) {
786 waklog_config
*merged
= ( waklog_config
* ) ap_pcalloc(p
, sizeof(waklog_config
) );
787 waklog_config
*pconf
= ( waklog_config
* ) parent_conf
;
788 waklog_config
*nconf
= ( waklog_config
* ) newloc_conf
;
790 merged
->protect
= nconf
->protect
== WAKLOG_UNSET
? pconf
->protect
: nconf
->protect
;
792 merged
->usertokens
= nconf
->usertokens
== WAKLOG_UNSET
? pconf
->usertokens
: nconf
->usertokens
;
794 merged
->keytab
= nconf
->keytab
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->keytab
) :
795 ( nconf
->keytab
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->keytab
) );
797 merged
->principal
= nconf
->principal
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->principal
) :
798 ( nconf
->principal
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->principal
) );
800 merged
->afs_cell
= nconf
->afs_cell
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->afs_cell
) :
801 ( nconf
->afs_cell
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->afs_cell
) );
803 merged
->default_keytab
= nconf
->default_keytab
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->default_keytab
) :
804 ( nconf
->default_keytab
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->default_keytab
) );
806 merged
->default_principal
= nconf
->default_principal
== WAKLOG_UNSET
? ap_pstrdup(p
, pconf
->default_principal
) :
807 ( nconf
->default_principal
== WAKLOG_UNSET
? WAKLOG_UNSET
: ap_pstrdup(p
, pconf
->default_principal
) );
810 return (void *) merged
;
815 set_waklog_protect (cmd_parms
* params
, void *mconfig
, int flag
)
817 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
818 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
822 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
823 "mod_waklog: waklog_protect set on %s", cfg
->path
? cfg
->path
: "NULL");
828 /* this adds a principal/keytab pair to get their tokens renewed by the
829 child process every few centons. */
831 void add_to_renewtable(MK_POOL
*p
, char *keytab
, char *principal
) {
835 if ( renewcount
>= SHARED_TABLE_SIZE
) {
836 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, NULL
, "mod_waklog: big problem. Increase the SHARED_TABLE_SIZE or \
837 decrease your tokens.");
841 /* check to see if it's already there */
843 for ( i
= 0; i
< renewcount
; i
++ ) {
844 if ( ! strcmp(renewtable
[i
].principal
, principal
) ) {
849 renewtable
[renewcount
].keytab
= ap_pstrdup(p
, keytab
);
850 renewtable
[renewcount
].principal
= ap_pstrdup(p
, principal
);
851 renewtable
[renewcount
].lastrenewed
= 0;
857 set_waklog_principal (cmd_parms
*params
, void *mconfig
, char *principal
, char *keytab
)
859 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
860 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
862 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
863 "mod_waklog: configuring principal: %s, keytab: %s", principal
, keytab
);
865 cfg
->principal
= ap_pstrdup(params
->pool
, principal
);
866 cfg
->keytab
= ap_pstrdup (params
->pool
, keytab
);
868 add_to_renewtable(params
->pool
, keytab
, principal
);
876 set_waklog_use_afs_cell (cmd_parms
* params
, void *mconfig
, char *file
)
878 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
879 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
881 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
882 "mod_waklog: will use afs_cell: %s", file
);
884 cfg
->afs_cell
= ap_pstrdup (params
->pool
, file
);
890 set_waklog_default_principal (cmd_parms
* params
, void *mconfig
, char *principal
, char *keytab
)
892 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
893 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
895 waklog_config
*srvcfg
= ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
897 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
898 "mod_waklog: set default princ/keytab: %s, %s for %s", principal
, keytab
, cfg
->path
? cfg
->path
: "NULL");
900 cfg
->default_principal
= ap_pstrdup (params
->pool
, principal
);
901 cfg
->default_keytab
= ap_pstrdup(params
->pool
, keytab
);
903 /* this also gets set at the server level */
904 if ( mconfig
&& ( ! cfg
->path
) ) {
905 srvcfg
->default_principal
= ap_pstrdup (params
->pool
, principal
);
906 srvcfg
->default_keytab
= ap_pstrdup(params
->pool
, keytab
);
908 log_error(APLOG_MARK
, APLOG_ERR
, 0, params
->server
, "only able to set default principal on a global level!");
909 return "Unable to set DefaultPrincipal outside of top level config!";
912 add_to_renewtable( params
->pool
, keytab
, principal
);
920 set_waklog_use_usertokens (cmd_parms
* params
, void *mconfig
, int flag
)
922 waklog_config
*cfg
= mconfig
? ( waklog_config
* ) mconfig
:
923 ( waklog_config
* ) ap_get_module_config(params
->server
->module_config
, &waklog_module
);
925 cfg
->usertokens
= flag
;
929 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, params
->server
,
930 "mod_waklog: waklog_use_user_tokens set");
935 #ifndef STANDARD20_MODULE_STUFF
936 static void waklog_child_exit( server_rec
*s
, MK_POOL
*p
) {
938 apr_status_t
waklog_child_exit( void *sr
) {
940 server_rec
*s
= (server_rec
*) sr
;
943 if ( child
.ccache
) {
944 krb5_cc_close(child
.kcontext
, child
.ccache
);
947 if ( child
.kcontext
) {
948 krb5_free_context(child
.kcontext
);
951 /* forget our tokens */
953 ktc_ForgetAllTokens ();
955 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
956 "mod_waklog: waklog_child_exit complete");
958 #ifdef STANDARD20_MODULE_STUFF
965 #ifdef STANDARD20_MODULE_STUFF
966 waklog_child_init (MK_POOL
* p
, server_rec
* s
)
968 waklog_child_init (server_rec
* s
, MK_POOL
* p
)
972 krb5_error_code code
;
977 cell
= strdup(AFS_CELL
);
979 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: child_init called for pid %d", getpid());
981 if ( !sharedspace
) {
982 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: child_init called without shared space? %d", getpid());
986 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: child_init called for pid %d", getpid());
988 memset (&child
, 0, sizeof(child
));
990 if ( code
= krb5_init_context(&child
.kcontext
) ) {
991 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't init kerberos context %d", code
);
994 if ( code
= krb5_cc_resolve(child
.kcontext
, "MEMORY:tmpcache", &child
.ccache
) ) {
995 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't initialize in-memory credentials cache %d", code
);
998 if ( pag_for_children
) {
1002 getModConfig (cfg
, s
);
1004 if ( cfg
->default_principal
!= WAKLOG_UNSET
) {
1005 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: child_init setting default user %s, %s", cfg
->default_principal
, cfg
->default_keytab
);
1006 set_auth( s
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1009 pr_Initialize( 0, AFSDIR_CLIENT_ETC_DIR
, cell
);
1011 #ifdef STANDARD20_MODULE_STUFF
1012 apr_pool_cleanup_register(p
, s
, waklog_child_exit
, apr_pool_cleanup_null
);
1015 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
1016 "mod_waklog: child_init returned");
1021 command_rec waklog_cmds
[] = {
1023 command ("WaklogProtected", set_waklog_protect
, 0, FLAG
,
1024 "enable waklog on a location or directory basis"),
1026 command ("WaklogPrincipal", set_waklog_principal
, 0, TAKE2
,
1027 "Use the supplied keytab rather than the default"),
1029 command ("WaklogUseAFSCell", set_waklog_use_afs_cell
, 0, TAKE1
,
1030 "Use the supplied AFS cell rather than the default"),
1032 command ("WaklogUseUserTokens", set_waklog_use_usertokens
, 0, FLAG
,
1033 "Use the requesting user tokens (from webauth)"),
1035 command ("WaklogDefaultPrincipal", set_waklog_default_principal
, 0, TAKE2
,
1036 "Set the default principal that the server runs as"),
1042 /* not currently using this */
1045 token_cleanup (void *data
)
1047 request_rec
*r
= (request_rec
*) data
;
1049 if (child
.token
.ticketLen
)
1051 memset (&child
.token
, 0, sizeof (struct ktc_token
));
1053 ktc_ForgetAllTokens ();
1055 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1056 "mod_waklog: ktc_ForgetAllTokens succeeded: pid: %d",
1063 waklog_child_routine (void *data
, child_info
* pinfo
)
1066 server_rec
*s
= (server_rec
*) data
;
1067 krb5_error_code code
;
1069 time_t sleep_time
= ( TKT_LIFE
/ 2 ) ;
1074 getModConfig( cfg
, s
);
1076 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: waklog_child_routine started, running as %d", getuid());
1078 memset (&child
, 0, sizeof(child
));
1080 if ( code
= krb5_init_context(&child
.kcontext
) ) {
1081 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't init kerberos context %d", code
);
1084 if ( code
= krb5_cc_resolve(child
.kcontext
, "MEMORY:tmpcache", &child
.ccache
) ) {
1085 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: can't initialize in-memory credentials cache %d", code
);
1088 /* need to do this so we can make PTS calls */
1089 cell
= strdup(AFS_CELL
); /* stupid */
1090 pr_Initialize( 0, AFSDIR_CLIENT_ETC_DIR
, cell
);
1094 for ( i
= 0; i
< renewcount
; ++i
) {
1095 renewtable
[i
].lastrenewed
= time(0);
1096 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: (pid %d) renewing %s / %s", getpid(), renewtable
[i
].principal
,
1097 renewtable
[i
].keytab
);
1099 set_auth( s
, NULL
, 0, renewtable
[i
].principal
, renewtable
[i
].keytab
, 1 );
1101 /* if this is our default token, we want to "stash" it in our current PAG so the parent maintains readability of
1102 things that it needs to read */
1104 if ( cfg
&& cfg
->default_principal
&& ( ! strcmp(cfg
->default_principal
, renewtable
[i
].principal
) ) ) {
1105 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: renewing/setting default tokens" );
1106 set_auth( s
, NULL
, 0, renewtable
[i
].principal
, renewtable
[i
].keytab
, 0 );
1111 sharedspace
->renewcount
++;
1120 left
-= ( time(0) - when
);
1129 #ifdef STANDARD20_MODULE_STUFF
1131 waklog_init_handler (apr_pool_t
* p
, apr_pool_t
* plog
,
1132 apr_pool_t
* ptemp
, server_rec
* s
)
1135 extern char *version
;
1140 int use_existing
= 1;
1142 char cache_file
[MAXNAMELEN
];
1144 pthread_rwlockattr_t rwlock_attr
;
1148 getModConfig (cfg
, s
);
1150 /* initialize_module() will be called twice, and if it's a DSO
1151 * then all static data from the first call will be lost. Only
1152 * set up our static data on the second call.
1153 * see http://issues.apache.org/bugzilla/show_bug.cgi?id=37519 */
1154 apr_pool_userdata_get (&data
, userdata_key
, s
->process
->pool
);
1158 apr_pool_userdata_set ((const void *) 1, userdata_key
,
1159 apr_pool_cleanup_null
, s
->process
->pool
);
1163 log_error (APLOG_MARK
, APLOG_INFO
, 0, s
,
1164 "mod_waklog: version %s initialized.", version
);
1166 if ( sharedspace
) {
1167 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: shared memory already allocated." );
1170 snprintf( cache_file
, MAXNAMELEN
, "/tmp/waklog_cache.%d", getpid() );
1172 if ( ( fd
= open( cache_file
, O_RDWR
, 0600 ) ) == -1 ) {
1174 if ( errno
== ENOENT
) {
1176 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: creating shared token cache file %s", cache_file
);
1178 if ( ( fd
= open( cache_file
, O_RDWR
|O_CREAT
|O_TRUNC
, 0600 ) ) == -1 ) {
1179 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot create shared token cache file %s (%d)", cache_file
, errno
);
1183 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot open existing shared token cache file %s (%d)", cache_file
, errno
);
1187 if ( use_existing
== 0 ) {
1188 struct sharedspace_s bob
;
1189 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: sizing our cache file %d to %d", fd
, sizeof(struct sharedspace_s
) );
1190 memset( &bob
, 0, sizeof(struct sharedspace_s
));
1191 write(fd
, &bob
, sizeof(struct sharedspace_s
));
1192 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: done sizing our cache file to %d", sizeof(struct sharedspace_s
) );
1195 /* mmap the region */
1197 if ( ( sharedspace
= (struct sharedspace_s
*) mmap ( NULL
, sizeof(struct sharedspace_s
), PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, 0 ) ) != MAP_FAILED
) {
1198 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: shared mmap region ok %d", sharedspace
);
1201 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: mmap failed %d", errno
);
1207 #define locktype pthread_rwlock_t
1209 #define locktype rwlock_t
1212 if ( sharedlock
= ( locktype
* ) mmap ( NULL
, sizeof(locktype
), PROT_READ
|PROT_WRITE
, MAP_SHARED
|MAP_ANON
, -1, 0 ) ) {
1213 #ifndef use_pthreads
1214 rwlock_init(sharedlock
, USYNC_PROCESS
, NULL
);
1216 pthread_rwlockattr_init(&rwlock_attr
);
1217 pthread_rwlockattr_setpshared(&rwlock_attr
, PTHREAD_PROCESS_SHARED
);
1218 pthread_rwlock_init(sharedlock
, &rwlock_attr
);
1221 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: rwlock mmap failed %d", errno
);
1226 /* set our default tokens */
1228 oldrenewcount
= sharedspace
->renewcount
;
1230 pag_for_children
= 0;
1232 proc
= (apr_proc_t
*) ap_pcalloc (s
->process
->pool
, sizeof (apr_proc_t
));
1234 rv
= apr_proc_fork (proc
, s
->process
->pool
);
1236 if (rv
== APR_INCHILD
)
1238 waklog_child_routine (s
, NULL
);
1242 apr_pool_note_subprocess (s
->process
->pool
, proc
, APR_KILL_ALWAYS
);
1244 /* parent and child */
1245 cfg
->forked
= proc
->pid
;
1246 pag_for_children
= 1;
1248 if ( use_existing
== 0 ) {
1249 /* wait here until our child process has gone and done it's renewing thing. */
1250 while( sharedspace
->renewcount
== oldrenewcount
) {
1251 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: waiting for tokens..." );
1256 if ( cfg
->default_principal
) {
1257 set_auth( s
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1264 waklog_init (server_rec
* s
, MK_POOL
* p
)
1266 extern char *version
;
1271 int use_existing
= 1;
1273 char cache_file
[MAXNAMELEN
];
1275 pthread_rwlockattr_t rwlock_attr
;
1278 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
1279 "mod_waklog: version %s initialized.", version
);
1281 if ( sharedspace
) {
1282 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: shared memory already allocated." );
1285 snprintf( cache_file
, MAXNAMELEN
, "/tmp/waklog_cache.%d", getpid() );
1287 if ( ( fd
= open( cache_file
, O_RDWR
, 0600 ) ) == -1 ) {
1289 if ( errno
== ENOENT
) {
1291 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: creating shared token cache file %s", cache_file
);
1293 if ( ( fd
= open( cache_file
, O_RDWR
|O_CREAT
|O_TRUNC
, 0600 ) ) == -1 ) {
1294 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot create shared token cache file %s (%d)", cache_file
, errno
);
1298 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: cannot open existing shared token cache file %s (%d)", cache_file
, errno
);
1303 if ( use_existing
== 0 ) {
1304 struct sharedspace_s bob
;
1305 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: sizing our cache file %d to %d", fd
, sizeof(struct sharedspace_s
) );
1306 memset( &bob
, 0, sizeof(struct sharedspace_s
));
1307 write(fd
, &bob
, sizeof(struct sharedspace_s
));
1308 log_error(APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: done sizing our cache file to %d", sizeof(struct sharedspace_s
) );
1311 /* mmap the region */
1313 if ( ( sharedspace
= (struct sharedspace_s
*) mmap ( NULL
, sizeof(struct sharedspace_s
), PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, 0 ) ) != -1 ) {
1314 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: shared mmap region ok %d", sharedspace
);
1317 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: mmap failed %d", errno
);
1323 #define locktype pthread_rwlock_t
1325 #define locktype rwlock_t
1328 /* mmap our shared space for our lock */
1329 if ( sharedlock
= ( locktype
* ) mmap ( NULL
, sizeof(locktype
), PROT_READ
|PROT_WRITE
, MAP_SHARED
|MAP_ANON
, -1, 0 ) ) {
1330 #ifndef use_pthreads
1331 rwlock_init(sharedlock
, USYNC_PROCESS
, NULL
);
1333 pthread_rwlockattr_init(&rwlock_attr
);
1334 pthread_rwlockattr_setpshared(&rwlock_attr
, PTHREAD_PROCESS_SHARED
);
1335 pthread_rwlock_init(sharedlock
, &rwlock_attr
);
1338 log_error( APLOG_MARK
, APLOG_DEBUG
, 0, s
, "mod_waklog: rwlock mmap failed %d", errno
);
1343 /* set our default tokens */
1345 getModConfig (cfg
, s
);
1347 oldrenewcount
= sharedspace
->renewcount
;
1349 pag_for_children
= 0;
1351 pid
= ap_bspawn_child (p
, waklog_child_routine
, s
, kill_always
,
1354 pag_for_children
= 1;
1356 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, s
,
1357 "mod_waklog: ap_bspawn_child: %d.", pid
);
1359 if ( use_existing
== 0 ) {
1360 /* wait here until our child process has gone and done it's renewing thing. */
1361 while( sharedspace
->renewcount
== oldrenewcount
) {
1362 log_error( APLOG_MARK
, APLOG_ERR
, 0, s
, "mod_waklog: waiting for tokens..." );
1367 if ( cfg
->default_principal
) {
1368 set_auth( s
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1375 waklog_phase0 (request_rec
* r
)
1379 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1380 "mod_waklog: phase0 called");
1382 cfg
= retrieve_config(r
);
1384 if ( cfg
->protect
&& cfg
->principal
) {
1385 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase0 using user %s", cfg
->principal
);
1386 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1387 } else if ( cfg
->default_principal
) {
1388 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase0 using default user %s", cfg
->default_principal
);
1389 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1391 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase0 not doing nothin.");
1398 waklog_phase1 (request_rec
* r
)
1402 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1403 "mod_waklog: phase1 called");
1405 cfg
= retrieve_config(r
);
1407 if ( cfg
->protect
&& cfg
->principal
) {
1408 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase1 using user %s", cfg
->principal
);
1409 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1410 } else if ( cfg
->default_principal
) {
1411 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase1 using default user %s", cfg
->default_principal
);
1412 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1414 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase1 not doing nothin.");
1421 waklog_phase3 (request_rec
* r
)
1425 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1426 "mod_waklog: phase 3 called");
1428 cfg
= retrieve_config(r
);
1430 if ( cfg
->protect
&& cfg
->principal
) {
1431 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase3 using user %s", cfg
->principal
);
1432 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1433 } else if ( cfg
->default_principal
) {
1434 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase3 using default user %s", cfg
->default_principal
);
1435 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1437 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase3 not doing nothin.");
1444 waklog_phase6 (request_rec
* r
)
1448 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1449 "mod_waklog: phase6 called");
1451 cfg
= retrieve_config(r
);
1453 if ( cfg
->protect
&& cfg
->principal
) {
1454 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase6 using user %s", cfg
->principal
);
1455 set_auth(r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1456 } else if ( cfg
->default_principal
) {
1457 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase6 using default user %s", cfg
->default_principal
);
1458 set_auth(r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1460 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase6 not doing nothin.");
1467 waklog_phase7 (request_rec
* r
)
1472 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1473 "mod_waklog: phase7 called");
1475 cfg
= retrieve_config (r
);
1477 if ( cfg
->protect
&& cfg
->usertokens
) {
1478 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase7 using usertokens");
1479 rc
= set_auth( r
->server
, r
, 1, NULL
, NULL
, 0);
1480 } else if ( cfg
->protect
&& cfg
->principal
) {
1481 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase7 using user %s", cfg
->principal
);
1482 rc
= set_auth( r
->server
, r
, 0, cfg
->principal
, cfg
->keytab
, 0);
1483 } else if ( cfg
->default_principal
) {
1484 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase7 using default user %s", cfg
->default_principal
);
1485 rc
= set_auth( r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1496 waklog_phase9 (request_rec
* r
)
1500 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1501 "mod_waklog: phase9 called");
1503 getModConfig (cfg
, r
->server
);
1505 if ( cfg
->default_principal
) {
1506 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
, "mod_waklog: phase9 using default user %s", cfg
->default_principal
);
1507 set_auth( r
->server
, r
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1515 #ifdef STANDARD20_MODULE_STUFF
1520 waklog_new_connection (conn_rec
* c
1521 #ifdef STANDARD20_MODULE_STUFF
1529 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, c
->base_server
,
1530 "mod_waklog: new_connection called: pid: %d", getpid ());
1532 getModConfig(cfg
, c
->base_server
);
1534 if ( cfg
->default_principal
) {
1535 log_error(APLOG_MARK
, APLOG_DEBUG
, 0, c
->base_server
, "mod_waklog: new conn setting default user %s",
1536 cfg
->default_principal
);
1537 set_auth( c
->base_server
, NULL
, 0, cfg
->default_principal
, cfg
->default_keytab
, 0);
1542 #ifdef STANDARD20_MODULE_STUFF
1550 ** Here's a quick explaination for phase0 and phase2:
1551 ** Apache does a stat() on the path between phase0 and
1552 ** phase2, and must by ACLed rl to succeed. So, at
1553 ** phase0 we acquire credentials for umweb:servers from
1554 ** a keytab, and at phase2 we must ensure we remove them.
1556 ** Failure to "unlog" would be a security risk.
1559 waklog_phase2 (request_rec
* r
)
1562 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1563 "mod_waklog: phase2 called");
1565 if (child
.token
.ticketLen
)
1567 memset (&child
.token
, 0, sizeof (struct ktc_token
));
1569 ktc_ForgetAllTokens ();
1571 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1572 "mod_waklog: ktc_ForgetAllTokens succeeded: pid: %d",
1576 log_error (APLOG_MARK
, APLOG_DEBUG
, 0, r
->server
,
1577 "mod_waklog: phase2 returning");
1582 #ifndef STANDARD20_MODULE_STUFF
1583 module MODULE_VAR_EXPORT waklog_module
= {
1584 STANDARD_MODULE_STUFF
,
1585 waklog_init
, /* module initializer */
1586 waklog_create_dir_config
, /* create per-dir config structures */
1587 waklog_merge_dir_config
, /* merge per-dir config structures */
1588 waklog_create_server_config
, /* create per-server config structures */
1589 waklog_merge_dir_config
, /* merge per-server config structures */
1590 waklog_cmds
, /* table of config file commands */
1591 NULL
, /* [#8] MIME-typed-dispatched handlers */
1592 waklog_phase1
, /* [#1] URI to filename translation */
1593 NULL
, /* [#4] validate user id from request */
1594 NULL
, /* [#5] check if the user is ok _here_ */
1595 waklog_phase3
, /* [#3] check access by host address */
1596 waklog_phase6
, /* [#6] determine MIME type */
1597 waklog_phase7
, /* [#7] pre-run fixups */
1598 waklog_phase9
, /* [#9] log a transaction */
1599 NULL
, /* [#2] header parser */
1600 waklog_child_init
, /* child_init */
1601 waklog_child_exit
, /* child_exit */
1602 waklog_phase0
/* [#0] post read-request */
1604 , NULL
, /* EAPI: add_module */
1605 NULL
, /* EAPI: remove_module */
1606 NULL
, /* EAPI: rewrite_command */
1607 waklog_new_connection
/* EAPI: new_connection */
1612 waklog_register_hooks (apr_pool_t
* p
)
1614 ap_hook_translate_name (waklog_phase1
, NULL
, NULL
, APR_HOOK_FIRST
);
1615 ap_hook_header_parser (waklog_phase2
, NULL
, NULL
, APR_HOOK_FIRST
);
1616 ap_hook_access_checker (waklog_phase3
, NULL
, NULL
, APR_HOOK_FIRST
);
1617 ap_hook_type_checker (waklog_phase6
, NULL
, NULL
, APR_HOOK_FIRST
);
1618 ap_hook_fixups (waklog_phase7
, NULL
, NULL
, APR_HOOK_FIRST
);
1619 ap_hook_log_transaction (waklog_phase9
, NULL
, NULL
, APR_HOOK_FIRST
);
1620 ap_hook_child_init (waklog_child_init
, NULL
, NULL
, APR_HOOK_FIRST
);
1621 ap_hook_post_read_request (waklog_phase0
, NULL
, NULL
, APR_HOOK_FIRST
);
1622 ap_hook_pre_connection (waklog_new_connection
, NULL
, NULL
, APR_HOOK_FIRST
);
1623 ap_hook_post_config (waklog_init_handler
, NULL
, NULL
, APR_HOOK_MIDDLE
);
1627 module AP_MODULE_DECLARE_DATA waklog_module
= {
1628 STANDARD20_MODULE_STUFF
,
1629 waklog_create_dir_config
, /* create per-dir conf structures */
1630 waklog_merge_dir_config
, /* merge per-dir conf structures */
1631 waklog_create_server_config
, /* create per-server conf structures */
1632 waklog_merge_dir_config
, /* merge per-server conf structures */
1633 waklog_cmds
, /* table of configuration directives */
1634 waklog_register_hooks
/* register hooks */