Use local EAP, even if the realm doesn't exist
[freeradius.git] / src / modules / rlm_eap / eap.c
index cfcec53..4eb9c04 100644 (file)
@@ -55,6 +55,7 @@
  */
 
 #include <freeradius-devel/ident.h>
+#include <freeradius-devel/modpriv.h>
 RCSID("$Id$")
 
 #include "rlm_eap.h"
@@ -76,20 +77,11 @@ int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs)
        char            buffer[64];
        char            namebuf[64];
        const char      *eaptype_name;
-       lt_dlhandle     handle;
        EAP_TYPES       *node;
 
        eaptype_name = eaptype_type2name(eap_type, namebuf, sizeof(namebuf));
        snprintf(buffer, sizeof(buffer), "rlm_eap_%s", eaptype_name);
 
-       /* Link the loaded EAP-Type */
-       handle = lt_dlopenext(buffer);
-       if (handle == NULL) {
-               radlog(L_ERR, "rlm_eap: Failed to link EAP-Type/%s: %s",
-                      eaptype_name, lt_dlerror());
-               return -1;
-       }
-
        /* Make room for the EAP-Type */
        node = (EAP_TYPES *)malloc(sizeof(EAP_TYPES));
        if (node == NULL) {
@@ -99,7 +91,6 @@ int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs)
        memset(node, 0, sizeof(*node));
 
        /* fill in the structure */
-       node->handle = handle;
        node->cs = cs;
 
        /*
@@ -112,6 +103,26 @@ int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs)
        node->typename = eaptype_name;
        node->type_data = NULL;
 
+#ifdef WITHOUT_LIBLTDL
+#ifdef WITH_DLOPEN
+#include <dlfcn.h>
+
+#ifdef RTLD_SELF
+       node->type = (EAP_TYPE *)lt_dlsym(RTLD_SELF, buffer);
+       if (node->type) goto open_self;
+#endif
+#endif
+#endif
+
+       /* Link the loaded EAP-Type */
+       node->handle = lt_dlopenext(buffer);
+       if (node->handle == NULL) {
+               free(node);
+               radlog(L_ERR, "rlm_eap: Failed to link EAP-Type/%s: %s",
+                      eaptype_name, lt_dlerror());
+               return -1;
+       }
+
        node->type = (EAP_TYPE *)lt_dlsym(node->handle, buffer);
        if (!node->type) {
                radlog(L_ERR, "rlm_eap: Failed linking to %s structure in %s: %s",
@@ -120,9 +131,13 @@ int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs)
                free(node);
                return -1;
        }
-       DEBUG("  eap: Linked to sub-module %s", buffer);
 
-       DEBUG("  eap: Instantiating eap-%s", eaptype_name);
+#if defined(WITHOUT_LIBLTDL) && defined (WITH_DLOPEN) && defined(RTLD_SELF)
+open_self:
+#endif
+       cf_log_module(cs, "Linked to sub-module %s", buffer);
+
+       cf_log_module(cs, "Instantiating eap-%s", eaptype_name);
 
        if ((node->type->attach) &&
            ((node->type->attach)(node->cs, &(node->type_data)) < 0)) {
@@ -144,8 +159,11 @@ int eaptype_load(EAP_TYPES **type, int eap_type, CONF_SECTION *cs)
 static int eaptype_call(EAP_TYPES *atype, EAP_HANDLER *handler)
 {
        int rcode = 1;
+       REQUEST *request = handler->request;
+       const char *module = request->module;
 
-       DEBUG2("  rlm_eap: processing type %s", atype->typename);
+       RDEBUG2("processing type %s", atype->typename);
+       request->module = atype->typename;
 
        rad_assert(atype != NULL);
 
@@ -175,11 +193,12 @@ static int eaptype_call(EAP_TYPES *atype, EAP_HANDLER *handler)
 
        default:
                /* Should never enter here */
-               radlog(L_DBG, "rlm_eap: Invalid operation on eap_type");
+               RDEBUG("Internal sanity check failed on eap_type");
                rcode = 0;
                break;
        }
 
+       request->module = module;
        return rcode;
 }
 
