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_USER r->connection->user
35 #define MK_AUTH_TYPE r->connection->ap_auth_type
36 #define MK_ARRAY_HEADER array_header
38 #define MK_POOL apr_pool_t
39 #define MK_TABLE_GET apr_table_get
40 #define MK_TABLE_SET apr_table_set
41 #define MK_TABLE_TYPE apr_table_t
42 #define MK_PSTRDUP apr_pstrdup
43 #define MK_USER r->user
44 #define MK_AUTH_TYPE r->ap_auth_type
45 #define MK_ARRAY_HEADER apr_array_header_t
51 /***************************************************************************
52 Auth Configuration Structure
53 ***************************************************************************/
56 char *krb_auth_realms;
58 char *krb_force_instance;
59 int krb_save_credentials;
66 int krb_method_gssapi;
67 int krb_method_k5pass;
71 int krb_method_k4pass;
76 #define command(name, func, var, type, usage) \
78 (void*)XtOffsetOf(kerb_auth_config, var), \
79 OR_AUTHCFG, type, usage }
81 #define command(name, func, var, type, usage) \
82 AP_INIT_ ## type (name, func, \
83 (void*)APR_XtOffsetOf(kerb_auth_config, var), \
87 static const command_rec kerb_auth_cmds[] = {
88 command("AuthKerberos", ap_set_flag_slot, krb_auth_enable,
89 FLAG, "Permit Kerberos auth without AuthType requirement."),
91 command("KrbAuthRealm", ap_set_string_slot, krb_auth_realms,
92 ITERATE, "Realms to attempt authentication against (can be multiple)."),
94 command("KrbAuthRealms", ap_set_string_slot, krb_auth_realms,
95 ITERATE, "Alias for KrbAuthRealm."),
98 command("KrbFailStatus", kerb_set_fail_slot, krb_fail_status,
99 TAKE1, "If auth fails, return status set here."),
102 command("KrbForceInstance", ap_set_string_slot, krb_force_instance,
103 TAKE1, "Force authentication against an instance specified here."),
105 command("KrbSaveCredentials", ap_set_flag_slot, krb_save_credentials,
106 FLAG, "Save and store credentials/tickets retrieved during auth."),
108 command("KrbSaveTickets", ap_set_flag_slot, krb_save_credentials,
109 FLAG, "Alias for KrbSaveCredentials."),
111 command("KrbTmpdir", ap_set_string_slot, krb_tmp_dir,
112 TAKE1, "Path to store ticket files and such in."),
114 command("KrbServiceName", ap_set_string_slot, service_name,
115 TAKE1, "Kerberos service name to be used by apache."),
118 command("KrbLifetime", ap_set_string_slot, krb_lifetime,
119 TAKE1, "Kerberos ticket lifetime."),
123 command("Krb5Keytab", ap_set_file_slot, krb_5_keytab,
124 TAKE1, "Location of Kerberos V5 keytab file."),
126 command("KrbForwardable", ap_set_flag_slot, krb_forwardable,
127 FLAG, "Credentials retrieved will be flagged as forwardable."),
129 command("KrbMethodGSSAPI", ap_set_flag_slot, krb_method_gssapi,
130 FLAG, "Enable GSSAPI authentication."),
132 command("KrbMethodK5Pass", ap_set_flag_slot, krb_method_k5pass,
133 FLAG, "Enable Kerberos V5 password authentication."),
137 command("Krb4Srvtab", ap_set_file_slot, krb_4_srvtab,
138 TAKE1, "Location of Kerberos V4 srvtab file."),
140 command("KrbMethodK4Pass", ap_set_flag_slot, krb_method_k4pass,
141 FLAG, "Enable Kerberos V4 password authentication."),
149 gss_ctx_id_t context;
150 gss_cred_id_t server_creds;
153 static gss_connection_t *gss_connection = NULL;
157 /***************************************************************************
158 Auth Configuration Initialization
159 ***************************************************************************/
160 static void *kerb_dir_create_config(MK_POOL *p, char *d)
162 kerb_auth_config *rec;
164 rec = (kerb_auth_config *) ap_pcalloc(p, sizeof(kerb_auth_config));
165 ((kerb_auth_config *)rec)->krb_auth_enable = 1;
166 ((kerb_auth_config *)rec)->krb_fail_status = HTTP_UNAUTHORIZED;
168 ((kerb_auth_config *)rec)->krb_method_k5pass = 1;
169 ((kerb_auth_config *)rec)->krb_method_gssapi = 1;
172 ((kerb_auth_config *)rec)->krb_method_k4pass = 1;
179 static const char *kerb_set_fail_slot(cmd_parms *cmd, void *struct_ptr,
182 int offset = (int) (long) cmd->info;
183 if (!strncasecmp(arg, "unauthorized", 12))
184 *(int *) ((char *)struct_ptr + offset) = HTTP_UNAUTHORIZED;
185 else if (!strncasecmp(arg, "forbidden", 9))
186 *(int *) ((char *)struct_ptr + offset) = HTTP_FORBIDDEN;
187 else if (!strncasecmp(arg, "declined", 8))
188 *(int *) ((char *)struct_ptr + offset) = DECLINED;
190 return "KrbAuthFailStatus must be Forbidden, Unauthorized, or Declined.";
196 /***************************************************************************
197 Username/Password Validation for Krb4
198 ***************************************************************************/
199 int kerb4_password_validate(request_rec *r, const char *user, const char *pass)
201 kerb_auth_config *conf =
202 (kerb_auth_config *)ap_get_module_config(r->per_dir_config,
205 int lifetime = DEFAULT_TKT_LIFE;
207 char *username = NULL;
208 char *instance = NULL;
211 username = (char *)ap_pstrdup(r->pool, user);
216 instance = strchr(username, '.');
224 realm = strchr(username, '@');
232 if (conf->krb_lifetime) {
233 lifetime = atoi(conf->krb_lifetime);
236 if (conf->krb_force_instance) {
237 instance = conf->krb_force_instance;
240 if (conf->krb_save_credentials) {
241 tfname = (char *)malloc(sizeof(char) * MAX_STRING_LEN);
242 sprintf(tfname, "%s/k5cc_ap_%s",
243 conf->krb_tmp_dir ? conf->krb_tmp_dir : "/tmp",
246 if (!strcmp(instance, "")) {
247 tfname = strcat(tfname, ".");
248 tfname = strcat(tfname, instance);
251 if (!strcmp(realm, "")) {
252 tfname = strcat(tfname, ".");
253 tfname = strcat(tfname, realm);
256 for (c = tfname + strlen(conf->krb_tmp_dir ? conf->krb_tmp_dir :
257 "/tmp") + 1; *c; c++) {
262 krb_set_tkt_string(tfname);
265 if (!strcmp(realm, "")) {
266 realm = (char *)malloc(sizeof(char) * (REALM_SZ + 1));
267 ret = krb_get_lrealm(realm, 1);
272 ret = krb_get_pw_in_tkt((char *)user, instance, realm, "krbtgt", realm,
273 lifetime, (char *)pass);
288 /***************************************************************************
289 Username/Password Validation for Krb5
290 ***************************************************************************/
293 krb5_verify_user(krb5_context context, krb5_principal principal,
294 krb5_ccache ccache, const char *password, krb5_boolean secure,
298 krb5_context kcontext;
299 krb5_principal server, client;
302 krb5_flags options = 0;
303 krb5_principal me = NULL;
304 krb5_data tgtname = {
310 memset((char *)&my_creds, 0, sizeof(my_creds));
311 my_creds.client = principal;
313 if (krb5_build_principal_ext(kcontext, &server,
314 krb5_princ_realm(kcontext, me)->length,
315 krb5_princ_realm(kcontext, me)->data,
316 tgtname.length, tgtname.data,
317 krb5_princ_realm(kcontext, me)->length,
318 krb5_princ_realm(kcontext, me)->data,
323 my_creds.server = server;
324 if (krb5_timeofday(kcontext, &now))
327 my_creds.times.starttime = 0;
329 my_creds.times.endtime = now + lifetime;
330 my_creds.times.renew_till = now + renewal;
333 ret = krb5_get_in_tkt_with_password(kcontext, options, 0, NULL, 0,
334 password, ccache, &my_creds, 0);
345 krb5_cache_cleanup(void *data)
347 krb5_context context;
349 krb5_error_code problem;
350 char *cache_name = (char *) data;
352 problem = krb5_init_context(&context);
354 ap_log_error(APLOG_MARK, APLOG_ERR, NULL, "krb5_init_context() failed");
358 problem = krb5_cc_resolve(context, cache_name, &cache);
360 ap_log_error(APLOG_MARK, APLOG_ERR, NULL,
361 "krb5_cc_resolve() failed (%s: %s)",
362 cache_name, krb5_get_err_text(context, problem));
366 krb5_cc_destroy(context, cache);
367 krb5_free_context(context);
371 create_krb5_ccache(krb5_context kcontext,
373 kerb_auth_config *conf,
374 krb5_principal princ,
377 char *c, ccname[MAX_STRING_LEN];
378 krb5_error_code problem;
381 krb5_ccache tmp_ccache = NULL;
383 snprintf(ccname, sizeof(ccname), "FILE:%s/k5cc_ap_%s",
384 conf->krb_tmp_dir ? conf->krb_tmp_dir : "/tmp",
387 for (c = ccname + strlen(conf->krb_tmp_dir ? conf->krb_tmp_dir :
388 "/tmp") + 1; *c; c++) {
393 problem = krb5_cc_resolve(kcontext, ccname, &tmp_ccache);
395 snprintf(errstr, sizeof(errstr),
396 "krb5_cc_resolve() failed: %s",
397 krb5_get_err_text(kcontext, problem));
398 ap_log_reason (errstr, r->uri, r);
403 problem = krb5_cc_initialize(kcontext, tmp_ccache, princ);
405 snprintf(errstr, sizeof(errstr),
406 "krb5_cc_initialize() failed: %s",
407 krb5_get_err_text(kcontext, problem));
408 ap_log_reason (errstr, r->uri, r);
413 ap_table_setn(r->subprocess_env, "KRB5CCNAME", ccname);
414 ap_register_cleanup(r->pool, ccname,
415 krb5_cache_cleanup, ap_null_cleanup);
417 *ccache = tmp_ccache;
424 krb5_cc_destroy(kcontext, tmp_ccache);
430 store_krb5_creds(krb5_context kcontext,
432 kerb_auth_config *conf,
433 krb5_ccache delegated_cred)
436 krb5_error_code problem;
437 krb5_principal princ;
441 problem = krb5_cc_get_principal(kcontext, delegated_cred, &princ);
443 snprintf(errstr, sizeof(errstr), "krb5_cc_get_principal() failed: %s",
444 krb5_get_err_text(kcontext, problem));
448 ret = create_krb5_ccache(kcontext, r, conf, princ, &ccache);
450 krb5_free_principal(kcontext, princ);
454 problem = krb5_cc_copy_cache(kcontext, delegated_cred, ccache);
455 krb5_free_principal(kcontext, princ);
457 snprintf(errstr, sizeof(errstr), "krb5_cc_copy_cache() failed: %s",
458 krb5_get_err_text(kcontext, problem));
459 krb5_cc_destroy(kcontext, ccache);
463 krb5_cc_close(kcontext, ccache);
468 int authenticate_user_krb5pwd(request_rec *r,
469 kerb_auth_config *conf,
470 const char *auth_line)
472 const char *sent_pw = NULL;
473 const char *realms = NULL;
474 krb5_context kcontext;
475 krb5_error_code code;
476 krb5_principal client = NULL;
477 krb5_ccache ccache = NULL;
480 code = krb5_init_context(&kcontext);
482 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
483 "Cannot initialize Kerberos5 context (%d)", code);
487 sent_pw = ap_uudecode(r->pool, auth_line);
488 r->connection->user = ap_getword (r->pool, &sent_pw, ':');
489 r->connection->ap_auth_type = "Basic";
491 /* do not allow user to override realm setting of server */
492 if (strchr(r->connection->user,'@')) {
493 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
494 "specifying realm in user name is prohibited");
495 ret = HTTP_UNAUTHORIZED;
500 code = krb5_cc_gen_new(kcontext, &krb5_mcc_ops, &ccache);
502 code = krb5_mcc_generate_new(kcontext, &ccache);
505 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
506 "Cannot generate new ccache: %s",
507 krb5_get_err_text(kcontext, code));
512 if (conf->krb_5_keytab)
513 /* setenv("KRB5_KTNAME", conf->krb_5_keytab, 1); */
514 kcontext->default_keytab = conf->krb_5_keytab;
516 realms = conf->krb_auth_realms;
518 if (realms && (code = krb5_set_default_realm(kcontext,
519 ap_getword_white(r->pool, &realms))))
522 code = krb5_parse_name(kcontext, r->connection->user, &client);
526 code = krb5_verify_user(kcontext, client, ccache, sent_pw, 1,
527 (conf->service_name) ? conf->service_name : "khttp");
528 krb5_free_principal(kcontext, client);
532 /* ap_getword_white() used above shifts the parameter, so it's not
533 needed to touch the realms variable */
534 } while (realms && *realms);
536 memset((char *)sent_pw, 0, strlen(sent_pw));
539 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO, r,
540 "Verifying krb5 password failed: %s",
541 krb5_get_err_text(kcontext, code));
542 ret = HTTP_UNAUTHORIZED;
546 if (conf->krb_save_credentials) {
547 ret = store_krb5_creds(kcontext, r, conf, ccache);
548 if (ret) /* Ignore error ?? */
556 krb5_free_principal(kcontext, client);
558 krb5_cc_destroy(kcontext, ccache);
559 krb5_free_context(kcontext);
564 /*********************************************************************
565 * GSSAPI Authentication
566 ********************************************************************/
569 get_gss_error(pool *p, OM_uint32 error_status, char *prefix)
571 OM_uint32 maj_stat, min_stat;
572 OM_uint32 msg_ctx = 0;
573 gss_buffer_desc status_string;
577 snprintf(buf, sizeof(buf), "%s", prefix);
580 maj_stat = gss_display_status (&min_stat,
586 if (sizeof(buf) > len + status_string.length + 1) {
587 sprintf(buf+len, ": %s", (char*) status_string.value);
588 len += status_string.length;
590 gss_release_buffer(&min_stat, &status_string);
591 } while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
593 return (ap_pstrdup(p, buf));
597 cleanup_gss_connection(void *data)
599 OM_uint32 minor_status;
600 gss_connection_t *gss_conn = (gss_connection_t *)data;
604 if (gss_conn->context != GSS_C_NO_CONTEXT)
605 gss_delete_sec_context(&minor_status, &gss_conn->context,
607 if (gss_conn->server_creds != GSS_C_NO_CREDENTIAL)
608 gss_release_cred(&minor_status, &gss_conn->server_creds);
612 store_gss_creds(request_rec *r, kerb_auth_config *conf, char *princ_name,
613 gss_cred_id_t delegated_cred)
615 OM_uint32 maj_stat, min_stat;
616 krb5_principal princ = NULL;
617 krb5_ccache ccache = NULL;
618 krb5_error_code problem;
619 krb5_context context;
620 int ret = SERVER_ERROR;
622 problem = krb5_init_context(&context);
624 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
625 "Cannot initialize krb5 context");
629 problem = krb5_parse_name(context, princ_name, &princ);
631 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
632 "Cannot parse delegated username (%s)", krb5_get_err_text(context, problem));
636 problem = create_krb5_ccache(context, r, conf, princ, &ccache);
638 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
639 "Cannot create krb5 ccache (%s)", krb5_get_err_text(context, problem));
643 maj_stat = gss_krb5_copy_ccache(&min_stat, delegated_cred, ccache);
644 if (GSS_ERROR(maj_stat)) {
645 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
646 "Cannot store delegated credential (%s)",
647 get_gss_error(r->pool, min_stat, "gss_krb5_copy_ccache"));
651 krb5_cc_close(context, ccache);
657 krb5_free_principal(context, princ);
659 krb5_cc_destroy(context, ccache);
660 krb5_free_context(context);
665 get_gss_creds(request_rec *r,
666 kerb_auth_config *conf,
667 gss_cred_id_t *server_creds)
669 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
670 OM_uint32 major_status, minor_status, minor_status2;
671 gss_name_t server_name = GSS_C_NO_NAME;
673 if (conf->service_name) {
674 input_token.value = conf->service_name;
675 input_token.length = strlen(conf->service_name) + 1;
678 input_token.value = "khttp";
679 input_token.length = 6;
681 major_status = gss_import_name(&minor_status, &input_token,
682 (conf->service_name) ?
683 GSS_C_NT_USER_NAME : GSS_C_NT_HOSTBASED_SERVICE,
685 if (GSS_ERROR(major_status)) {
686 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, r,
687 "%s", get_gss_error(r->pool, minor_status,
688 "gss_import_name() failed"));
692 major_status = gss_acquire_cred(&minor_status, server_name, GSS_C_INDEFINITE,
693 GSS_C_NO_OID_SET, GSS_C_ACCEPT,
694 server_creds, NULL, NULL);
695 gss_release_name(&minor_status2, &server_name);
696 if (GSS_ERROR(major_status)) {
697 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE, r,
698 "%s", get_gss_error(r->pool, minor_status,
699 "gss_acquire_cred() failed"));
707 authenticate_user_gss(request_rec *r,
708 kerb_auth_config *conf,
709 const char *auth_line)
711 OM_uint32 major_status, minor_status, minor_status2;
712 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
713 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
714 const char *auth_param = NULL;
716 gss_name_t client_name = GSS_C_NO_NAME;
717 gss_cred_id_t delegated_cred = GSS_C_NO_CREDENTIAL;
719 if (gss_connection == NULL) {
720 gss_connection = ap_pcalloc(r->connection->pool, sizeof(*gss_connection));
721 if (gss_connection == NULL) {
722 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
723 "ap_pcalloc() failed (not enough memory)");
727 memset(gss_connection, 0, sizeof(*gss_connection));
728 ap_register_cleanup(r->connection->pool, gss_connection, cleanup_gss_connection, ap_null_cleanup);
731 if (conf->krb_5_keytab)
732 setenv("KRB5_KTNAME", conf->krb_5_keytab, 1);
734 if (gss_connection->server_creds == GSS_C_NO_CREDENTIAL) {
735 ret = get_gss_creds(r, conf, &gss_connection->server_creds);
740 /* ap_getword() shifts parameter */
741 auth_param = ap_getword_white(r->pool, &auth_line);
742 if (auth_param == NULL) {
743 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
744 "No Authorization parameter in request from client");
745 ret = HTTP_UNAUTHORIZED;
749 input_token.length = ap_base64decode_len(auth_param);
750 input_token.value = ap_pcalloc(r->connection->pool, input_token.length);
751 if (input_token.value == NULL) {
752 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
753 "ap_pcalloc() failed (not enough memory)");
757 input_token.length = ap_base64decode(input_token.value, auth_param);
759 major_status = gss_accept_sec_context(&minor_status,
760 &gss_connection->context,
761 gss_connection->server_creds,
763 GSS_C_NO_CHANNEL_BINDINGS,
770 if (output_token.length) {
774 len = ap_base64encode_len(output_token.length);
775 token = ap_pcalloc(r->connection->pool, len + 1);
777 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
778 "ap_pcalloc() failed (not enough memory)");
780 gss_release_buffer(&minor_status2, &output_token);
783 ap_base64encode(token, output_token.value, output_token.length);
785 ap_table_set(r->err_headers_out, "WWW-Authenticate",
786 ap_pstrcat(r->pool, "GSS-Negotiate ", token, NULL));
787 gss_release_buffer(&minor_status2, &output_token);
790 if (GSS_ERROR(major_status)) {
791 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
792 "%s", get_gss_error(r->pool, minor_status,
793 "gss_accept_sec_context() failed"));
794 ret = HTTP_UNAUTHORIZED;
798 if (major_status & GSS_S_CONTINUE_NEEDED) {
799 /* Some GSSAPI mechanism (eg GSI from Globus) may require multiple
800 * iterations to establish authentication */
801 ret = HTTP_UNAUTHORIZED;
805 major_status = gss_export_name(&minor_status, client_name, &output_token);
806 gss_release_name(&minor_status, &client_name);
807 if (GSS_ERROR(major_status)) {
808 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
809 "%s", get_gss_error(r->pool, minor_status,
810 "gss_export_name() failed"));
815 r->connection->ap_auth_type = "Negotiate";
816 r->connection->user = ap_pstrdup(r->pool, output_token.value);
818 if (conf->krb_save_credentials && delegated_cred != GSS_C_NO_CREDENTIAL)
819 store_gss_creds(r, conf, (char *)output_token.value, delegated_cred);
821 gss_release_buffer(&minor_status, &output_token);
825 /* If the user comes from a realm specified by configuration don't include
826 its realm name in the username so that the authorization routine could
827 work for both Password-based and Ticket-based authentication. It's
828 administrators responsibility to include only such realm that have
829 unified principal instances, i.e. if the same principal name occures in
830 multiple realms, it must be always assigned to a single user.
832 p = strchr(r->connection->user, '@');
834 const char *realms = conf->gss_krb5_realms;
836 while (realms && *realms) {
837 if (strcmp(p+1, ap_getword_white(r->pool, &realms)) == 0) {
849 gss_release_cred(&minor_status, &delegated_cred);
851 if (output_token.length)
852 gss_release_buffer(&minor_status, &output_token);
854 if (client_name != GSS_C_NO_NAME)
855 gss_release_name(&minor_status, &client_name);
863 note_auth_failure(request_rec *r, const kerb_auth_config *conf)
865 const char *auth_name = NULL;
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 ");
874 if (conf->krb_method_k5pass)
875 ap_table_add(r->err_headers_out, "WWW-Authenticate",
876 ap_pstrcat(r->pool, "Basic realm=\"", auth_name, "\"", NULL));
880 if (conf->krb_method_k4pass)
881 ap_table_add(r->err_headers_out, "WWW-Authenticate",
882 ap_pstrcat(r->pool, "Basic realm=\"", auth_name, "\"", NULL));
886 int kerb_authenticate_user(request_rec *r)
888 kerb_auth_config *conf =
889 (kerb_auth_config *) ap_get_module_config(r->per_dir_config,
891 const char *auth_type = NULL;
892 const char *auth_line = NULL;
893 const char *type = NULL;
896 /* get the type specified in .htaccess */
897 type = ap_auth_type(r);
900 if (type != NULL && strcasecmp(type, "KerberosV5") == 0) {
901 ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
902 "The use of KerberosV5 in AuthType is obsolete, please consider using the AuthKerberos option");
903 conf->krb_auth_enable = 1;
908 if (type != NULL && strcasecmp(type, "KerberosV4") == 0) {
909 ap_log_rerror(APLOG_MARK, APLOG_WARNING, r,
910 "The use of KerberosV4 in AuthType is obsolete, please consider using the AuthKerberos option");
911 conf->krb_auth_enable = 1;
915 if (!conf->krb_auth_enable)
918 /* get what the user sent us in the HTTP header */
919 auth_line = MK_TABLE_GET(r->headers_in, "Authorization");
921 note_auth_failure(r, conf);
922 return HTTP_UNAUTHORIZED;
924 auth_type = ap_getword_white(r->pool, &auth_line);
926 ret = HTTP_UNAUTHORIZED;
929 if (conf->krb_method_gssapi &&
930 strcasecmp(auth_type, "GSS-Negotiate") == 0) {
931 ret = authenticate_user_gss(r, conf, auth_line);
932 } else if (conf->krb_method_k5pass &&
933 strcasecmp(auth_type, "Basic") == 0) {
934 ret = authenticate_user_krb5pwd(r, conf, auth_line);
939 if (ret == HTTP_UNAUTHORIZED && conf->krb_method_k4pass &&
940 strcasecmp(auth_type, "Basic") == 0)
941 ret = authenticate_user_krb4pwd(r, conf, auth_line);
944 if (ret == HTTP_UNAUTHORIZED)
945 note_auth_failure(r, conf);
951 /***************************************************************************
952 Module Setup/Configuration
953 ***************************************************************************/
955 module MODULE_VAR_EXPORT kerb_auth_module = {
956 STANDARD_MODULE_STUFF,
957 NULL, /* module initializer */
958 kerb_dir_create_config, /* per-directory config creator */
959 NULL, /* per-directory config merger */
960 NULL, /* per-server config creator */
961 NULL, /* per-server config merger */
962 kerb_auth_cmds, /* command table */
963 NULL, /* [ 9] content handlers */
964 NULL, /* [ 2] URI-to-filename translation */
965 kerb_authenticate_user, /* [ 5] check/validate user_id */
966 NULL, /* [ 6] check user_id is valid *here* */
967 NULL, /* [ 4] check access by host address */
968 NULL, /* [ 7] MIME type checker/setter */
969 NULL, /* [ 8] fixups */
970 NULL, /* [10] logger */
971 NULL, /* [ 3] header parser */
972 NULL, /* process initialization */
973 NULL, /* process exit/cleanup */
974 NULL /* [ 1] post read_request handling */
977 void kerb_register_hooks(apr_pool_t *p)
979 ap_hook_check_user_id(kerb_authenticate_user, NULL, NULL, APR_HOOK_MIDDLE);
982 module AP_MODULE_DECLARE_DATA kerb_auth_module =
984 STANDARD20_MODULE_STUFF,
985 kerb_dir_create_config, /* create per-dir conf structures */
986 NULL, /* merge per-dir conf structures */
987 NULL, /* create per-server conf structures */
988 NULL, /* merge per-server conf structures */
989 kerb_auth_cmds, /* table of configuration directives */
990 kerb_register_hooks /* register hooks */