res_qry.c
来自「RADIUS协议的认证计费服务」· C语言 代码 · 共 1,034 行 · 第 1/2 页
C
1,034 行
#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: res_qry.c,v 1.1.1.1 2001/08/10 20:49:29 bonze Exp $";/**************************************************************************** * * res_qry.c * * This file contains the AATV and the functions required for * Resource Querying. * ***************************************************************************/#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 <string.h>#include "radius.h"extern int debug_flag;extern AUTH_REQ_Q global_auth_q;extern UINT4 self_ip[];extern u_short auth_port;/**************************************************************************** * * RES_QRY_RESP AATV definition * ***************************************************************************/static int rad_rq_resp_action PROTO ((AUTH_REQ *, int, char *));static int add_resources PROTO ((VALUE_PAIR *, char *, CLIENT_ENTRY *));static ASSIGNED_IP *make_ip_node PROTO ((UINT4, UINT4, USER_ENTRY *, int));static char nas_proc PROTO ((AUTH_REQ *, AUTH_REQ *));static char proxy_proc PROTO ((AUTH_REQ *, AUTH_REQ *));static int add_local_vpn PROTO ((AUTH_REQ *, char *));static AATV rq_resp_aatv = DEF_AATV_DIRECT("RES_QRY_RESP", rad_rq_resp_action);AATVPTR rad_rq_resp_aatv = &rq_resp_aatv;/*************************************************************************** * * Function: rq_req_init * * Purpose: Make up AUTH_REQ structures with code PW_RESOUECE_QUERY_REQ * for each Proxy client and insert them into the given queue. * ***************************************************************************/voidrq_req_init (){ CLIENT_ENTRY *client_ent; CLIENT_ENTRY *client_list; char *func = "rq_req_init"; dprintf (2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func)); client_list = get_client_list (); /* Process clients. */ for (client_ent = client_list; client_ent != (CLIENT_ENTRY *) NULL; client_ent = client_ent->next) { if ((((client_ent->client_type & CE_PROXY) != CE_PROXY) && ((client_ent->client_type & CE_NAS) != CE_NAS)) || client_ent->version == VER1) { client_ent->state = GOT_RQ_RESP; continue; } send_rq_req (client_ent); } return;} /* end of rq_req_init () *//**************************************************************************** * * Function: rad_rq_resp_action * Purpose: Action function of the RES_QRY_RESP AATV. It handles the * incoming Resource Query Responses while in the Initialization * FSM. * ****************************************************************************/static intrad_rq_resp_action (authreq, value, afpar)AUTH_REQ *authreq;int value;char *afpar;{ AUTH_REQ *auth; AUTH_REQ_Q *aaq; AATV *paatv; CLIENT_ENTRY *ce; char *func = "rad_rq_resp_action"; dprintf (2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func)); authreq->fsmstatus = EV_ACK; aaq = queue_find (PW_RESOURCE_QUERY_REQ); for (auth = aaq->q; auth != (AUTH_REQ *) NULL; auth = auth->next) { if (auth->code != PW_RESOURCE_QUERY_REQ) { continue; } if (auth->ipaddr == authreq->ipaddr && auth->rep_id == authreq->rep_id) { break; /* Found original Resource Query Request. */ } } if (auth == (AUTH_REQ *) NULL) { /* Reply does not match any request. Silently drop it */ return EV_NAK; } if (auth->type == USR_PROXY || auth->type == (USR_PROXY | USR_CHILD)) { authreq->ipaddr = auth->nas_ip; authreq->rep_id = auth->fwd_id; paatv = find_aatv ("REPLY"); call_action (paatv, authreq, 0, ""); free_authreq (auth); return EV_DONE; } if (get_vp (authreq->request, PW_NAS_IP_ADDRESS) == (VALUE_PAIR *) NULL) { logit (LOG_DAEMON, LOG_ERR, "%s: Missing NAS IP Address", func); return EV_NAK; } if (get_vp_vend (authreq->request, PW_USR_RQ_INDEX, VC_USR) == NULL_VP) { logit (LOG_DAEMON, LOG_ERR, "%s: Missing Resource Query Index", func); return EV_NAK; } if (find_client (authreq->ipaddr, &ce) != 0) { return EV_NAK; }/* XXX Moved this code from find_client () - It didn't seem to get used XXX if ((ce->client_type & CE_DAS ) != CE_DAS) { logit (LOG_DAEMON, LOG_ERR, "%s: Received a Resource Query Request from a RADIUS server that is not a DAS", func); return (EV_NAK); }*/ /* * Call add_resources() only if there are a/v pairs * other than the NAS-IP-Address and the Index. */ if ((authreq->cur_count > 2) && add_resources (authreq->request, authreq->client->file_pfx, ce) == EV_NAK) { return EV_NAK; } if ((ce->client_type & CE_NAS) == CE_NAS) { return nas_proc (auth, authreq); } else if ((ce->client_type & CE_PROXY) == CE_PROXY) { return proxy_proc (auth, authreq); } else { logit (LOG_DAEMON, LOG_ERR,"%s: Received Resource Query Response from a host that is not a NAS or a Proxy", func); return EV_NAK; }} /* end of rad_rq_resp_action () *//*************************************************************************** * * Function: add_resources * * Purpose: Creates resource records and places them on the appropriate * resource queue * **************************************************************************/static intadd_resources (vp_list, file_pfx, ce)VALUE_PAIR *vp_list;char *file_pfx;CLIENT_ENTRY *ce;{ char default_pool; UINT4 ipaddr = 0; UINT4 nas; u_int length; int nas_port = 0; int result = EV_ACK; char *name = (char *) NULL; char *packet; VALUE_PAIR *list; VALUE_PAIR *q; VALUE_PAIR *vp; USER_ENTRY *user = (USER_ENTRY *) NULL; ADDR_POOL *apool = (ADDR_POOL *) NULL; ASSIGNED_IP **a; ASSIGNED_IP **rem; ASSIGNED_IP *temp; FILE_LIST *file_ent; struct in_addr add; char *func = "add_resources"; dprintf (2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func)); if ((q = get_vp (vp_list, PW_NAS_IP_ADDRESS)) == (VALUE_PAIR *) NULL) { return EV_NAK; } nas = q->lvalue; if ((file_ent = find_file_ent (file_pfx)) == (FILE_LIST *) NULL) { logit (LOG_DAEMON, LOG_ERR, "%s: NULL file entry", func); return EV_NAK; } if (file_ent->user_list == (USER_ENTRY *) NULL) { logit (LOG_DAEMON, LOG_ERR, "%s: No users defined in %s.users", func, file_pfx); /* * This is okay because if no users are defined, * then no users can be authenticated. */ return EV_ACK; } q = vp_list; for ( ; q != (VALUE_PAIR *) NULL ; q = q->next) { if (q->attribute != PW_USR_PACKET || q->ap->vendor_id != VC_USR) { continue; } if ((packet = (char *) malloc (q->lvalue)) == (char *) NULL) { logit (LOG_DAEMON, LOG_INFO, "%s: Malloc Failed\n", func); return EV_NAK; } memcpy (packet, q->strvalue, q->lvalue); length = q->lvalue; list = gen_valpairs ((AUTH_HDR *) packet, length, ce->veps, GVP_DROP); if ((vp = get_vp (list, PW_USER_NAME)) != (VALUE_PAIR *) NULL) { if ((name = strdup (vp->strvalue)) == (char *) NULL) { free (packet); list_free (list); logit (LOG_DAEMON, LOG_INFO, "%s: Malloc Failed\n", func); return EV_NAK; } } else { free (packet); list_free (list); continue; } if ((vp = get_vp (list, PW_FRAMED_IP_ADDRESS)) != (VALUE_PAIR *) NULL) { ipaddr = vp->lvalue; } else { /* * Ok to not find a Framed IP Address. * We could be managing Sessions-Allowed. */ } if ((vp = get_vp (list, PW_NAS_PORT)) != (VALUE_PAIR *) NULL) { nas_port = vp->lvalue; } else { free (packet); list_free (list); continue; } free (packet); list_free (list); for (user = file_ent->user_list; user != (USER_ENTRY *) NULL; user = user->next) { if (strcmp (user->name, name) == 0) { break; } } if (user == (USER_ENTRY *) NULL) { logit (LOG_DAEMON, LOG_INFO, "%s: User %s does not exist", func, name); free (name); continue; } free (name); /* Don't need this anymore */ apool = file_ent->pool_list; default_pool = 0; if (strcmp (user->pool_name, DEF_POOL_NAME) != 0) { apool = apool->next; /* First entry is Default pool */ for (; apool != (ADDR_POOL *) NULL; apool = apool->next) { if ((ipaddr & apool->netmask) == apool->network) { break; } } } else { default_pool = 1; } if (apool == (ADDR_POOL *) NULL) { add.s_addr = ipaddr; logit (LOG_DAEMON, LOG_INFO, "%s: Couldn't find pool for %s", func, inet_ntoa (add)); continue; } if (!default_pool && apool->count >= apool->range) { add.s_addr = apool->ip_address; logit (LOG_DAEMON, LOG_INFO, "%s: Address Pool %s full or this resource already allocated", func, inet_ntoa (add)); continue; } if (user->count >= user->sessions) { logit (LOG_DAEMON, LOG_INFO, "%s: User %s cannot be assigned any more addresses", func, user->name); continue; } user->count++; /* Find a place in the address pool to insert new node */ a = &apool->user_q; rem = a; if (!default_pool && *a != (ASSIGNED_IP *) NULL) { for ( ; *a != (ASSIGNED_IP *) NULL ; a = &((*a)->next)) { if ((*a)->ip_address == ipaddr) { add.s_addr = ipaddr; logit (LOG_DAEMON, LOG_INFO, "%s: Address %s already assigned", func, inet_ntoa (add)); result = EV_NAK; break; } if ((*a)->ip_address < ipaddr) { rem = &(*a)->next; } } } if (result == EV_NAK) { result = EV_ACK; user->count--; continue; } temp = make_ip_node (ipaddr, nas, user, nas_port);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?