📄 rf_req.c
字号:
#ifdef USR_CCA/* * * Copyright (c) 1996 U.S. Robotics, Access Corp. * All rights reserved. * * Permission to copy, display, distribute and make derivative works * from this material in whole or in part for any purpose is granted * provided that the above copyright notice and this paragraph are * duplicated in all copies. THIS SOFTWARE IS PROVIDED "AS IS" AND * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES INCLUDING, WITHOUT * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE. * * If providing code not subject to a copyright please indicate that the * code has been dedicated to the public. * *//* * Copyright [C] The Regents of the University of Michigan and Merit Network, * Inc. 1992, 1993, 1994, 1995, 1996, 1997, 1998 All Rights Reserved * * Permission to use, copy, and modify this software and its documentation * for any purpose and without fee is hereby granted, provided: * * 1) that the above copyright notice and this permission notice appear in all * copies of the software and derivative works or modified versions thereof, * * 2) that both the copyright notice and this permission and disclaimer notice * appear in all supporting documentation, and * * 3) that all derivative works made from this material are returned to the * Regents of the University of Michigan and Merit Network, Inc. with * permission to copy, to display, to distribute, and to make derivative * works from the provided material in whole or in part for any purpose. * * Users of this code are requested to notify Merit Network, Inc. of such use * by sending email to aaa-admin@merit.edu * * Please also use aaa-admin@merit.edu to inform Merit Network, Inc of any * derivative works. * * Distribution of this software or derivative works or the associated * documentation is not allowed without an additional license. * * Licenses for other uses are available on an individually negotiated * basis. Contact aaa-license@merit.edu for more information. * * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF THE * UNIVERSITY OF MICHIGAN AND MERIT NETWORK, INC. DO NOT WARRANT THAT THE * FUNCTIONS CONTAINED IN THE SOFTWARE WILL MEET LICENSEE'S REQUIREMENTS OR * THAT OPERATION WILL BE UNINTERRUPTED OR ERROR FREE. The Regents of the * University of Michigan and Merit Network, Inc. shall not be liable for any * special, indirect, incidental or consequential damages with respect to any * claim by Licensee or any third party arising from use of the software. * * Merit AAA Server Support * Merit Network, Inc. * 4251 Plymouth Road, Suite C. * Ann Arbor, Michigan, USA 48105-2785 * * attn: John Vollbrecht * voice: 734-764-9430 * fax: 734-647-3185 * email: aaa-admin@merit.edu * */static char rcsid[] = "$Id: rf_req.c,v 1.1.1.1 2001/08/10 20:49:29 bonze Exp $";/*************************************************************************** * * This file defines the Resource Free Request AATV and other functions * required by this AATV * ***************************************************************************/#include <sys/param.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/ioctl.h>#include <sys/file.h>#include <sys/time.h>#include <sys/file.h>#include <sys/wait.h>#include <sys/stat.h>#if defined(sys5)#include <sys/sysmacros.h>#endif /* sys5 */#include <net/if.h>#include <stdio.h>#include <stdlib.h>#include <netdb.h>#include <fcntl.h>#include <errno.h>#include <memory.h>#include <signal.h>#include <syslog.h>#include "radius.h"extern int debug_flag;extern FILE *ddt;extern FSM_ENT **fsm;extern UINT4 self_ip[];/*************************************************************************** * * rad_rf_req_aatv definition * **************************************************************************/static int rad_rf_req_action PROTO((AUTH_REQ *, int, char *));static int rad_rf_req_timer PROTO((void));static AATV rf_req_aatv = DEF_AATV_DIRECT("RES_FREE_REQ", rad_rf_req_action);AATVPTR rad_rf_req_aatv = &rf_req_aatv;/************************************************************************** * * Function: rad_rf_req_action * * Purpose: processes the Resource Free Request and takes appropriate * action. * *************************************************************************/static intrad_rf_req_action (authreq, value, afpar)AUTH_REQ *authreq;int value;char *afpar;{ char for_us = FALSE; char type; UINT4 ipaddr; UINT4 vpn_id; UINT4 *adptr; char *das; VALUE_PAIR *assign; VALUE_PAIR *nas; VALUE_PAIR *nas_port; VALUE_PAIR *uname; VALUE_PAIR *vpn; AATV *paatv; FILE *debugout = stdout; struct in_addr addr; char *func = "rad_rf_req_action"; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func)); if (ddt != (FILE *) NULL) { debugout = ddt; } debug_list (debugout, authreq->request); paatv = find_aatv ("REPLY"); if ((vpn = get_vp_vend (authreq->request, PW_USR_VPN_ID, VC_USR)) != NULL_VP) {/* if (vpn->lvalue != VENDOR_ID_LENGTH + SUB_ID_LENGTH + INT_LEN) { addr.s_addr = authreq->ipaddr; logit (LOG_DAEMON, LOG_ERR, "%s: Invalid VPN-ID length in Resource Free Request from %s", func, inet_ntoa (addr)); authreq->fsmstatus = EV_NAK; return EV_NAK; } memcpy ((char *) &vpn_id, vpn->strvalue, sizeof (UINT4));*/ vpn_id = ntohl(vpn_id); dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: VPN ID = %ld", func, vpn_id)); if ((das = find_das (authreq->client->file_pfx, vpn_id, &type)) != (char *) NULL) { if (type == AA_LOCAL_VPN) { for_us = TRUE; } else { ipaddr = get_ipaddr (das); for (adptr = self_ip; *adptr > 0; adptr++) { if (*adptr == ipaddr) { for_us = TRUE; break; } } } if (for_us == FALSE) { avpair_del (&authreq->cur_request, PW_USR_VPN_ID, VC_USR); avpair_del (&authreq->cur_request, PW_USR_VPN_NAME, VC_USR); avpair_del (&authreq->cur_request, PW_USR_VPN_NEIGHBOR, VC_USR); avpair_del (&authreq->cur_request, PW_USR_VPN_GATEWAY, VC_USR); authreq->ipaddr = ntohl(inet_addr (das)); authreq->fsmstatus = EV_ACK; dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: authreq->cur_request:", func)); debug_list (debugout, authreq->cur_request); call_action (paatv, authreq, 0, das); return EV_ACK; } } /* else could be a locally defined user */ } ipaddr = 0; if ((uname = get_vp (authreq->request, PW_USER_NAME)) == NULL_VP) { logit (LOG_DAEMON, LOG_ERR, "%s: Missing user name in Resource Free Request", func); return EV_NAK; } if ((assign = get_vp (authreq->request, PW_FRAMED_IP_ADDRESS)) == NULL_VP) { ipaddr = 0; } else { if (assign->lvalue == 0) { logit (LOG_DAEMON, LOG_ERR, "%s: Invalid Framed-IP-Address in Resource Free Request", func); return EV_NAK; } ipaddr = assign->lvalue; } if ((nas = get_vp (authreq->request, PW_NAS_IP_ADDRESS)) == NULL_VP) { logit (LOG_DAEMON, LOG_ERR, "%s: Missing NAS IP Address in Resource Free Request", func); return EV_NAK; } if ((nas_port = get_vp (authreq->request, PW_NAS_PORT)) == NULL_VP) { logit (LOG_DAEMON, LOG_ERR, "%s: Missing NAS Port in Resource Free Request", func); return EV_NAK; } /* * User-name and Framed-IP-address present in the Resource * Free Request. Return this user's resources to the pools * (the address pool in this implementation) and return an ACK. */ authreq->fsmstatus = free_resources (uname->strvalue, ipaddr, nas->lvalue, nas_port->lvalue); authreq->ttl = 1; authreq->timer = 1; vpn = avpair_add (NULL, nas->attribute, &nas->lvalue, 0); list_free (authreq->cur_request); authreq->cur_request = vpn; authreq->cur_count = 1; authreq->code = PW_RESOURCE_FREE_RESP; if (authreq->fsmstatus == EV_ACK) { addr.s_addr = authreq->ipaddr; call_action (paatv, authreq, 0, inet_ntoa (addr)); } return authreq->fsmstatus; /* free_resources returns EV_ACK on success, EV_NAK otherwise */} /* end of rad_rf_req_action *//************************************************************************* * * Function: find_das * * Purpose: Finds the IP address/DNS name of the DAS, given the VPN-ID * ************************************************************************/char *find_das (file_pfx, vpn_id, type)char *file_pfx;UINT4 vpn_id;char *type;{ FILE_LIST *file_ent; AUTH_ENTRY *auth_ent; char *func = "find_das"; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func)); if ((file_ent = find_file_ent (file_pfx)) == (FILE_LIST *) NULL) { dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: NULL file_ent", func)); return (char *) NULL; } if ((auth_ent = file_ent->auth_list) == (AUTH_ENTRY *) NULL) { file_ent = get_default_file_entry (); if ((auth_ent = file_ent->auth_list) == (AUTH_ENTRY *) NULL) { dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: Missing default authfile", func)); return (char *) NULL; } } for (; auth_ent; auth_ent = auth_ent->next) { if (auth_ent->vpn->id == vpn_id) { *type = auth_ent->type; return auth_ent->host; } } return (char *) NULL;} /* end of find_das () *//*************************************************************************** * * Function: dup_authreq * * Purpose: Calls make_dup to duplicate the given authreq structure and * then links it into the correct global queue * **************************************************************************/AUTH_REQ *dup_authreq (authreq)AUTH_REQ *authreq;{ AUTH_REQ *new_authreq; AUTH_REQ_Q *aaq; char *func = "dup_authreq"; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func)); aaq = queue_find (authreq->code); new_authreq = make_dup (authreq); /* Link new request on global request queue */ if (new_authreq != (AUTH_REQ *) NULL) { return enqueue_authreq (aaq, new_authreq); } return ((AUTH_REQ *) NULL);} /* end of dup_authreq () *//*************************************************************************** * * Function: rf_req_timer * * Purpose: Handles timeout and resending of Resource free requests * which are forwarded to Remote Radius Servers. * **************************************************************************/static intrad_rf_req_timer (){ int pending = 0; AATV *aatv_ent; AUTH_REQ *auth_ent; AUTH_REQ_Q *aaq; char *func = "rad_rf_req_timer"; dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func)); aaq = queue_find (PW_RESOURCE_FREE_REQ); for (auth_ent = aaq->q; auth_ent != (AUTH_REQ *) NULL; auth_ent = auth_ent->next) { if (auth_ent->code != PW_RESOURCE_FREE_REQ) { continue; } if (auth_ent->timer == 0) { continue; } if (auth_ent->retry_cnt >= RF_REQ_RETRIES) { auth_ent->timer = 1; pending++; continue; } if (auth_ent->timer > 1) { pending++; continue; } auth_ent->timer = RF_REQ_TIMER + 1; aatv_ent = find_aatv ("REDO"); call_action (aatv_ent, auth_ent, 0, ""); pending++; } return pending;} /* end of rad_rf_req_timer () *//************************************************************************** * * Function: Creates a duplicate of the given AUTH_REQ structure * * Purpose: Creates a duplicate of the given AUTH_REQ structure * *************************************************************************/AUTH_REQ *make_dup (authreq)AUTH_REQ *authreq;{ AUTH_REQ *new_authreq; char *func = "make_dup"; if ((new_authreq = (AUTH_REQ *) malloc (sizeof (AUTH_REQ))) == (AUTH_REQ *) NULL) { logit (LOG_DAEMON, LOG_ALERT, "%s: FATAL out of memory", func); abort (); } memcpy ((char *) new_authreq, (char *) authreq, sizeof (AUTH_REQ)); new_authreq->event_q = (EVENT_ENT *) NULL; new_authreq->request = NULL_VP; new_authreq->cur_request = NULL_VP; new_authreq->user_check = NULL_VP; new_authreq->user_deny = NULL_VP; new_authreq->next = (AUTH_REQ *) NULL; list_copy (&new_authreq->request, authreq->request); list_copy (&new_authreq->cur_request, authreq->cur_request); list_copy (&new_authreq->user_check, authreq->user_check); list_copy (&new_authreq->user_deny, authreq->user_deny); return new_authreq;} /* end of make_dup () */#endif /* USR_CCA */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -