Create the request->reply data structure as soon as the request
authoraland <aland>
Mon, 2 Oct 2000 15:30:52 +0000 (15:30 +0000)
committeraland <aland>
Mon, 2 Oct 2000 15:30:52 +0000 (15:30 +0000)
passes a number of sanity checks.  After this point (rad_process),
the server will send a reply (reject or otherwise), so we might
as well have the reply structure sitting around.

Updated authorization, authentication, and accounting to
use request->reply everywhere.

Updated the module functions to pull the check/reply items out of
the 'request' structure, instead of passing them around as
seperate variables.

All of the modules still need to be updated for this new API.

The changes in auth.c drop the 'user_msg'.  There are a bunch
of 'FIXME's in the source now.

src/include/modules.h
src/main/acct.c
src/main/auth.c
src/main/modules.c
src/main/radiusd.c
src/main/util.c

index 6d0bb21..473701d 100644 (file)
@@ -53,10 +53,8 @@ enum {
 };
 
 int setup_modules(void);
-int module_authorize(REQUEST *request, 
-       VALUE_PAIR **check_items, VALUE_PAIR **reply_items);
-int module_authenticate(int type, REQUEST *request, 
-   VALUE_PAIR **check_items, VALUE_PAIR **reply_items);
+int module_authorize(REQUEST *request);
+int module_authenticate(int type, REQUEST *request);
 int module_preacct(REQUEST *request);
 int module_accounting(REQUEST *request);
 
index 8ed6501..812e150 100644 (file)
@@ -60,8 +60,7 @@ int rad_accounting(REQUEST *request)
                /*
                 *      Now send back an ACK to the NAS.
                 */
-               request->reply = build_reply(PW_ACCOUNTING_RESPONSE, request,
-                                            NULL, NULL);
+               request->reply->code = PW_ACCOUNTING_RESPONSE;
                reply = RLM_MODULE_OK;
        }
 
index 52cf64b..6d9a076 100644 (file)
@@ -106,8 +106,7 @@ static int check_expiration(VALUE_PAIR *check_item, char *umsg, const char **use
  *     NOTE: NOT the same as the RLM_ values !
  */
 static int rad_check_password(REQUEST *request,
-       VALUE_PAIR *check_item, VALUE_PAIR *user_reply, 
-       const char **user_msg)
+       VALUE_PAIR *check_item, const char **user_msg)
 {
        VALUE_PAIR      *auth_type_pair;
        VALUE_PAIR      *password_pair;
@@ -226,7 +225,7 @@ static int rad_check_password(REQUEST *request,
                         *      status into the values as defined at
                         *      the top of this function.
                         */
-                       result = module_authenticate(auth_type, request, &request->config_items, &user_reply);
+                       result = module_authenticate(auth_type, request);
                        switch (result) {
                                /*
                                 *      An authentication module FAIL
@@ -262,7 +261,6 @@ int rad_authenticate(REQUEST *request)
        VALUE_PAIR      *check_item;
        VALUE_PAIR      *reply_item;
        VALUE_PAIR      *auth_item;
-       VALUE_PAIR      *user_reply;
        VALUE_PAIR      *tmp;
        int             result, r;
        char            umsg[MAX_STRING_LEN + 1];
@@ -273,7 +271,6 @@ int rad_authenticate(REQUEST *request)
        int             seen_callback_id;
        char            buf[1024];
 
-       user_reply = NULL;
        password = "";
 
        /*
@@ -316,7 +313,7 @@ int rad_authenticate(REQUEST *request)
                 *      the reply attributes from the proxy.
                 */
                if (request->proxy_reply->vps) {
-                       user_reply = request->proxy_reply->vps;
+                       request->reply->vps = request->proxy_reply->vps;
                        request->proxy_reply->vps = NULL;
                }
        }
@@ -368,7 +365,7 @@ int rad_authenticate(REQUEST *request)
        /*
         *      Get the user's authorization information from the database
         */
-       r = module_authorize(request, &request->config_items, &user_reply);
+       r = module_authorize(request);
        if (r != RLM_MODULE_OK) {
                if (r != RLM_MODULE_FAIL && r != RLM_MODULE_HANDLED) {
                        radlog(L_AUTH, "Invalid user: [%s%s%s] (%s)",
@@ -376,10 +373,10 @@ int rad_authenticate(REQUEST *request)
                            log_auth_pass ? "/" : "",
                            log_auth_pass ? password : "",
                            auth_name(buf, sizeof(buf), request, 1));
-                       request->reply = build_reply(PW_AUTHENTICATION_REJECT,
-                                                    request, NULL, NULL);
+                       request->reply->code = PW_AUTHENTICATION_REJECT;
                }
-               pairfree(user_reply);
+               pairfree(request->reply->vps);
+               request->reply->vps = NULL;
                return r;
        }
 
@@ -391,7 +388,6 @@ int rad_authenticate(REQUEST *request)
         */
        if ((request->proxy == NULL) &&
            (pairfind(request->config_items, PW_PROXY_TO_REALM) != NULL)) {
-               pairfree(user_reply);
                return 0;
        }
 
@@ -409,18 +405,12 @@ int rad_authenticate(REQUEST *request)
        do {
                if ((result = check_expiration(request->config_items, umsg, &user_msg))<0)
                                break;
-               result = rad_check_password(request, request->config_items, user_reply, 
+               result = rad_check_password(request, request->config_items, 
                        &user_msg);
                if (result > 0) {
                        /* don't reply! */
-                       pairfree(user_reply);
                        return -1;
                }
-               if (result == -2) {
-                       reply_item = pairfind(user_reply, PW_REPLY_MESSAGE);
-                       if (reply_item != NULL)
-                               user_msg = (char *)reply_item->strvalue;
-               }
        } while(0);
 
        if (result < 0) {
@@ -428,8 +418,14 @@ int rad_authenticate(REQUEST *request)
                 *      Failed to validate the user.
                 */
                DEBUG2("  auth: Failed to validate the user.");
-               request->reply = build_reply(PW_AUTHENTICATION_REJECT, request,
-                                            NULL, user_msg);
+               request->reply->code = PW_AUTHENTICATION_REJECT;
+               pairfree(request->reply->vps);
+               request->reply->vps = NULL;
+               
+               /*
+                *  FIXME! Add 'user_msg' to the reject!
+                */
+
                if (auth_item != NULL && log_auth) {
                        char clean_buffer[1024];
                        u_char *p;
@@ -481,13 +477,19 @@ int rad_authenticate(REQUEST *request)
                                user_msg =
                "\r\nYou are already logged in - access denied\r\n\n";
                        }
-                       request->reply = build_reply(PW_AUTHENTICATION_REJECT,
-                                                    request, NULL, user_msg);
-               radlog(L_ERR, "Multiple logins: [%s] (%s) max. %d%s",
-                               namepair->strvalue,
-                               auth_name(buf, sizeof(buf), request, 1),
-                               check_item->lvalue,
-                               r == 2 ? " [MPP attempt]" : "");
+
+                       request->reply->code = PW_AUTHENTICATION_REJECT;
+                       pairfree(request->reply->vps);
+                       request->reply->vps = NULL;
+
+                       /*
+                        *  FIXME!  Add user_msg to the reject
+                        */
+                       radlog(L_ERR, "Multiple logins: [%s] (%s) max. %d%s",
+                              namepair->strvalue,
+                              auth_name(buf, sizeof(buf), request, 1),
+                              check_item->lvalue,
+                              r == 2 ? " [MPP attempt]" : "");
                        result = -1;
                }
        }
@@ -513,8 +515,14 @@ int rad_authenticate(REQUEST *request)
                        result = -1;
                        user_msg =
                        "You are calling outside your allowed timespan\r\n";
-                       request->reply = build_reply(PW_AUTHENTICATION_REJECT,
-                                                    request, NULL, user_msg);
+
+                       request->reply->code = PW_AUTHENTICATION_REJECT;
+                       pairfree(request->reply->vps);
+                       request->reply->vps = NULL;
+
+                       /*
+                        *  FIXME!  Add user_msg to the reject
+                        */
                        radlog(L_ERR, "Outside allowed timespan: [%s]"
                                   " (%s) time allowed: %s",
                                        auth_username(namepair),
@@ -525,7 +533,7 @@ int rad_authenticate(REQUEST *request)
                        /*
                         *      User is allowed, but set Session-Timeout.
                         */
-                       if ((reply_item = pairfind(user_reply,
+                       if ((reply_item = pairfind(request->reply->vps,
                            PW_SESSION_TIMEOUT)) != NULL) {
                                if (reply_item->lvalue > (unsigned) r)
                                        reply_item->lvalue = r;
@@ -537,7 +545,7 @@ int rad_authenticate(REQUEST *request)
                                        exit(1);
                                }
                                reply_item->lvalue = r;
-                               pairadd(&user_reply, reply_item);
+                               pairadd(&request->reply->vps, reply_item);
                        }
                }
        }
@@ -546,7 +554,6 @@ int rad_authenticate(REQUEST *request)
         *      Result should be >= 0 here - if not, we return.
         */
        if (result < 0) {
-               pairfree(user_reply);
                return 0;
        }
 
@@ -567,15 +574,15 @@ int rad_authenticate(REQUEST *request)
         */
        exec_program = NULL;
        exec_wait = 0;
-       if ((auth_item = pairfind(user_reply, PW_EXEC_PROGRAM)) != NULL) {
+       if ((auth_item = pairfind(request->reply->vps, PW_EXEC_PROGRAM)) != NULL) {
                exec_wait = 0;
                exec_program = strdup(auth_item->strvalue);
-               pairdelete(&user_reply, PW_EXEC_PROGRAM);
+               pairdelete(&request->reply->vps, PW_EXEC_PROGRAM);
        }
-       if ((auth_item = pairfind(user_reply, PW_EXEC_PROGRAM_WAIT)) != NULL) {
+       if ((auth_item = pairfind(request->reply->vps, PW_EXEC_PROGRAM_WAIT)) != NULL) {
                exec_wait = 1;
                exec_program = strdup(auth_item->strvalue);
-               pairdelete(&user_reply, PW_EXEC_PROGRAM_WAIT);
+               pairdelete(&request->reply->vps, PW_EXEC_PROGRAM_WAIT);
        }
 
        /*
@@ -583,11 +590,11 @@ int rad_authenticate(REQUEST *request)
         *      This is nice for certain Exec-Program programs.
         */
        seen_callback_id = 0;
-       if ((auth_item = pairfind(user_reply, PW_CALLBACK_ID)) != NULL) {
+       if ((auth_item = pairfind(request->reply->vps, PW_CALLBACK_ID)) != NULL) {
                seen_callback_id = 1;
                radius_xlate(buf, sizeof(auth_item->strvalue),
                             (char *)auth_item->strvalue,
-                            request->packet->vps, user_reply);
+                            request->packet->vps, request->reply->vps);
                strNcpy((char *)auth_item->strvalue, buf,
                        sizeof(auth_item->strvalue));
                auth_item->length = strlen((char *)auth_item->strvalue);
@@ -600,7 +607,7 @@ int rad_authenticate(REQUEST *request)
         */
        if (exec_program && exec_wait) {
                if (radius_exec_program(exec_program,
-                   request->packet->vps, &user_reply, exec_wait, &user_msg) != 0) {
+                   request->packet->vps, &request->reply->vps, exec_wait, &user_msg) != 0) {
                        /*
                         *      Error. radius_exec_program() returns -1 on
                         *      fork/exec errors, or >0 if the exec'ed program
@@ -608,8 +615,15 @@ int rad_authenticate(REQUEST *request)
                         */
                        if (user_msg == NULL)
                user_msg = "\r\nAccess denied (external check failed).";
-                       request->reply = build_reply(PW_AUTHENTICATION_REJECT,
-                                                    request, NULL, user_msg);
+
+                       request->reply->code = PW_AUTHENTICATION_REJECT;
+                       pairfree(request->reply->vps);
+                       request->reply->vps = NULL;
+
+                       /*
+                        *  FIXME!  Add user_msg to the request.
+                        */
+
                        if (log_auth) {
                                radlog(L_AUTH,
                                        "Login incorrect: [%s] (%s) "
@@ -617,7 +631,6 @@ int rad_authenticate(REQUEST *request)
                                        auth_username(namepair),
                                        auth_name(buf, sizeof(buf), request, 1));
                        }
-                       pairfree(user_reply);
                        return 0;
                }
        }
@@ -633,15 +646,15 @@ int rad_authenticate(REQUEST *request)
         *      (if you knew how I use the exec_wait, you'd understand).
         */
        if (seen_callback_id) {
-               pairdelete(&user_reply, PW_FRAMED_PROTOCOL);
-               pairdelete(&user_reply, PW_FRAMED_IP_ADDRESS);
-               pairdelete(&user_reply, PW_FRAMED_IP_NETMASK);
-               pairdelete(&user_reply, PW_FRAMED_ROUTE);
-               pairdelete(&user_reply, PW_FRAMED_MTU);
-               pairdelete(&user_reply, PW_FRAMED_COMPRESSION);
-               pairdelete(&user_reply, PW_FILTER_ID);
-               pairdelete(&user_reply, PW_PORT_LIMIT);
-               pairdelete(&user_reply, PW_CALLBACK_NUMBER);
+               pairdelete(&request->reply->vps, PW_FRAMED_PROTOCOL);
+               pairdelete(&request->reply->vps, PW_FRAMED_IP_ADDRESS);
+               pairdelete(&request->reply->vps, PW_FRAMED_IP_NETMASK);
+               pairdelete(&request->reply->vps, PW_FRAMED_ROUTE);
+               pairdelete(&request->reply->vps, PW_FRAMED_MTU);
+               pairdelete(&request->reply->vps, PW_FRAMED_COMPRESSION);
+               pairdelete(&request->reply->vps, PW_FILTER_ID);
+               pairdelete(&request->reply->vps, PW_PORT_LIMIT);
+               pairdelete(&request->reply->vps, PW_CALLBACK_NUMBER);
        }
 
        /*
@@ -649,11 +662,11 @@ int rad_authenticate(REQUEST *request)
         *      through radius_xlate, modifying them in place.
         */
        if (user_msg == NULL) {
-         reply_item = pairfind(user_reply, PW_REPLY_MESSAGE);
+         reply_item = pairfind(request->reply->vps, PW_REPLY_MESSAGE);
          while (reply_item) {
                radius_xlate(buf, sizeof(reply_item->strvalue),
                             (char *)reply_item->strvalue,
-                            request->packet->vps, user_reply);
+                            request->packet->vps, request->reply->vps);
                strNcpy((char *)reply_item->strvalue, buf,
                        sizeof(reply_item->strvalue));
                reply_item->length = strlen((char *)reply_item->strvalue);
@@ -662,8 +675,11 @@ int rad_authenticate(REQUEST *request)
          }
        }
 
-       request->reply = build_reply(PW_AUTHENTICATION_ACK, request,
-                                    user_reply, user_msg);
+       request->reply->code = PW_AUTHENTICATION_ACK;
+
+       /*
+        * FIXME!  Add user_msg to the reply!
+        */
 
        if (log_auth) {
                radlog(L_AUTH,
@@ -678,11 +694,10 @@ int rad_authenticate(REQUEST *request)
                 *      No need to check the exit status here.
                 */
                radius_exec_program(exec_program,
-                       request->packet->vps, &user_reply, exec_wait, NULL);
+                       request->packet->vps, &request->reply->vps, exec_wait, NULL);
        }
 
        if (exec_program) free(exec_program);
-       pairfree(user_reply);
        return 0;
 }
 
index 94b383f..be61b2b 100644 (file)
@@ -539,8 +539,7 @@ static void update_username(REQUEST *request, char *newname)
  *     Call all authorization modules until one returns
  *     somethings else than RLM_MODULE_OK
  */
-int module_authorize(REQUEST *request,
-                    VALUE_PAIR **check_items, VALUE_PAIR **reply_items)
+int module_authorize(REQUEST *request)
 {
        config_module_t *this;
        int             rcode = RLM_MODULE_OK;
@@ -551,8 +550,9 @@ int module_authorize(REQUEST *request,
        while (this && rcode == RLM_MODULE_OK) {
                DEBUG2("  authorize: %s", this->instance->entry->module->name);
                rcode = (this->instance->entry->module->authorize)(
-                        this->instance->insthandle, request, check_items,
-                        reply_items);
+                        this->instance->insthandle, request,
+                        &request->config_items,
+                        &request->reply->vps);
                this = this->next;
        }
 
@@ -610,8 +610,7 @@ int module_authorize(REQUEST *request,
 /*
  *     Authenticate a user/password with various methods.
  */
-int module_authenticate(int auth_type, REQUEST *request, 
-                    VALUE_PAIR **check_items, VALUE_PAIR **reply_items)
+int module_authenticate(int auth_type, REQUEST *request)
 {
        config_module_t *this;
 
@@ -635,7 +634,8 @@ int module_authenticate(int auth_type, REQUEST *request,
 
        DEBUG2("  authenticate: %s", this->instance->entry->module->name);
        return (this->instance->entry->module->authenticate)(
-               this->instance->insthandle, request, check_items, reply_items);
+               this->instance->insthandle, request,
+               &request->config_items, &request->reply->vps);
 }
 
 
index 71e41a6..3fba108 100644 (file)
@@ -209,7 +209,7 @@ static void reread_config(int reload)
        if (!reload) {
                radlog(L_INFO, "Starting - reading configuration files ...");
 #ifdef WITH_USERCOLLIDE
-               radlog(L_INFO, "User collission code on ... ");
+               radlog(L_INFO, "User collision code on ... ");
 #endif
        } else if (pid == radius_pid) {
                radlog(L_INFO, "Reloading configuration files.");
@@ -1141,6 +1141,27 @@ int rad_process(REQUEST *request, int dospawn)
        assert(request->magic == REQUEST_MAGIC);
 
        /*
+        *      The request passes many of our sanity checks.  From
+        *      here on in, if anything goes wrong, we send a reject
+        *      message, instead of dropping the packet.
+        *
+        *      Build the reply template from the request template.
+        */
+       if ((request->reply = rad_alloc(0)) == NULL) {
+               fprintf(stderr, "out of memory\n");
+               exit(1);
+       }
+       request->reply->sockfd     = request->packet->sockfd;
+       request->reply->dst_ipaddr = request->packet->src_ipaddr;
+       request->reply->dst_port   = request->packet->src_port;
+       request->reply->id         = request->packet->id;
+       request->reply->code       = 0; /* UNKNOWN code */
+       memcpy(request->reply->vector, request->packet->vector,
+              sizeof(request->reply->vector));
+       request->reply->vps = NULL;
+       request->reply->data = NULL;
+       
+       /*
         *      If we're spawning a child thread, let it do all of
         *      the work of handling a request, and exit.
         */
@@ -1181,15 +1202,14 @@ static void rad_reject(REQUEST *request)
                 *      reject message sent.
                 */
        case PW_AUTHENTICATION_REQUEST:
-               request->reply = build_reply(PW_AUTHENTICATION_REJECT,
-                                            request, NULL, NULL);
+               request->reply->code = PW_AUTHENTICATION_REJECT;
                break;
        }
        
        /*
         *      If a reply exists, send it.
         */
-       if (request->reply) {
+       if (request->reply->code) {
                rad_send(request->reply, request->secret);
        }
 }
@@ -1256,7 +1276,7 @@ int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
                request->username = pairfind(request->packet->vps,
                                             PW_USER_NAME);
        }
-       
+
        /*
         *      We have the semaphore, and have decoded the packet.
         *      Let's process the request.
@@ -1295,12 +1315,24 @@ int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
        }
 
        /*
-        *      If there's a reply, send it to the NAS.
+        *      If we have a reply to send, copy the Proxy-State
+        *      attributes from the request to the tail of the reply,
+        *      and send the packet.
         */
        assert(request->magic == REQUEST_MAGIC);
-       if (request->reply)
+       if (request->reply->code != 0) {
+               VALUE_PAIR *vp;
+
+               /*
+                *      Need to copy Proxy-State from request->packet->vps
+                */
+               vp = paircopy2(request->packet->vps, PW_PROXY_STATE);
+               if (vp != NULL)
+                       pairadd(&(request->reply->vps), vp);
+
                rad_send(request->reply, request->secret);
-       
+       }
+
        /*
         *      We're done processing the request, set the
         *      request to be finished, clean up as necessary,
index d0d161f..7714e2e 100644 (file)
@@ -95,33 +95,15 @@ void request_free(REQUEST *request)
 }
 
 
+#if 0
 /*
  *     Build a reply radius packet, based on the request data.
  */
 RADIUS_PACKET *build_reply(int code, REQUEST *request,
        VALUE_PAIR *vps, const char *user_msg)
 {
-       RADIUS_PACKET   *rp;
        VALUE_PAIR      *vp;
 
-       if ((rp = rad_alloc(0)) == NULL) {
-               fprintf(stderr, "out of memory\n");
-               exit(1);
-       }
-       rp->sockfd     = request->packet->sockfd;
-       rp->dst_ipaddr = request->packet->src_ipaddr;
-       rp->dst_port   = request->packet->src_port;
-       rp->id         = request->packet->id;
-       rp->code       = code;
-       memcpy(rp->vector, request->packet->vector, sizeof(rp->vector));
-       rp->vps        = paircopy(vps);
-
-       /*
-        *      Need to copy PROXY_PAIRS from request->packet->vps
-        */
-       if ((vp = paircopy2(request->packet->vps, PW_PROXY_STATE)) != NULL)
-               pairadd(&(rp->vps), vp);
-
        if (user_msg && (vp = paircreate(PW_REPLY_MESSAGE, PW_TYPE_STRING))) {
                strNcpy((char *)vp->strvalue, user_msg, sizeof(vp->strvalue));
                vp->length = strlen(user_msg);
@@ -138,3 +120,4 @@ RADIUS_PACKET *build_reply(int code, REQUEST *request,
 
        return rp;
 }
+#endif