#include "http_protocol.h"
#include "http_log.h"
#include "ap_config.h"
+#include <krb5.h>
#include <sys/ioccom.h>
#include <stropts.h>
#include <kerberosIV/des.h>
#include <afs/venus.h>
+#define KEYTAB_PATH "/usr/local/etc/kerbero/keytab.cosign"
+#define IN_TKT_SERVICE "krbtgt/UMICH.EDU"
+
module waklog_module;
struct ClearToken {
};
typedef struct {
- int configured;
- int protect;
+ int configured;
+ int protect;
+ char *keytab;
} waklog_host_config;
cfg = (waklog_host_config *)ap_pcalloc( p, sizeof( waklog_host_config ));
cfg->configured = 0;
cfg->protect = 0;
+ cfg->keytab = NULL;
return( cfg );
}
cfg = (waklog_host_config *)ap_pcalloc( p, sizeof( waklog_host_config ));
cfg->configured = 0;
cfg->protect = 0;
+ cfg->keytab = NULL;
return( cfg );
}
}
+ static const char *
+set_waklog_use_keytab( cmd_parms *params, void *mconfig, char *file )
+{
+ waklog_host_config *cfg;
+
+ if ( params->path == NULL ) {
+ cfg = (waklog_host_config *) ap_get_module_config(
+ params->server->module_config, &waklog_module );
+ } else {
+ cfg = (waklog_host_config *)mconfig;
+ }
+
+ cfg->keytab = file;
+ cfg->configured = 1;
+ return( NULL );
+}
+
+
static void
waklog_child_init( server_rec *s, pool *p )
{
NULL, RSRC_CONF | ACCESS_CONF, FLAG,
"enable waklog on a location or directory basis" },
+ { "WaklogUseKeytab", set_waklog_use_keytab,
+ NULL, RSRC_CONF, TAKE1,
+ "Use the supplied keytab file rather than the user's TGT" },
+
{ NULL }
};
}
+ static int
+waklog_ktinit( request_rec *r )
+{
+ krb5_error_code kerror;
+ krb5_context kcontext;
+ krb5_principal kprinc;
+ krb5_principal sprinc;
+ krb5_get_init_creds_opt kopts;
+ krb5_creds kcreds;
+ krb5_ccache kccache;
+ krb5_keytab keytab = 0;
+ char ktbuf[ MAX_KEYTAB_NAME_LEN + 1 ];
+ char krbpath [ 24 ];
+
+ if (( kerror = krb5_init_context( &kcontext ))) {
+ /* Authentication Required ( kerberos error ) */
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ (char *)error_message( kerror ));
+
+ return;
+ }
+
+ if (( kerror = krb5_parse_name( kcontext, r->connection->user,
+ &kprinc ))) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ (char *)error_message( kerror ));
+
+ return;
+ }
+
+ snprintf( krbpath, sizeof( krbpath ), "/ticket/waklog" );
+
+ if (( kerror = krb5_cc_resolve( kcontext, krbpath, &kccache )) != 0 ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ (char *)error_message( kerror ));
+
+ return;
+ }
+
+ krb5_get_init_creds_opt_init( &kopts );
+ krb5_get_init_creds_opt_set_tkt_life( &kopts, 10*60*60 );
+ krb5_get_init_creds_opt_set_renew_life( &kopts, 0 );
+ krb5_get_init_creds_opt_set_forwardable( &kopts, 1 );
+ krb5_get_init_creds_opt_set_proxiable( &kopts, 0 );
+
+ if ( KEYTAB_PATH == '\0' ) {
+ if (( kerror = krb5_kt_default_name(
+ kcontext, ktbuf, MAX_KEYTAB_NAME_LEN )) != 0 ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ (char *)error_message( kerror ));
+
+ return;
+ }
+ } else {
+ if ( strlen( KEYTAB_PATH ) > MAX_KEYTAB_NAME_LEN ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ "server configuration error" );
+
+ return;
+ }
+ strcpy( ktbuf, KEYTAB_PATH );
+ }
+
+ if (( kerror = krb5_kt_resolve( kcontext, ktbuf, &keytab )) != 0 ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ (char *)error_message( kerror ));
+
+ return;
+ }
+
+ if (( kerror = krb5_sname_to_principal( kcontext, NULL, "cosign",
+ KRB5_NT_SRV_HST, &sprinc )) != 0 ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ (char *)error_message( kerror ));
+
+ return;
+ }
+
+ if (( kerror = krb5_get_init_creds_keytab( kcontext, &kcreds,
+ kprinc, keytab, NULL, IN_TKT_SERVICE, &kopts ))) {
+
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ (char *)error_message( kerror ));
+
+ return;
+ }
+
+
+ (void)krb5_kt_close( kcontext, keytab );
+ krb5_free_principal( kcontext, sprinc );
+
+ if (( kerror = krb5_cc_initialize( kcontext, kccache, kprinc )) != 0 ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ (char *)error_message( kerror ));
+
+ return;
+ }
+
+ if (( kerror = krb5_cc_store_cred( kcontext, kccache, &kcreds )) != 0 ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ (char *)error_message( kerror ));
+
+ return;
+ }
+
+ krb5_free_cred_contents( kcontext, &kcreds );
+ krb5_free_principal( kcontext, kprinc );
+ krb5_cc_close( kcontext, kccache );
+ krb5_free_context( kcontext );
+}
+
+
static int
waklog_get_tokens( request_rec *r )
{
return( DECLINED );
}
+ if ( cfg->keytab ) {
+ ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
+ "mod_waklog: keytab is configured: %s", cfg->keytab );
+
+ /* check for afs token? */
+
+ /* authenticate using keytab file */
+
+ /* 524 */
+
+ /* get afs token */
+
+ return OK;
+ }
+
if (( rc = krb_get_cred( "afs", "", urealm, &cr )) != KSUCCESS ) {
ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
"mod_waklog: krb_get_cred: %s", krb_err_txt[ rc ] );
ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server,
"mod_waklog: get_ad_tkt: %s", krb_err_txt[ rc ] );
- /* user doesn't have tickets: use server's srvtab */
+ /* fail here or just let AFS deny permission? */
return OK;
}