fixed problem with multiple afs service tickets being fetched.
[hcoop/zz_old/modwaklog.git] / mod_waklog.c
CommitLineData
bed98ff9 1#include "httpd.h"
2#include "http_config.h"
3#include "http_protocol.h"
4#include "http_log.h"
5#include "ap_config.h"
6
7#include <sys/ioccom.h>
8#include <stropts.h>
9#include <kerberosIV/krb.h>
10#include <kerberosIV/des.h>
11#include <afs/venus.h>
12
313dde40 13module waklog_module;
bed98ff9 14
15struct ClearToken {
16 long AuthHandle;
17 char HandShakeKey[ 8 ];
18 long ViceId;
19 long BeginTimestamp;
20 long EndTimestamp;
21};
22
313dde40 23typedef struct {
24 int configured;
25 int protect;
26} waklog_host_config;
27
28
29 static void *
30waklog_create_dir_config( pool *p, char *path )
31{
32 waklog_host_config *cfg;
33
34 cfg = (waklog_host_config *)ap_pcalloc( p, sizeof( waklog_host_config ));
35 cfg->configured = 0;
36 cfg->protect = 0;
37
38 return( cfg );
39}
40
41
42 static void *
43waklog_create_server_config( pool *p, server_rec *s )
44{
45 waklog_host_config *cfg;
46
47 cfg = (waklog_host_config *)ap_pcalloc( p, sizeof( waklog_host_config ));
48 cfg->configured = 0;
49 cfg->protect = 0;
50
51 return( cfg );
52}
53
54
b429ae96 55 static void
313dde40 56waklog_init( server_rec *s, pool *p )
b429ae96 57{
58 extern char *version;
59
60 ap_log_error( APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, s,
313dde40 61 "mod_waklog: version %s initialized.", version );
b429ae96 62 return;
63}
64
bed98ff9 65
313dde40 66 static const char *
67set_waklog_protect( cmd_parms *params, void *mconfig, int flag )
68{
69 waklog_host_config *cfg;
70
71 if ( params->path == NULL ) {
72 cfg = (waklog_host_config *) ap_get_module_config(
73 params->server->module_config, &waklog_module );
74 } else {
75 cfg = (waklog_host_config *)mconfig;
76 }
77
78 cfg->protect = flag;
79 cfg->configured = 1;
80 return( NULL );
81}
82
83
b74fad73 84 static void
313dde40 85waklog_child_init( server_rec *s, pool *p )
b74fad73 86{
87 setpag();
b74fad73 88 return;
89}
90
91
313dde40 92command_rec waklog_cmds[ ] =
93{
94 { "WaklogProtected", set_waklog_protect,
95 NULL, RSRC_CONF | ACCESS_CONF, FLAG,
96 "enable waklog on a location or directory basis" },
97
98 { NULL }
99};
100
101
bed98ff9 102 static void
103pioctl_cleanup( void *data )
104{
105 request_rec *r = (request_rec *)data;
106 struct ViceIoctl vi;
107
108 vi.in = NULL;
109 vi.in_size = 0;
110 vi.out = NULL;
111 vi.out_size = 0;
112
113 if ( pioctl( 0, VIOCUNPAG, &vi, 0 ) < 0 ) {
114 ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
313dde40 115 "mod_waklog: unlog pioctl failed" );
bed98ff9 116 }
117
1e18ef7d 118 ap_log_error( APLOG_MARK, APLOG_DEBUG, r->server,
313dde40 119 "mod_waklog: unlog pioctl succeeded" );
b74fad73 120 return;
bed98ff9 121}
122
123
124 static int
313dde40 125waklog_get_tokens( request_rec *r )
bed98ff9 126{
127 CREDENTIALS cr;
128 struct ViceIoctl vi;
129 struct ClearToken ct;
130 int i, rc;
131 char buf[ 1024 ], *s;
132 char *urealm = "UMICH.EDU";
133 char *lrealm = "umich.edu";
313dde40 134 waklog_host_config *cfg;
135
136 /* directory config? */
137 cfg = (waklog_host_config *)ap_get_module_config(
138 r->per_dir_config, &waklog_module);
bed98ff9 139
313dde40 140 /* server config? */
141 if ( !cfg->configured ) {
142 cfg = (waklog_host_config *)ap_get_module_config(
143 r->server->module_config, &waklog_module);
144 }
145
146 if ( !cfg->protect ) {
147 return( DECLINED );
148 }
bed98ff9 149
bed98ff9 150 if (( rc = krb_get_cred( "afs", "", urealm, &cr )) != KSUCCESS ) {
151 ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
313dde40 152 "mod_waklog: krb_get_cred: %s", krb_err_txt[ rc ] );
1e18ef7d 153
154 if (( rc = get_ad_tkt( "afs", "", urealm, 255 )) != KSUCCESS ) {
155 ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server,
156 "mod_waklog: get_ad_tkt: %s", krb_err_txt[ rc ] );
157
158 /* user doesn't have tickets: use server's srvtab */
159
160 return OK;
161 }
162
163 if (( rc = krb_get_cred( "afs", "", urealm, &cr )) != KSUCCESS ) {
164 ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
165 "mod_waklog: krb_get_cred: %s", krb_err_txt[ rc ] );
166 return OK;
167 }
bed98ff9 168 }
169
b429ae96 170 ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server,
313dde40 171 "mod_waklog: %s.%s@%s", cr.service, cr.instance, cr.realm );
b429ae96 172 ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server,
313dde40 173 "mod_waklog: %d %d %d", cr.lifetime, cr.kvno, cr.issue_date );
b429ae96 174 ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server,
313dde40 175 "mod_waklog: %s %s", cr.pname, cr.pinst );
b429ae96 176 ap_log_error( APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server,
313dde40 177 "mod_waklog: %d", cr.ticket_st.length );
bed98ff9 178
179 s = buf;
180 memmove( s, &cr.ticket_st.length, sizeof( int ));
181 s += sizeof( int );
182 memmove( s, cr.ticket_st.dat, cr.ticket_st.length );
183 s += cr.ticket_st.length;
184
185 ct.AuthHandle = cr.kvno;
186 memmove( ct.HandShakeKey, cr.session, sizeof( cr.session ));
187 ct.ViceId = 0;
188 ct.BeginTimestamp = cr.issue_date;
189 ct.EndTimestamp = krb_life_to_time( cr.issue_date, cr.lifetime );
190
191 i = sizeof( struct ClearToken );
192 memmove( s, &i, sizeof( int ));
193 s += sizeof( int );
194 memmove( s, &ct, sizeof( struct ClearToken ));
195 s += sizeof( struct ClearToken );
196
197 i = 0;
198 memmove( s, &i, sizeof( int ));
199 s += sizeof( int );
200
201 strcpy( s, lrealm );
202 s += strlen( lrealm ) + 1;
203
204 vi.in = buf;
205 vi.in_size = s - buf;
206 vi.out = buf;
207 vi.out_size = sizeof( buf );
208
209 if ( pioctl( 0, VIOCSETTOK, &vi, 0 ) < 0 ) {
210 ap_log_error( APLOG_MARK, APLOG_ERR, r->server,
313dde40 211 "mod_waklog: pioctl failed" );
bed98ff9 212 }
213
214 /* we'll need to unlog when this connection is done. */
215 ap_register_cleanup( r->pool, (void *)r, pioctl_cleanup, ap_null_cleanup );
216
1e18ef7d 217 ap_log_error( APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
218 "mod_waklog: finished with get_token" );
bed98ff9 219
220 return OK;
221}
222
223
313dde40 224module MODULE_VAR_EXPORT waklog_module = {
bed98ff9 225 STANDARD_MODULE_STUFF,
313dde40 226 waklog_init, /* module initializer */
227 waklog_create_dir_config, /* create per-dir config structures */
bed98ff9 228 NULL, /* merge per-dir config structures */
313dde40 229 waklog_create_server_config, /* create per-server config structures */
bed98ff9 230 NULL, /* merge per-server config structures */
313dde40 231 waklog_cmds, /* table of config file commands */
bed98ff9 232 NULL, /* [#8] MIME-typed-dispatched handlers */
233 NULL, /* [#1] URI to filename translation */
234 NULL, /* [#4] validate user id from request */
235 NULL, /* [#5] check if the user is ok _here_ */
236 NULL, /* [#3] check access by host address */
237 NULL, /* [#6] determine MIME type */
313dde40 238 waklog_get_tokens, /* [#7] pre-run fixups */
bed98ff9 239 NULL, /* [#9] log a transaction */
313dde40 240 NULL, /* [#2] header parser */
241 waklog_child_init, /* child_init */
bed98ff9 242 NULL, /* child_exit */
243 NULL /* [#0] post read-request */
244#ifdef EAPI
245 ,NULL, /* EAPI: add_module */
246 NULL, /* EAPI: remove_module */
247 NULL, /* EAPI: rewrite_command */
248 NULL /* EAPI: new_connection */
249#endif
250};