--- /dev/null
+/*
+ * Ticket lifetime. This defines the table used to lookup lifetime
+ * for the fixed part of rande of the one byte lifetime field. Values
+ * less than 0x80 are intrpreted as the number of 5 minute intervals.
+ * Values from 0x80 to 0xBF should be looked up in this table. The
+ * value of 0x80 is the same using both methods: 10 and two-thirds
+ * hours . The lifetime of 0xBF is 30 days. The intervening values
+ * of have a fixed ratio of roughly 1.06914. The value 0xFF is
+ * defined to mean a ticket has no expiration time. This should be
+ * used advisedly since individual servers may impose defacto
+ * upperbounds on ticket lifetimes.
+ */
+
+#define TKTLIFENUMFIXED 64
+#define TKTLIFEMINFIXED 0x80
+#define TKTLIFEMAXFIXED 0xBF
+#define TKTLIFENOEXPIRE 0xFF
+#define MAXTKTLIFETIME (30*24*3600) /* 30 days */
+#ifndef NEVERDATE
+#define NEVERDATE ((unsigned long)-1L)
+#endif
+
+static int tkt_lifetimes[TKTLIFENUMFIXED] = {
+ 38400, /* 10.67 hours, 0.44 days */
+ 41055, /* 11.40 hours, 0.48 days */
+ 43894, /* 12.19 hours, 0.51 days */
+ 46929, /* 13.04 hours, 0.54 days */
+ 50174, /* 13.94 hours, 0.58 days */
+ 53643, /* 14.90 hours, 0.62 days */
+ 57352, /* 15.93 hours, 0.66 days */
+ 61318, /* 17.03 hours, 0.71 days */
+ 65558, /* 18.21 hours, 0.76 days */
+ 70091, /* 19.47 hours, 0.81 days */
+ 74937, /* 20.82 hours, 0.87 days */
+ 80119, /* 22.26 hours, 0.93 days */
+ 85658, /* 23.79 hours, 0.99 days */
+ 91581, /* 25.44 hours, 1.06 days */
+ 97914, /* 27.20 hours, 1.13 days */
+ 104684, /* 29.08 hours, 1.21 days */
+ 111922, /* 31.09 hours, 1.30 days */
+ 119661, /* 33.24 hours, 1.38 days */
+ 127935, /* 35.54 hours, 1.48 days */
+ 136781, /* 37.99 hours, 1.58 days */
+ 146239, /* 40.62 hours, 1.69 days */
+ 156350, /* 43.43 hours, 1.81 days */
+ 167161, /* 46.43 hours, 1.93 days */
+ 178720, /* 49.64 hours, 2.07 days */
+ 191077, /* 53.08 hours, 2.21 days */
+ 204289, /* 56.75 hours, 2.36 days */
+ 218415, /* 60.67 hours, 2.53 days */
+ 233517, /* 64.87 hours, 2.70 days */
+ 249664, /* 69.35 hours, 2.89 days */
+ 266926, /* 74.15 hours, 3.09 days */
+ 285383, /* 79.27 hours, 3.30 days */
+ 305116, /* 84.75 hours, 3.53 days */
+ 326213, /* 90.61 hours, 3.78 days */
+ 348769, /* 96.88 hours, 4.04 days */
+ 372885, /* 103.58 hours, 4.32 days */
+ 398668, /* 110.74 hours, 4.61 days */
+ 426234, /* 118.40 hours, 4.93 days */
+ 455705, /* 126.58 hours, 5.27 days */
+ 487215, /* 135.34 hours, 5.64 days */
+ 520904, /* 144.70 hours, 6.03 days */
+ 556921, /* 154.70 hours, 6.45 days */
+ 595430, /* 165.40 hours, 6.89 days */
+ 636601, /* 176.83 hours, 7.37 days */
+ 680618, /* 189.06 hours, 7.88 days */
+ 727680, /* 202.13 hours, 8.42 days */
+ 777995, /* 216.11 hours, 9.00 days */
+ 831789, /* 231.05 hours, 9.63 days */
+ 889303, /* 247.03 hours, 10.29 days */
+ 950794, /* 264.11 hours, 11.00 days */
+ 1016537, /* 282.37 hours, 11.77 days */
+ 1086825, /* 301.90 hours, 12.58 days */
+ 1161973, /* 322.77 hours, 13.45 days */
+ 1242318, /* 345.09 hours, 14.38 days */
+ 1328218, /* 368.95 hours, 15.37 days */
+ 1420057, /* 394.46 hours, 16.44 days */
+ 1518247, /* 421.74 hours, 17.57 days */
+ 1623226, /* 450.90 hours, 18.79 days */
+ 1735464, /* 482.07 hours, 20.09 days */
+ 1855462, /* 515.41 hours, 21.48 days */
+ 1983758, /* 551.04 hours, 22.96 days */
+ 2120925, /* 589.15 hours, 24.55 days */
+ 2267576, /* 629.88 hours, 26.25 days */
+ 2424367, /* 673.44 hours, 28.06 days */
+ 2592000}; /* 720.00 hours, 30.00 days */
+
+/*
+ * krb_life_to_time - takes a start time and a Kerberos standard
+ * lifetime char and returns the corresponding end time. There are
+ * four simple cases to be handled. The first is a life of 0xff,
+ * meaning no expiration, and results in an end time of 0xffffffff.
+ * The second is when life is less than the values covered by the
+ * table. In this case, the end time is the start time plus the
+ * number of 5 minute intervals specified by life. The third case
+ * returns start plus the MAXTKTLIFETIME if life is greater than
+ * TKTLIFEMAXFIXED. The last case, uses the life value (minus
+ * TKTLIFEMINFIXED) as an index into the table to extract the lifetime
+ * in seconds, which is added to start to produce the end time.
+ */
+unsigned long krb_life_to_time(start, life)
+unsigned long start;
+int life;
+{
+ life = (unsigned char) life;
+ if (life == TKTLIFENOEXPIRE) return NEVERDATE;
+ if (life < TKTLIFEMINFIXED) return start + life*5*60;
+ if (life > TKTLIFEMAXFIXED) return start + MAXTKTLIFETIME;
+ return start + tkt_lifetimes[life - TKTLIFEMINFIXED];
+}
+
+/*
+ * krb_time_to_life - takes start and end times for the ticket and
+ * returns a Kerberos standard lifetime char, possibily using the
+ * tkt_lifetimes table for lifetimes above 127*5 minutes. First, the
+ * special case of (end == NEVERDATE) is handled to mean no
+ * expiration. Then negative lifetimes and those greater than the
+ * maximum ticket lifetime are rejected. Then lifetimes less than the
+ * first table entry are handled by rounding the requested lifetime
+ * *up* to the next 5 minute interval. The final step is to search
+ * the table for the smallest entry *greater than or equal* to the
+ * requested entry.
+ */
+int krb_time_to_life(start, end)
+unsigned long start;
+unsigned long end;
+{
+ long lifetime;
+ int i;
+
+ if (end == NEVERDATE) return TKTLIFENOEXPIRE;
+ lifetime = end - start;
+ if (lifetime > MAXTKTLIFETIME || lifetime <= 0) return 0;
+ if (lifetime < tkt_lifetimes[0]) return (lifetime + 5*60 - 1)/(5*60);
+ for (i=0; i<TKTLIFENUMFIXED; i++) {
+ if (lifetime <= tkt_lifetimes[i]) {
+ return i+TKTLIFEMINFIXED;
+ }
+ }
+ return 0;
+}
--- /dev/null
+#include "httpd.h"
+#include "http_config.h"
+#include "http_protocol.h"
+#include "http_log.h"
+#include "ap_config.h"
+
+#include <sys/ioccom.h>
+#include <stropts.h>
+#include <kerberosIV/krb.h>
+#include <kerberosIV/des.h>
+#include <afs/venus.h>
+
+#define SRVTAB "/usr/local/etc/srvtab.itdwww"
+
+struct ClearToken {
+ long AuthHandle;
+ char HandShakeKey[ 8 ];
+ long ViceId;
+ long BeginTimestamp;
+ long EndTimestamp;
+};
+
+
+ static void
+pioctl_cleanup( void *data )
+{
+ request_rec *r = (request_rec *)data;
+ struct ViceIoctl vi;
+
+ vi.in = NULL;
+ vi.in_size = 0;
+ vi.out = NULL;
+ vi.out_size = 0;
+
+ if ( pioctl( 0, VIOCUNPAG, &vi, 0 ) < 0 ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ "unlog pioctl failed\n" );
+ }
+
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ "unlog pioctl succeeded\n" );
+}
+
+
+ static int
+get_afs_tokens( request_rec *r )
+{
+ CREDENTIALS cr;
+ struct ViceIoctl vi;
+ struct ClearToken ct;
+ int i, rc;
+ char buf[ 1024 ], *s;
+ char *urealm = "UMICH.EDU";
+ char *lrealm = "umich.edu";
+
+ setpag();
+
+ if (( rc = get_ad_tkt( "afs", "", urealm, 255 )) != KSUCCESS ) {
+ ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, r->server,
+ "get_ad_tkt: %s\n", krb_err_txt[ rc ] );
+
+ /* user doesn't have tickets: use server's srvtab */
+
+ return OK;
+ }
+
+ if (( rc = krb_get_cred( "afs", "", urealm, &cr )) != KSUCCESS ) {
+ ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
+ "krb_get_cred: %s\n", krb_err_txt[ rc ] );
+ return OK;
+ }
+
+ ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, "%s.%s@%s\n", cr.service, cr.instance, cr.realm );
+ ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, "%d %d %d\n", cr.lifetime, cr.kvno, cr.issue_date );
+ ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, "%s %s\n", cr.pname, cr.pinst );
+ ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, "%d\n", cr.ticket_st.length );
+
+ s = buf;
+ memmove( s, &cr.ticket_st.length, sizeof( int ));
+ s += sizeof( int );
+ memmove( s, cr.ticket_st.dat, cr.ticket_st.length );
+ s += cr.ticket_st.length;
+
+ ct.AuthHandle = cr.kvno;
+ memmove( ct.HandShakeKey, cr.session, sizeof( cr.session ));
+ ct.ViceId = 0;
+ ct.BeginTimestamp = cr.issue_date;
+ ct.EndTimestamp = krb_life_to_time( cr.issue_date, cr.lifetime );
+
+ i = sizeof( struct ClearToken );
+ memmove( s, &i, sizeof( int ));
+ s += sizeof( int );
+ memmove( s, &ct, sizeof( struct ClearToken ));
+ s += sizeof( struct ClearToken );
+
+ i = 0;
+ memmove( s, &i, sizeof( int ));
+ s += sizeof( int );
+
+ strcpy( s, lrealm );
+ s += strlen( lrealm ) + 1;
+
+ vi.in = buf;
+ vi.in_size = s - buf;
+ vi.out = buf;
+ vi.out_size = sizeof( buf );
+
+ if ( pioctl( 0, VIOCSETTOK, &vi, 0 ) < 0 ) {
+ ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
+ "pioctl failed\n" );
+ }
+
+ /* we'll need to unlog when this connection is done. */
+ ap_register_cleanup( r->pool, (void *)r, pioctl_cleanup, ap_null_cleanup );
+
+ap_log_error( APLOG_MARK, APLOG_ERR, r->server, "done with token stuff\n" );
+
+ return OK;
+}
+
+
+module MODULE_VAR_EXPORT afs_module = {
+ STANDARD_MODULE_STUFF,
+ NULL, /* module initializer */
+ NULL, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ NULL, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ NULL, /* table of config file commands */
+ NULL, /* [#8] MIME-typed-dispatched handlers */
+ NULL, /* [#1] URI to filename translation */
+ NULL, /* [#4] validate user id from request */
+ NULL, /* [#5] check if the user is ok _here_ */
+ NULL, /* [#3] check access by host address */
+ NULL, /* [#6] determine MIME type */
+ NULL, /* [#7] pre-run fixups */
+ NULL, /* [#9] log a transaction */
+ get_afs_tokens, /* [#2] header parser */
+ NULL, /* child_init */
+ NULL, /* child_exit */
+ NULL /* [#0] post read-request */
+#ifdef EAPI
+ ,NULL, /* EAPI: add_module */
+ NULL, /* EAPI: remove_module */
+ NULL, /* EAPI: rewrite_command */
+ NULL /* EAPI: new_connection */
+#endif
+};