@@ -196,6 +215,7 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
        VALUE_PAIR      *vp;
        char            namebuf[64];
        const char      *eaptype_name;
+       REQUEST         *request = handler->request;
 
        eaptype = &handler->eap_ds->response->type;
 
@@ -204,7 +224,15 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
         */
        if ((eaptype->type == 0) ||
            (eaptype->type > PW_EAP_MAX_TYPES)) {
-               DEBUG2(" rlm_eap: Asked to select bad type");
+               RDEBUG2("Asked to select bad type");
+               return EAP_INVALID;
+       }
+
+       /*
+        *      Multiple levels of nesting are invalid.
+        */
+       if (handler->request->parent && handler->request->parent->parent) {
+               RDEBUG2("Multiple levels of TLS nesting is invalid.");
                return EAP_INVALID;
        }
 
@@ -213,13 +241,13 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
         */
        switch(eaptype->type) {
        case PW_EAP_IDENTITY:
-               DEBUG2("  rlm_eap: EAP Identity");
+               RDEBUG2("EAP Identity");
 
                /*
                 *      Allow per-user configuration of EAP types.
                 */
                vp = pairfind(handler->request->config_items,
-                             PW_EAP_TYPE);
+                             PW_EAP_TYPE, 0);
                if (vp) default_eap_type = vp->vp_integer;
 
        do_initiate:
