⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 users.c

📁 RADIUS协议的认证计费服务
💻 C
📖 第 1 页 / 共 5 页
字号:
	UINT4            addr;	UINT4           *adptr;	IP_ADDRESS      *each_ip;	if (ce != (CLIENT_ENTRY *) NULL)	{		for (each_ip = ce->addrs;			each_ip != (IP_ADDRESS *) NULL;			each_ip = each_ip->next)		{			addr = ntohl(each_ip->ipaddr.s_addr);			for (adptr = self_ip; *adptr > 0; adptr++)			{				if (*adptr == addr)				{					return 1;				}			}		}	}	return 0;} /* end of client_is_us () *//************************************************************************* * *	Function: client_queue_size * *	Purpose: Returns count of events queued up for the given client. * *	Returns: count of queued events, *		 0 otherwise. * *************************************************************************/intclient_queue_size (cli)CLIENT_ENTRY     *cli;{	int             i = 0;	EVENT_ENT      *event;	static char    *func = "client_queue_size";	if (cli == (CLIENT_ENTRY *) NULL)	{		return 0;	}		for (event = cli->event_q;		event != (EVENT_ENT *) NULL;		event = event->client_next)	{		i++;	/* Count the event queued here. */	}	return i;} /* end of client_queue_size () *//************************************************************************* * *	Function: config_files * *	Purpose: Read database files into memory data structures.  Reads *		 "RADIUS_CLIENTS" and "RADIUS_AUTH" files unconditionally *		 and "RADIUS_USERS" file if users_flag is not zero.  Will * 		 read multiple users and authfiles if the "file_pfx" is *		 specified in a client entry (allowing use of different *		 files for different client NASes). * *		 If clear_flag is greater than zero, remove existing entries. * *		 A new CLIENT_ENTRY is added to the client_list for each *		 client appearing in the "RADIUS_CLIENTS" file.  A new *		 FILE_LIST entry is added for each unique file_pfx found *		 in the "RADIUS_CLIENTS" file.  Each FILE_LIST entry points *		 to a list of USER_ENTRYs containing the information read *		 from the "RADIUS_USERS" file with the corresponding *		 file_pfx.  Also each FILE_LIST entry contains a pointer to *		 the list of AUTH_ENTRYs containing realm information read *		 from the "RADIUS_AUTH" file with the corresponding file_pfx. *		 If either the "RADIUS_USERS" file or the "RADIUS_AUTH" file *		 with the given file_pfx did not exist, the default *		 (non-prefixed) file name entries are used instead. * *************************************************************************/intconfig_files (users_flag, clear_flag, dolog)int             users_flag;int             clear_flag;int             dolog;{	int             i;	int             result;	FILE_LIST      *file_ent;	struct hostent *hp;	char          **paddr;	static char    *func = "config_files";	dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func));	if (clear_flag > 0) /* Free current list, if already set up */	{		free_file_lists ();	}	authfile_id[0] = '\0';	clients_id[0] = '\0';	/*	 * Add default file_list entry - the entry for the "users" and	 * "authfile" with no optional prefix	 */	add_file_list ("");	/*	 *	Determine the IP address(es) of this machine	 *	 *	NOTE: This could hang for a while!	 */	if ((hp = gethostbyname (ourhostname)) == (struct hostent *) NULL)	{		logit (LOG_DAEMON, LOG_CRIT,			"%s: Couldn't get our own IP address(es)", func);		return (-1);	}	/*	 *	First clear, then save our IP address(es)	 *	leaving a zero entry at the end.	 */	memset ((char *) self_ip, '\0', sizeof (self_ip));	if (hp->h_addr_list != (char **) NULL)	{		for (i = 0, paddr = hp->h_addr_list;			(*paddr != (char *) NULL) &&				(i < sizeof (self_ip) / 4 - 1);			i++, paddr++)		{			memcpy ((char *) &self_ip[i], (char *) *paddr,				hp->h_length);			self_ip[i] = ntohl(self_ip[i]);		}	}	/*	 *	Release /etc/resolv.conf (hopefully).	 */	endhostent ();	if ((result = read_clients (dolog)) < 0)	{		logit (LOG_DAEMON, LOG_ERR,			"%s: FATAL error '%d' from read_clients()",			func, result);		return (-1);	}	/*	 * Finally, go through all the file_list entries just added, reading	 * in the "users" and "authfile" for each prefix found.	 */	for (file_ent = file_list; file_ent; file_ent = file_ent->next)	{#if !(defined(USE_DBM) || defined(USE_NDBM))		if (users_flag)			if (read_users (file_ent, dolog) != 0)			{				return (-1);			}#endif	/* USE_DBM || USE_NDBM */		if (read_auth (file_ent, dolog) != 0)		{			return (-1);		}	}	if (result < 0)	{		return (-1);	}	return 0;} /* end of config_files () *//************************************************************************* * *	Function: config_fini * *	Purpose: Cleanup environment after config_files() has run. * *************************************************************************/voidconfig_fini (){	free_clients (old_clients);	old_clients = (CLIENT_ENTRY *) NULL;	if ((file_logging == 1) && (msgfd != (FILE *) NULL))	{		fflush (msgfd);	}	if (dnspid == -1)	{		dnspid = 0;	}	update_clients ();       /* Start up the DNS resolver. */	doing_init = 0;		/* Done with initialization */	return;} /* end of config_fini () *//************************************************************************* * *	Function: config_init * *	Purpose: Setup environment for config_files() to run in. * *************************************************************************/voidconfig_init (){	is_engine = 1; /* flag set when engine calls us */	/*	 *	Set dnspid to defer the call to update_clients()	 *	until the end of config_files().	 */	if (dnspid == 0)	{		dnspid = -1;	}	doing_init = 1;		/* Indicate we're doing initialization */	/*	 *	Save the old clients list so we can pick up	 *	the DNS addresses for the new list.	 */	old_clients = client_list;	client_list = (CLIENT_ENTRY *) NULL;	return;} /* end of config_init () *//************************************************************************* * *	Function: dns_recv * *	Purpose: Process received DNS updates for clients database. * *************************************************************************/voiddns_recv (sin, from_ipaddr, rcvlen)struct sockaddr_in *sin;UINT4               from_ipaddr;int                 rcvlen;{	u_char           aliascnt;	int              cnt;	int              count;	UINT4            temp;	UINT4           *ourad;	char            *ptr;	IP_ADDRESS      *an_address;	DNS_NAME        *a_name;	CLIENT_ENTRY    *client_ent;	static int       notify_count = 0;	static char     *func = "dns_recv";	notify_count++;	dprintf(4, (LOG_AUTH, LOG_DEBUG, "%s: entered (%d)",		func, notify_count)); 	ddumpx(3, (LOG_DAEMON, LOG_DEBUG, recv_buffer, rcvlen, 0,		"%s: Packet received from %s", func,		ip_hostname (from_ipaddr)));	/* Reset client_ent cache. */	last_client_found = (CLIENT_ENTRY *) NULL;	last_client_name = (char *) NULL;	last_client_ipaddr = 0;	ptr = recv_buffer + 1;	for (ourad = self_ip;		(*ourad != (UINT4) 0) && (*ourad != from_ipaddr);		ourad++)	{		continue;	}	if (*ourad == (UINT4) 0)	{		logit (LOG_DAEMON, LOG_INFO, "%s: from %s - Security Breach",			func, ip_hostname (from_ipaddr));		return;	}	for (client_ent = client_list;		client_ent != (CLIENT_ENTRY *) NULL; 		client_ent = client_ent->next)	{		if (strcmp (ptr, client_ent->hostname) == 0)		{			break;		}	}	if (client_ent == (CLIENT_ENTRY *) NULL)	{		return;	}			ptr += strlen (ptr) + 1;	/* Point over name */	aliascnt = *ptr++;	if (*ptr != '\0') /* If alias or IP address present, clear old ones */	{		/*		 *	Reset expire_time with some randomness (0 - 60 minutes)		 *	to avoid a burst of calls to gethostbyname().		 *		 *	[0, 1, 2, 3] * 1200 == [0, 1200, 2400, 3600]		 */		client_ent->expire_time = (time (0) + dns_address_aging +						(rand () & 3) * 60 * 20) & ~3;		dprintf(2, (LOG_AUTH, LOG_DEBUG,			"%s: expire time = 0x%08X",			func, client_ent->expire_time));		for (an_address = client_ent->addrs;			an_address != (IP_ADDRESS *) NULL;			an_address = client_ent->addrs)		{			client_ent->addrs = an_address->next;			free (an_address);			dns_addr_mf.f++;		} 		for (a_name = client_ent->names;			a_name != (DNS_NAME *) NULL;			a_name = client_ent->names)		{			client_ent->names = a_name->next;			free (a_name);			dns_name_mf.f++;		}	}	else /* no alias or IP address present */	{		memcpy ((char *) &temp, ptr, sizeof (struct in_addr));		if (temp == TRY_AGAIN) /* TRY_AGAIN is in netdb.h */		{			client_ent->expire_time = (time (0) + dns_address_aging)									& ~3;			logit (LOG_DAEMON, LOG_ALERT,				"%s: DNS timeout on client or host '%s'",				func, client_ent->hostname);			return;		}		else		{			/*			 *	Name couldn't be resolved -- log it and retry			 *	shortly.  Cleverly (or foolishly) use the low			 *	two bits of expire_time to control the logging			 *	frequency.			 */			if ((cnt = client_ent->expire_time & 3) == 0)			{				/* Log every fourth time (or once per hour) */				logit (LOG_DAEMON, LOG_ALERT,				     "%s: DNS couldn't resolve name '%s' (%ld)",					func, client_ent->hostname, temp);			}			client_ent->expire_time =				((time (0) + (dns_address_aging / 4)) & ~3) |					(++cnt & 3);			if (client_ent->addrs != (IP_ADDRESS *) NULL)			{				return;			}			/* Add invalid address to client_ent */			memset (ptr, 255, sizeof (struct in_addr));		}	}	/* Add alias names to client_ent structure */	count = 0;	while (aliascnt-- > 0)	{		count++;		if (count > MAX_ALIAS)		{			logit (LOG_DAEMON, LOG_ALERT,				"%s: FATAL: Too many aliases for client '%s'",				func, client_ent->hostname);			abort ();		}		/* Note that DNS_NAME structure reserves one extra character. */		a_name = (DNS_NAME *)				get_memory (sizeof (DNS_NAME) + strlen (ptr),						func, "DNS_NAME");		dns_name_mf.m++;		/* Note that type zero will always be the last one. */		strcpy (a_name->name, ptr); 		ptr += strlen (ptr) + 1;		a_name->type =  (u_char) *ptr++;		a_name->next = client_ent->names;		client_ent->names = a_name;	}	/*	 * For each address in the list, add the address to the client_ent.	 */	while (*ptr != '\0')	{		an_address = (IP_ADDRESS *) get_memory (sizeof (IP_ADDRESS),							func, "IP_ADDRESS");		dns_addr_mf.m++;		an_address->next = client_ent->addrs;		memcpy ((char *) &temp, ptr, sizeof (struct in_addr));		an_address->ipaddr.s_addr = ntohl(temp);		client_ent->addrs = an_address;		ptr += sizeof (struct in_addr);	}	if ((notify_count % DNS_SLEEP) == 0)	{		logit (LOG_DAEMON, LOG_INFO, "%s: Notified of (%d) DNS changes",			func, notify_count);	}	return;} /* end of dns_recv () *//************************************************************************* * *	Function: fieldcpy * *	Purpose: Copy a data field from the buffer to which "uptr" points. *		 Advance the buffer past the data field. * *	Returns: actual length of the data field, *		 or -1, if error. * *************************************************************************/static intfieldcpy (string, uptr, len)char           *string;	/* Receiving buffer. */char          **uptr;	/* Pointer to original data passed in. */int             len;	/* Size of receiving buffer "string" */{	int             accum;	int             count;	char           *beg_string;	char           *end;	char           *end_tag;	/* end of tag in data string */	char           *ptr;	char            hex_buf[4];	/* 2 hex digits or 3 octal digits */	static char    *func = "fieldcpy";	ptr = *uptr;	end = string + len - 1; /* Leave room for NULL character at end. */	beg_string = string;	/* Tagged attribute values are of the form :<tag>:<value> */	if (*ptr == ':')	{		ptr++;	/* Skip leading colon character. */		if ((end_tag = strchr (ptr, ':')) == (char *) NULL)		{			logit (LOG_DAEMON, LOG_INFO,				"%s: No terminating colon for tag in ':%s'",				func, ptr);			return (-1);		}		*end_tag = '\0';		accum = atoi (ptr);	/* fieldcpy() tag value */		if ((accum < 0) || ( 255 < accum))		{			logit (LOG_DAEMON, LOG_INFO,				"%s: Tag '%s' (%d) out of range (0-255)",				func, ptr, accum);			return (-1);		}		*string = accum;	/* Insert tag into buffer. */		string++;		ptr = end_tag + 1;	/* Position past tag. */	}	/* Quoted attribute strings are of the form "<value>" */	if (*ptr == '"')	{		ptr++;	/* Skip leading quote character. */		while (*ptr != '"' && *ptr != '\0' && *ptr != '\n')		{			if (*ptr == '\\')			{				accum = 0;				count = 0;				ptr++;				/* octal conversion */				while ((count < 3) &&					(*ptr >= '0') &&					(*ptr <= '7'))				{					count++;					accum = (accum << 3) + (*ptr++ - '0');				}				if (count > 0)				{					*string++ = accum;				}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -