2 #include "http_config.h"
3 #include "http_protocol.h"
8 #include <sys/ioccom.h>
10 #include <kerberosIV/krb.h>
11 #include <kerberosIV/des.h>
12 #include <afs/venus.h>
14 #define KEYTAB_PATH "/usr/local/users/clunis/keytab.umweb.mysql"
15 #define PRINCIPAL "umweb/mysql"
16 #define IN_TKT_SERVICE "krbtgt/UMICH.EDU"
22 char HandShakeKey
[ 8 ];
36 waklog_create_dir_config( pool
*p
, char *path
)
38 waklog_host_config
*cfg
;
40 cfg
= (waklog_host_config
*)ap_pcalloc( p
, sizeof( waklog_host_config
));
49 waklog_create_server_config( pool
*p
, server_rec
*s
)
51 waklog_host_config
*cfg
;
53 cfg
= (waklog_host_config
*)ap_pcalloc( p
, sizeof( waklog_host_config
));
62 waklog_init( server_rec
*s
, pool
*p
)
66 ap_log_error( APLOG_MARK
, APLOG_INFO
|APLOG_NOERRNO
, s
,
67 "mod_waklog: version %s initialized.", version
);
73 set_waklog_protect( cmd_parms
*params
, void *mconfig
, int flag
)
75 waklog_host_config
*cfg
;
77 if ( params
->path
== NULL
) {
78 cfg
= (waklog_host_config
*) ap_get_module_config(
79 params
->server
->module_config
, &waklog_module
);
81 cfg
= (waklog_host_config
*)mconfig
;
91 set_waklog_use_keytab( cmd_parms
*params
, void *mconfig
, char *file
)
93 waklog_host_config
*cfg
;
95 if ( params
->path
== NULL
) {
96 cfg
= (waklog_host_config
*) ap_get_module_config(
97 params
->server
->module_config
, &waklog_module
);
99 cfg
= (waklog_host_config
*)mconfig
;
102 ap_log_error( APLOG_MARK
, APLOG_INFO
|APLOG_NOERRNO
, params
->server
,
103 "mod_waklog: using keytab: %s", file
);
112 waklog_child_init( server_rec
*s
, pool
*p
)
119 command_rec waklog_cmds
[ ] =
121 { "WaklogProtected", set_waklog_protect
,
122 NULL
, RSRC_CONF
| ACCESS_CONF
, FLAG
,
123 "enable waklog on a location or directory basis" },
125 { "WaklogUseKeytab", set_waklog_use_keytab
,
126 NULL
, RSRC_CONF
, TAKE1
,
127 "Use the supplied keytab file rather than the user's TGT" },
134 pioctl_cleanup( void *data
)
136 request_rec
*r
= (request_rec
*)data
;
144 if ( pioctl( 0, VIOCUNPAG
, &vi
, 0 ) < 0 ) {
145 ap_log_error( APLOG_MARK
, APLOG_ERR
, r
->server
,
146 "mod_waklog: unlog pioctl failed" );
149 ap_log_error( APLOG_MARK
, APLOG_DEBUG
, r
->server
,
150 "mod_waklog: unlog pioctl succeeded" );
156 waklog_ktinit( request_rec
*r
)
158 krb5_error_code kerror
;
159 krb5_context kcontext
;
160 krb5_principal kprinc
;
161 krb5_principal sprinc
;
162 krb5_get_init_creds_opt kopts
;
165 krb5_keytab keytab
= 0;
166 char ktbuf
[ MAX_KEYTAB_NAME_LEN
+ 1 ];
169 if (( kerror
= krb5_init_context( &kcontext
))) {
170 /* Authentication Required ( kerberos error ) */
171 ap_log_error( APLOG_MARK
, APLOG_ERR
, r
->server
,
172 (char *)error_message( kerror
));
177 if (( kerror
= krb5_parse_name( kcontext
, "PRINCIPAL", &kprinc
))) {
178 ap_log_error( APLOG_MARK
, APLOG_ERR
, r
->server
,
179 (char *)error_message( kerror
));
184 snprintf( krbpath
, sizeof( krbpath
), "/ticket/waklog" );
186 if (( kerror
= krb5_cc_resolve( kcontext
, krbpath
, &kccache
)) != 0 ) {
187 ap_log_error( APLOG_MARK
, APLOG_ERR
, r
->server
,
188 (char *)error_message( kerror
));
193 krb5_get_init_creds_opt_init( &kopts
);
194 krb5_get_init_creds_opt_set_tkt_life( &kopts
, 10*60*60 );
195 krb5_get_init_creds_opt_set_renew_life( &kopts
, 0 );
196 krb5_get_init_creds_opt_set_forwardable( &kopts
, 1 );
197 krb5_get_init_creds_opt_set_proxiable( &kopts
, 0 );
199 if ( KEYTAB_PATH
== '\0' ) {
200 if (( kerror
= krb5_kt_default_name(
201 kcontext
, ktbuf
, MAX_KEYTAB_NAME_LEN
)) != 0 ) {
202 ap_log_error( APLOG_MARK
, APLOG_ERR
, r
->server
,
203 (char *)error_message( kerror
));
208 if ( strlen( KEYTAB_PATH
) > MAX_KEYTAB_NAME_LEN
) {
209 ap_log_error( APLOG_MARK
, APLOG_ERR
, r
->server
,
210 "server configuration error" );
214 strcpy( ktbuf
, KEYTAB_PATH
);
217 if (( kerror
= krb5_kt_resolve( kcontext
, ktbuf
, &keytab
)) != 0 ) {
218 ap_log_error( APLOG_MARK
, APLOG_ERR
, r
->server
,
219 (char *)error_message( kerror
));
224 if (( kerror
= krb5_sname_to_principal( kcontext
, NULL
, "cosign",
225 KRB5_NT_SRV_HST
, &sprinc
)) != 0 ) {
226 ap_log_error( APLOG_MARK
, APLOG_ERR
, r
->server
,
227 (char *)error_message( kerror
));
232 if (( kerror
= krb5_get_init_creds_keytab( kcontext
, &kcreds
,
233 kprinc
, keytab
, NULL
, IN_TKT_SERVICE
, &kopts
))) {
235 ap_log_error( APLOG_MARK
, APLOG_ERR
, r
->server
,
236 (char *)error_message( kerror
));
242 (void)krb5_kt_close( kcontext
, keytab
);
243 krb5_free_principal( kcontext
, sprinc
);
245 if (( kerror
= krb5_cc_initialize( kcontext
, kccache
, kprinc
)) != 0 ) {
246 ap_log_error( APLOG_MARK
, APLOG_ERR
, r
->server
,
247 (char *)error_message( kerror
));
252 if (( kerror
= krb5_cc_store_cred( kcontext
, kccache
, &kcreds
)) != 0 ) {
253 ap_log_error( APLOG_MARK
, APLOG_ERR
, r
->server
,
254 (char *)error_message( kerror
));
259 krb5_free_cred_contents( kcontext
, &kcreds
);
260 krb5_free_principal( kcontext
, kprinc
);
261 krb5_cc_close( kcontext
, kccache
);
262 krb5_free_context( kcontext
);
269 waklog_get_tokens( request_rec
*r
)
273 struct ClearToken ct
;
275 char buf
[ 1024 ], *s
;
276 char *urealm
= "UMICH.EDU";
277 char *lrealm
= "umich.edu";
278 waklog_host_config
*cfg
;
280 /* directory config? */
281 cfg
= (waklog_host_config
*)ap_get_module_config(
282 r
->per_dir_config
, &waklog_module
);
285 if ( !cfg
->configured
) {
286 cfg
= (waklog_host_config
*)ap_get_module_config(
287 r
->server
->module_config
, &waklog_module
);
290 if ( cfg
->keytab
!= NULL
) {
291 ap_log_error( APLOG_MARK
, APLOG_NOERRNO
|APLOG_ERR
, r
->server
,
292 "mod_waklog: keytab is configured: %s", cfg
->keytab
);
294 /* authenticate using keytab file */
299 ap_log_error( APLOG_MARK
, APLOG_NOERRNO
|APLOG_ERR
, r
->server
,
300 "mod_waklog: keytab is not configured" );
303 if ( !cfg
->protect
) {
307 if (( rc
= krb_get_cred( "afs", "", urealm
, &cr
)) != KSUCCESS
) {
308 ap_log_error( APLOG_MARK
, APLOG_NOERRNO
|APLOG_ERR
, r
->server
,
309 "mod_waklog: krb_get_cred: %s", krb_err_txt
[ rc
] );
311 if (( rc
= get_ad_tkt( "afs", "", urealm
, 255 )) != KSUCCESS
) {
312 ap_log_error( APLOG_MARK
, APLOG_NOERRNO
|APLOG_DEBUG
, r
->server
,
313 "mod_waklog: get_ad_tkt: %s", krb_err_txt
[ rc
] );
315 /* fail here or just let AFS deny permission? */
320 if (( rc
= krb_get_cred( "afs", "", urealm
, &cr
)) != KSUCCESS
) {
321 ap_log_error( APLOG_MARK
, APLOG_NOERRNO
|APLOG_ERR
, r
->server
,
322 "mod_waklog: krb_get_cred: %s", krb_err_txt
[ rc
] );
327 ap_log_error( APLOG_MARK
, APLOG_NOERRNO
|APLOG_DEBUG
, r
->server
,
328 "mod_waklog: %s.%s@%s", cr
.service
, cr
.instance
, cr
.realm
);
329 ap_log_error( APLOG_MARK
, APLOG_NOERRNO
|APLOG_DEBUG
, r
->server
,
330 "mod_waklog: %d %d %d", cr
.lifetime
, cr
.kvno
, cr
.issue_date
);
331 ap_log_error( APLOG_MARK
, APLOG_NOERRNO
|APLOG_DEBUG
, r
->server
,
332 "mod_waklog: %s %s", cr
.pname
, cr
.pinst
);
333 ap_log_error( APLOG_MARK
, APLOG_NOERRNO
|APLOG_DEBUG
, r
->server
,
334 "mod_waklog: %d", cr
.ticket_st
.length
);
337 memmove( s
, &cr
.ticket_st
.length
, sizeof( int ));
339 memmove( s
, cr
.ticket_st
.dat
, cr
.ticket_st
.length
);
340 s
+= cr
.ticket_st
.length
;
342 ct
.AuthHandle
= cr
.kvno
;
343 memmove( ct
.HandShakeKey
, cr
.session
, sizeof( cr
.session
));
345 ct
.BeginTimestamp
= cr
.issue_date
;
346 ct
.EndTimestamp
= krb_life_to_time( cr
.issue_date
, cr
.lifetime
);
348 i
= sizeof( struct ClearToken
);
349 memmove( s
, &i
, sizeof( int ));
351 memmove( s
, &ct
, sizeof( struct ClearToken
));
352 s
+= sizeof( struct ClearToken
);
355 memmove( s
, &i
, sizeof( int ));
359 s
+= strlen( lrealm
) + 1;
362 vi
.in_size
= s
- buf
;
364 vi
.out_size
= sizeof( buf
);
366 if ( pioctl( 0, VIOCSETTOK
, &vi
, 0 ) < 0 ) {
367 ap_log_error( APLOG_MARK
, APLOG_ERR
, r
->server
,
368 "mod_waklog: pioctl failed" );
371 /* we'll need to unlog when this connection is done. */
372 ap_register_cleanup( r
->pool
, (void *)r
, pioctl_cleanup
, ap_null_cleanup
);
374 ap_log_error( APLOG_MARK
, APLOG_DEBUG
|APLOG_NOERRNO
, r
->server
,
375 "mod_waklog: finished with get_token" );
381 module MODULE_VAR_EXPORT waklog_module
= {
382 STANDARD_MODULE_STUFF
,
383 waklog_init
, /* module initializer */
384 waklog_create_dir_config
, /* create per-dir config structures */
385 NULL
, /* merge per-dir config structures */
386 waklog_create_server_config
, /* create per-server config structures */
387 NULL
, /* merge per-server config structures */
388 waklog_cmds
, /* table of config file commands */
389 NULL
, /* [#8] MIME-typed-dispatched handlers */
390 NULL
, /* [#1] URI to filename translation */
391 NULL
, /* [#4] validate user id from request */
392 NULL
, /* [#5] check if the user is ok _here_ */
393 NULL
, /* [#3] check access by host address */
394 NULL
, /* [#6] determine MIME type */
395 waklog_get_tokens
, /* [#7] pre-run fixups */
396 NULL
, /* [#9] log a transaction */
397 NULL
, /* [#2] header parser */
398 waklog_child_init
, /* child_init */
399 NULL
, /* child_exit */
400 NULL
/* [#0] post read-request */
402 ,NULL
, /* EAPI: add_module */
403 NULL
, /* EAPI: remove_module */
404 NULL
, /* EAPI: rewrite_command */
405 NULL
/* EAPI: new_connection */