- DEBUG2("WARNING: No NAS-Port attribute in request. CANNOT return a Framed-IP-Address + NAS-Port.\n");
- pairdelete(&request->reply->vps, PW_FRAMED_IP_ADDRESS);
- }
- }
-
- /*
- * See if we need to execute a program.
- * FIXME: somehow cache this info, and only execute the
- * program when we receive an Accounting-START packet.
- * Only at that time we know dynamic IP etc.
- */
- exec_program = NULL;
- exec_wait = 0;
- if ((auth_item = pairfind(request->reply->vps, PW_EXEC_PROGRAM)) != NULL) {
- exec_wait = 0;
- exec_program = strdup((char *)auth_item->strvalue);
- pairdelete(&request->reply->vps, PW_EXEC_PROGRAM);
- }
- if ((auth_item = pairfind(request->reply->vps, PW_EXEC_PROGRAM_WAIT)) != NULL) {
- exec_wait = 1;
- exec_program = strdup((char *)auth_item->strvalue);
- pairdelete(&request->reply->vps, PW_EXEC_PROGRAM_WAIT);
- }
-
- /*
- * Hack - allow % expansion in certain value strings.
- * This is nice for certain Exec-Program programs.
- */
- seen_callback_id = 0;
- if ((auth_item = pairfind(request->reply->vps, PW_CALLBACK_ID)) != NULL) {
- seen_callback_id = 1;
- radius_xlat(buf, sizeof(auth_item->strvalue),
- (char *)auth_item->strvalue, request, NULL);
- strNcpy((char *)auth_item->strvalue, buf,
- sizeof(auth_item->strvalue));
- auth_item->length = strlen((char *)auth_item->strvalue);
- }
-
-
- /*
- * If we want to exec a program, but wait for it,
- * do it first before sending the reply.
- */
- if (exec_program && exec_wait) {
- r = radius_exec_program(exec_program, request,
- exec_wait,
- umsg, sizeof(umsg),
- request->packet->vps, &tmp);
- free(exec_program);
- exec_program = NULL;
-
- /*
- * Always add the value-pairs to the reply.
- */
- pairmove(&request->reply->vps, &tmp);
- pairfree(&tmp);
-
- if (r != 0) {
- /*
- * Error. radius_exec_program() returns -1 on
- * fork/exec errors, or >0 if the exec'ed program
- * had a non-zero exit status.
- */
- if (umsg[0] == '\0') {
- user_msg = "\r\nAccess denied (external check failed).";
- } else {
- user_msg = &umsg[0];
- }
-
- request->reply->code = PW_AUTHENTICATION_REJECT;
- tmp = pairmake("Reply-Message", user_msg, T_OP_SET);
-
- pairadd(&request->reply->vps, tmp);
- rad_authlog("Login incorrect (external check failed)",
- request, 0);
-
- rad_postauth_reject(request);
-
- return RLM_MODULE_REJECT;
- }
- }
-
- /*
- * Delete "normal" A/V pairs when using callback.
- *
- * FIXME: This is stupid. The portmaster should accept
- * these settings instead of insisting on using a
- * dialout location.
- *
- * FIXME2: Move this into the above exec thingy?
- * (if you knew how I use the exec_wait, you'd understand).
- */
- if (seen_callback_id) {
- 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);
- }
-
- /*
- * Filter (possibly multiple) Reply-Message attributes
- * through radius_xlat, modifying them in place.
- */
- if (user_msg == NULL) {
- reply_item = pairfind(request->reply->vps, PW_REPLY_MESSAGE);
- while (reply_item) {
- radius_xlat(buf, sizeof(reply_item->strvalue),
- (char *)reply_item->strvalue, request, NULL);
- strNcpy((char *)reply_item->strvalue, buf,
- sizeof(reply_item->strvalue));
- reply_item->length = strlen((char *)reply_item->strvalue);
- user_msg = NULL;
- reply_item = pairfind(reply_item->next, PW_REPLY_MESSAGE);