Patch to enhance Heimdal support in rlm_krb5
Thomas Kula
kula at tproa.net
Sat Apr 21 04:07:16 CEST 2007
Included is a patch that adds two enhancements to the
Heimdal support in rlm_krb5:
- Logging of the parsed name is changed so that if a
user is using an instance the instance is logged.
This threw me off when I was first setting up rlm_krb5,
since I was using the kula/wireless at TPROA.NET and it
was logging the parsed name as kula at TPROA.NET.
- I've switched to using krb5_verify_user_opt and set
up the options so that you can supply something other
than the default service principal and can specify
to use a keytab for verification that isn't the
system default keytab.
This patch has undergone some light testing with radclient,
using all combinations of default/non-default service name
and keytab. It was tested on a NetBSD 3.1 system using
Heimdal 0.72. I suspect more recent versions of Heimdal
would work with this just fine, but have not verified that.
The patch is also located at
http://kula.tproa.net/code/rlm_krb5.diff
##### begin patch ######
--- src/modules/rlm_krb5/rlm_krb5.c.orig 2005-12-19 17:21:37.000000000 -0500
+++ src/modules/rlm_krb5/rlm_krb5.c 2007-04-20 21:43:21.000000000 -0400
@@ -323,16 +323,41 @@
#else /* HEIMDAL_KRB5 */
/* validate user/pass, heimdal krb5 way */
-static int krb5_auth(void *instance, REQUEST *request)
+static int krb5_auth(rlm_krb5_t *instance, REQUEST *request)
{
int r;
- krb5_error_code ret;
+ krb5_error_code ret, ret2;
krb5_ccache id;
krb5_principal userP;
krb5_context context = *((rlm_krb5_t *)instance)->context; /* copy data */
const char *user, *pass;
+ /* arbitrary 64-byte limit on service names; I've never seen a
+ service name this long, and hope never to. -srl */
+ /* stolen from the above mit kerb stuff -- kula */
+
+ char service[64] = "host";
+ char *servername = NULL;
+ char *princ_name;
+
+ krb5_verify_opt krb_verify_options;
+ krb5_keytab keytab;
+
+ if (instance->service_princ != NULL) {
+ servername = strchr(instance->service_princ, '/');
+ if (servername != NULL) {
+ *servername = '\0';
+ }
+
+ strncpy(service,instance->service_princ,sizeof(service));
+ service[sizeof(service)-1] = '\0';
+ if (servername != NULL) {
+ *servername = '/';
+ servername++;
+ }
+ }
+
/*
* We can only authenticate user requests which HAVE
* a User-Name attribute.
@@ -375,26 +400,71 @@
/*
* Heimdal krb5 verification
*/
- radlog(L_AUTH, "rlm_krb5: Parsed name is: %s@%s\n",
- *userP->name.name_string.val,
- userP->realm);
+
+
+ /*
+ * The following bit allows us to also log user/instance at REALM if someone
+ * logs in using an instance
+ */
+
+ ret = krb5_unparse_name(context, userP, &princ_name);
+ if ( ret != 0 ) {
+ radlog(L_AUTH, "rlm_krb5: krb5_unparse_name unparsable name\n");
+ } else {
+ radlog(L_AUTH, "rlm_krb5: Parsed name is: %s\n", princ_name);
+ free(princ_name);
+ }
krb5_cc_default(context, &id);
- ret = krb5_verify_user(context,
- userP,
- id,
- pass, 1, "radius");
-
- if (ret == 0)
- return RLM_MODULE_OK;
-
- radlog(L_AUTH, "rlm_krb5: failed verify_user: %s (%s@%s )",
- error_message(ret),
- *userP->name.name_string.val,
- userP->realm);
+ /* Set up krb5_verify_user options */
+ krb5_verify_opt_init(&krb_verify_options);
+
+ krb5_verify_opt_set_ccache(&krb_verify_options, id);
+
+ /*
+ * Resolve keytab name. This allows us to use something other than
+ * the default system keytab
+ */
+
+ if (instance->keytab != NULL)
+ {
+ ret = krb5_kt_resolve(context, instance->keytab, &keytab);
+
+ if ( ret )
+ {
+ radlog(L_AUTH, "rlm_krb: unable to resolve keytab %s: %s",
+ instance->keytab, error_message(ret));
+ krb5_kt_close(context, keytab);
+ return RLM_MODULE_REJECT;
+ }
+ krb5_verify_opt_set_keytab(&krb_verify_options, keytab);
+ }
+
+ /* Verify aquired credentials against the keytab */
+
+ krb5_verify_opt_set_secure(&krb_verify_options, 1);
+
+ /* Allow us to use an arbitrary service name */
+
+ krb5_verify_opt_set_service(&krb_verify_options, service);
+
+
+ /* Verify the user, using the above set options */
+ ret = krb5_verify_user_opt(context, userP, pass, &krb_verify_options);
+
+ /* We are done with the keytab, close it */
+ ret2 = krb5_kt_close(context, keytab);
+
+ if (ret == 0)
+ return RLM_MODULE_OK;
+
+ radlog(L_AUTH, "rlm_krb5: failed verify_user: %s (%s@%s )",
+ error_message(ret),
+ *userP->name.name_string.val,
+ userP->realm);
- return RLM_MODULE_REJECT;
+ return RLM_MODULE_REJECT;
}
#endif /* HEIMDAL_KRB5 */
##### end patch #####
--
Thomas L. Kula | kula at tproa.net
More information about the Freeradius-Devel
mailing list