/*
- * Daniel Kouril <kouril@users.sourceforge.org>
+ * Daniel Kouril <kouril@users.sourceforge.net>
*
* Source and Documentation can be found at:
* http://modauthkerb.sourceforge.net/
* Based on work by
* James E. Robinson, III <james@ncstate.net>
* Daniel Henninger <daniel@ncsu.edu>
+ * Ludek Sulak <xsulak@fi.muni.cz>
*/
/* ====================================================================
#ident "$Id$"
+#define MODAUTHKERB_VERSION "5.0-rc2"
+
#ifndef APXS1
#include "ap_compat.h"
#include "apr_strings.h"
# undef closesocket
#endif
#include <krb.h>
+#include <netdb.h> /* gethostbyname() */
#endif /* KRB4 */
#ifdef APXS1
va_start(ap, fmt);
vsnprintf(errstr, sizeof(errstr), fmt, ap);
va_end(ap);
-
+
+ /* these functions also print out current errno (if not zero), resulting in
+ * lines of the format:
+ * (errno)strerror(errno): errstr
+ * This behaviour can be avoided by using APLOG_NOERRNO */
#ifdef APXS1
ap_log_rerror(file, line, level, r, "%s", errstr);
#else
ret = krb_get_pw_in_tkt(name, instance, realm, "krbtgt", realm,
DEFAULT_TKT_LIFE, password);
- if (ret)
- /* log(krb_err_txt[ret]) */
+ if (ret) {
+ log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "Cannot get krb4 ticket: krb_get_pw_in_tkt() failed: %s",
+ krb_get_err_text(ret));
return ret;
+ }
hostname = ap_get_server_name(r);
hp = gethostbyname(hostname);
if (hp == NULL) {
dest_tkt();
+ log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "Cannot verify krb4 ticket: gethostbyname() failed: %s",
+ hstrerror(h_errno));
return h_errno;
}
memcpy(&addr, hp->h_addr, sizeof(addr));
ret = krb_mk_req(&ticket, linstance, phost, lrealm, 0);
if (ret) {
+ log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "Cannot verify krb4 ticket: krb_mk_req() failed: %s",
+ krb_get_err_text(ret));
dest_tkt();
return ret;
}
ret = krb_rd_req(&ticket, linstance, phost, addr, &authdata, srvtab);
- if (ret)
+ if (ret) {
+ log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "Cannot verify krb4 ticket: krb_rd_req() failed: %s",
+ krb_get_err_text(ret));
dest_tkt();
+ }
return ret;
}
} while (realms && *realms);
if (ret) {
- log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "Verifying krb4 password failed (%d)", ret);
+ log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Verifying krb4 password failed");
ret = HTTP_UNAUTHORIZED;
goto end;
}
krb5_ccache tmp_ccache = NULL;
#ifdef HEIMDAL
+ /* new MIT krb5-1.3.x also supports this call */
problem = krb5_cc_gen_new(kcontext, &krb5_fcc_ops, &tmp_ccache);
#else
problem = krb5_fcc_generate_new(kcontext, &tmp_ccache);
if (conf->krb_5_keytab)
krb5_kt_resolve(kcontext, conf->krb_5_keytab, &keytab);
- /* setenv("KRB5_KTNAME", conf->krb_5_keytab, 1); */
realms = conf->krb_auth_realms;
do {
ap_register_cleanup(r->connection->pool, gss_connection, cleanup_gss_connection, ap_null_cleanup);
}
- if (conf->krb_5_keytab)
- setenv("KRB5_KTNAME", conf->krb_5_keytab, 1);
+ if (conf->krb_5_keytab) {
+ char *ktname;
+ /* we don't use the ap_* calls here, since the string passed to putenv()
+ * will become part of the enviroment and shouldn't be free()ed by apache
+ */
+ ktname = malloc(strlen("KRB5_KTNAME=") + strlen(conf->krb_5_keytab) + 1);
+ if (ktname == NULL) {
+ log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "malloc() failed: not enough memory");
+ ret = HTTP_INTERNAL_SERVER_ERROR;
+ goto end;
+ }
+ sprintf(ktname, "KRB5_KTNAME=%s", conf->krb_5_keytab);
+ putenv(ktname);
+ }
if (gss_connection->server_creds == GSS_C_NO_CREDENTIAL) {
ret = get_gss_creds(r, conf, &gss_connection->server_creds);
}
input_token.length = ap_base64decode(input_token.value, auth_param);
- major_status = gss_accept_sec_context(&minor_status,
+#if 0
+ major_status = gss_accept_sec_context(
+#else
+ major_status = gss_accept_sec_context_spnego(
+#endif
+ &minor_status,
&gss_connection->context,
gss_connection->server_creds,
&input_token,
ap_base64encode(token, output_token.value, output_token.length);
token[len] = '\0';
ap_table_set(r->err_headers_out, "WWW-Authenticate",
- ap_pstrcat(r->pool, "GSS-Negotiate ", token, NULL));
+ ap_pstrcat(r->pool, "Negotiate ", token, NULL));
gss_release_buffer(&minor_status2, &output_token);
}
/* XXX should the WWW-Authenticate header be cleared first? */
#ifdef KRB5
if (use_krb5 && conf->krb_method_gssapi)
- ap_table_add(r->err_headers_out, "WWW-Authenticate", "GSS-Negotiate ");
+ ap_table_add(r->err_headers_out, "WWW-Authenticate", "Negotiate");
if (use_krb5 && conf->krb_method_k5pass) {
ap_table_add(r->err_headers_out, "WWW-Authenticate",
ap_pstrcat(r->pool, "Basic realm=\"", auth_name, "\"", NULL));
#ifdef KRB5
if (use_krb5 && conf->krb_method_gssapi &&
- strcasecmp(auth_type, "GSS-Negotiate") == 0) {
+ strcasecmp(auth_type, "Negotiate") == 0) {
ret = authenticate_user_gss(r, conf, auth_line);
} else if (use_krb5 && conf->krb_method_k5pass &&
strcasecmp(auth_type, "Basic") == 0) {
NULL /* [ 1] post read_request handling */
};
#else
+static int
+kerb_init_handler(apr_pool_t *p, apr_pool_t *plog,
+ apr_pool_t *ptemp, server_rec *s)
+{
+ ap_add_version_component(p, "mod_auth_kerb/" MODAUTHKERB_VERSION);
+ return OK;
+}
+
void kerb_register_hooks(apr_pool_t *p)
{
+ ap_hook_post_config(kerb_init_handler, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_check_user_id(kerb_authenticate_user, NULL, NULL, APR_HOOK_MIDDLE);
}