📄 users.c
字号:
/* * RADIUS -- Remote Authentication Dial In User Service * * * Livingston Enterprises, Inc. 6920 Koll Center Parkway Pleasanton, CA 94566 * * Copyright 1992 Livingston Enterprises, Inc. * * Permission to use, copy, modify, and distribute this software for any * purpose and without fee is hereby granted, provided that this copyright * and permission notice appear on all copies and supporting documentation, * the name of Livingston Enterprises, Inc. not be used in advertising or * publicity pertaining to distribution of the program without specific * prior permission, and notice be given in supporting documentation that * copying and distribution is by permission of Livingston Enterprises, Inc. * * Livingston Enterprises, Inc. makes no representations about the suitability * of this software for any purpose. It is provided "as is" without express * or implied warranty. * * Copyright (c) 1996 Ascend Communications, Inc. * 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. * *//* * 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 * *//* * * Public entry points in this file: * * add_file_list * addr_is_us * change_pw * client_is_us * client_queue_size * config_files * config_fini * config_init * dns_recv * find_auth_type * find_auth_ent * find_client * find_client_by_name * find_file_ent [[if USR_CCA is defined]] * find_host_by_name * free_user_ent * get_client_list * get_default_file_entry * get_our_addr * host_is_us * ip_hostname * pair_parse * return_file_list * update_expire * user_find * user_gettime * user_update * */static char sccsid[] = "@(#)users.c 1.3 Copyright 1992 Livingston Enterprises Inc";static char rcsid[] = "$Id: users.c,v 1.1.1.1 2001/08/10 20:49:29 bonze Exp $";#include <sys/types.h>#include <sys/param.h>#include <sys/socket.h>#include <sys/time.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <stdlib.h>#include <netdb.h>#include <memory.h>#include <unistd.h>#include <ctype.h>#include <dirent.h>#include <syslog.h>#include "radius.h"static int fieldcpy PROTO((char *, char **, int));#ifdef USR_CCAstatic char check_user PROTO((USER_ENTRY *));FILE_LIST *find_file_ent PROTO((char *));#else /* USR_CCA */static FILE_LIST *find_file_ent PROTO((char *));#endif /* USR_CCA */static void free_clients PROTO((CLIENT_ENTRY *));static void free_file_lists PROTO((void));static int get_client_type PROTO((int, VENDOR_LIST **));#ifdef USR_CCAstatic char parse_dns_nbns PROTO((char **, UINT4 *, UINT4 *));#endif /* USR_CCA */static char *parse_id PROTO((char *));static int read_auth PROTO((FILE_LIST *, int));static int read_clients PROTO((int));static int read_users PROTO((FILE_LIST *, int));#if defined(ultrix) || defined(__hpux) || defined(__bsdi__) || defined(linux) || defined(SCO)extern int h_errno;#endif /* ultrix */extern char send_buffer[RAD_SEND_BUFFER_SIZE];extern char recv_buffer[RAD_RECV_BUFFER_SIZE];extern char ourhostname[MAXHOSTNAMELEN];extern AATV *authtype_tv[]; /* AATVs by authentication types */extern int debug_flag;extern int dumpcore;extern char *radius_dir;extern FILE *ddt;extern int authfile_cnt;extern int clients_cnt;extern int users_cnt;extern int file_logging; /* 0 => syslog, 1 => logfile, 2 => stderr */extern AATV *rad_ipc_aatv;extern FILE *msgfd;int default_reply_holdtime = CLEANUP_DELAY;int spawn_flag = 1; /* 0 => no spawning, 1 => spawning allowed */int dnspid = 0; /* PID of current DNS resolver process */UINT4 dns_address_aging = ADDRESS_AGING;UINT4 dns_address_window = 60; /* one minute */int doing_init = 1; /* Always initing if not engine */char default_radius_server[128] = DEFAULT_RADIUS_SERVER;char default_tacacs_server[128] = DEFAULT_TACACS_SERVER;char authfile_id[128];char clients_id[128];int rad_ipc_port = 0;MF_ENT dns_addr_mf = { 0, 0 }; /* For DNS address structs. */MF_ENT dns_client_mf = { 0, 0 }; /* For DNS address structs. */MF_ENT dns_name_mf = { 0, 0 }; /* For DNS address structs. */MF_ENT vendor_mf = { 0, 0 }; /* For vendors. */MF_ENT vendor_list_mf = { 0, 0 }; /* For vendor lists. */#ifdef USR_CCAchar dns_done = FALSE;UINT4 self_ip[SELF_IP_LEN]; /* Used with multi-homed servers */#else /* USR_CCA */static UINT4 self_ip[11]; /* Used with multi-homed servers */#endif /* USR_CCA */static FILE_LIST *file_list = (FILE_LIST *) NULL;static CLIENT_ENTRY *client_list = (CLIENT_ENTRY *) NULL;static int is_engine = 0; /* rlmadmin(8) will not change this */static CLIENT_ENTRY *old_clients;static UINT4 last_client_ipaddr;static CLIENT_ENTRY *last_client_found;static char *last_client_name;/************************************************************************* * * Function: add_file_list * * Purpose: Find an existing FILE_LIST entry on file_list with the * specified prefix or add and init a new one if the * entry doesn't already exist. * *************************************************************************/intadd_file_list (prefix)char *prefix;{ FILE_LIST *file_ent; FILE_LIST **fl_prev;#ifdef USR_CCA ADDR_POOL *apool;#endif /* USR_CCA */ static char *func = "add_file_list"; dprintf(4, (LOG_AUTH, LOG_DEBUG, "%s: entered", func)); for (fl_prev = &file_list, file_ent = file_list; file_ent; fl_prev = &file_ent->next, file_ent = *fl_prev) { if (strcmp (file_ent->prefix, prefix) == 0) { return 0; } } if ((file_ent = (FILE_LIST *) calloc (1, sizeof (FILE_LIST))) == (FILE_LIST *) NULL) { logit (LOG_DAEMON, LOG_ALERT, "%s: Couldn't allocate FILE_ENTRY storage", func); return (-1); } file_ent->prefix = add_string (prefix, ASIS); file_ent->user_list = (USER_ENTRY *) NULL; file_ent->auth_list = (AUTH_ENTRY *) NULL;#ifdef USR_CCA /* * Add an entry for the default pool. That is, the pool for * users who are statically assigned Framed IP addresses in * the users file. */ if ((file_ent->pool_list = (ADDR_POOL *) calloc (1, sizeof (ADDR_POOL))) == (ADDR_POOL *) NULL) { logit (LOG_DAEMON, LOG_ALERT, "%s: Couldn't allocate ADDR_POOL storage", func); return (-1); } apool = file_ent->pool_list; apool->name = DEF_POOL_NAME; apool->ip_address = 0; apool->netmask = 0; apool->network = 0; apool->range = 0; apool->count = 0; apool->user_q = (ASSIGNED_IP *) NULL; apool->next = (ADDR_POOL *) NULL;#endif /* USR_CCA */ file_ent->next = (FILE_LIST *) NULL; *fl_prev = file_ent; return 0;} /* end of add_file_list () *//************************************************************************* * * Function: addr_is_us * * Purpose: Determine if we are the given host. * * Returns: 1 if the given address is ours, * 0 otherwise. * *************************************************************************/intaddr_is_us (addr)UINT4 addr;{ UINT4 *adptr; for (adptr = self_ip; *adptr > 0; adptr++) { if (*adptr == addr) { return 1; } } return 0;} /* end of addr_is_us () *//************************************************************************* * * Function: change_pw * * Purpose: Find the named user and change the password to the new value. * * Remarks: This is called from passchange() only after the new * password has been validated. The user was previously * found using user_find() so we know the user is in memory. * * Returns: zero, if user's password has been changed in memory, * non-zero, otherwise. * *************************************************************************/intchange_pw (name, protocol, curpass, newpass)char *name;int protocol;VALUE_PAIR *curpass;char *newpass;{ int namelen; FILE_LIST *file_ent; VALUE_PAIR *dbpass; VALUE_PAIR *prot_ent; USER_ENTRY *user_ent; USER_ENTRY *dflt_ent; FILE *debugout = stdout; static char *func = "change_pw"; dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func)); if ((file_ent = find_file_ent ((char *) NULL)) == (FILE_LIST *) NULL) { return (-1); } dflt_ent = file_list->user_list; /* * If there is no user file for this prefix, then use the * first entry in file_list as the default file_ent. */ if ((user_ent = file_ent->user_list) == (USER_ENTRY *) NULL) { if (dflt_ent == (USER_ENTRY *) NULL) { /* No file entry, no password */ return (-1); } user_ent = dflt_ent; } if ((namelen = strlen (name)) == 0) { return 1; /* A null name would match every line. */ } /* * First check what type of lookup to do. * See if user file(s) have been cached in memory. */ for (; user_ent; user_ent = user_ent->next) { /* Allow match for entry specifying framed protocol * type specified in "protocol". An entry with a * matching name but no framed-protocol type check * item matches unconditionally. An entry with a * matching name and a framed-protocol type check * item must match value in "protocol". */ if (strcmp (user_ent->name, name) == 0) { if ((prot_ent = get_vp (user_ent->check, PW_FRAMED_PROTOCOL)) == NULL_VP) { break; } if (prot_ent->lvalue == protocol) { break; } } } if (!user_ent) /* rc 1 => User not found */ { return 1; } /* Find the password entry. */ dbpass = get_vp_ci (user_ent->check, CI_USER_PASSWORD, 0); if ((dbpass == NULL_VP) || (dbpass->strvalue == (char *) NULL)) { /* Missing our local copy of the password */ logit (LOG_DAEMON, LOG_ERR, "%s: - Missing Local Password: %s", func); return 1; } /* Let's be paranoid about this */ if (strcmp (dbpass->strvalue, curpass->strvalue)) { logit (LOG_DAEMON, LOG_ERR, "%s: - Password does not match cached password.", func); return 1; } /* Go ahead and change it */ avpair_string_mod (dbpass, newpass, -1); if (debug_flag >= 2) { if (ddt) { debugout = ddt; } fprintf (debugout, "Check items:\n"); debug_list (debugout, user_ent->check); fprintf (debugout, "Reply items:\n"); debug_list (debugout, user_ent->reply); } return (0); /* rc 0 => User found */} /* end of change_pw () */#ifdef USR_CCA/************************************************************************* * * Function: check_user * * Purpose: Processes Simultaneous-Use, Sessions-Allowed and * Address-Pool attributes, and checks for a valid * Termination-Action value. * ************************************************************************/static charcheck_user (user_ent)USER_ENTRY *user_ent;{ VALUE_PAIR *vp; char *func = "check_user"; if ((vp = get_vp_ci (user_ent->reply, CI_SIMULTANEOUS_USE, 0)) != NULL_VP) { user_ent->sessions = vp->lvalue; avpair_del (&user_ent->reply, CI_SIMULTANEOUS_USE, 0); } if ((vp = get_vp_ci (user_ent->reply, CI_ADDRESS_POOL_NAME, 0)) != NULL_VP) { user_ent->pool_name = vp->strvalue; avpair_del (&user_ent->reply, CI_ADDRESS_POOL_NAME, 0); if ((vp = get_vp (user_ent->reply, PW_FRAMED_IP_ADDRESS)) != NULL_VP) { logit (LOG_DAEMON,LOG_ERR, "%s: User %s has a static Framed-IP-Address and an Address Pool defined", func, user_ent->name); return (-1); } } if (user_ent->sessions > 1 || strcmp (user_ent->pool_name, DEF_POOL_NAME) != 0) { if (((vp = get_vp (user_ent->reply, PW_TERMINATION_ACTION)) == NULL_VP)) { /* * This user's resources are to be managed. * A Termination-Action attribute is required. */ logit (LOG_DAEMON, LOG_ERR, "%s: User %s-> Missing Termination Action attribute", func, user_ent->name); return (-1); } else if (vp->lvalue != MANAGE_RESOURCES) { logit (LOG_DAEMON, LOG_ERR, "%s: User %s-> Invalid Termination Action Attribute", func, user_ent->name); return (-1); } } return (0);} /* end of check_user () */#endif /* USR_CCA *//************************************************************************* * * Function: client_is_us * * Purpose: Determine if we are the given host. * * Returns: 1, if the given hostname is the name of this host, * 0, otherwise. * *************************************************************************/intclient_is_us (ce)CLIENT_ENTRY *ce;{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -