X-Git-Url: https://git.hcoop.net/hcoop/debian/libapache-mod-waklog.git/blobdiff_plain/e21f34f04cb952253473f450a7e3fdaeb9eb75e8..403921efdf7e0bf0f79576a5d0c17219dcb42ef4:/mod_waklog.c diff --git a/mod_waklog.c b/mod_waklog.c index 81606e5..1d65fbf 100644 --- a/mod_waklog.c +++ b/mod_waklog.c @@ -23,8 +23,6 @@ #define KEYTAB_PATH "/home/drh/keytab.umweb.drhtest" #define PRINCIPAL "umweb/drhtest" -#define AFS "afs" -#define IN_TKT_SERVICE "krbtgt/UMICH.EDU" #define K5PATH "FILE:/tmp/waklog.creds.k5" #define K4PATH "/tmp/waklog.creds.k4" @@ -44,7 +42,7 @@ typedef struct { int protect; char *keytab; char *keytab_principal; - char *afs_instance; + char *afs_cell; } waklog_host_config; typedef struct { @@ -63,7 +61,7 @@ waklog_create_dir_config( pool *p, char *path ) cfg->protect = 0; cfg->keytab = 0; cfg->keytab_principal = 0; - cfg->afs_instance = 0; + cfg->afs_cell = "umich.edu"; return( cfg ); } @@ -79,7 +77,7 @@ waklog_create_server_config( pool *p, server_rec *s ) cfg->protect = 0; cfg->keytab = 0; cfg->keytab_principal = 0; - cfg->afs_instance = 0; + cfg->afs_cell = "umich.edu"; return( cfg ); } @@ -155,7 +153,7 @@ command_rec waklog_cmds[ ] = static void -pioctl_cleanup( void *data ) +token_cleanup( void *data ) { request_rec *r = (request_rec *)data; @@ -172,28 +170,27 @@ pioctl_cleanup( void *data ) static int -waklog_ktinit( server_rec *s ) +waklog_kinit( server_rec *s ) { krb5_error_code kerror; - krb5_context kcontext; - krb5_principal kprinc; + krb5_context kcontext = NULL; + krb5_principal kprinc = NULL; krb5_get_init_creds_opt kopts; krb5_creds v5creds; CREDENTIALS v4creds; - krb5_ccache kccache; - krb5_keytab keytab = 0; + krb5_ccache kccache = NULL; + krb5_keytab keytab = NULL; char ktbuf[ MAX_KEYTAB_NAME_LEN + 1 ]; - krb5_timestamp now; waklog_host_config *cfg; ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, s, - "mod_waklog: waklog_ktinit called" ); + "mod_waklog: waklog_kinit called" ); if (( kerror = krb5_init_context( &kcontext ))) { ap_log_error( APLOG_MARK, APLOG_ERR, s, (char *)error_message( kerror )); - goto cleanup1; + goto cleanup; } /* use the path */ @@ -201,14 +198,14 @@ waklog_ktinit( server_rec *s ) ap_log_error( APLOG_MARK, APLOG_ERR, s, (char *)error_message( kerror )); - goto cleanup2; + goto cleanup; } if (( kerror = krb5_parse_name( kcontext, PRINCIPAL, &kprinc ))) { ap_log_error( APLOG_MARK, APLOG_ERR, s, (char *)error_message( kerror )); - goto cleanup3; + goto cleanup; } krb5_get_init_creds_opt_init( &kopts ); @@ -221,33 +218,26 @@ waklog_ktinit( server_rec *s ) &waklog_module ); /* which keytab should we use? */ - strcpy( ktbuf, cfg->keytab ? cfg->keytab : KEYTAB_PATH ); - - if ( strlen( ktbuf ) > MAX_KEYTAB_NAME_LEN ) { - ap_log_error( APLOG_MARK, APLOG_ERR, s, - "server configuration error" ); - - goto cleanup4; - } + strncpy( ktbuf, cfg->keytab ? cfg->keytab : KEYTAB_PATH, sizeof( ktbuf ) - 1 ); ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, s, - "mod_waklog: waklog_ktinit using: %s", ktbuf ); + "mod_waklog: waklog_kinit using: %s", ktbuf ); if (( kerror = krb5_kt_resolve( kcontext, ktbuf, &keytab )) != 0 ) { ap_log_error( APLOG_MARK, APLOG_ERR, s, (char *)error_message( kerror )); - goto cleanup4; + goto cleanup; } /* get the krbtgt */ if (( kerror = krb5_get_init_creds_keytab( kcontext, &v5creds, - kprinc, keytab, 0, IN_TKT_SERVICE, &kopts ))) { + kprinc, keytab, 0, NULL, &kopts ))) { ap_log_error( APLOG_MARK, APLOG_ERR, s, (char *)error_message( kerror )); - goto cleanup5; + goto cleanup; } if (( kerror = krb5_verify_init_creds( kcontext, &v5creds, @@ -256,82 +246,40 @@ waklog_ktinit( server_rec *s ) ap_log_error( APLOG_MARK, APLOG_ERR, s, (char *)error_message( kerror )); - goto cleanup6; + goto cleanup; } if (( kerror = krb5_cc_initialize( kcontext, kccache, kprinc )) != 0 ) { ap_log_error( APLOG_MARK, APLOG_ERR, s, (char *)error_message( kerror )); - goto cleanup6; + goto cleanup; } - if (( kerror = krb5_cc_store_cred( kcontext, kccache, &v5creds )) != 0 ) { + kerror = krb5_cc_store_cred( kcontext, kccache, &v5creds ); + krb5_free_cred_contents( kcontext, &v5creds ); + if ( kerror != 0 ) { ap_log_error( APLOG_MARK, APLOG_ERR, s, (char *)error_message( kerror )); - goto cleanup6; - } - -#if 0 - /* convert K5 => K4 */ - ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, s, - "mod_waklog: before krb524_convert_creds" ); - - if (( kerror = krb524_convert_creds_kdc( kcontext, - &v5creds, &v4creds )) != 0 ) { - - ap_log_error( APLOG_MARK, APLOG_ERR, s, - (char *)error_message( kerror )); - - goto cleanup6; - } - - /* use the path */ - krb_set_tkt_string( (char *)K4PATH ); - - /* initialize ticket cache */ - ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, s, - "mod_waklog: before in_tkt" ); - - if (( kerror = in_tkt( v4creds.pname, v4creds.pinst )) != KSUCCESS ) { - ap_log_error( APLOG_MARK, APLOG_ERR, s, - (char *)error_message( kerror )); - - goto cleanup6; - } - - /* stash, ticket, session key, etc for future use */ - ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, s, - "mod_waklog: before krb_save_credentials" ); - - if (( kerror = krb_save_credentials( v4creds.service, - v4creds.instance, v4creds.realm, v4creds.session, - v4creds.lifetime, v4creds.kvno, &(v4creds.ticket_st), - v4creds.issue_date )) != 0 ) { - - ap_log_error( APLOG_MARK, APLOG_ERR, s, - (char *)error_message( kerror )); - - goto cleanup6; + goto cleanup; } -#endif /* 0 */ ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, s, - "mod_waklog: waklog_ktinit success" ); - -cleanup6: if ( v5creds.client == kprinc ) { - v5creds.client = 0; - } - krb5_free_cred_contents( kcontext, &v5creds ); -cleanup5: (void)krb5_kt_close( kcontext, keytab ); -cleanup4: krb5_free_principal( kcontext, kprinc ); -cleanup3: krb5_cc_close( kcontext, kccache ); -cleanup2: krb5_free_context( kcontext ); -cleanup1: + "mod_waklog: waklog_kinit success" ); + +cleanup: + if ( keytab ) + (void)krb5_kt_close( kcontext, keytab ); + if ( kprinc ) + krb5_free_principal( kcontext, kprinc ); + if ( kccache ) + krb5_cc_close( kcontext, kccache ); + if ( kcontext ) + krb5_free_context( kcontext ); ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, s, - "mod_waklog: waklog_ktinit: exiting" ); + "mod_waklog: waklog_kinit: exiting" ); return( 0 ); } @@ -345,14 +293,15 @@ waklog_aklog( request_rec *r ) const char *k4path = NULL; const char *k5path = NULL; krb5_error_code kerror; - krb5_context kcontext; + krb5_context kcontext = NULL; krb5_creds increds; krb5_creds *v5credsp = NULL; CREDENTIALS v4creds; - krb5_ccache kccache; - struct ktc_principal server = { "afs", "", "umich.edu" }; + krb5_ccache kccache = NULL; + struct ktc_principal server = { "afs", "", "" }; struct ktc_principal client; struct ktc_token token; + waklog_host_config *cfg; k5path = ap_table_get( r->subprocess_env, "KRB5CCNAME" ); k4path = ap_table_get( r->subprocess_env, "KRBTKFILE" ); @@ -363,7 +312,7 @@ waklog_aklog( request_rec *r ) if ( !k5path || !k4path ) { ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server, "mod_waklog: waklog_aklog giving up" ); - return; + goto cleanup; } /* @@ -375,24 +324,36 @@ waklog_aklog( request_rec *r ) ap_log_error( APLOG_MARK, APLOG_ERR, r->server, (char *)error_message( kerror )); - return; + goto cleanup; } + krb524_init_ets(kcontext); + memset( (char *)&increds, 0, sizeof(increds)); + cfg = (waklog_host_config *) ap_get_module_config( + r->server->module_config, &waklog_module ); + + /* afs/ or afs */ + strncpy( buf, "afs", sizeof( buf ) - 1 ); + if ( strcmp( cfg->afs_cell, "umich.edu" ) ) { + strncat( buf, "/" , sizeof( buf ) - strlen( buf ) - 1 ); + strncat( buf, cfg->afs_cell, sizeof( buf ) - strlen( buf ) - 1 ); + } + /* set server part */ - if (( kerror = krb5_parse_name( kcontext, AFS, &increds.server ))) { + if (( kerror = krb5_parse_name( kcontext, buf, &increds.server ))) { ap_log_error( APLOG_MARK, APLOG_ERR, r->server, (char *)error_message( kerror )); - return; + goto cleanup; } if (( kerror = krb5_cc_resolve( kcontext, k5path, &kccache )) != 0 ) { ap_log_error( APLOG_MARK, APLOG_ERR, r->server, (char *)error_message( kerror )); - return; + goto cleanup; } /* set client part */ @@ -405,16 +366,16 @@ waklog_aklog( request_rec *r ) /* get the V5 credentials */ if (( kerror = krb5_get_credentials( kcontext, 0, kccache, &increds, &v5credsp ) ) ) { - ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server, - "mod_waklog: krb5_get_credentials: %s", krb_err_txt[ kerror ] ); - return; + ap_log_error( APLOG_MARK, APLOG_ERR, r->server, + "mod_waklog: krb5_get_credentials: %s", error_message( kerror )); + goto cleanup; } /* get the V4 credentials */ if (( kerror = krb524_convert_creds_kdc( kcontext, v5credsp, &v4creds ) ) ) { - ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server, - "mod_waklog: krb524_convert_creds_kdc: %s", krb_err_txt[ kerror ] ); - return; + ap_log_error( APLOG_MARK, APLOG_ERR, r->server, + "mod_waklog: krb524_convert_creds_kdc: %s", error_message( kerror )); + goto cleanup; } /* assemble the token */ @@ -444,16 +405,18 @@ waklog_aklog( request_rec *r ) "mod_waklog: %d", v4creds.ticket_st.length ); /* build the name */ - strcpy( buf, v4creds.pname ); + strncpy( buf, v4creds.pname, sizeof( buf ) - 1 ); if ( v4creds.pinst[ 0 ] ) { - strcat( buf, "." ); - strcat( buf, v4creds.pinst ); + strncat( buf, ".", sizeof( buf ) - strlen( buf ) - 1 ); + strncat( buf, v4creds.pinst, sizeof( buf ) - strlen( buf ) - 1 ); } /* assemble the client */ - strncpy( client.name, buf, MAXKTCNAMELEN - 1 ); - strcpy( client.instance, "" ); - strncpy( client.cell, v4creds.realm, MAXKTCNAMELEN - 1 ); + strncpy( client.name, buf, sizeof( client.name ) - 1 ); + strncpy( client.instance, "", sizeof( client.instance) - 1 ); + strncpy( client.cell, v4creds.realm, sizeof( client.cell ) - 1 ); + + strncpy( server.cell, cfg->afs_cell , sizeof( server.cell ) - 1 ); ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server, "mod_waklog: server: name=%s, instance=%s, cell=%s", @@ -478,27 +441,33 @@ waklog_aklog( request_rec *r ) memmove( &child->token, &token, sizeof( struct ktc_token ) ); /* we'll need to unlog when this connection is done. */ - ap_register_cleanup( r->pool, (void *)r, pioctl_cleanup, ap_null_cleanup ); + ap_register_cleanup( r->pool, (void *)r, token_cleanup, ap_null_cleanup ); } - krb5_free_cred_contents( kcontext, v5credsp ); - krb5_free_principal( kcontext, increds.client ); - krb5_cc_close( kcontext, kccache ); - krb5_free_context( kcontext ); +cleanup: + if ( v5credsp ) + krb5_free_cred_contents( kcontext, v5credsp ); + if ( increds.client ) + krb5_free_principal( kcontext, increds.client ); + if ( increds.server ) + krb5_free_principal( kcontext, increds.server ); + if ( kccache ) + krb5_cc_close( kcontext, kccache ); + if ( kcontext ) + krb5_free_context( kcontext ); ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server, "mod_waklog: finished with waklog_aklog" ); + return; + } static int waklog_child_routine( void *s, child_info *pinfo ) { - ap_log_error( APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, s, - "mod_waklog: waklog_child_routine called" ); - if ( !getuid() ) { - ap_log_error( APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, s, + ap_log_error( APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, s, "mod_waklog: waklog_child_routine called as root" ); /* this was causing the credential file to get owned by root */ @@ -507,8 +476,8 @@ waklog_child_routine( void *s, child_info *pinfo ) } while( 1 ) { - waklog_ktinit( s ); - sleep( 60 /* 10*60*60 - 5*60 */ ); + waklog_kinit( s ); + sleep( 300 /* 10*60*60 - 5*60 */ ); } } @@ -526,7 +495,7 @@ waklog_init( server_rec *s, pool *p ) pid = ap_bspawn_child( p, waklog_child_routine, s, kill_always, NULL, NULL, NULL ); - ap_log_error( APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, s, + ap_log_error( APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, s, "mod_waklog: ap_bspawn_child: %d.", pid ); }