4 #include "http_config.h"
7 #include "http_protocol.h"
8 #include "http_request.h"
20 module kerb_auth_module;
22 module AP_MODULE_DECLARE_DATA kerb_auth_module;
25 /***************************************************************************
26 Macros To Ease Compatibility
27 ***************************************************************************/
30 #define MK_TABLE_GET ap_table_get
31 #define MK_TABLE_SET ap_table_set
32 #define MK_TABLE_TYPE table
33 #define MK_PSTRDUP ap_pstrdup
34 #define MK_PROXY STD_PROXY
35 #define MK_USER r->connection->user
36 #define MK_AUTH_TYPE r->connection->ap_auth_type
37 #define MK_ARRAY_HEADER array_header
39 #define MK_POOL apr_pool_t
40 #define MK_TABLE_GET apr_table_get
41 #define MK_TABLE_SET apr_table_set
42 #define MK_TABLE_TYPE apr_table_t
43 #define MK_PSTRDUP apr_pstrdup
44 #define MK_PROXY PROXYREQ_PROXY
45 #define MK_USER r->user
46 #define MK_AUTH_TYPE r->ap_auth_type
47 #define MK_ARRAY_HEADER apr_array_header_t
53 /***************************************************************************
54 Auth Configuration Structure
55 ***************************************************************************/
58 char *krb_auth_realms;
60 char *krb_force_instance;
61 int krb_save_credentials;
68 int krb_method_gssapi;
69 int krb_method_k5pass;
73 int krb_method_k4pass;
78 #define command(name, func, var, type, usage) \
80 (void*)XtOffsetOf(kerb_auth_config, var), \
81 OR_AUTHCFG, type, usage }
83 #define command(name, func, var, type, usage) \
84 AP_INIT_ ## type (name, func, \
85 (void*)APR_XtOffsetOf(kerb_auth_config, var), \
89 static const command_rec kerb_auth_cmds[] = {
90 command("AuthKerberos", ap_set_flag_slot, krb_auth_enable,
91 FLAG, "Permit Kerberos auth without AuthType requirement."),
93 command("KrbAuthRealm", ap_set_string_slot, krb_auth_realms,
94 ITERATE, "Realms to attempt authentication against (can be multiple)."),
96 command("KrbAuthRealm", ap_set_string_slot, krb_auth_realms,
97 ITERATE, "Alias for KrbAuthRealm."),
100 command("KrbFailStatus", kerb_set_fail_slot, krb_fail_status,
101 TAKE1, "If auth fails, return status set here."),
104 command("KrbForceInstance", ap_set_string_slot, krb_force_instance,
105 TAKE1, "Force authentication against an instance specified here."),
107 command("KrbSaveCredentials", ap_set_flag_slot, krb_save_credentials,
108 FLAG, "Save and store credentials/tickets retrieved during auth."),
110 command("KrbSaveTickets", ap_set_flag_slot, krb_save_credentials,
111 FLAG, "Alias for KrbSaveCredentials."),
113 command("KrbTmpdir", ap_set_string_slot, krb_tmp_dir,
114 TAKE1, "Path to store ticket files and such in."),
116 command("KrbServiceName", ap_set_string_slot, service_name,
117 TAKE1, "Kerberos service name to be used by apache."),
120 command("KrbLifetime", ap_set_string_slot, krb_lifetime,
121 TAKE1, "Kerberos ticket lifetime."),
125 command("Krb5Keytab", ap_set_file_slot, krb_5_keytab,
126 TAKE1, "Location of Kerberos V5 keytab file."),
128 command("KrbForwardable", ap_set_flag_slot, krb_forwardable,
129 FLAG, "Credentials retrieved will be flagged as forwardable."),
131 command("KrbMethodGSSAPI", ap_set_flag_slot, krb_method_gssapi,
132 FLAG, "Enable GSSAPI authentication."),
134 command("KrbMethodK5Pass", ap_set_flag_slot, krb_method_k5pass,
135 FLAG, "Enable Kerberos V5 password authentication."),
139 command("Krb4Srvtab", ap_set_file_slot, krb_4_srvtab,
140 TAKE1, "Location of Kerberos V4 srvtab file."),
142 command("KrbMethodK4Pass", ap_set_flag_slot, krb_method_k4pass,
143 FLAG, "Enable Kerberos V4 password authentication."),
150 /***************************************************************************
151 GSSAPI Support Initialization
152 ***************************************************************************/
155 gss_ctx_id_t context;
156 gss_cred_id_t server_creds;
159 static gss_connection_t *gss_connection = NULL;
162 cleanup_gss_connection(void *data)
164 OM_uint32 minor_status;
165 gss_connection_t *gss_conn = (gss_connection_t *)data;
169 if (gss_conn->context != GSS_C_NO_CONTEXT)
170 gss_delete_sec_context(&minor_status, &gss_conn->context,
172 if (gss_conn->server_creds != GSS_C_NO_CREDENTIAL)
173 gss_release_cred(&minor_status, &gss_conn->server_creds);
180 /***************************************************************************
181 Auth Configuration Initialization
182 ***************************************************************************/
183 static void *kerb_dir_create_config(MK_POOL *p, char *d)
185 kerb_auth_config *rec;
187 rec = (kerb_auth_config *) ap_pcalloc(p, sizeof(kerb_auth_config));
188 ((kerb_auth_config *)rec)->krb_auth_enable = 1;
189 ((kerb_auth_config *)rec)->krb_fail_status = HTTP_UNAUTHORIZED;
191 ((kerb_auth_config *)rec)->krb_method_k5pass = 1;
192 ((kerb_auth_config *)rec)->krb_method_gssapi = 1;
195 ((kerb_auth_config *)rec)->krb_method_k4pass = 1;
203 /***************************************************************************
204 Auth Configuration Parsers
205 ***************************************************************************/
206 static const char *kerb_set_fail_slot(cmd_parms *cmd, void *struct_ptr,
209 int offset = (int) (long) cmd->info;
210 if (!strncasecmp(arg, "unauthorized", 12))
211 *(int *) ((char *)struct_ptr + offset) = HTTP_UNAUTHORIZED;
212 else if (!strncasecmp(arg, "forbidden", 9))
213 *(int *) ((char *)struct_ptr + offset) = HTTP_FORBIDDEN;
214 else if (!strncasecmp(arg, "declined", 8))
215 *(int *) ((char *)struct_ptr + offset) = DECLINED;
217 return "KrbAuthFailStatus must be Forbidden, Unauthorized, or Declined.";
224 krb5_verify_user(krb5_context context, krb5_principal principal,
225 krb5_ccache ccache, const char *password, krb5_boolean secure,
229 krb5_context kcontext;
230 krb5_principal server, client;
233 krb5_flags options = 0;
234 krb5_principal me = NULL;
235 krb5_data tgtname = {
241 memset((char *)&my_creds, 0, sizeof(my_creds));
242 my_creds.client = principal;
244 if (krb5_build_principal_ext(kcontext, &server,
245 krb5_princ_realm(kcontext, me)->length,
246 krb5_princ_realm(kcontext, me)->data,
247 tgtname.length, tgtname.data,
248 krb5_princ_realm(kcontext, me)->length,
249 krb5_princ_realm(kcontext, me)->data,
254 my_creds.server = server;
255 if (krb5_timeofday(kcontext, &now))
258 my_creds.times.starttime = 0;
260 my_creds.times.endtime = now + lifetime;
261 my_creds.times.renew_till = now + renewal;
264 ret = krb5_get_in_tkt_with_password(kcontext, options, 0, NULL, 0,
265 password, ccache, &my_creds, 0);
275 /***************************************************************************
276 Username/Password Validation
277 ***************************************************************************/
280 krb5_cache_cleanup(void *data)
282 krb5_context context;
284 krb5_error_code problem;
285 char *cache_name = (char *) data;
287 problem = krb5_init_context(&context);
289 ap_log_error(APLOG_MARK, APLOG_ERR, NULL, "krb5_init_context() failed");
293 problem = krb5_cc_resolve(context, cache_name, &cache);
295 ap_log_error(APLOG_MARK, APLOG_ERR, NULL,
296 "krb5_cc_resolve() failed (%s: %s)",
297 cache_name, krb5_get_err_text(context, problem));
301 krb5_cc_destroy(context, cache);
302 krb5_free_context(context);
306 create_krb5_ccache(krb5_context kcontext,
308 kerb_auth_config *conf,
309 krb5_principal princ,
312 char *c, ccname[MAX_STRING_LEN];
313 krb5_error_code problem;
316 krb5_ccache tmp_ccache = NULL;
318 snprintf(ccname, sizeof(ccname), "FILE:%s/k5cc_ap_%s",
319 conf->krb_tmp_dir ? conf->krb_tmp_dir : "/tmp",
322 for (c = ccname + strlen(conf->krb_tmp_dir ? conf->krb_tmp_dir :
323 "/tmp") + 1; *c; c++) {
329 /* not sure what's the purpose of this call here */
330 problem = krb5_cc_set_default_name(kcontext, ccname);
332 snprintf(errstr, sizeof(errstr),
333 "krb5_cc_set_default_name() failed: %s",
334 krb5_get_err_text(kcontext, problem));
335 ap_log_reason (errstr, r->uri, r);
343 /* XXX Dan: Why is this done? Cleanup? But the file would not be
344 * accessible from another processes (CGI) */
345 unlink(ccname+strlen("FILE:"));
348 problem = krb5_cc_resolve(kcontext, ccname, &tmp_ccache);
350 snprintf(errstr, sizeof(errstr),
351 "krb5_cc_resolve() failed: %s",
352 krb5_get_err_text(kcontext, problem));
353 ap_log_reason (errstr, r->uri, r);
358 problem = krb5_cc_initialize(kcontext, tmp_ccache, princ);
360 snprintf(errstr, sizeof(errstr),
361 "krb5_cc_initialize() failed: %s",
362 krb5_get_err_text(kcontext, problem));
363 ap_log_reason (errstr, r->uri, r);
368 ap_table_setn(r->subprocess_env, "KRB5CCNAME", ccname);
369 ap_register_cleanup(r->pool, ccname,
370 krb5_cache_cleanup, ap_null_cleanup);
372 *ccache = tmp_ccache;
379 krb5_cc_destroy(kcontext, tmp_ccache);
381 return ret; /* XXX */
385 store_krb5_creds(krb5_context kcontext,
387 kerb_auth_config *conf,
388 krb5_ccache delegated_cred)
391 krb5_error_code problem;
392 krb5_principal princ;
396 problem = krb5_cc_get_principal(kcontext, delegated_cred, &princ);
398 snprintf(errstr, sizeof(errstr), "krb5_cc_get_principal() failed: %s",
399 krb5_get_err_text(kcontext, problem));
403 ret = create_krb5_ccache(kcontext, r, conf, princ, &ccache);
405 krb5_free_principal(kcontext, princ);
409 problem = krb5_cc_copy_cache(kcontext, delegated_cred, ccache);
410 krb5_free_principal(kcontext, princ);
412 snprintf(errstr, sizeof(errstr), "krb5_cc_copy_cache() failed: %s",
413 krb5_get_err_text(kcontext, problem));
414 krb5_cc_destroy(kcontext, ccache);
418 krb5_cc_close(kcontext, ccache);
422 int authenticate_user_krb5pwd(request_rec *r,
423 kerb_auth_config *conf,
424 const char *auth_line)
426 const char *sent_pw = NULL;
427 const char *realms = NULL;
428 krb5_context kcontext;
429 krb5_error_code code;
430 krb5_principal client = NULL;
431 krb5_ccache ccache = NULL;
434 code = krb5_init_context(&kcontext);
436 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
437 "Cannot initialize Kerberos5 context (%d)", code);
441 sent_pw = ap_uudecode(r->pool, auth_line);
442 r->connection->user = ap_getword (r->pool, &sent_pw, ':');
443 r->connection->ap_auth_type = "Basic";
445 /* do not allow user to override realm setting of server */
446 if (strchr(r->connection->user,'@')) {
447 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
448 "specifying realm in user name is prohibited");
449 ret = HTTP_UNAUTHORIZED;
454 code = krb5_cc_gen_new(kcontext, &krb5_mcc_ops, &ccache);
456 code = krb5_mcc_generate_new(kcontext, &ccache);
459 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
460 "Cannot generate new ccache: %s",
461 krb5_get_err_text(kcontext, code));
466 realms = conf->krb_auth_realms;
468 if (realms && krb5_set_default_realm(kcontext,
469 ap_getword_white(r->pool, &realms)))
472 code = krb5_parse_name(kcontext, r->connection->user, &client);
476 code = krb5_verify_user(kcontext, client, ccache, sent_pw, 1, "khttp");
477 krb5_free_principal(kcontext, client);
481 /* ap_getword_white() used above shifts the parameter, so it's not
482 needed to touch the realms variable */
483 } while (realms && *realms);
485 memset((char *)sent_pw, 0, strlen(sent_pw));
488 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
489 "Verifying krb5 password failed: %s",
490 krb5_get_err_text(kcontext, code));
491 ret = HTTP_UNAUTHORIZED;
495 if (conf->krb_save_credentials) {
496 ret = store_krb5_creds(kcontext, r, conf, ccache);
497 if (ret) /* Ignore error ?? */
505 krb5_free_principal(kcontext, client);
507 krb5_cc_destroy(kcontext, ccache);
508 krb5_free_context(kcontext);
515 int kerb4_password_validate(request_rec *r, const char *user, const char *pass)
517 kerb_auth_config *conf =
518 (kerb_auth_config *)ap_get_module_config(r->per_dir_config,
521 int lifetime = DEFAULT_TKT_LIFE;
523 char *username = NULL;
524 char *instance = NULL;
527 username = (char *)ap_pstrdup(r->pool, user);
532 instance = strchr(username, '.');
540 realm = strchr(username, '@');
548 if (conf->krb_lifetime) {
549 lifetime = atoi(conf->krb_lifetime);
552 if (conf->krb_force_instance) {
553 instance = conf->krb_force_instance;
556 if (conf->krb_save_credentials) {
557 tfname = (char *)malloc(sizeof(char) * MAX_STRING_LEN);
558 sprintf(tfname, "%s/k5cc_ap_%s",
559 conf->krb_tmp_dir ? conf->krb_tmp_dir : "/tmp",
562 if (!strcmp(instance, "")) {
563 tfname = strcat(tfname, ".");
564 tfname = strcat(tfname, instance);
567 if (!strcmp(realm, "")) {
568 tfname = strcat(tfname, ".");
569 tfname = strcat(tfname, realm);
572 for (c = tfname + strlen(conf->krb_tmp_dir ? conf->krb_tmp_dir :
573 "/tmp") + 1; *c; c++) {
578 krb_set_tkt_string(tfname);
581 if (!strcmp(realm, "")) {
582 realm = (char *)malloc(sizeof(char) * (REALM_SZ + 1));
583 ret = krb_get_lrealm(realm, 1);
588 ret = krb_get_pw_in_tkt((char *)user, instance, realm, "krbtgt", realm,
589 lifetime, (char *)pass);
606 /***************************************************************************
608 ***************************************************************************/
611 get_gss_error(pool *p, OM_uint32 error_status, char *prefix)
613 OM_uint32 maj_stat, min_stat;
614 OM_uint32 msg_ctx = 0;
615 gss_buffer_desc status_string;
619 snprintf(buf, sizeof(buf), "%s: ", prefix);
622 maj_stat = gss_display_status (&min_stat,
628 if (sizeof(buf) > len + status_string.length + 1) {
629 sprintf(buf+len, "%s:", (char*) status_string.value);
630 len += status_string.length;
632 gss_release_buffer(&min_stat, &status_string);
633 } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
635 return (ap_pstrdup(p, buf));
639 get_gss_creds(request_rec *r,
640 kerb_auth_config *conf,
641 gss_cred_id_t *server_creds)
644 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
645 OM_uint32 major_status, minor_status;
646 gss_name_t server_name = GSS_C_NO_NAME;
648 if (conf->service_name) {
649 input_token.value = conf->service_name;
650 input_token.length = strlen(conf->service_name) + 1;
653 input_token.value = "khttp";
654 input_token.length = 6;
656 major_status = gss_import_name(&minor_status, &input_token,
657 (conf->service_name) ?
658 GSS_C_NT_USER_NAME : GSS_C_NT_HOSTBASED_SERVICE,
660 if (GSS_ERROR(major_status)) {
661 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, r,
662 "%s", get_gss_error(r->pool, minor_status,
663 "gss_import_name() failed"));
669 if (conf->krb_5_keytab)
670 setenv("KRB5_KTNAME", conf->krb_5_keytab, 1);
673 major_status = gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE,
674 GSS_C_NO_OID_SET, GSS_C_ACCEPT,
675 server_creds, NULL, NULL);
677 if (conf->krb_5_keytab)
678 unsetenv("KRB5_KTNAME");
680 if (GSS_ERROR(major_status)) {
681 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, r,
682 "%s", get_gss_error(r->pool, minor_status,
683 "gss_acquire_cred() failed"));
697 authenticate_user_gss(request_rec *r,
698 kerb_auth_config *conf,
699 const char *auth_line)
701 OM_uint32 major_status, minor_status, minor_status2;
702 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
703 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
704 const char *auth_param = NULL;
706 gss_name_t client_name = GSS_C_NO_NAME;
707 gss_cred_id_t delegated_cred = GSS_C_NO_CREDENTIAL;
709 if (gss_connection == NULL) {
710 gss_connection = ap_pcalloc(r->connection->pool, sizeof(*gss_connection));
711 if (gss_connection == NULL) {
712 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
713 "ap_pcalloc() failed (not enough memory)");
717 memset(gss_connection, 0, sizeof(*gss_connection));
718 ap_register_cleanup(r->connection->pool, gss_connection, cleanup_gss_connection, ap_null_cleanup);
721 if (gss_connection->server_creds == GSS_C_NO_CREDENTIAL) {
722 ret = get_gss_creds(r, conf, &gss_connection->server_creds);
727 /* ap_getword() shifts parameter */
728 auth_param = ap_getword_white(r->pool, &auth_line);
729 if (auth_param == NULL) {
730 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
731 "No Authorization parameter in request from client");
732 ret = HTTP_UNAUTHORIZED;
736 input_token.length = ap_base64decode_len(auth_param);
737 input_token.value = ap_pcalloc(r->connection->pool, input_token.length);
738 if (input_token.value == NULL) {
739 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
740 "ap_pcalloc() failed (not enough memory)");
744 input_token.length = ap_base64decode(input_token.value, auth_param);
746 major_status = gss_accept_sec_context(&minor_status,
747 &gss_connection->context,
748 gss_connection->server_creds,
750 GSS_C_NO_CHANNEL_BINDINGS,
757 if (output_token.length) {
761 len = ap_base64encode_len(output_token.length);
762 token = ap_pcalloc(r->connection->pool, len + 1);
764 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
765 "ap_pcalloc() failed (not enough memory)");
767 gss_release_buffer(&minor_status2, &output_token);
770 ap_base64encode(token, output_token.value, output_token.length);
772 ap_table_set(r->err_headers_out, "WWW-Authenticate",
773 ap_pstrcat(r->pool, "GSS-Negotiate ", token, NULL));
774 gss_release_buffer(&minor_status2, &output_token);
777 if (GSS_ERROR(major_status)) {
778 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
779 "%s", get_gss_error(r->pool, minor_status,
780 "gss_accept_sec_context() failed"));
781 ret = HTTP_UNAUTHORIZED;
785 if (major_status & GSS_S_CONTINUE_NEEDED) {
786 /* Some GSSAPI mechanism (eg GSI from Globus) may require multiple
787 * iterations to establish authentication */
788 ret = HTTP_UNAUTHORIZED;
792 major_status = gss_export_name(&minor_status, client_name, &output_token);
793 gss_release_name(&minor_status, &client_name);
794 if (GSS_ERROR(major_status)) {
795 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
796 "%s", get_gss_error(r->pool, minor_status,
797 "gss_export_name() failed"));
802 r->connection->ap_auth_type = "Negotiate";
803 r->connection->user = ap_pstrdup(r->pool, output_token.value);
805 /* If the user comes from a realm specified by configuration don't include
806 its realm name in the username so that the authorization routine could
807 work for both Password-based and Ticket-based authentication. It's
808 administrators responsibility to include only such realm that have
809 unified principal instances, i.e. if the same principal name occures in
810 multiple realms, it must be always assigned to a single user.
812 p = strchr(r->connection->user, '@');
814 const char *realms = conf->gss_krb5_realms;
816 while (realms && *realms) {
817 if (strcmp(p+1, ap_getword_white(r->pool, &realms)) == 0) {
825 gss_release_buffer(&minor_status, &output_token);
828 /* This should be only done if afs token are requested or gss_save creds is
830 /* gss_export_cred() from the GGF GSS Extensions could be used */
831 if (delegated_cred != GSS_C_NO_CREDENTIAL &&
832 (conf->gss_save_creds || (conf->gss_krb5_cells && k_hasafs()))) {
833 krb5_init_context(&krb_ctx);
834 do_afs_log(krb_ctx, r, delegated_cred->ccache, conf->gss_krb5_cells);
835 ret = store_krb5_creds(krb_ctx, r, conf, delegated_cred->ccache);
836 krb5_free_context(krb_ctx);
845 gss_release_cred(&minor_status, &delegated_cred);
847 if (output_token.length)
848 gss_release_buffer(&minor_status, &output_token);
850 if (client_name != GSS_C_NO_NAME)
851 gss_release_name(&minor_status, &client_name);
859 note_auth_failure(request_rec *r, const kerb_auth_config *conf)
861 const char *auth_type = NULL;
862 const char *auth_name = NULL;
864 /* get the type specified in .htaccess */
865 auth_type = ap_auth_type(r);
867 /* get the user realm specified in .htaccess */
868 auth_name = ap_auth_name(r);
870 /* XXX should the WWW-Authenticate header be cleared first? */
872 if (conf->krb_method_gssapi)
873 ap_table_add(r->err_headers_out, "WWW-Authenticate", "GSS-Negotiate ");
875 if (auth_type && strncasecmp(auth_type, "KerberosV5", 10) == 0)
876 ap_table_add(r->err_headers_out, "WWW-Authenticate",
877 ap_pstrcat(r->pool, "Basic realm=\"", auth_name, "\"", NULL));
882 /***************************************************************************
884 ***************************************************************************/
885 int kerb_authenticate_user(request_rec *r)
887 kerb_auth_config *conf =
888 (kerb_auth_config *) ap_get_module_config(r->per_dir_config,
890 const char *auth_type = NULL;
891 const char *auth_line = NULL;
892 const char *type = NULL;
895 /* get the type specified in .htaccess */
896 type = ap_auth_type(r);
898 if (!conf->krb_auth_enable &&
899 (type == NULL || (strncasecmp(type, "Kerberos", 8) != 0)))
902 /* get what the user sent us in the HTTP header */
903 auth_line = MK_TABLE_GET(r->headers_in, "Authorization");
905 note_auth_failure(r, conf);
906 return HTTP_UNAUTHORIZED;
908 auth_type = ap_getword_white(r->pool, &auth_line);
910 ret = HTTP_UNAUTHORIZED;
912 /* XXX Support for AuthType=Kerberos */
915 if (conf->krb_method_gssapi &&
916 strcasecmp(auth_type, "GSS-Negotiate") == 0) {
917 ret = authenticate_user_gss(r, conf, auth_line);
918 } else if (conf->krb_method_k5pass &&
919 strcasecmp(auth_type, "Basic") == 0) {
920 ret = authenticate_user_krb5pwd(r, conf, auth_line);
925 if (ret == HTTP_UNAUTHORIZED && conf->krb_method_k4pass &&
926 strcasecmp(auth_type, "Basic") == 0)
927 ret = authenticate_user_krb4pwd(r, conf, auth_line);
930 if (ret == HTTP_UNAUTHORIZED)
931 note_auth_failure(r, conf);
938 int kerb_check_user_access(request_rec *r)
942 const MK_ARRAY_HEADER *reqs_arr = ap_requires(r);
944 kerb_auth_config *conf =
945 (kerb_auth_config *)ap_get_module_config(r->per_dir_config,
948 if (reqs_arr == NULL) {
951 reqs = (require_line *)reqs_arr->elts;
953 for (x = 0; x < reqs_arr->nelts; x++) {
954 t = reqs[x].requirement;
955 w = ap_getword_white(r->pool, &t);
956 if (strcmp(w, "realm") == 0) {
957 while (t[0] != '\0') {
958 w = ap_getword_conf(r->pool, &t);
959 if (strcmp(MK_USER, w) == 0) {
973 /***************************************************************************
974 Module Setup/Configuration
975 ***************************************************************************/
977 module MODULE_VAR_EXPORT kerb_auth_module = {
978 STANDARD_MODULE_STUFF,
979 NULL, /* module initializer */
980 kerb_dir_create_config, /* per-directory config creator */
981 NULL, /* per-directory config merger */
982 NULL, /* per-server config creator */
983 NULL, /* per-server config merger */
984 kerb_auth_cmds, /* command table */
985 NULL, /* [ 9] content handlers */
986 NULL, /* [ 2] URI-to-filename translation */
987 kerb_authenticate_user, /* [ 5] check/validate user_id */
988 NULL, /* [ 6] check user_id is valid *here* */
989 NULL, /* [ 4] check access by host address */
990 NULL, /* [ 7] MIME type checker/setter */
991 NULL, /* [ 8] fixups */
992 NULL, /* [10] logger */
993 NULL, /* [ 3] header parser */
994 NULL, /* process initialization */
995 NULL, /* process exit/cleanup */
996 NULL /* [ 1] post read_request handling */
999 void kerb_register_hooks(apr_pool_t *p)
1001 ap_hook_check_user_id(kerb_authenticate_user, NULL, NULL, APR_HOOK_MIDDLE);
1004 module AP_MODULE_DECLARE_DATA kerb_auth_module =
1006 STANDARD20_MODULE_STUFF,
1007 kerb_dir_create_config, /* create per-dir conf structures */
1008 NULL, /* merge per-dir conf structures */
1009 NULL, /* create per-server conf structures */
1010 NULL, /* merge per-server conf structures */
1011 kerb_auth_cmds, /* table of configuration directives */
1012 kerb_register_hooks /* register hooks */