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("KrbAuthRealms", 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."),
151 gss_ctx_id_t context;
152 gss_cred_id_t server_creds;
155 static gss_connection_t *gss_connection = NULL;
159 /***************************************************************************
160 Auth Configuration Initialization
161 ***************************************************************************/
162 static void *kerb_dir_create_config(MK_POOL *p, char *d)
164 kerb_auth_config *rec;
166 rec = (kerb_auth_config *) ap_pcalloc(p, sizeof(kerb_auth_config));
167 ((kerb_auth_config *)rec)->krb_auth_enable = 1;
168 ((kerb_auth_config *)rec)->krb_fail_status = HTTP_UNAUTHORIZED;
170 ((kerb_auth_config *)rec)->krb_method_k5pass = 1;
171 ((kerb_auth_config *)rec)->krb_method_gssapi = 1;
174 ((kerb_auth_config *)rec)->krb_method_k4pass = 1;
181 static const char *kerb_set_fail_slot(cmd_parms *cmd, void *struct_ptr,
184 int offset = (int) (long) cmd->info;
185 if (!strncasecmp(arg, "unauthorized", 12))
186 *(int *) ((char *)struct_ptr + offset) = HTTP_UNAUTHORIZED;
187 else if (!strncasecmp(arg, "forbidden", 9))
188 *(int *) ((char *)struct_ptr + offset) = HTTP_FORBIDDEN;
189 else if (!strncasecmp(arg, "declined", 8))
190 *(int *) ((char *)struct_ptr + offset) = DECLINED;
192 return "KrbAuthFailStatus must be Forbidden, Unauthorized, or Declined.";
198 /***************************************************************************
199 Username/Password Validation for Krb4
200 ***************************************************************************/
201 int kerb4_password_validate(request_rec *r, const char *user, const char *pass)
203 kerb_auth_config *conf =
204 (kerb_auth_config *)ap_get_module_config(r->per_dir_config,
207 int lifetime = DEFAULT_TKT_LIFE;
209 char *username = NULL;
210 char *instance = NULL;
213 username = (char *)ap_pstrdup(r->pool, user);
218 instance = strchr(username, '.');
226 realm = strchr(username, '@');
234 if (conf->krb_lifetime) {
235 lifetime = atoi(conf->krb_lifetime);
238 if (conf->krb_force_instance) {
239 instance = conf->krb_force_instance;
242 if (conf->krb_save_credentials) {
243 tfname = (char *)malloc(sizeof(char) * MAX_STRING_LEN);
244 sprintf(tfname, "%s/k5cc_ap_%s",
245 conf->krb_tmp_dir ? conf->krb_tmp_dir : "/tmp",
248 if (!strcmp(instance, "")) {
249 tfname = strcat(tfname, ".");
250 tfname = strcat(tfname, instance);
253 if (!strcmp(realm, "")) {
254 tfname = strcat(tfname, ".");
255 tfname = strcat(tfname, realm);
258 for (c = tfname + strlen(conf->krb_tmp_dir ? conf->krb_tmp_dir :
259 "/tmp") + 1; *c; c++) {
264 krb_set_tkt_string(tfname);
267 if (!strcmp(realm, "")) {
268 realm = (char *)malloc(sizeof(char) * (REALM_SZ + 1));
269 ret = krb_get_lrealm(realm, 1);
274 ret = krb_get_pw_in_tkt((char *)user, instance, realm, "krbtgt", realm,
275 lifetime, (char *)pass);
290 /***************************************************************************
291 Username/Password Validation for Krb5
292 ***************************************************************************/
295 krb5_verify_user(krb5_context context, krb5_principal principal,
296 krb5_ccache ccache, const char *password, krb5_boolean secure,
300 krb5_context kcontext;
301 krb5_principal server, client;
304 krb5_flags options = 0;
305 krb5_principal me = NULL;
306 krb5_data tgtname = {
312 memset((char *)&my_creds, 0, sizeof(my_creds));
313 my_creds.client = principal;
315 if (krb5_build_principal_ext(kcontext, &server,
316 krb5_princ_realm(kcontext, me)->length,
317 krb5_princ_realm(kcontext, me)->data,
318 tgtname.length, tgtname.data,
319 krb5_princ_realm(kcontext, me)->length,
320 krb5_princ_realm(kcontext, me)->data,
325 my_creds.server = server;
326 if (krb5_timeofday(kcontext, &now))
329 my_creds.times.starttime = 0;
331 my_creds.times.endtime = now + lifetime;
332 my_creds.times.renew_till = now + renewal;
335 ret = krb5_get_in_tkt_with_password(kcontext, options, 0, NULL, 0,
336 password, ccache, &my_creds, 0);
347 krb5_cache_cleanup(void *data)
349 krb5_context context;
351 krb5_error_code problem;
352 char *cache_name = (char *) data;
354 problem = krb5_init_context(&context);
356 ap_log_error(APLOG_MARK, APLOG_ERR, NULL, "krb5_init_context() failed");
360 problem = krb5_cc_resolve(context, cache_name, &cache);
362 ap_log_error(APLOG_MARK, APLOG_ERR, NULL,
363 "krb5_cc_resolve() failed (%s: %s)",
364 cache_name, krb5_get_err_text(context, problem));
368 krb5_cc_destroy(context, cache);
369 krb5_free_context(context);
373 create_krb5_ccache(krb5_context kcontext,
375 kerb_auth_config *conf,
376 krb5_principal princ,
379 char *c, ccname[MAX_STRING_LEN];
380 krb5_error_code problem;
383 krb5_ccache tmp_ccache = NULL;
385 snprintf(ccname, sizeof(ccname), "FILE:%s/k5cc_ap_%s",
386 conf->krb_tmp_dir ? conf->krb_tmp_dir : "/tmp",
389 for (c = ccname + strlen(conf->krb_tmp_dir ? conf->krb_tmp_dir :
390 "/tmp") + 1; *c; c++) {
395 problem = krb5_cc_resolve(kcontext, ccname, &tmp_ccache);
397 snprintf(errstr, sizeof(errstr),
398 "krb5_cc_resolve() failed: %s",
399 krb5_get_err_text(kcontext, problem));
400 ap_log_reason (errstr, r->uri, r);
405 problem = krb5_cc_initialize(kcontext, tmp_ccache, princ);
407 snprintf(errstr, sizeof(errstr),
408 "krb5_cc_initialize() failed: %s",
409 krb5_get_err_text(kcontext, problem));
410 ap_log_reason (errstr, r->uri, r);
415 ap_table_setn(r->subprocess_env, "KRB5CCNAME", ccname);
416 ap_register_cleanup(r->pool, ccname,
417 krb5_cache_cleanup, ap_null_cleanup);
419 *ccache = tmp_ccache;
426 krb5_cc_destroy(kcontext, tmp_ccache);
432 store_krb5_creds(krb5_context kcontext,
434 kerb_auth_config *conf,
435 krb5_ccache delegated_cred)
438 krb5_error_code problem;
439 krb5_principal princ;
443 problem = krb5_cc_get_principal(kcontext, delegated_cred, &princ);
445 snprintf(errstr, sizeof(errstr), "krb5_cc_get_principal() failed: %s",
446 krb5_get_err_text(kcontext, problem));
450 ret = create_krb5_ccache(kcontext, r, conf, princ, &ccache);
452 krb5_free_principal(kcontext, princ);
456 problem = krb5_cc_copy_cache(kcontext, delegated_cred, ccache);
457 krb5_free_principal(kcontext, princ);
459 snprintf(errstr, sizeof(errstr), "krb5_cc_copy_cache() failed: %s",
460 krb5_get_err_text(kcontext, problem));
461 krb5_cc_destroy(kcontext, ccache);
465 krb5_cc_close(kcontext, ccache);
470 int authenticate_user_krb5pwd(request_rec *r,
471 kerb_auth_config *conf,
472 const char *auth_line)
474 const char *sent_pw = NULL;
475 const char *realms = NULL;
476 krb5_context kcontext;
477 krb5_error_code code;
478 krb5_principal client = NULL;
479 krb5_ccache ccache = NULL;
482 code = krb5_init_context(&kcontext);
484 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
485 "Cannot initialize Kerberos5 context (%d)", code);
489 sent_pw = ap_uudecode(r->pool, auth_line);
490 r->connection->user = ap_getword (r->pool, &sent_pw, ':');
491 r->connection->ap_auth_type = "Basic";
493 /* do not allow user to override realm setting of server */
494 if (strchr(r->connection->user,'@')) {
495 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
496 "specifying realm in user name is prohibited");
497 ret = HTTP_UNAUTHORIZED;
502 code = krb5_cc_gen_new(kcontext, &krb5_mcc_ops, &ccache);
504 code = krb5_mcc_generate_new(kcontext, &ccache);
507 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
508 "Cannot generate new ccache: %s",
509 krb5_get_err_text(kcontext, code));
514 if (conf->krb_5_keytab)
515 setenv("KRB5_KTNAME", conf->krb_5_keytab, 1);
517 realms = conf->krb_auth_realms;
519 if (realms && (code = krb5_set_default_realm(kcontext,
520 ap_getword_white(r->pool, &realms))))
523 code = krb5_parse_name(kcontext, r->connection->user, &client);
527 code = krb5_verify_user(kcontext, client, ccache, sent_pw, 1,
528 (conf->service_name) ? conf->service_name : "khttp");
529 krb5_free_principal(kcontext, client);
533 /* ap_getword_white() used above shifts the parameter, so it's not
534 needed to touch the realms variable */
535 } while (realms && *realms);
537 memset((char *)sent_pw, 0, strlen(sent_pw));
540 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
541 "Verifying krb5 password failed: %s",
542 krb5_get_err_text(kcontext, code));
543 ret = HTTP_UNAUTHORIZED;
547 if (conf->krb_save_credentials) {
548 ret = store_krb5_creds(kcontext, r, conf, ccache);
549 if (ret) /* Ignore error ?? */
557 krb5_free_principal(kcontext, client);
559 krb5_cc_destroy(kcontext, ccache);
560 krb5_free_context(kcontext);
565 /*********************************************************************
566 * GSSAPI Authentication
567 ********************************************************************/
570 get_gss_error(pool *p, OM_uint32 error_status, char *prefix)
572 OM_uint32 maj_stat, min_stat;
573 OM_uint32 msg_ctx = 0;
574 gss_buffer_desc status_string;
578 snprintf(buf, sizeof(buf), "%s", prefix);
581 maj_stat = gss_display_status (&min_stat,
587 if (sizeof(buf) > len + status_string.length + 1) {
588 sprintf(buf+len, ": %s", (char*) status_string.value);
589 len += status_string.length;
591 gss_release_buffer(&min_stat, &status_string);
592 } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
594 return (ap_pstrdup(p, buf));
598 cleanup_gss_connection(void *data)
600 OM_uint32 minor_status;
601 gss_connection_t *gss_conn = (gss_connection_t *)data;
605 if (gss_conn->context != GSS_C_NO_CONTEXT)
606 gss_delete_sec_context(&minor_status, &gss_conn->context,
608 if (gss_conn->server_creds != GSS_C_NO_CREDENTIAL)
609 gss_release_cred(&minor_status, &gss_conn->server_creds);
613 store_gss_creds(request_rec *r, kerb_auth_config *conf, char *princ_name,
614 gss_cred_id_t delegated_cred)
616 OM_uint32 maj_stat, min_stat;
617 krb5_principal princ = NULL;
618 krb5_ccache ccache = NULL;
619 krb5_error_code problem;
620 krb5_context context;
621 int ret = SERVER_ERROR;
623 problem = krb5_init_context(&context);
625 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
626 "Cannot initialize krb5 context");
630 problem = krb5_parse_name(context, princ_name, &princ);
632 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
633 "Cannot parse delegated username (%s)", krb5_get_err_text(context, problem));
637 problem = create_krb5_ccache(context, r, conf, princ, &ccache);
639 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
640 "Cannot create krb5 ccache (%s)", krb5_get_err_text(context, problem));
644 maj_stat = gss_krb5_copy_ccache(&min_stat, delegated_cred, ccache);
645 if (GSS_ERROR(maj_stat)) {
646 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
647 "Cannot store delegated credential (%s)",
648 get_gss_error(r->pool, min_stat, "gss_krb5_copy_ccache"));
652 krb5_cc_close(context, ccache);
658 krb5_free_principal(context, princ);
660 krb5_cc_destroy(context, ccache);
661 krb5_free_context(context);
666 get_gss_creds(request_rec *r,
667 kerb_auth_config *conf,
668 gss_cred_id_t *server_creds)
670 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
671 OM_uint32 major_status, minor_status, minor_status2;
672 gss_name_t server_name = GSS_C_NO_NAME;
674 if (conf->service_name) {
675 input_token.value = conf->service_name;
676 input_token.length = strlen(conf->service_name) + 1;
679 input_token.value = "khttp";
680 input_token.length = 6;
682 major_status = gss_import_name(&minor_status, &input_token,
683 (conf->service_name) ?
684 GSS_C_NT_USER_NAME : GSS_C_NT_HOSTBASED_SERVICE,
686 if (GSS_ERROR(major_status)) {
687 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, r,
688 "%s", get_gss_error(r->pool, minor_status,
689 "gss_import_name() failed"));
693 major_status = gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE,
694 GSS_C_NO_OID_SET, GSS_C_ACCEPT,
695 server_creds, NULL, NULL);
696 gss_release_name(&minor_status2, &server_name);
697 if (GSS_ERROR(major_status)) {
698 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, r,
699 "%s", get_gss_error(r->pool, minor_status,
700 "gss_acquire_cred() failed"));
708 authenticate_user_gss(request_rec *r,
709 kerb_auth_config *conf,
710 const char *auth_line)
712 OM_uint32 major_status, minor_status, minor_status2;
713 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
714 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
715 const char *auth_param = NULL;
717 gss_name_t client_name = GSS_C_NO_NAME;
718 gss_cred_id_t delegated_cred = GSS_C_NO_CREDENTIAL;
720 if (gss_connection == NULL) {
721 gss_connection = ap_pcalloc(r->connection->pool, sizeof(*gss_connection));
722 if (gss_connection == NULL) {
723 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
724 "ap_pcalloc() failed (not enough memory)");
728 memset(gss_connection, 0, sizeof(*gss_connection));
729 ap_register_cleanup(r->connection->pool, gss_connection, cleanup_gss_connection, ap_null_cleanup);
732 if (conf->krb_5_keytab)
733 setenv("KRB5_KTNAME", conf->krb_5_keytab, 1);
735 if (gss_connection->server_creds == GSS_C_NO_CREDENTIAL) {
736 ret = get_gss_creds(r, conf, &gss_connection->server_creds);
741 /* ap_getword() shifts parameter */
742 auth_param = ap_getword_white(r->pool, &auth_line);
743 if (auth_param == NULL) {
744 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
745 "No Authorization parameter in request from client");
746 ret = HTTP_UNAUTHORIZED;
750 input_token.length = ap_base64decode_len(auth_param);
751 input_token.value = ap_pcalloc(r->connection->pool, input_token.length);
752 if (input_token.value == NULL) {
753 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
754 "ap_pcalloc() failed (not enough memory)");
758 input_token.length = ap_base64decode(input_token.value, auth_param);
760 major_status = gss_accept_sec_context(&minor_status,
761 &gss_connection->context,
762 gss_connection->server_creds,
764 GSS_C_NO_CHANNEL_BINDINGS,
771 if (output_token.length) {
775 len = ap_base64encode_len(output_token.length);
776 token = ap_pcalloc(r->connection->pool, len + 1);
778 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
779 "ap_pcalloc() failed (not enough memory)");
781 gss_release_buffer(&minor_status2, &output_token);
784 ap_base64encode(token, output_token.value, output_token.length);
786 ap_table_set(r->err_headers_out, "WWW-Authenticate",
787 ap_pstrcat(r->pool, "GSS-Negotiate ", token, NULL));
788 gss_release_buffer(&minor_status2, &output_token);
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_accept_sec_context() failed"));
795 ret = HTTP_UNAUTHORIZED;
799 if (major_status & GSS_S_CONTINUE_NEEDED) {
800 /* Some GSSAPI mechanism (eg GSI from Globus) may require multiple
801 * iterations to establish authentication */
802 ret = HTTP_UNAUTHORIZED;
806 major_status = gss_export_name(&minor_status, client_name, &output_token);
807 gss_release_name(&minor_status, &client_name);
808 if (GSS_ERROR(major_status)) {
809 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
810 "%s", get_gss_error(r->pool, minor_status,
811 "gss_export_name() failed"));
816 r->connection->ap_auth_type = "Negotiate";
817 r->connection->user = ap_pstrdup(r->pool, output_token.value);
819 if (conf->krb_save_credentials && delegated_cred != GSS_C_NO_CREDENTIAL)
820 store_gss_creds(r, conf, (char *)output_token.value, delegated_cred);
822 gss_release_buffer(&minor_status, &output_token);
826 /* If the user comes from a realm specified by configuration don't include
827 its realm name in the username so that the authorization routine could
828 work for both Password-based and Ticket-based authentication. It's
829 administrators responsibility to include only such realm that have
830 unified principal instances, i.e. if the same principal name occures in
831 multiple realms, it must be always assigned to a single user.
833 p = strchr(r->connection->user, '@');
835 const char *realms = conf->gss_krb5_realms;
837 while (realms && *realms) {
838 if (strcmp(p+1, ap_getword_white(r->pool, &realms)) == 0) {
850 gss_release_cred(&minor_status, &delegated_cred);
852 if (output_token.length)
853 gss_release_buffer(&minor_status, &output_token);
855 if (client_name != GSS_C_NO_NAME)
856 gss_release_name(&minor_status, &client_name);
864 note_auth_failure(request_rec *r, const kerb_auth_config *conf)
866 const char *auth_name = NULL;
868 /* get the user realm specified in .htaccess */
869 auth_name = ap_auth_name(r);
871 /* XXX should the WWW-Authenticate header be cleared first? */
873 if (conf->krb_method_gssapi)
874 ap_table_add(r->err_headers_out, "WWW-Authenticate", "GSS-Negotiate ");
875 if (conf->krb_method_k5pass)
876 ap_table_add(r->err_headers_out, "WWW-Authenticate",
877 ap_pstrcat(r->pool, "Basic realm=\"", auth_name, "\"", NULL));
881 if (conf->krb_method_k4pass)
882 ap_table_add(r->err_headers_out, "WWW-Authenticate",
883 ap_pstrcat(r->pool, "Basic realm=\"", auth_name, "\"", NULL));
887 int kerb_authenticate_user(request_rec *r)
889 kerb_auth_config *conf =
890 (kerb_auth_config *) ap_get_module_config(r->per_dir_config,
892 const char *auth_type = NULL;
893 const char *auth_line = NULL;
894 const char *type = NULL;
897 /* get the type specified in .htaccess */
898 type = ap_auth_type(r);
901 if (type != NULL && strcasecmp(type, "KerberosV5") == 0) {
902 ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
903 "The use of KerberosV5 in AuthType is obsolete, please consider using the AuthKerberos option");
904 conf->krb_auth_enable = 1;
909 if (type != NULL && strcasecmp(type, "KerberosV4") == 0) {
910 ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
911 "The use of KerberosV4 in AuthType is obsolete, please consider using the AuthKerberos option");
912 conf->krb_auth_enable = 1;
916 if (!conf->krb_auth_enable)
919 /* get what the user sent us in the HTTP header */
920 auth_line = MK_TABLE_GET(r->headers_in, "Authorization");
922 note_auth_failure(r, conf);
923 return HTTP_UNAUTHORIZED;
925 auth_type = ap_getword_white(r->pool, &auth_line);
927 ret = HTTP_UNAUTHORIZED;
930 if (conf->krb_method_gssapi &&
931 strcasecmp(auth_type, "GSS-Negotiate") == 0) {
932 ret = authenticate_user_gss(r, conf, auth_line);
933 } else if (conf->krb_method_k5pass &&
934 strcasecmp(auth_type, "Basic") == 0) {
935 ret = authenticate_user_krb5pwd(r, conf, auth_line);
940 if (ret == HTTP_UNAUTHORIZED && conf->krb_method_k4pass &&
941 strcasecmp(auth_type, "Basic") == 0)
942 ret = authenticate_user_krb4pwd(r, conf, auth_line);
945 if (ret == HTTP_UNAUTHORIZED)
946 note_auth_failure(r, conf);
953 int kerb_check_user_access(request_rec *r)
957 const MK_ARRAY_HEADER *reqs_arr = ap_requires(r);
959 kerb_auth_config *conf =
960 (kerb_auth_config *)ap_get_module_config(r->per_dir_config,
963 if (reqs_arr == NULL) {
966 reqs = (require_line *)reqs_arr->elts;
968 for (x = 0; x < reqs_arr->nelts; x++) {
969 t = reqs[x].requirement;
970 w = ap_getword_white(r->pool, &t);
971 if (strcmp(w, "realm") == 0) {
972 while (t[0] != '\0') {
973 w = ap_getword_conf(r->pool, &t);
974 if (strcmp(MK_USER, w) == 0) {
988 /***************************************************************************
989 Module Setup/Configuration
990 ***************************************************************************/
992 module MODULE_VAR_EXPORT kerb_auth_module = {
993 STANDARD_MODULE_STUFF,
994 NULL, /* module initializer */
995 kerb_dir_create_config, /* per-directory config creator */
996 NULL, /* per-directory config merger */
997 NULL, /* per-server config creator */
998 NULL, /* per-server config merger */
999 kerb_auth_cmds, /* command table */
1000 NULL, /* [ 9] content handlers */
1001 NULL, /* [ 2] URI-to-filename translation */
1002 kerb_authenticate_user, /* [ 5] check/validate user_id */
1003 NULL, /* [ 6] check user_id is valid *here* */
1004 NULL, /* [ 4] check access by host address */
1005 NULL, /* [ 7] MIME type checker/setter */
1006 NULL, /* [ 8] fixups */
1007 NULL, /* [10] logger */
1008 NULL, /* [ 3] header parser */
1009 NULL, /* process initialization */
1010 NULL, /* process exit/cleanup */
1011 NULL /* [ 1] post read_request handling */
1014 void kerb_register_hooks(apr_pool_t *p)
1016 ap_hook_check_user_id(kerb_authenticate_user, NULL, NULL, APR_HOOK_MIDDLE);
1019 module AP_MODULE_DECLARE_DATA kerb_auth_module =
1021 STANDARD20_MODULE_STUFF,
1022 kerb_dir_create_config, /* create per-dir conf structures */
1023 NULL, /* merge per-dir conf structures */
1024 NULL, /* create per-server conf structures */
1025 NULL, /* merge per-server conf structures */
1026 kerb_auth_cmds, /* table of configuration directives */
1027 kerb_register_hooks /* register hooks */