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;
202 static const char *kerb_set_fail_slot(cmd_parms *cmd, void *struct_ptr,
205 int offset = (int) (long) cmd->info;
206 if (!strncasecmp(arg, "unauthorized", 12))
207 *(int *) ((char *)struct_ptr + offset) = HTTP_UNAUTHORIZED;
208 else if (!strncasecmp(arg, "forbidden", 9))
209 *(int *) ((char *)struct_ptr + offset) = HTTP_FORBIDDEN;
210 else if (!strncasecmp(arg, "declined", 8))
211 *(int *) ((char *)struct_ptr + offset) = DECLINED;
213 return "KrbAuthFailStatus must be Forbidden, Unauthorized, or Declined.";
221 krb5_verify_user(krb5_context context, krb5_principal principal,
222 krb5_ccache ccache, const char *password, krb5_boolean secure,
226 krb5_context kcontext;
227 krb5_principal server, client;
230 krb5_flags options = 0;
231 krb5_principal me = NULL;
232 krb5_data tgtname = {
238 memset((char *)&my_creds, 0, sizeof(my_creds));
239 my_creds.client = principal;
241 if (krb5_build_principal_ext(kcontext, &server,
242 krb5_princ_realm(kcontext, me)->length,
243 krb5_princ_realm(kcontext, me)->data,
244 tgtname.length, tgtname.data,
245 krb5_princ_realm(kcontext, me)->length,
246 krb5_princ_realm(kcontext, me)->data,
251 my_creds.server = server;
252 if (krb5_timeofday(kcontext, &now))
255 my_creds.times.starttime = 0;
257 my_creds.times.endtime = now + lifetime;
258 my_creds.times.renew_till = now + renewal;
261 ret = krb5_get_in_tkt_with_password(kcontext, options, 0, NULL, 0,
262 password, ccache, &my_creds, 0);
272 /***************************************************************************
273 Username/Password Validation
274 ***************************************************************************/
277 krb5_cache_cleanup(void *data)
279 krb5_context context;
281 krb5_error_code problem;
282 char *cache_name = (char *) data;
284 problem = krb5_init_context(&context);
286 ap_log_error(APLOG_MARK, APLOG_ERR, NULL, "krb5_init_context() failed");
290 problem = krb5_cc_resolve(context, cache_name, &cache);
292 ap_log_error(APLOG_MARK, APLOG_ERR, NULL,
293 "krb5_cc_resolve() failed (%s: %s)",
294 cache_name, krb5_get_err_text(context, problem));
298 krb5_cc_destroy(context, cache);
299 krb5_free_context(context);
303 create_krb5_ccache(krb5_context kcontext,
305 kerb_auth_config *conf,
306 krb5_principal princ,
309 char *c, ccname[MAX_STRING_LEN];
310 krb5_error_code problem;
313 krb5_ccache tmp_ccache = NULL;
315 snprintf(ccname, sizeof(ccname), "FILE:%s/k5cc_ap_%s",
316 conf->krb_tmp_dir ? conf->krb_tmp_dir : "/tmp",
319 for (c = ccname + strlen(conf->krb_tmp_dir ? conf->krb_tmp_dir :
320 "/tmp") + 1; *c; c++) {
326 /* not sure what's the purpose of this call here */
327 problem = krb5_cc_set_default_name(kcontext, ccname);
329 snprintf(errstr, sizeof(errstr),
330 "krb5_cc_set_default_name() failed: %s",
331 krb5_get_err_text(kcontext, problem));
332 ap_log_reason (errstr, r->uri, r);
340 /* XXX Dan: Why is this done? Cleanup? But the file would not be
341 * accessible from another processes (CGI) */
342 unlink(ccname+strlen("FILE:"));
345 problem = krb5_cc_resolve(kcontext, ccname, &tmp_ccache);
347 snprintf(errstr, sizeof(errstr),
348 "krb5_cc_resolve() failed: %s",
349 krb5_get_err_text(kcontext, problem));
350 ap_log_reason (errstr, r->uri, r);
355 problem = krb5_cc_initialize(kcontext, tmp_ccache, princ);
357 snprintf(errstr, sizeof(errstr),
358 "krb5_cc_initialize() failed: %s",
359 krb5_get_err_text(kcontext, problem));
360 ap_log_reason (errstr, r->uri, r);
365 ap_table_setn(r->subprocess_env, "KRB5CCNAME", ccname);
366 ap_register_cleanup(r->pool, ccname,
367 krb5_cache_cleanup, ap_null_cleanup);
369 *ccache = tmp_ccache;
376 krb5_cc_destroy(kcontext, tmp_ccache);
378 return ret; /* XXX */
382 store_krb5_creds(krb5_context kcontext,
384 kerb_auth_config *conf,
385 krb5_ccache delegated_cred)
388 krb5_error_code problem;
389 krb5_principal princ;
393 problem = krb5_cc_get_principal(kcontext, delegated_cred, &princ);
395 snprintf(errstr, sizeof(errstr), "krb5_cc_get_principal() failed: %s",
396 krb5_get_err_text(kcontext, problem));
400 ret = create_krb5_ccache(kcontext, r, conf, princ, &ccache);
402 krb5_free_principal(kcontext, princ);
406 problem = krb5_cc_copy_cache(kcontext, delegated_cred, ccache);
407 krb5_free_principal(kcontext, princ);
409 snprintf(errstr, sizeof(errstr), "krb5_cc_copy_cache() failed: %s",
410 krb5_get_err_text(kcontext, problem));
411 krb5_cc_destroy(kcontext, ccache);
415 krb5_cc_close(kcontext, ccache);
419 int authenticate_user_krb5pwd(request_rec *r,
420 kerb_auth_config *conf,
421 const char *auth_line)
423 const char *sent_pw = NULL;
424 const char *realms = NULL;
425 krb5_context kcontext;
426 krb5_error_code code;
427 krb5_principal client = NULL;
428 krb5_ccache ccache = NULL;
431 code = krb5_init_context(&kcontext);
433 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
434 "Cannot initialize Kerberos5 context (%d)", code);
438 sent_pw = ap_uudecode(r->pool, auth_line);
439 r->connection->user = ap_getword (r->pool, &sent_pw, ':');
440 r->connection->ap_auth_type = "Basic";
442 /* do not allow user to override realm setting of server */
443 if (strchr(r->connection->user,'@')) {
444 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
445 "specifying realm in user name is prohibited");
446 ret = HTTP_UNAUTHORIZED;
451 code = krb5_cc_gen_new(kcontext, &krb5_mcc_ops, &ccache);
453 code = krb5_mcc_generate_new(kcontext, &ccache);
456 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
457 "Cannot generate new ccache: %s",
458 krb5_get_err_text(kcontext, code));
463 realms = conf->krb_auth_realms;
465 if (realms && krb5_set_default_realm(kcontext,
466 ap_getword_white(r->pool, &realms)))
469 code = krb5_parse_name(kcontext, r->connection->user, &client);
473 code = krb5_verify_user(kcontext, client, ccache, sent_pw, 1, "khttp");
474 krb5_free_principal(kcontext, client);
478 /* ap_getword_white() used above shifts the parameter, so it's not
479 needed to touch the realms variable */
480 } while (realms && *realms);
482 memset((char *)sent_pw, 0, strlen(sent_pw));
485 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
486 "Verifying krb5 password failed: %s",
487 krb5_get_err_text(kcontext, code));
488 ret = HTTP_UNAUTHORIZED;
492 if (conf->krb_save_credentials) {
493 ret = store_krb5_creds(kcontext, r, conf, ccache);
494 if (ret) /* Ignore error ?? */
502 krb5_free_principal(kcontext, client);
504 krb5_cc_destroy(kcontext, ccache);
505 krb5_free_context(kcontext);
512 int kerb4_password_validate(request_rec *r, const char *user, const char *pass)
514 kerb_auth_config *conf =
515 (kerb_auth_config *)ap_get_module_config(r->per_dir_config,
518 int lifetime = DEFAULT_TKT_LIFE;
520 char *username = NULL;
521 char *instance = NULL;
524 username = (char *)ap_pstrdup(r->pool, user);
529 instance = strchr(username, '.');
537 realm = strchr(username, '@');
545 if (conf->krb_lifetime) {
546 lifetime = atoi(conf->krb_lifetime);
549 if (conf->krb_force_instance) {
550 instance = conf->krb_force_instance;
553 if (conf->krb_save_credentials) {
554 tfname = (char *)malloc(sizeof(char) * MAX_STRING_LEN);
555 sprintf(tfname, "%s/k5cc_ap_%s",
556 conf->krb_tmp_dir ? conf->krb_tmp_dir : "/tmp",
559 if (!strcmp(instance, "")) {
560 tfname = strcat(tfname, ".");
561 tfname = strcat(tfname, instance);
564 if (!strcmp(realm, "")) {
565 tfname = strcat(tfname, ".");
566 tfname = strcat(tfname, realm);
569 for (c = tfname + strlen(conf->krb_tmp_dir ? conf->krb_tmp_dir :
570 "/tmp") + 1; *c; c++) {
575 krb_set_tkt_string(tfname);
578 if (!strcmp(realm, "")) {
579 realm = (char *)malloc(sizeof(char) * (REALM_SZ + 1));
580 ret = krb_get_lrealm(realm, 1);
585 ret = krb_get_pw_in_tkt((char *)user, instance, realm, "krbtgt", realm,
586 lifetime, (char *)pass);
603 /***************************************************************************
605 ***************************************************************************/
608 get_gss_error(pool *p, OM_uint32 error_status, char *prefix)
610 OM_uint32 maj_stat, min_stat;
611 OM_uint32 msg_ctx = 0;
612 gss_buffer_desc status_string;
616 snprintf(buf, sizeof(buf), "%s: ", prefix);
619 maj_stat = gss_display_status (&min_stat,
625 if (sizeof(buf) > len + status_string.length + 1) {
626 sprintf(buf+len, "%s:", (char*) status_string.value);
627 len += status_string.length;
629 gss_release_buffer(&min_stat, &status_string);
630 } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
632 return (ap_pstrdup(p, buf));
636 get_gss_creds(request_rec *r,
637 kerb_auth_config *conf,
638 gss_cred_id_t *server_creds)
641 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
642 OM_uint32 major_status, minor_status;
643 gss_name_t server_name = GSS_C_NO_NAME;
645 if (conf->service_name) {
646 input_token.value = conf->service_name;
647 input_token.length = strlen(conf->service_name) + 1;
650 input_token.value = "khttp";
651 input_token.length = 6;
653 major_status = gss_import_name(&minor_status, &input_token,
654 (conf->service_name) ?
655 GSS_C_NT_USER_NAME : GSS_C_NT_HOSTBASED_SERVICE,
657 if (GSS_ERROR(major_status)) {
658 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, r,
659 "%s", get_gss_error(r->pool, minor_status,
660 "gss_import_name() failed"));
666 if (conf->krb_5_keytab)
667 setenv("KRB5_KTNAME", conf->krb_5_keytab, 1);
670 major_status = gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE,
671 GSS_C_NO_OID_SET, GSS_C_ACCEPT,
672 server_creds, NULL, NULL);
674 if (conf->krb_5_keytab)
675 unsetenv("KRB5_KTNAME");
677 if (GSS_ERROR(major_status)) {
678 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, r,
679 "%s", get_gss_error(r->pool, minor_status,
680 "gss_acquire_cred() failed"));
694 authenticate_user_gss(request_rec *r,
695 kerb_auth_config *conf,
696 const char *auth_line)
698 OM_uint32 major_status, minor_status, minor_status2;
699 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
700 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
701 const char *auth_param = NULL;
703 gss_name_t client_name = GSS_C_NO_NAME;
704 gss_cred_id_t delegated_cred = GSS_C_NO_CREDENTIAL;
706 if (gss_connection == NULL) {
707 gss_connection = ap_pcalloc(r->connection->pool, sizeof(*gss_connection));
708 if (gss_connection == NULL) {
709 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
710 "ap_pcalloc() failed (not enough memory)");
714 memset(gss_connection, 0, sizeof(*gss_connection));
715 ap_register_cleanup(r->connection->pool, gss_connection, cleanup_gss_connection, ap_null_cleanup);
718 if (gss_connection->server_creds == GSS_C_NO_CREDENTIAL) {
719 ret = get_gss_creds(r, conf, &gss_connection->server_creds);
724 /* ap_getword() shifts parameter */
725 auth_param = ap_getword_white(r->pool, &auth_line);
726 if (auth_param == NULL) {
727 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
728 "No Authorization parameter in request from client");
729 ret = HTTP_UNAUTHORIZED;
733 input_token.length = ap_base64decode_len(auth_param);
734 input_token.value = ap_pcalloc(r->connection->pool, input_token.length);
735 if (input_token.value == NULL) {
736 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
737 "ap_pcalloc() failed (not enough memory)");
741 input_token.length = ap_base64decode(input_token.value, auth_param);
743 major_status = gss_accept_sec_context(&minor_status,
744 &gss_connection->context,
745 gss_connection->server_creds,
747 GSS_C_NO_CHANNEL_BINDINGS,
754 if (output_token.length) {
758 len = ap_base64encode_len(output_token.length);
759 token = ap_pcalloc(r->connection->pool, len + 1);
761 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
762 "ap_pcalloc() failed (not enough memory)");
764 gss_release_buffer(&minor_status2, &output_token);
767 ap_base64encode(token, output_token.value, output_token.length);
769 ap_table_set(r->err_headers_out, "WWW-Authenticate",
770 ap_pstrcat(r->pool, "GSS-Negotiate ", token, NULL));
771 gss_release_buffer(&minor_status2, &output_token);
774 if (GSS_ERROR(major_status)) {
775 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
776 "%s", get_gss_error(r->pool, minor_status,
777 "gss_accept_sec_context() failed"));
778 ret = HTTP_UNAUTHORIZED;
782 if (major_status & GSS_S_CONTINUE_NEEDED) {
783 /* Some GSSAPI mechanism (eg GSI from Globus) may require multiple
784 * iterations to establish authentication */
785 ret = HTTP_UNAUTHORIZED;
789 major_status = gss_export_name(&minor_status, client_name, &output_token);
790 gss_release_name(&minor_status, &client_name);
791 if (GSS_ERROR(major_status)) {
792 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
793 "%s", get_gss_error(r->pool, minor_status,
794 "gss_export_name() failed"));
799 r->connection->ap_auth_type = "Negotiate";
800 r->connection->user = ap_pstrdup(r->pool, output_token.value);
802 /* If the user comes from a realm specified by configuration don't include
803 its realm name in the username so that the authorization routine could
804 work for both Password-based and Ticket-based authentication. It's
805 administrators responsibility to include only such realm that have
806 unified principal instances, i.e. if the same principal name occures in
807 multiple realms, it must be always assigned to a single user.
809 p = strchr(r->connection->user, '@');
811 const char *realms = conf->gss_krb5_realms;
813 while (realms && *realms) {
814 if (strcmp(p+1, ap_getword_white(r->pool, &realms)) == 0) {
822 gss_release_buffer(&minor_status, &output_token);
825 /* This should be only done if afs token are requested or gss_save creds is
827 /* gss_export_cred() from the GGF GSS Extensions could be used */
828 if (delegated_cred != GSS_C_NO_CREDENTIAL &&
829 (conf->gss_save_creds || (conf->gss_krb5_cells && k_hasafs()))) {
830 krb5_init_context(&krb_ctx);
831 do_afs_log(krb_ctx, r, delegated_cred->ccache, conf->gss_krb5_cells);
832 ret = store_krb5_creds(krb_ctx, r, conf, delegated_cred->ccache);
833 krb5_free_context(krb_ctx);
842 gss_release_cred(&minor_status, &delegated_cred);
844 if (output_token.length)
845 gss_release_buffer(&minor_status, &output_token);
847 if (client_name != GSS_C_NO_NAME)
848 gss_release_name(&minor_status, &client_name);
856 note_auth_failure(request_rec *r, const kerb_auth_config *conf)
858 const char *auth_type = NULL;
859 const char *auth_name = NULL;
861 /* get the type specified in .htaccess */
862 auth_type = ap_auth_type(r);
864 /* get the user realm specified in .htaccess */
865 auth_name = ap_auth_name(r);
867 /* XXX should the WWW-Authenticate header be cleared first? */
869 if (conf->krb_method_gssapi)
870 ap_table_add(r->err_headers_out, "WWW-Authenticate", "GSS-Negotiate ");
872 if (auth_type && strncasecmp(auth_type, "KerberosV5", 10) == 0)
873 ap_table_add(r->err_headers_out, "WWW-Authenticate",
874 ap_pstrcat(r->pool, "Basic realm=\"", auth_name, "\"", NULL));
879 /***************************************************************************
881 ***************************************************************************/
882 int kerb_authenticate_user(request_rec *r)
884 kerb_auth_config *conf =
885 (kerb_auth_config *) ap_get_module_config(r->per_dir_config,
887 const char *auth_type = NULL;
888 const char *auth_line = NULL;
889 const char *type = NULL;
892 /* get the type specified in .htaccess */
893 type = ap_auth_type(r);
896 if (type != NULL && strcasecmp(type, "KerberosV5") == 0) {
897 ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
898 "The use of KerberosV5 in AuthType is obsolete, please consider using the AuthKerberos option");
899 conf->krb_auth_enable = 1;
904 if (type != NULL && strcasecmp(type, "KerberosV4") == 0) {
905 ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
906 "The use of KerberosV4 in AuthType is obsolete, please consider using the AuthKerberos option");
907 conf->krb_auth_enable = 1;
911 if (!conf->krb_auth_enable)
914 /* get what the user sent us in the HTTP header */
915 auth_line = MK_TABLE_GET(r->headers_in, "Authorization");
917 note_auth_failure(r, conf);
918 return HTTP_UNAUTHORIZED;
920 auth_type = ap_getword_white(r->pool, &auth_line);
922 ret = HTTP_UNAUTHORIZED;
925 if (conf->krb_method_gssapi &&
926 strcasecmp(auth_type, "GSS-Negotiate") == 0) {
927 ret = authenticate_user_gss(r, conf, auth_line);
928 } else if (conf->krb_method_k5pass &&
929 strcasecmp(auth_type, "Basic") == 0) {
930 ret = authenticate_user_krb5pwd(r, conf, auth_line);
935 if (ret == HTTP_UNAUTHORIZED && conf->krb_method_k4pass &&
936 strcasecmp(auth_type, "Basic") == 0)
937 ret = authenticate_user_krb4pwd(r, conf, auth_line);
940 if (ret == HTTP_UNAUTHORIZED)
941 note_auth_failure(r, conf);
948 int kerb_check_user_access(request_rec *r)
952 const MK_ARRAY_HEADER *reqs_arr = ap_requires(r);
954 kerb_auth_config *conf =
955 (kerb_auth_config *)ap_get_module_config(r->per_dir_config,
958 if (reqs_arr == NULL) {
961 reqs = (require_line *)reqs_arr->elts;
963 for (x = 0; x < reqs_arr->nelts; x++) {
964 t = reqs[x].requirement;
965 w = ap_getword_white(r->pool, &t);
966 if (strcmp(w, "realm") == 0) {
967 while (t[0] != '\0') {
968 w = ap_getword_conf(r->pool, &t);
969 if (strcmp(MK_USER, w) == 0) {
983 /***************************************************************************
984 Module Setup/Configuration
985 ***************************************************************************/
987 module MODULE_VAR_EXPORT kerb_auth_module = {
988 STANDARD_MODULE_STUFF,
989 NULL, /* module initializer */
990 kerb_dir_create_config, /* per-directory config creator */
991 NULL, /* per-directory config merger */
992 NULL, /* per-server config creator */
993 NULL, /* per-server config merger */
994 kerb_auth_cmds, /* command table */
995 NULL, /* [ 9] content handlers */
996 NULL, /* [ 2] URI-to-filename translation */
997 kerb_authenticate_user, /* [ 5] check/validate user_id */
998 NULL, /* [ 6] check user_id is valid *here* */
999 NULL, /* [ 4] check access by host address */
1000 NULL, /* [ 7] MIME type checker/setter */
1001 NULL, /* [ 8] fixups */
1002 NULL, /* [10] logger */
1003 NULL, /* [ 3] header parser */
1004 NULL, /* process initialization */
1005 NULL, /* process exit/cleanup */
1006 NULL /* [ 1] post read_request handling */
1009 void kerb_register_hooks(apr_pool_t *p)
1011 ap_hook_check_user_id(kerb_authenticate_user, NULL, NULL, APR_HOOK_MIDDLE);
1014 module AP_MODULE_DECLARE_DATA kerb_auth_module =
1016 STANDARD20_MODULE_STUFF,
1017 kerb_dir_create_config, /* create per-dir conf structures */
1018 NULL, /* merge per-dir conf structures */
1019 NULL, /* create per-server conf structures */
1020 NULL, /* merge per-server conf structures */
1021 kerb_auth_cmds, /* table of configuration directives */
1022 kerb_register_hooks /* register hooks */