@@ -229,7 +257,7 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                if ((default_eap_type < PW_EAP_MD5) ||
                    (default_eap_type > PW_EAP_MAX_TYPES) ||
                    (inst->types[default_eap_type] == NULL)) {
-                       DEBUG2(" rlm_eap: No such EAP type %s",
+                       RDEBUG2("No such EAP type %s",
                               eaptype_type2name(default_eap_type,
                                                 namebuf, sizeof(namebuf)));
                        return EAP_INVALID;
@@ -253,13 +281,13 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
 
                if ((default_eap_type == PW_EAP_TNC) &&
                    !handler->request->parent) {
-                       DEBUG2(" rlm_eap: ERROR: EAP-TNC must be run inside of a TLS method.");
+                       RDEBUG2("ERROR: EAP-TNC must be run inside of a TLS method.");
                        return EAP_INVALID;
                }
 
                if (eaptype_call(inst->types[default_eap_type],
                                 handler) == 0) {
-                       DEBUG2(" rlm_eap: Default EAP type %s failed in initiate",
+                       RDEBUG2("Default EAP type %s failed in initiate",
                               eaptype_type2name(default_eap_type,
                                                 namebuf, sizeof(namebuf)));
                        return EAP_INVALID;
@@ -275,7 +303,7 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                 *      alternative types, one per octet, or to use
                 *      0 for no alternative.
                 */
-               DEBUG2("  rlm_eap: EAP NAK");
+               RDEBUG2("EAP NAK");
 
                /*
                 *      Delete old data, if necessary.
@@ -287,7 +315,7 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                }
 
                if (eaptype->data == NULL) {
-                       DEBUG2(" rlm_eap: Empty NAK packet, cannot decide what EAP type the client wants.");
+                       RDEBUG2("Empty NAK packet, cannot decide what EAP type the client wants.");
                        return EAP_INVALID;
                }
 
@@ -297,7 +325,7 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                 */
                default_eap_type = 0;
                vp = pairfind(handler->request->config_items,
-                             PW_EAP_TYPE);
+                             PW_EAP_TYPE, 0);
                for (i = 0; i < eaptype->length; i++) {
                        /*
                         *      It is invalid to request identity,
@@ -307,15 +335,23 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                         *      common choices.
                         */
                        if (eaptype->data[i] < PW_EAP_MD5) {
-                               DEBUG2(" rlm_eap: NAK asked for bad type %d",
+                               RDEBUG2("NAK asked for bad type %d",
                                       eaptype->data[i]);
                                return EAP_INVALID;
                        }
 
                        if ((eaptype->data[i] > PW_EAP_MAX_TYPES) ||
                            !inst->types[eaptype->data[i]]) {
-                               DEBUG2(" rlm_eap: NAK asked for unsupported type %d",
-                                      eaptype->data[i]);
+                               DICT_VALUE *dv;
+
+                               dv = dict_valbyattr(PW_EAP_TYPE, 0, eaptype->data[i]);
+                               if (dv) {
+                                       RDEBUG2("NAK asked for unsupported type %s",
+                                               dv->name);
+                               } else {
+                                       RDEBUG2("NAK asked for unsupported type %d",
+                                               eaptype->data[i]);
+                               }
                                continue;
                        }
 
@@ -327,7 +363,7 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                         *      Prevent a firestorm if the client is confused.
                         */
                        if (handler->eap_type == eaptype->data[i]) {
-                               DEBUG2(" rlm_eap: ERROR! Our request for %s was NAK'd with a request for %s.  Skipping the requested type.",
+                               RDEBUG2("ERROR! Our request for %s was NAK'd with a request for %s.  Skipping the requested type.",
                                       eaptype_name, eaptype_name);
                                continue;
                        }
@@ -338,7 +374,7 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                         */
                        if (vp && (vp->vp_integer != eaptype->data[i])) {
                                char    mynamebuf[64];
-                               DEBUG2("  rlm_eap: Client wants %s, while we require %s.  Skipping the requested type.",
+                               RDEBUG2("Client wants %s, while we require %s.  Skipping the requested type.",
                                       eaptype_name,
                                       eaptype_type2name(vp->vp_integer,
                                                         mynamebuf,
@@ -354,12 +390,12 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                 *      We probably want to return 'fail' here...
                 */
                if (!default_eap_type) {
-                       DEBUG2(" rlm_eap: No common EAP types found.");
+                       RDEBUG2("No common EAP types found.");
                        return EAP_INVALID;
                }
                eaptype_name = eaptype_type2name(default_eap_type,
                                                 namebuf, sizeof(namebuf));
-               DEBUG2(" rlm_eap: EAP-NAK asked for EAP-Type/%s",
+               RDEBUG2("EAP-NAK asked for EAP-Type/%s",
                       eaptype_name);
 
                goto do_initiate;
@@ -372,13 +408,13 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                        eaptype_name = eaptype_type2name(eaptype->type,
                                                         namebuf,
                                                         sizeof(namebuf));
-                       DEBUG2("  rlm_eap: EAP/%s", eaptype_name);
+                       RDEBUG2("EAP/%s", eaptype_name);
 
                        /*
                         *      We haven't configured it, it doesn't exit.
                         */
                        if (!inst->types[eaptype->type]) {
-                               DEBUG2(" rlm_eap: EAP type %d is unsupported",
+                               RDEBUG2("EAP type %d is unsupported",
                                       eaptype->type);
                                return EAP_INVALID;
                        }
@@ -387,7 +423,7 @@ int eaptype_select(rlm_eap_t *inst, EAP_HANDLER *handler)
                        handler->eap_type = eaptype->type;
                        if (eaptype_call(inst->types[eaptype->type],
                                         handler) == 0) {
-                               DEBUG2(" rlm_eap: Handler failed in EAP/%s",
+                               RDEBUG2("Handler failed in EAP/%s",
                                       eaptype_name);
                                return EAP_INVALID;
                        }
@@ -460,7 +496,7 @@ int eap_compose(EAP_HANDLER *handler)
                        ++reply->id;
                }
        } else {
-               DEBUG2("  rlm_eap: Underlying EAP-Type set EAP ID to %d",
+               RDEBUG2("Underlying EAP-Type set EAP ID to %d",
                       reply->id);
        }
 
@@ -502,9 +538,9 @@ int eap_compose(EAP_HANDLER *handler)
         *      Don't add a Message-Authenticator if it's already
         *      there.
         */
-       vp = pairfind(request->reply->vps, PW_MESSAGE_AUTHENTICATOR);
+       vp = pairfind(request->reply->vps, PW_MESSAGE_AUTHENTICATOR, 0);
        if (!vp) {
-               vp = paircreate(PW_MESSAGE_AUTHENTICATOR, PW_TYPE_OCTETS);
+               vp = paircreate(PW_MESSAGE_AUTHENTICATOR, 0, PW_TYPE_OCTETS);
                memset(vp->vp_octets, 0, AUTH_VECTOR_LEN);
                vp->length = AUTH_VECTOR_LEN;
                pairadd(&(request->reply->vps), vp);
@@ -559,9 +595,9 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
        VALUE_PAIR *vp, *proxy;
        VALUE_PAIR *eap_msg;
 
-       eap_msg = pairfind(request->packet->vps, PW_EAP_MESSAGE);
+       eap_msg = pairfind(request->packet->vps, PW_EAP_MESSAGE, 0);
        if (eap_msg == NULL) {
-               DEBUG2("  rlm_eap: No EAP-Message, not doing EAP");
+               RDEBUG2("No EAP-Message, not doing EAP");
                return EAP_NOOP;
        }
 
@@ -569,9 +605,9 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
         *      Look for EAP-Type = None (FreeRADIUS specific attribute)
         *      this allows you to NOT do EAP for some users.
         */
-       vp = pairfind(request->packet->vps, PW_EAP_TYPE);
+       vp = pairfind(request->packet->vps, PW_EAP_TYPE, 0);
        if (vp && vp->vp_integer == 0) {
-               DEBUG2("  rlm_eap: Found EAP-Message, but EAP-Type = None, so we're not doing EAP.");
+               RDEBUG2("Found EAP-Message, but EAP-Type = None, so we're not doing EAP.");
                return EAP_NOOP;
        }
 
@@ -585,7 +621,7 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
         *      Check for a Proxy-To-Realm.  Don't get excited over LOCAL
         *      realms (sigh).
         */
-       proxy = pairfind(request->config_items, PW_PROXY_TO_REALM);
+       proxy = pairfind(request->config_items, PW_PROXY_TO_REALM, 0);
        if (proxy) {
                REALM *realm;
 
@@ -594,7 +630,7 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
                 *      to it.
                 */
                realm = realm_find(proxy->vp_strvalue);
-               if (realm && (realm->auth_pool == NULL)) {
+               if (!realm || (realm && (realm->auth_pool == NULL))) {
                        proxy = NULL;
                }
        }
@@ -619,13 +655,13 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
                 */
                if (proxy) {
                do_proxy:
-                       DEBUG2("  rlm_eap: Request is supposed to be proxied to Realm %s.  Not doing EAP.", proxy->vp_strvalue);
+                       RDEBUG2("Request is supposed to be proxied to Realm %s.  Not doing EAP.", proxy->vp_strvalue);
                        return EAP_NOOP;
                }
 
-               DEBUG2("  rlm_eap: Got EAP_START message");
+               RDEBUG2("Got EAP_START message");
                if ((eap_ds = eap_ds_alloc()) == NULL) {
-                       DEBUG2("  rlm_eap: EAP Start failed in allocation");
+                       RDEBUG2("EAP Start failed in allocation");
                        return EAP_FAIL;
                }
 
@@ -661,7 +697,7 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
        if (eap_msg->length < (EAP_HEADER_LEN + 1)) {
                if (proxy) goto do_proxy;
 
-               DEBUG2("  rlm_eap: Ignoring EAP-Message which is too short to be meaningful.");
+               RDEBUG2("Ignoring EAP-Message which is too short to be meaningful.");
                return EAP_FAIL;
        }
 
@@ -669,7 +705,7 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
         *      Create an EAP-Type containing the EAP-type
         *      from the packet.
         */
-       vp = paircreate(PW_EAP_TYPE, PW_TYPE_INTEGER);
+       vp = paircreate(PW_EAP_TYPE, 0, PW_TYPE_INTEGER);
        if (vp) {
                vp->vp_integer = eap_msg->vp_octets[4];
                pairadd(&(request->packet->vps), vp);
@@ -695,9 +731,9 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
         */
        if ((eap_msg->vp_octets[0] == 0) ||
            (eap_msg->vp_octets[0] > PW_EAP_MAX_CODES)) {
-               DEBUG2("  rlm_eap: Unknown EAP packet");
+               RDEBUG2("Unknown EAP packet");
        } else {
-               DEBUG2("  rlm_eap: EAP packet type %s id %d length %d",
+               RDEBUG2("EAP packet type %s id %d length %d",
                       eap_codes[eap_msg->vp_octets[0]],
                       eap_msg->vp_octets[1],
                       eap_msg->length);
@@ -711,7 +747,7 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
         */
        if ((eap_msg->vp_octets[0] != PW_EAP_REQUEST) &&
            (eap_msg->vp_octets[0] != PW_EAP_RESPONSE)) {
-               DEBUG2("  rlm_eap: Ignoring EAP packet which we don't know how to handle.");
+               RDEBUG2("Ignoring EAP packet which we don't know how to handle.");
                return EAP_FAIL;
        }
 
@@ -728,7 +764,7 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
            ((eap_msg->vp_octets[4] == 0) ||
             (eap_msg->vp_octets[4] > PW_EAP_MAX_TYPES) ||
             (inst->types[eap_msg->vp_octets[4]] == NULL))) {
-               DEBUG2("  rlm_eap:  Ignoring Unknown EAP type");
+               RDEBUG2(" Ignoring Unknown EAP type");
                return EAP_NOOP;
        }
 
@@ -753,13 +789,13 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
            ((eap_msg->vp_octets[5] == 0) ||
             (eap_msg->vp_octets[5] > PW_EAP_MAX_TYPES) ||
             (inst->types[eap_msg->vp_octets[5]] == NULL))) {
-               DEBUG2("  rlm_eap: Ignoring NAK with request for unknown EAP type");
+               RDEBUG2("Ignoring NAK with request for unknown EAP type");
                return EAP_NOOP;
        }
 
        if ((eap_msg->vp_octets[4] == PW_EAP_TTLS) ||
            (eap_msg->vp_octets[4] == PW_EAP_PEAP)) {
-               DEBUG2("  rlm_eap: Continuing tunnel setup.");
+               RDEBUG2("Continuing tunnel setup.");
                return EAP_OK;
        }
 
@@ -770,7 +806,7 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
         *      use the State attribute to match this EAP-Message to
         *      an ongoing conversation.
         */
-       DEBUG2("  rlm_eap: No EAP Start, assuming it's an on-going EAP conversation");
+       RDEBUG2("No EAP Start, assuming it's an on-going EAP conversation");
 
        return EAP_NOTFOUND;
 }
@@ -780,6 +816,15 @@ int eap_start(rlm_eap_t *inst, REQUEST *request)
  */
 void eap_fail(EAP_HANDLER *handler)
 {
+       /*
+        *      Delete any previous replies.
+        */
+       pairdelete(&handler->request->reply->vps, PW_EAP_MESSAGE, 0);
+       pairdelete(&handler->request->reply->vps, PW_STATE, 0);
+
+       eap_packet_free(&handler->eap_ds->request);
+       handler->eap_ds->request = eap_packet_alloc();
+
        handler->eap_ds->request->code = PW_EAP_FAILURE;
        eap_compose(handler);
 }
@@ -796,7 +841,7 @@ void eap_success(EAP_HANDLER *handler)
 /*
  * Basic EAP packet verfications & validations
  */
-static int eap_validation(eap_packet_t *eap_packet)
+static int eap_validation(REQUEST *request, eap_packet_t *eap_packet)
 {
        uint16_t len;
 
@@ -812,15 +857,15 @@ static int eap_validation(eap_packet_t *eap_packet)
            (eap_packet->data[0] <= 0) ||
            (eap_packet->data[0] > PW_EAP_MAX_TYPES)) {
 
-               radlog(L_AUTH, "rlm_eap: Incorrect EAP Message, "
-                               "Ignoring the packet");
+               radlog_request(L_AUTH, 0, request, 
+                              "Badly formatted EAP Message: Ignoring the packet");
                return EAP_INVALID;
        }
 
        /* we don't expect notification, but we send it */
        if (eap_packet->data[0] == PW_EAP_NOTIFICATION) {
-               radlog(L_AUTH, "rlm_eap: Got NOTIFICATION, "
-                               "Ignoring the packet");
+               radlog_request(L_AUTH, 0, request, "Got NOTIFICATION, "
+                              "Ignoring the packet");
                return EAP_INVALID;
        }
 
@@ -831,7 +876,7 @@ static int eap_validation(eap_packet_t *eap_packet)
 /*
  *  Get the user Identity only from EAP-Identity packets
  */
-static char *eap_identity(eap_packet_t *eap_packet)
+static char *eap_identity(REQUEST *request, eap_packet_t *eap_packet)
 {
        int size;
        uint16_t len;
@@ -847,16 +892,12 @@ static char *eap_identity(eap_packet_t *eap_packet)
        len = ntohs(len);
 
        if ((len <= 5) || (eap_packet->data[1] == 0x00)) {
-               radlog(L_ERR, "rlm_eap: UserIdentity Unknown ");
+               RDEBUG("UserIdentity Unknown ");
                return NULL;
        }
 
        size = len - 5;
-       identity = (char *)malloc(size + 1);
-       if (identity == NULL) {
-               radlog(L_ERR, "rlm_eap: out of memory");
-               return NULL;
-       }
+       identity = rad_malloc(size + 1);
        memcpy(identity, &eap_packet->data[1], size);
        identity[size] = '\0';
 
@@ -934,7 +975,7 @@ EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
        /*
         *      Ensure it's a valid EAP-Request, or EAP-Response.
         */
-       if (eap_validation(eap_packet) == EAP_INVALID) {
+       if (eap_validation(request, eap_packet) == EAP_INVALID) {
                free(*eap_packet_p);
                *eap_packet_p = NULL;
                return NULL;
@@ -948,8 +989,8 @@ EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
                handler = eaplist_find(inst, request, eap_packet);
                if (handler == NULL) {
                        /* Either send EAP_Identity or EAP-Fail */
-                       radlog(L_ERR, "rlm_eap: Either EAP-request timed out OR"
-                               " EAP-response to an unknown EAP-request");
+                       RDEBUG("Either EAP-request timed out OR"
+                              " EAP-response to an unknown EAP-request");
                        free(*eap_packet_p);
                        *eap_packet_p = NULL;
                        return NULL;
@@ -965,13 +1006,13 @@ EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
                 */
                if ((eap_packet->data[0] != PW_EAP_NAK) &&
                    (eap_packet->data[0] != handler->eap_type)) {
-                       radlog(L_ERR, "rlm_eap: Response appears to match, but EAP type is wrong.");
+                       RDEBUG("Response appears to match, but EAP type is wrong.");
                        free(*eap_packet_p);
                        *eap_packet_p = NULL;
                        return NULL;
                }
 
-               vp = pairfind(request->packet->vps, PW_USER_NAME);
+               vp = pairfind(request->packet->vps, PW_USER_NAME, 0);
                if (!vp) {
                        /*
                         *      NAS did not set the User-Name
@@ -980,10 +1021,10 @@ EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
                         *      request vps so that autz's work
                         *      correctly
                        */
-                       DEBUG2("rlm_eap: Broken NAS did not set User-Name, setting from EAP Identity");
+                      RDEBUG2("Broken NAS did not set User-Name, setting from EAP Identity");
                        vp = pairmake("User-Name", handler->identity, T_OP_EQ);
                        if (vp == NULL) {
-                               radlog(L_ERR, "rlm_eap: out of memory");
+                              RDEBUG("Out of memory");
                                free(*eap_packet_p);
                                *eap_packet_p = NULL;
                                return NULL;
@@ -1003,16 +1044,16 @@ EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
                        */
                        if (strncmp(handler->identity, vp->vp_strvalue,
                                   MAX_STRING_LEN) != 0) {
-                               radlog(L_ERR, "rlm_eap: Identity does not match User-Name.  Authentication failed.");
+                               RDEBUG("Identity does not match User-Name.  Authentication failed.");
                                free(*eap_packet_p);
                                *eap_packet_p = NULL;
                                return NULL;
                        }
               }
        } else {                /* packet was EAP identity */
-               handler = eap_handler_alloc();
+               handler = eap_handler_alloc(inst);
                if (handler == NULL) {
-                       radlog(L_ERR, "rlm_eap: out of memory");
+                       RDEBUG("Out of memory.");
                        free(*eap_packet_p);
                        *eap_packet_p = NULL;
                        return NULL;
@@ -1021,16 +1062,16 @@ EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
                /*
                 *      All fields in the handler are set to zero.
                 */
-               handler->identity = eap_identity(eap_packet);
+               handler->identity = eap_identity(request, eap_packet);
                if (handler->identity == NULL) {
-                       radlog(L_ERR, "rlm_eap: Identity Unknown, authentication failed");
+                       RDEBUG("Identity Unknown, authentication failed");
                        free(*eap_packet_p);
                        *eap_packet_p = NULL;
-                       eap_handler_free(handler);
+                       eap_handler_free(inst, handler);
                        return NULL;
                }
 
-               vp = pairfind(request->packet->vps, PW_USER_NAME);
+               vp = pairfind(request->packet->vps, PW_USER_NAME, 0);
                if (!vp) {
                        /*
                         *      NAS did not set the User-Name
@@ -1039,13 +1080,13 @@ EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
                         *      request vps so that autz's work
                         *      correctly
                        */
-                       DEBUG2("rlm_eap: WARNING NAS did not set User-Name.  Setting it locally from EAP Identity");
+                      RDEBUG2("WARNING NAS did not set User-Name.  Setting it locally from EAP Identity");
                        vp = pairmake("User-Name", handler->identity, T_OP_EQ);
                        if (vp == NULL) {
-                               radlog(L_ERR, "rlm_eap: out of memory");
+                               RDEBUG("Out of memory");
                                free(*eap_packet_p);
                                *eap_packet_p = NULL;
-                              eap_handler_free(handler);
+                              eap_handler_free(inst, handler);
                                return NULL;
                        }
                        vp->next = request->packet->vps;
@@ -1059,10 +1100,10 @@ EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
                        */
                        if (strncmp(handler->identity, vp->vp_strvalue,
                                   MAX_STRING_LEN) != 0) {
-                               radlog(L_ERR, "rlm_eap: Identity does not match User-Name, setting from EAP Identity.");
+                               RDEBUG("Identity does not match User-Name, setting from EAP Identity.");
                                free(*eap_packet_p);
                                *eap_packet_p = NULL;
-                               eap_handler_free(handler);
+                               eap_handler_free(inst, handler);
                                return NULL;
                        }
               }
@@ -1072,7 +1113,7 @@ EAP_HANDLER *eap_handler(rlm_eap_t *inst, eap_packet_t **eap_packet_p,
        if (handler->eap_ds == NULL) {
                free(*eap_packet_p);
                *eap_packet_p = NULL;
-               eap_handler_free(handler);
+               eap_handler_free(inst, handler);
                return NULL;
        }