Returned to single mod_auth_kerb.c file.
[mod_auth_kerb.cvs/.git] / src / mod_auth_kerb.c
1 /*************************************************************************** 
2  Included Headers And Module Declaration
3  ***************************************************************************/
4 #ifdef APXS1
5 #include "httpd.h"
6 #include "http_config.h"
7 #include "http_core.h"
8 #include "http_log.h"
9 #include "http_protocol.h"
10 #include "http_request.h"
11
12 module kerb_auth_module;
13 #else
14 #ifdef APXS2
15 #include "apr_strings.h"
16 #include "apr_lib.h"
17 #include "ap_config.h"
18 #include "httpd.h"
19 #include "http_config.h"
20 #include "http_core.h"
21 #include "http_log.h"
22 #include "http_protocol.h"
23 #include "http_request.h"
24
25 module AP_MODULE_DECLARE_DATA kerb_auth_module;
26 #endif /* APXS2 */
27 #endif /* APXS1 */
28
29 #ifdef KRB5
30 #include <krb5.h>
31 #endif /* KRB5 */
32
33 #ifdef KRB4
34 #include <krb.h>
35 #endif /* KRB4 */
36
37
38
39
40 /*************************************************************************** 
41  Macros To Ease Compatibility
42  ***************************************************************************/
43 #ifdef APXS1
44 #define MK_POOL pool
45 #define MK_TABLE_GET ap_table_get
46 #define MK_TABLE_SET ap_table_set
47 #define MK_TABLE_TYPE table
48 #define MK_PSTRDUP ap_pstrdup
49 #define MK_PROXY STD_PROXY
50 #define MK_RERROR_LEVEL ""
51 #define MK_USER r->connection->user
52 #define MK_AUTH_TYPE r->connection->ap_auth_type
53 #define MK_ARRAY_HEADER array_header
54 #else
55 #ifdef APXS2
56 #define MK_POOL apr_pool_t
57 #define MK_TABLE_GET apr_table_get
58 #define MK_TABLE_SET apr_table_set
59 #define MK_TABLE_TYPE apr_table_t
60 #define MK_PSTRDUP apr_pstrdup
61 #define MK_PROXY PROXYREQ_PROXY
62 #define MK_RERROR_LEVEL "0, "
63 #define MK_USER r->user
64 #define MK_AUTH_TYPE r->ap_auth_type
65 #define MK_ARRAY_HEADER apr_array_header_t
66 #endif /* APXS2 */
67 #endif /* APXS1 */
68
69
70
71
72 /*************************************************************************** 
73  Auth Configuration Structure
74  ***************************************************************************/
75 typedef struct {
76         char *krb_auth_type;
77 #ifdef KRB4
78         char *krb_4_srvtab;
79 #endif /* KRB4 */
80 #ifdef KRB5
81         char *krb_5_keytab;
82 #endif /* KRB5 */
83         int krb_authoritative;
84         char *krb_default_realm;
85         int krb_fail_status;
86         char *krb_force_instance;
87 #ifdef KRB5
88         int krb_forwardable;
89 #endif /* KRB5 */
90         char *krb_lifetime;
91 #ifdef KRB5
92         char *krb_renewable;
93 #endif /* KRB5 */
94         int krb_save_credentials;
95         char *krb_tmp_dir;
96 } kerb_auth_config;
97
98
99
100
101 /*************************************************************************** 
102  Auth Configuration Initialization
103  ***************************************************************************/
104 static void *kerb_dir_config(AP_POOL *p, char *d)
105 {
106         static void *rec;
107         rec = (void *) ap_pcalloc(p, sizeof(kerb_auth_config));
108         ((kerb_auth_config *)rec)->krb_fail_status = HTTP_UNAUTHORIZED;
109         ((kerb_auth_config *)rec)->krb_authoritative = 0;
110         ((kerb_auth_config *)rec)->krb_auth_type = MK_PSTRDUP(p, "None");
111         return rec;
112 }
113
114
115
116
117 /*************************************************************************** 
118  Auth Configuration Parsers
119  ***************************************************************************/
120 static const char *kerb_set_fail_slot(cmd_parms *cmd, void *struct_ptr,
121                                         const char *arg)
122 {
123         int offset = (int) (long) cmd->info;
124         if (!strncasecmp(arg, "unauthorized", 12))
125                 *(int *) ((char *)struct_ptr + offset) = HTTP_UNAUTHORIZED;
126         else if (!strncasecmp(arg, "forbidden", 9))
127                 *(int *) ((char *)struct_ptr + offset) = HTTP_FORBIDDEN;
128         else if (!strncasecmp(arg, "declined", 8))
129                 *(int *) ((char *)struct_ptr + offset) = DECLINED;
130         else
131                 return "KrbAuthFailStatus must be Forbidden, Unauthorized, or Declined.";
132         return NULL;
133 }
134
135 /* these are either char *struct_ptr, char *arg or void *struct_ptr, const char *arg */
136 static const char *kerb_set_type_slot(cmd_parms *cmd, void *struct_ptr,
137                                         const char *arg)
138 {
139         int offset = (int) (long) cmd->info;
140         if
141 #ifdef KRB5
142            (!strncasecmp(arg, "v5", 2))
143                 *(char **) ((char *)struct_ptr + offset) = MK_PSTRDUP(cmd->pool, "KerberosV5");
144         else if
145 #endif /* KRB5 */
146 #ifdef KRB4
147            (!strncasecmp(arg, "v4", 2))
148                 *(char **) ((char *)struct_ptr + offset) = MK_PSTRDUP(cmd->pool, "KerberosV4");
149 #endif /* KRB4 */
150         else if
151            (!strncasecmp(arg, "dualv5v4", 8))
152                 *(char **) ((char *)struct_ptr + offset) = MK_PSTRDUP(cmd->pool, "KerberosDualV5V4");
153         else if
154            (!strncasecmp(arg, "dualv4v5", 8))
155                 *(char **) ((char *)struct_ptr + offset) = MK_PSTRDUP(cmd->pool, "KerberosDualV4V5");
156 #if defined(KRB4) && defined(KRB5)
157 #endif /* KRB4 && KRB5 */
158         else
159                 return "AuthKerberos must be V5, V4, DualV4V5, or DualV5V4.";
160         return NULL;
161 }
162
163
164
165
166 /*************************************************************************** 
167  Auth Configuration Commands
168  ***************************************************************************/
169 #ifdef APXS1
170 command_rec kerb_auth_cmds[] = {
171         {
172                 "AuthKerberos",
173                 kerb_set_type_slot,
174                 (void*)XtOffsetOf(kerb_auth_config, krb_auth_type),
175                 OR_AUTHCFG,
176                 TAKE1,
177                 "Permit Kerberos auth without AuthType requirement."
178         },
179
180 #ifdef KRB4
181         {
182                 "Krb4Srvtab",
183                 ap_set_file_slot,
184                 (void*)XtOffsetOf(kerb_auth_config, krb_4_srvtab),
185                 RSRC_CONF & ACCESS_CONF,
186                 TAKE1,
187                 "Location of Kerberos V4 srvtab file."
188         },
189 #endif /* KRB4 */
190
191 #ifdef KRB5
192         {
193                 "Krb5Keytab",
194                 ap_set_file_slot,
195                 (void*)XtOffsetOf(kerb_auth_config, krb_5_keytab),
196                 RSRC_CONF & ACCESS_CONF,
197                 TAKE1,
198                 "Location of Kerberos V5 keytab file."
199         },
200 #endif /* KRB5 */
201
202         {
203                 "KrbAuthoritative",
204                 ap_set_flag_slot,
205                 (void*)XtOffsetOf(kerb_auth_config, krb_authoritative),
206                 OR_AUTHCFG,
207                 FLAG,
208                 "Refuse to pass request down to lower modules."
209         },
210
211         {
212                 "KrbDefaultRealm",
213                 ap_set_string_slot,
214                 (void*)XtOffsetOf(kerb_auth_config, krb_default_realm),
215                 OR_AUTHCFG,
216                 TAKE1,
217                 "Default realm to authenticate users against."
218         },
219
220         {
221                 "KrbFailStatus",
222                 kerb_set_fail_slot,
223                 (void*)XtOffsetOf(kerb_auth_config, krb_fail_status),
224                 OR_AUTHCFG,
225                 TAKE1,
226                 "If auth fails, return status set here."
227         },
228
229         {
230                 "KrbForceInstance",
231                 ap_set_string_slot,
232                 (void*)XtOffsetOf(kerb_auth_config, krb_force_instance),
233                 OR_AUTHCFG,
234                 TAKE1,
235                 "Force authentication against an instance specified here."
236         },
237
238 #ifdef KRB5
239         {
240                 "KrbForwardable",
241                 ap_set_flag_slot,
242                 (void*)XtOffsetOf(kerb_auth_config, krb_forwardable),
243                 OR_AUTHCFG,
244                 FLAG,
245                 "Credentials retrieved will be flagged as forwardable."
246         },
247 #endif /* KRB5 */
248
249         {
250                 "KrbLifetime",
251                 ap_set_string_slot,
252                 (void*)XtOffsetOf(kerb_auth_config, krb_lifetime),
253                 OR_AUTHCFG,
254                 TAKE1,
255                 "Lifetime of tickets retrieved."
256         },
257
258 #ifdef KRB5
259         {
260                 "KrbRenewable",
261                 ap_set_string_slot,
262                 (void*)XtOffsetOf(kerb_auth_config, krb_renewable),
263                 OR_AUTHCFG,
264                 TAKE1,
265                 "Credentials retrieved will be renewable for this length."
266         },
267 #endif /* KRB5 */
268
269         {
270                 "KrbSaveCredentials",
271                 ap_set_flag_slot,
272                 (void*)XtOffsetOf(kerb_auth_config, krb_save_credentials),
273                 OR_AUTHCFG,
274                 FLAG,
275                 "Save and store credentials/tickets retrieved during auth."
276         },
277
278         {
279                 "KrbSaveTickets",
280                 ap_set_flag_slot,
281                 (void*)XtOffsetOf(kerb_auth_config, krb_save_credentials),
282                 OR_AUTHCFG,
283                 FLAG,
284                 "Alias for KrbSaveCredentials."
285         },
286
287         {
288                 "KrbTmpdir",
289                 ap_set_string_slot,
290                 (void*)XtOffsetOf(kerb_auth_config, krb_tmp_dir),
291                 OR_AUTHCFG,
292                 TAKE1,
293                 "Path to store ticket files and such in."
294         },
295
296         { NULL }
297 };
298 #else
299 #ifdef APXS2
300 static const command_rec kerb_auth_cmds[] = {
301         AP_INIT_TAKE1(
302                 "AuthKerberos",
303                 kerb_set_type_slot,
304                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_auth_type),
305                 OR_AUTHCFG,
306                 "Permit Kerberos auth without AuthType requirement."
307         ),
308
309 #ifdef KRB4
310         AP_INIT_TAKE1(
311                 "Krb4Srvtab",
312                 ap_set_file_slot,
313                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_4_srvtab),
314                 RSRC_CONF & ACCESS_CONF,
315                 "Location of Kerberos V4 srvtab file."
316         ),
317 #endif /* KRB4 */
318
319 #ifdef KRB5
320         AP_INIT_TAKE1(
321                 "Krb5Keytab",
322                 ap_set_file_slot,
323                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_5_keytab),
324                 RSRC_CONF & ACCESS_CONF,
325                 "Location of Kerberos V5 keytab file."
326         ),
327 #endif /* KRB5 */
328
329         AP_INIT_FLAG(
330                 "KrbAuthoritative",
331                 ap_set_flag_slot,
332                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_authoritative),
333                 OR_AUTHCFG,
334                 "Refuse to pass request down to lower modules."
335         ),
336
337         AP_INIT_TAKE1(
338                 "KrbDefaultRealm",
339                 ap_set_string_slot,
340                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_default_realm),
341                 OR_AUTHCFG,
342                 "Default realm to authenticate users against."
343         ),
344
345         AP_INIT_TAKE1(
346                 "KrbFailStatus",
347                 kerb_set_fail_slot,
348                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_fail_status),
349                 OR_AUTHCFG,
350                 "If auth fails, return status set here."
351         ),
352
353         AP_INIT_TAKE1(
354                 "KrbForceInstance",
355                 ap_set_string_slot,
356                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_force_instance),
357                 OR_AUTHCFG,
358                 "Force authentication against an instance specified here."
359         ),
360
361 #ifdef KRB5
362         AP_INIT_FLAG(
363                 "KrbForwardable",
364                 ap_set_flag_slot,
365                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_forwardable),
366                 OR_AUTHCFG,
367                 "Credentials retrieved will be flagged as forwardable."
368         ),
369 #endif /* KRB5 */
370
371         AP_INIT_TAKE1(
372                 "KrbLifetime",
373                 ap_set_string_slot,
374                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_lifetime),
375                 OR_AUTHCFG,
376                 "Lifetime of tickets retrieved."
377         ),
378
379 #ifdef KRB5
380         AP_INIT_TAKE1(
381                 "KrbRenewable",
382                 ap_set_string_slot,
383                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_renewable),
384                 OR_AUTHCFG,
385                 "Credentials retrieved will be renewable for this length."
386         ),
387 #endif /* KRB5 */
388
389         AP_INIT_FLAG(
390                 "KrbSaveCredentials",
391                 ap_set_flag_slot,
392                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_save_credentials),
393                 OR_AUTHCFG,
394                 "Save and store credentials/tickets retrieved during auth."
395         ),
396
397         AP_INIT_FLAG(
398                 "KrbSaveTickets",
399                 ap_set_flag_slot,
400                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_save_credentials),
401                 OR_AUTHCFG,
402                 "Alias for KrbSaveCredentials."
403         ),
404
405         AP_INIT_TAKE1(
406                 "KrbTmpdir",
407                 ap_set_string_slot,
408                 (void*)APR_XtOffsetOf(kerb_auth_config, krb_tmp_dir),
409                 OR_AUTHCFG,
410                 "Path to store ticket files and such in."
411         ),
412
413         { NULL }
414 };
415 #endif /* APXS2 */
416 #endif /* APXS1 */
417
418
419
420
421 /*************************************************************************** 
422  Username/Password Validation
423  ***************************************************************************/
424 #ifdef KRB5
425 int kerb5_password_validate(const char *user, const char *pass) {
426         int ret;
427         krb5_context kcontext;
428         krb5_principal server, me;
429         krb5_creds my_creds;
430         krb5_timestamp now;
431         krb5_deltat lifetime = 0;
432         krb5_data tgtname = {
433                 0,
434                 KRB5_TGS_NAME_SIZE,
435                 KRB5_TGS_NAME
436         };
437
438         if (krb5_init_context(&kcontext))
439                 return 0;
440
441         memset((char *)&my_creds, 0, sizeof(my_creds));
442         if(krb5_parse_name(kcontext, user, &me))
443                 return 0;
444         my_creds.client = me;
445
446         if (krb5_build_principal_ext(kcontext, &server,
447                                 krb5_princ_realm(kcontext, me)->length,
448                                 krb5_princ_realm(kcontext, me)->data,
449                                 tgtname.length, tgtname.data,
450                                 krb5_princ_realm(kcontext, me)->length,
451                                 krb5_princ_realm(kcontext, me)->data,
452                                 0)) {
453                 return 0;
454         }
455         my_creds.server = server;
456         if (krb5_timeofday(kcontext, &now))
457                 return 0;
458         my_creds.times.starttime = 0;
459         my_creds.times.endtime = now + lifetime;
460         my_creds.times.renew_till = 0;
461
462         ret = krb5_get_in_tkt_with_password(kcontext, 0, 0, NULL, 0,
463                                 pass, NULL, &my_creds, 0);
464         if (ret) {
465                 return 0;
466         }
467
468         krb5_free_cred_contents(kcontext, &my_creds);
469
470         return 1;
471 }
472 #endif /* KRB5 */
473
474 #ifdef KRB4
475 int kerb4_password_validate(const char *user, const char *pass) {
476         int ret;
477         char realm[REALM_SZ];
478
479         ret = krb_get_lrealm(realm, 1);
480         if (ret != KSUCCESS)
481                 return !KRB4_OK;
482
483         ret = krb_get_pw_in_tkt((char *)user, "", realm, "krbtgt", realm,
484                                         DEFAULT_TKT_LIFE, (char *)pass);
485         switch (ret) {
486                 case INTK_OK:
487                 case INTK_W_NOTALL:
488                         return KRB4_OK;
489                         break;
490
491                 default:
492                         return !KRB4_OK;
493                         break;
494         }
495 }
496 #endif /* KRB4 */
497
498
499
500
501 /*************************************************************************** 
502  User Authentication
503  ***************************************************************************/
504 int kerb_authenticate_user(request_rec *r) {
505         const char *name;               /* AuthName specified */
506         const char *type;               /* AuthType specified */
507         int KerberosV5 = 0;             /* Kerberos V5 check enabled */
508         int KerberosV4 = 0;             /* Kerberos V4 check enabled */
509         int KerberosV4first = 0;        /* Kerberos V4 check first */
510         const char *sent_pw;            /* Password sent by browser */
511         int res;                        /* Response holder */
512         int retcode;                    /* Return code holder */
513         const char *t;                  /* Decoded auth_line */
514         const char *authtype;           /* AuthType to send back to browser */
515         const char *auth_line = MK_TABLE_GET(r->headers_in,
516                                         (r->proxyreq == MK_PROXY)
517                                                 ? "Proxy-Authorization"
518                                                 : "Authorization");
519         kerb_auth_config *conf =
520                 (kerb_auth_config *)ap_get_module_config(r->per_dir_config,
521                                         &kerb_auth_module);
522
523         type = ap_auth_type(r);
524
525         if (type != NULL) {
526 #ifdef KRB5
527                 if ((strncasecmp(type, "KerberosV5", 10) == 0) ||
528                     (strncasecmp(conf->krb_auth_type, "KerberosV5", 10) == 0)) {
529                         KerberosV5 = 1;
530                 }
531 #endif /* KRB5 */
532
533 #ifdef KRB4
534                 if ((strncasecmp(type, "KerberosV4", 10) == 0) ||
535                     (strncasecmp(conf->krb_auth_type, "KerberosV4", 10) == 0)) {
536                         KerberosV4 = 1;
537                 }
538 #endif /* KRB4 */
539
540 #if defined(KRB5) && defined(KRB4)
541                 if ((strncasecmp(type, "KerberosDualV5V4", 15) == 0) ||
542                     (strncasecmp(conf->krb_auth_type, "KerberosDualV5V4", 15) == 0)) {
543                         KerberosV5 = 1;
544                         KerberosV4 = 1;
545                 }
546
547                 if ((strncasecmp(type, "KerberosDualV4V5", 15) == 0) ||
548                     (strncasecmp(conf->krb_auth_type, "KerberosDualV4V5", 15) == 0)) {
549                         KerberosV5 = 1;
550                         KerberosV4 = 1;
551                         KerberosV4first = 1;
552                 }
553 #endif /* KRB5 && KRB4 */
554         }
555
556         if (!KerberosV4 && !KerberosV5) {
557                 if (conf->krb_authoritative) {
558                         return HTTP_UNAUTHORIZED;
559                 }
560                 else {
561                         return DECLINED;
562                 }
563         }
564
565         name = ap_auth_name(r);
566         if (!name) {
567                 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
568                                 MK_RERROR_LEVEL "need AuthName: %s", r->uri);
569                 return HTTP_INTERNAL_SERVER_ERROR;
570         }
571
572         if (!auth_line) {
573                 MK_TABLE_SET(r->err_headers_out, "WWW-Authenticate",
574                         ap_pstrcat(r->pool, "Basic realm=\"", name, "\"", NULL));
575                 return HTTP_UNAUTHORIZED;
576         }
577
578         type = ap_getword_white(r->pool, &auth_line);
579         t = ap_pbase64decode(r->pool, auth_line);
580         MK_USER = ap_getword_nulls(r->pool, &t, ':');
581         MK_AUTH_TYPE = "Kerberos";
582         sent_pw = ap_getword_white(r->pool, &t);
583
584         retcode = DECLINED;
585
586 #ifdef KRB5
587         if (KerberosV5 && !KerberosV4first && retcode != OK) {
588                 MK_AUTH_TYPE = "KerberosV5";
589                 if (kerb5_password_validate(MK_USER, sent_pw)) {
590                         retcode = OK;
591                 }
592                 else {
593                         retcode = conf->krb_fail_status;
594                 }
595         }
596 #endif /* KRB5 */
597
598 #ifdef KRB4
599         if (KerberosV4 && retcode != OK) {
600                 MK_AUTH_TYPE = "KerberosV4";
601                 if (kerb4_password_validate(MK_USER, sent_pw)) {
602                         retcode = OK;
603                 }
604                 else {
605                         retcode = conf->krb_fail_status;
606                 }
607         }
608 #endif /* KRB4 */
609
610 #if defined(KRB5) && defined(KRB4)
611         if (KerberosV5 && KerberosV4first && retcode != OK) {
612                 MK_AUTH_TYPE = "KerberosV5"
613                 if (kerb5_password_validate(MK_USER, sent_pw)) {
614                         retcode = OK;
615                 }
616                 else {
617                         retcode = conf->krb_fail_status;
618                 }
619         }
620 #endif /* KRB5 && KRB4 */
621
622         if (conf->krb_authoritative && retcode == DECLINED) {
623                 return HTTP_UNAUTHORIZED;
624         }
625         else {
626                 return retcode;
627         }
628 }
629
630
631
632
633 /*************************************************************************** 
634  Access Verification
635  ***************************************************************************/
636 int check_user_access(request_rec *r) {
637         register int x;
638         const char *t, *w;
639         const MK_ARRAY_HEADER *reqs_arr = ap_requires(r);
640         require_line *reqs;
641         kerb_auth_config *conf =
642                 (kerb_auth_config *)ap_get_module_config(r->per_dir_config,
643                                                 &kerb_auth_module);
644
645         if (reqs_arr == NULL) {
646                 return OK;
647         }
648         reqs = (require_line *)reqs_arr->elts;
649
650         for (x = 0; x < reqs_arr->nelts; x++) {
651                 t = reqs[x].requirement;
652                 w = ap_getword_white(r->pool, &t);
653                 if (strcmp(w, "realm") == 0) {
654                         while (t[0] != '\0') {
655                                 w = ap_getword_conf(r->pool, &t);
656                                 if (strcmp(MK_USER, w) == 0) {
657                                         return OK;
658                                 }
659                         }
660                 }
661         }
662
663         return DECLINED;
664 }
665
666
667
668
669 /*************************************************************************** 
670  Module Setup/Configuration
671  ***************************************************************************/
672 #ifdef APXS1
673 module MODULE_VAR_EXPORT kerb_auth_module = {
674         STANDARD_MODULE_STUFF,
675         NULL,                           /*      module initializer            */
676         kerb_dir_config,                /*      per-directory config creator  */
677         NULL,                           /*      per-directory config merger   */
678         NULL,                           /*      per-server    config creator  */
679         NULL,                           /*      per-server    config merger   */
680         kerb_auth_cmds,                 /*      command table                 */
681         NULL,                           /* [ 9] content handlers              */
682         NULL,                           /* [ 2] URI-to-filename translation   */
683         kerb_authenticate_user,         /* [ 5] check/validate user_id        */
684         kerb_check_user_access,         /* [ 6] check user_id is valid *here* */
685         NULL,                           /* [ 4] check access by host address  */
686         NULL,                           /* [ 7] MIME type checker/setter      */
687         NULL,                           /* [ 8] fixups                        */
688         NULL,                           /* [10] logger                        */
689         NULL,                           /* [ 3] header parser                 */
690         NULL,                           /*      process initialization        */
691         NULL,                           /*      process exit/cleanup          */
692         NULL                            /* [ 1] post read_request handling    */
693 #ifdef EAPI
694         ,                               /*            EAPI Additions          */
695         NULL,                           /* EAPI add module                    */
696         NULL,                           /* EAPI remove module                 */
697         NULL,                           /* EAPI rewrite command               */
698         NULL                            /* EAPI new connection                */
699 #endif /* EAPI */
700 };
701 #else
702 #ifdef APXS2
703 void kerb_register_hooks(apr_pool_t *p)
704 {
705         ap_hook_check_user_id(kerb_authenticate_user, NULL, NULL, APR_HOOK_MIDDLE);
706         ap_hook_access_checker(kerb_check_user_access, NULL, NULL, APR_HOOK_MIDDLE);
707 }
708
709 module AP_MODULE_DECLARE_DATA kerb_auth_module =
710 {
711         STANDARD20_MODULE_STUFF,
712         kerb_dir_config,                /* create per-dir    conf structures  */
713         NULL,                           /* merge  per-dir    conf structures  */
714         NULL,                           /* create per-server conf structures  */
715         NULL,                           /* merge  per-server conf structures  */
716         kerb_auth_cmds,                 /* table of configuration directives  */
717         kerb_register_hooks             /* register hooks                     */
718 };
719 #endif /* APXS2 */
720 #endif /* APXS1 */