X-Git-Url: http://git.hcoop.net/hcoop/zz_old/modwaklog.git/blobdiff_plain/42d78dfb8c27d7fc3f424edaaf437bf734db200f..bce7d4d9aa632d757285cc408933ed39f8301539:/mod_waklog.c diff --git a/mod_waklog.c b/mod_waklog.c index 6788b24..0a0fae5 100644 --- a/mod_waklog.c +++ b/mod_waklog.c @@ -24,8 +24,12 @@ #define MAXNAMELEN 1024 #endif +#ifdef STANDARD20_MODULE_STUFF +#define APACHE2 +#endif + /********************* APACHE1 ******************************************************************************/ -#ifndef STANDARD20_MODULE_STUFF +#ifndef APACHE2 #include "ap_config.h" #if defined(sun) #include @@ -38,18 +42,15 @@ { name, func, \ NULL , \ RSRC_CONF | ACCESS_CONF , type, usage } +module waklog_module; /********************* APACHE2 ******************************************************************************/ #else #include #include -//#include #define ap_pcalloc apr_pcalloc #define ap_pdupstr apr_pdupstr #define ap_pstrdup apr_pstrdup - -module AP_MODULE_DECLARE_DATA waklog_module; - #define MK_POOL apr_pool_t #define MK_TABLE_GET apr_table_get #define MK_TABLE_SET apr_table_set @@ -62,14 +63,11 @@ extern unixd_config_rec unixd_config; AP_INIT_ ## type (name, (void*) func, \ NULL, \ RSRC_CONF | ACCESS_CONF, usage) -typedef struct -{ - int dummy; -} -child_info; - +module AP_MODULE_DECLARE_DATA waklog_module; +typedef struct { int dummy; } child_info; const char *userdata_key = "waklog_init"; -#endif /* STANDARD20_MODULE_STUFF */ + +#endif /* APACHE2 */ /**************************************************************************************************/ #include @@ -92,12 +90,6 @@ const char *userdata_key = "waklog_init"; #define APLOG_DEBUG APLOG_ERR #endif -#ifndef CELL_IN_PRINCIPAL -int cell_in_principal = 1; -#else -int cell_in_principal = 0; -#endif - /* this is used to turn off pag generation for the backround worker child during startup */ int pag_for_children = 1; @@ -107,6 +99,8 @@ typedef struct int configured; int protect; int usertokens; + int cell_in_principal; + int disable_token_cache; char *keytab; char *principal; char *default_principal; @@ -164,7 +158,6 @@ struct renew_ent renewtable[SHARED_TABLE_SIZE]; int renewcount = 0; -module waklog_module; #define getModConfig(P, X) P = (waklog_config *) ap_get_module_config( (X)->module_config, &waklog_module ); @@ -181,15 +174,6 @@ module waklog_module; #include #include -#define KEYTAB "/etc/keytab.wwwserver" -#define PRINCIPAL "someplacewwwserver" -#define AFS_CELL "someplace.edu" - -/* If there's an error, retry more aggressively */ -#define ERR_SLEEP_TIME 5*60 - - -#define K5PATH "FILE:/tmp/waklog.creds.k5" static void log_error (const char *file, int line, int level, int status, @@ -202,7 +186,7 @@ log_error (const char *file, int line, int level, int status, vsnprintf (errstr, 1024, fmt, ap); va_end (ap); -#ifdef STANDARD20_MODULE_STUFF +#ifdef APACHE2 ap_log_error (file, line, level | APLOG_NOERRNO, status, s, "(%d) %s", getpid(), errstr); #else ap_log_error (file, line, level | APLOG_NOERRNO, s, "(%d) %s", getpid(), errstr); @@ -261,6 +245,8 @@ set_auth ( server_rec *s, request_rec *r, int self, char *principal, char *keyta int stored = -1; time_t mytime; int indentical; + int cell_in_principal; + int attempt; char k5user[MAXNAMELEN]; char *k5secret; @@ -295,7 +281,7 @@ set_auth ( server_rec *s, request_rec *r, int self, char *principal, char *keyta log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: cfg is %d", cfg ); } -#ifdef STANDARD20_MODULE_STUFF +#ifdef APACHE2 if ( self ) { /* pull out our principal name and stuff from the environment -- webauth better have sent through. This here is also where you'd suck stuff out of KRB5CCNAME if we were @@ -487,39 +473,49 @@ set_auth ( server_rec *s, request_rec *r, int self, char *principal, char *keyta /* now, to the 'aklog' portion of our program. */ strncpy( buf, "afs", sizeof(buf) - 1 ); - - if ( cfg->afs_cell && strcmp( cfg->afs_cell, AFS_CELL ) ) { - strncat(buf, "/", sizeof(buf) - strlen(buf) - 1); - strncat(buf, cfg->afs_cell, sizeof(buf) - strlen(buf) - 1); - } else if ( cell_in_principal ) { - strncat(buf, "/", sizeof(buf) - strlen(buf) - 1); - strncat(buf, AFS_CELL, sizeof(buf) - strlen(buf) - 1); - } - log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: using AFS principal: %s", buf); - - if ((kerror = krb5_parse_name (child.kcontext, buf, &increds.server))) { - log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_parse name %s", error_message(kerror)); - goto cleanup; - } - - if ((kerror = krb5_cc_get_principal(child.kcontext, child.ccache, &increds.client))) { - log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_cc_get_princ %s", error_message(kerror)); - goto cleanup; - } - - log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: retrieved data from ccache for %s", k5user); - - increds.times.endtime = 0; - - increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; - - if (kerror = krb5_get_credentials (child.kcontext, 0, child.ccache, &increds, &v5credsp )) { - log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_get_credentials: %s", - error_message(kerror)); - goto cleanup; + /** we make two attempts here, one for afs@REALM and one for afs/cell@REALM */ + for(attempt = 0; attempt <= 1; attempt++) { + cell_in_principal = (cfg->cell_in_principal + attempt) % 2; + + log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: cell_in_principal=%d", cell_in_principal ); + if (cell_in_principal) { + strncat(buf, "/", sizeof(buf) - strlen(buf) - 1); + strncat(buf, cfg->afs_cell, sizeof(buf) - strlen(buf) - 1); + } + + log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: using AFS principal: %s", buf); + + if ((kerror = krb5_parse_name (child.kcontext, buf, &increds.server))) { + log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_parse name %s", error_message(kerror)); + goto cleanup; + } + + if ((kerror = krb5_cc_get_principal(child.kcontext, child.ccache, &increds.client))) { + log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_cc_get_princ %s", error_message(kerror)); + goto cleanup; + } + + log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: retrieved data from ccache for %s", k5user); + + increds.times.endtime = 0; + + increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; + + if (kerror = krb5_get_credentials (child.kcontext, 0, child.ccache, &increds, &v5credsp )) { + /* only complain once we've tried both afs@REALM and afs/cell@REALM */ + if (attempt>=1) { + log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: krb5_get_credentials: %s", + error_message(kerror)); + goto cleanup; + } else { + continue; + } + } + cfg->cell_in_principal = cell_in_principal; + break; } - + log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: get_credentials passed for %s", k5user); if ( v5credsp->ticket.length >= MAXKTCTICKETLEN ) { @@ -561,11 +557,7 @@ set_auth ( server_rec *s, request_rec *r, int self, char *principal, char *keyta strncpy(client.cell, buf, sizeof(client.cell)); /* assemble the server's cell */ - if ( cfg->afs_cell ) { - strncpy(server.cell, cfg->afs_cell, sizeof(server.cell) - 1); - } else { - strncpy(server.cell, AFS_CELL, sizeof(server.cell) - 1); - } + strncpy(server.cell, cfg->afs_cell, sizeof(server.cell) - 1); log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: preparing to init PTS connection for %s", server.cell); @@ -717,6 +709,7 @@ waklog_create_server_config (MK_POOL * p, server_rec * s) cfg->path = "(server)"; cfg->protect = WAKLOG_UNSET; cfg->usertokens = WAKLOG_UNSET; + cfg->disable_token_cache = WAKLOG_UNSET; cfg->keytab = WAKLOG_UNSET; cfg->principal = WAKLOG_UNSET; cfg->default_principal = WAKLOG_UNSET; @@ -744,6 +737,7 @@ waklog_create_dir_config (MK_POOL * p, char *dir) cfg->path = ap_pstrdup(p, dir ); cfg->protect = WAKLOG_UNSET; cfg->usertokens = WAKLOG_UNSET; + cfg->disable_token_cache = WAKLOG_UNSET; cfg->keytab = WAKLOG_UNSET; cfg->principal = WAKLOG_UNSET; cfg->default_principal = WAKLOG_UNSET; @@ -766,6 +760,8 @@ static void *waklog_merge_dir_config(MK_POOL *p, void *parent_conf, void *newloc merged->path = child->path != WAKLOG_UNSET ? child->path : parent->path; merged->usertokens = child->usertokens != WAKLOG_UNSET ? child->usertokens : parent->usertokens; + + merged->disable_token_cache = child->disable_token_cache != WAKLOG_UNSET ? child->disable_token_cache : parent->disable_token_cache; merged->principal = child->principal != WAKLOG_UNSET ? child->principal : parent->principal; @@ -791,6 +787,8 @@ static void *waklog_merge_server_config(MK_POOL *p, void *parent_conf, void *new merged->usertokens = nconf->usertokens == WAKLOG_UNSET ? pconf->usertokens : nconf->usertokens; + merged->disable_token_cache = nconf->disable_token_cache == WAKLOG_UNSET ? pconf->disable_token_cache : nconf->disable_token_cache; + merged->keytab = nconf->keytab == WAKLOG_UNSET ? ap_pstrdup(p, pconf->keytab) : ( nconf->keytab == WAKLOG_UNSET ? WAKLOG_UNSET : ap_pstrdup(p, pconf->keytab) ); @@ -812,7 +810,7 @@ static void *waklog_merge_server_config(MK_POOL *p, void *parent_conf, void *new } static const char * -set_waklog_protect (cmd_parms * params, void *mconfig, int flag) +set_waklog_enabled (cmd_parms * params, void *mconfig, int flag) { waklog_config *cfg = mconfig ? ( waklog_config * ) mconfig : ( waklog_config * ) ap_get_module_config(params->server->module_config, &waklog_module ); @@ -820,7 +818,7 @@ set_waklog_protect (cmd_parms * params, void *mconfig, int flag) cfg->protect = flag; cfg->configured = 1; log_error (APLOG_MARK, APLOG_DEBUG, 0, params->server, - "mod_waklog: waklog_protect set on %s", cfg->path ? cfg->path : "NULL"); + "mod_waklog: waklog_enabled set on %s", cfg->path ? cfg->path : "NULL"); return (NULL); } @@ -854,7 +852,7 @@ void add_to_renewtable(MK_POOL *p, char *keytab, char *principal) { } static const char * -set_waklog_principal (cmd_parms *params, void *mconfig, char *principal, char *keytab) +set_waklog_location_principal (cmd_parms *params, void *mconfig, char *principal, char *keytab) { waklog_config *cfg = mconfig ? ( waklog_config * ) mconfig : ( waklog_config * ) ap_get_module_config(params->server->module_config, &waklog_module ); @@ -873,16 +871,24 @@ set_waklog_principal (cmd_parms *params, void *mconfig, char *principal, char *k } static const char * -set_waklog_use_afs_cell (cmd_parms * params, void *mconfig, char *file) +set_waklog_afs_cell (cmd_parms * params, void *mconfig, char *file) { - waklog_config *cfg = mconfig ? ( waklog_config * ) mconfig : + waklog_config *waklog_mconfig = ( waklog_config * ) mconfig; + waklog_config *waklog_srvconfig = ( waklog_config * ) ap_get_module_config(params->server->module_config, &waklog_module ); - log_error (APLOG_MARK, APLOG_DEBUG, 0, params->server, + log_error (APLOG_MARK, APLOG_INFO, 0, params->server, "mod_waklog: will use afs_cell: %s", file); - cfg->afs_cell = ap_pstrdup (params->pool, file); - cfg->configured = 1; + waklog_srvconfig->cell_in_principal = 0; + waklog_srvconfig->afs_cell = ap_pstrdup (params->pool, file); + waklog_srvconfig->configured = 1; + + if (waklog_mconfig != NULL) { + waklog_mconfig->cell_in_principal = waklog_srvconfig->cell_in_principal; + waklog_mconfig->afs_cell = ap_pstrdup (params->pool, file); + waklog_mconfig->configured = 1; + } return (NULL); } @@ -932,7 +938,23 @@ set_waklog_use_usertokens (cmd_parms * params, void *mconfig, int flag) } -#ifndef STANDARD20_MODULE_STUFF +static const char * +set_waklog_disable_token_cache (cmd_parms * params, void *mconfig, int flag) +{ + waklog_config *cfg = mconfig ? ( waklog_config * ) mconfig : + ( waklog_config * ) ap_get_module_config(params->server->module_config, &waklog_module ); + + cfg->disable_token_cache = flag; + + cfg->configured = 1; + + log_error (APLOG_MARK, APLOG_DEBUG, 0, params->server, + "mod_waklog: waklog_disable_token_cache set"); + return (NULL); +} + + +#ifndef APACHE2 static void waklog_child_exit( server_rec *s, MK_POOL *p ) { #else apr_status_t waklog_child_exit( void *sr ) { @@ -955,14 +977,14 @@ apr_status_t waklog_child_exit( void *sr ) { log_error (APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: waklog_child_exit complete"); -#ifdef STANDARD20_MODULE_STUFF +#ifdef APACHE2 return APR_SUCCESS; #endif } static void -#ifdef STANDARD20_MODULE_STUFF +#ifdef APACHE2 waklog_child_init (MK_POOL * p, server_rec * s) #else waklog_child_init (server_rec * s, MK_POOL * p) @@ -974,8 +996,6 @@ waklog_child_init (server_rec * s, MK_POOL * p) char *cell; - cell = strdup(AFS_CELL); - log_error (APLOG_MARK, APLOG_DEBUG, 0, s, "mod_waklog: child_init called for pid %d", getpid()); if ( !sharedspace ) { @@ -1006,9 +1026,10 @@ waklog_child_init (server_rec * s, MK_POOL * p) set_auth( s, NULL, 0, cfg->default_principal, cfg->default_keytab, 0); } + cell = strdup(cfg->afs_cell); pr_Initialize( 0, AFSDIR_CLIENT_ETC_DIR, cell ); -#ifdef STANDARD20_MODULE_STUFF +#ifdef APACHE2 apr_pool_cleanup_register(p, s, waklog_child_exit, apr_pool_cleanup_null); #endif @@ -1020,21 +1041,24 @@ waklog_child_init (server_rec * s, MK_POOL * p) command_rec waklog_cmds[] = { - command ("WaklogProtected", set_waklog_protect, 0, FLAG, - "enable waklog on a location or directory basis"), + command ("WaklogAFSCell", set_waklog_afs_cell, 0, TAKE1, + "Use the supplied AFS cell (required)"), - command ("WaklogPrincipal", set_waklog_principal, 0, TAKE2, - "Use the supplied keytab rather than the default"), + command ("WaklogEnabled", set_waklog_enabled, 0, FLAG, + "enable waklog on a server, location, or directory basis"), - command ("WaklogUseAFSCell", set_waklog_use_afs_cell, 0, TAKE1, - "Use the supplied AFS cell rather than the default"), + command ("WaklogDefaultPrincipal", set_waklog_default_principal, 0, TAKE2, + "Set the default principal that the server runs as"), - command ("WaklogUseUserTokens", set_waklog_use_usertokens, 0, FLAG, - "Use the requesting user tokens (from webauth)"), + command ("WaklogLocationPrincipal", set_waklog_location_principal, 0, TAKE2, + "Set the principal on a -specific basis"), - command ("WaklogDefaultPrincipal", set_waklog_default_principal, 0, TAKE2, - "Set the default principal that the server runs as"), - + command ("WaklogDisableTokenCache", set_waklog_disable_token_cache, 0, FLAG, + "Ignore the token cache (location-specific); useful for scripts that need kerberos tickets."), + + command ("WaklogUseUserTokens", set_waklog_use_usertokens, 0, FLAG, + "Use the requesting user tokens (from webauth)"), + {NULL} }; @@ -1086,7 +1110,7 @@ waklog_child_routine (void *data, child_info * pinfo) } /* need to do this so we can make PTS calls */ - cell = strdup(AFS_CELL); /* stupid */ + cell = strdup(cfg->afs_cell); /* stupid */ pr_Initialize( 0, AFSDIR_CLIENT_ETC_DIR, cell ); while(1) { @@ -1126,7 +1150,7 @@ waklog_child_routine (void *data, child_info * pinfo) } -#ifdef STANDARD20_MODULE_STUFF +#ifdef APACHE2 static int waklog_init_handler (apr_pool_t * p, apr_pool_t * plog, apr_pool_t * ptemp, server_rec * s) @@ -1153,6 +1177,14 @@ waklog_init_handler (apr_pool_t * p, apr_pool_t * plog, * see http://issues.apache.org/bugzilla/show_bug.cgi?id=37519 */ apr_pool_userdata_get (&data, userdata_key, s->process->pool); + + if (cfg->afs_cell==NULL) { + log_error (APLOG_MARK, APLOG_ERR, 0, s, + "mod_waklog: afs_cell==NULL; please provide the WaklogAFSCell directive"); + /** clobber apache */ + exit(-1); + } + if (!data) { apr_pool_userdata_set ((const void *) 1, userdata_key, @@ -1161,7 +1193,7 @@ waklog_init_handler (apr_pool_t * p, apr_pool_t * plog, else { log_error (APLOG_MARK, APLOG_INFO, 0, s, - "mod_waklog: version %s initialized.", version); + "mod_waklog: version %s initialized for cell %s", version, cfg->afs_cell); if ( sharedspace ) { log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_waklog: shared memory already allocated." ); @@ -1512,13 +1544,13 @@ waklog_phase9 (request_rec * r) static -#ifdef STANDARD20_MODULE_STUFF +#ifdef APACHE2 int #else void #endif waklog_new_connection (conn_rec * c -#ifdef STANDARD20_MODULE_STUFF +#ifdef APACHE2 , void *dummy #endif ) @@ -1539,7 +1571,7 @@ waklog_new_connection (conn_rec * c return -#ifdef STANDARD20_MODULE_STUFF +#ifdef APACHE2 0 #endif ; @@ -1579,32 +1611,32 @@ waklog_phase2 (request_rec * r) return DECLINED; } -#ifndef STANDARD20_MODULE_STUFF +#ifndef APACHE2 module MODULE_VAR_EXPORT waklog_module = { STANDARD_MODULE_STUFF, - waklog_init, /* module initializer */ + waklog_init, /* module initializer */ waklog_create_dir_config, /* create per-dir config structures */ - waklog_merge_dir_config, /* merge per-dir config structures */ - waklog_create_server_config, /* create per-server config structures */ - waklog_merge_dir_config, /* merge per-server config structures */ - waklog_cmds, /* table of config file commands */ - NULL, /* [#8] MIME-typed-dispatched handlers */ - waklog_phase1, /* [#1] URI to filename translation */ - NULL, /* [#4] validate user id from request */ - NULL, /* [#5] check if the user is ok _here_ */ - waklog_phase3, /* [#3] check access by host address */ - waklog_phase6, /* [#6] determine MIME type */ - waklog_phase7, /* [#7] pre-run fixups */ - waklog_phase9, /* [#9] log a transaction */ - NULL, /* [#2] header parser */ - waklog_child_init, /* child_init */ - waklog_child_exit, /* child_exit */ - waklog_phase0 /* [#0] post read-request */ + waklog_merge_dir_config, /* merge per-dir config structures */ + waklog_create_server_config, /* create per-server config structures */ + waklog_merge_dir_config, /* merge per-server config structures */ + waklog_cmds, /* table of config file commands */ + NULL, /* [#8] MIME-typed-dispatched handlers */ + waklog_phase1, /* [#1] URI to filename translation */ + NULL, /* [#4] validate user id from request */ + NULL, /* [#5] check if the user is ok _here_ */ + waklog_phase3, /* [#3] check access by host address */ + waklog_phase6, /* [#6] determine MIME type */ + waklog_phase7, /* [#7] pre-run fixups */ + waklog_phase9, /* [#9] log a transaction */ + NULL, /* [#2] header parser */ + waklog_child_init, /* child_init */ + waklog_child_exit, /* child_exit */ + waklog_phase0 /* [#0] post read-request */ #ifdef EAPI - , NULL, /* EAPI: add_module */ - NULL, /* EAPI: remove_module */ - NULL, /* EAPI: rewrite_command */ - waklog_new_connection /* EAPI: new_connection */ + , NULL, /* EAPI: add_module */ + NULL, /* EAPI: remove_module */ + NULL, /* EAPI: rewrite_command */ + waklog_new_connection /* EAPI: new_connection */ #endif }; #else