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

📄 rlm_fastusers.c

📁 RADIUS认证协议
💻 C
📖 第 1 页 / 共 2 页
字号:
	int userfound = 0;	/*	 * Now we have to make sure it's the right user by	 * comparing the check pairs	 */	while((cur) && (!userfound)) {		if((strcmp(cur->name, username)==0) &&				paircmp(request, request->packet->vps, cur->check, &request->reply->vps) == 0) {			/*			 * Usercollide means we have to compare check pairs			 * AND the password			 */			if(mainconfig.do_usercollide) {				if((userfound = fastuser_passcheck(request, cur, username))==0) {					cur = cur->next;				}			} else {				userfound = 1;				DEBUG2("  fastusers: Matched %s at %d", cur->name, cur->lineno);			}		} else {			cur = cur->next;		}	}	if(cur) {		return cur;	}	return (PAIR_LIST *)0;}/* * Generate and log statistics about our hash table */static void fastuser_tablestats(PAIR_LIST **hashtable, int size) {	int i, count;	int countarray[256];	int toomany=0;	PAIR_LIST *cur;	memset(countarray, 0, sizeof(countarray));	for(i=0; i<size; i++) {		count = 0;		for(cur=hashtable[i]; cur; cur=cur->next) {			count++;		}		if(count<256) {			countarray[count]++;		} else {			toomany++;		}	}	for(i=0; i<256; i++)		if(countarray[i]) {			radlog(L_INFO, "rlm_fastusers:  Hash buckets with %d users:  %d",						i, countarray[i]);		}	if(toomany) {		radlog(L_INFO, "rlm_fastusers:  Hash buckets with more than 256:  %d",					toomany);	}}static int fastuser_passcheck(REQUEST *request, PAIR_LIST *user,			      const char *name UNUSED){	int found=0;	VALUE_PAIR	*check_save;	/*	 * We check for REJECT specially here or a REJECT	 * user will never match	 */	check_save = pairfind(user->check, PW_AUTHTYPE);	if((check_save) && check_save->lvalue == PW_AUTHTYPE_REJECT)  {		DEBUG2("  fastusers(uc):  User '%s' line %d is Auth-Type Reject, but usercollide match",					user->name, user->lineno);		return 1;	}	/* Save the orginal config items */	check_save = request->config_items;	request->config_items = NULL;	DEBUG2("  fastusers(uc): Checking %s at %d", user->name, user->lineno);	/* Copy this users check pairs to the request */	request->config_items = paircopy(user->check);	/* Check the req to see if we matched */	if(rad_check_password(request)==0) {		DEBUG2("  fastusers(uc): Matched %s at %d", user->name, user->lineno);		found = 1;	}	/* Restore check items */	pairfree(&request->config_items);	request->config_items = check_save;	return found;}/* *	(Re-)read the "users" file into memory. */static int fastuser_instantiate(CONF_SECTION *conf, void **instance){	struct fastuser_instance *inst=0;	inst = rad_malloc(sizeof *inst);	if (!inst)		return -1;	memset(inst, 0, sizeof(*inst));	if (cf_section_parse(conf, inst, module_config) < 0) {		free(inst);		return -1;	}	inst->next_reload = time(NULL) + inst->hash_reload;	inst->hashtable = NULL;	inst->lastusersload = 0;	inst->lastacctusersload = 0;	if(fastuser_buildhash(inst) < 0) {		radlog(L_ERR, "rlm_fastusers:  error building user hash.  aborting");		return -1;	}	/*	 * Need code here to read acct_users file	 */	*instance = inst;	return 0;}/* *	Find the named user in the database.  Create the *	set of attribute-value pairs to check and reply with *	for this user from the database. The main code only *	needs to check the password, the rest is done here. */static int fastuser_authorize(void *instance, REQUEST *request){	VALUE_PAIR	*namepair;	VALUE_PAIR	*check_tmp;	VALUE_PAIR	*reply_tmp;	PAIR_LIST		*user;	PAIR_LIST		*curdefault;	const char	*name;	int			userfound=0;	int			defaultfound=0;	int			hashidx=0;	struct fastuser_instance *inst = instance;	/*	 * Do we need to reload the cache?	 * Really we should spawn a thread to do this	 */	if((inst->hash_reload) && (request->timestamp > inst->next_reload)) {		inst->next_reload = request->timestamp + inst->hash_reload;		radlog(L_INFO, "rlm_fastusers:  Reloading fastusers hash");		if(fastuser_buildhash(inst) < 0) {			radlog(L_ERR, "rlm_fastusers:  error building user hash.  aborting");			return RLM_MODULE_FAIL;		}	}	/*	 *	Grab the canonical user name.	 */	namepair = request->username;	name = namepair ? (char *) namepair->strvalue : "NONE";	/*	 *	Find the entry for the user.	 */	hashidx = fastuser_hash(name, inst->hashsize);	user = inst->hashtable[hashidx];	if((user=fastuser_find(request, user, name))!=NULL) {		userfound = 1;	}	/*	 * If there's no lastdefault and we	 * don't fallthrough, just copy the	 * pairs for this user and return	 */	if((user) && (userfound) && (user->lastdefault == NULL)) {		DEBUG2("rlm_fastusers:  user found before DEFAULT");		check_tmp = paircopy(user->check);		pairmove(&request->config_items, &check_tmp);		pairfree(&check_tmp);		reply_tmp = paircopy(user->reply);		pairmove(&request->reply->vps, &reply_tmp);		pairfree(&reply_tmp);		if(!fallthrough(user->reply)) {			pairdelete(&request->reply->vps, PW_FALL_THROUGH);			return(rad_check_return(user->check));		} else {			user=user->next;			user=fastuser_find(request, user, name);		}	}	/*	 * When we get here, we've either found	 * the user or not, but to preserve order	 * we start at the top of the default	 * list and work our way thru	 * When we get to the user's 'lastdefault'	 * we check to see if we should stop	 * and return	 */	DEBUG2("rlm_fastusers:  checking defaults");	curdefault = inst->defaults;	while(curdefault) {		if(paircmp(request, request->packet->vps, curdefault->check,							&request->reply->vps) == 0) {			DEBUG2("  fastusers: Matched %s at %d",							curdefault->name, curdefault->lineno);			defaultfound = 1;			check_tmp = paircopy(curdefault->check);			pairmove(&request->config_items, &check_tmp);			pairfree(&check_tmp);			reply_tmp = paircopy(curdefault->reply);			pairmove(&request->reply->vps, &reply_tmp);			pairfree(&reply_tmp);			/*			 * There's no fallthru on this default which			 * is *before* we find the user in the file,			 * so we know it's safe to quit here			 */			if (!fallthrough(curdefault->reply))			  break;		}		/*		 * If we found the user, we want to stop		 * processing once we get to 'lastdefault'		 * This way we can process this user's entry		 * in the order it was found in the file		 */		while((userfound && (user) && (curdefault == user->lastdefault))) {				DEBUG2("  fastusers:  found lastdefault at line %d",						   curdefault->lineno);			check_tmp = paircopy(user->check);			pairmove(&request->config_items, &check_tmp);			pairfree(&check_tmp);			reply_tmp = paircopy(user->reply);			pairmove(&request->reply->vps, &reply_tmp);			pairfree(&reply_tmp);			if(!fallthrough(user->reply)) {				pairdelete(&request->reply->vps, PW_FALL_THROUGH);				return(rad_check_return(user->check));			}			/*			 * Find next occurence of THIS user in			 * the users file			 */			user=user->next;			user=fastuser_find(request, user, name);		}		curdefault = curdefault->next;	}	if(userfound || defaultfound) {		pairdelete(&request->reply->vps, PW_FALL_THROUGH);		return(rad_check_return(request->config_items));	} else {		DEBUG2("rlm_fastusers:  user not found");		return RLM_MODULE_NOTFOUND;	}}/* *	Authentication - unused. */static int fastuser_authenticate(void *instance, REQUEST *request){	instance = instance;	request = request;	return RLM_MODULE_OK;}/* *	Pre-Accounting - read the acct_users file for check_items and *	config_items. Reply items are Not Recommended(TM) in acct_users, *	except for Fallthrough, which should work * *	This function is mostly a copy of file_authorize */static int fastuser_preacct(void *instance, REQUEST *request){	VALUE_PAIR	*namepair;	const char	*name;	VALUE_PAIR	*request_pairs;	VALUE_PAIR	**config_pairs;	VALUE_PAIR	*reply_pairs = NULL;	VALUE_PAIR	*check_tmp;	VALUE_PAIR	*reply_tmp;	PAIR_LIST	*pl = NULL;	int		found = 0;	struct fastuser_instance *inst = instance;	namepair = request->username;	name = namepair ? (char *) namepair->strvalue : "NONE";	request_pairs = request->packet->vps;	config_pairs = &request->config_items;	/*	 *	Find the entry for the user.	 */	for (pl = inst->acctusers; pl; pl = pl->next) {		if (strcmp(name, pl->name) && strcmp(pl->name, "DEFAULT"))			continue;		if (paircmp(request, request_pairs, pl->check, &reply_pairs) == 0) {			DEBUG2("  acct_users: Matched %s at %d",			       pl->name, pl->lineno);			found = 1;			check_tmp = paircopy(pl->check);			reply_tmp = paircopy(pl->reply);			pairmove(&reply_pairs, &reply_tmp);			pairmove(config_pairs, &check_tmp);			pairfree(&reply_tmp);			pairfree(&check_tmp); /* should be NULL */			/*			 *	Fallthrough?			 */			if (!fallthrough(pl->reply))				break;		}	}	/*	 *	See if we succeeded.	 */	if (!found)		return RLM_MODULE_NOOP; /* on to the next module */	/*	 *	FIXME: log a warning if there are any reply items other than	 *	Fallthrough	 */	pairfree(&reply_pairs); /* Don't need these */	return RLM_MODULE_OK;}/* *  Clean up. */static int fastuser_detach(void *instance){	struct fastuser_instance *inst = instance;	int hashindex;	PAIR_LIST *cur;	/* Free hash table */	for(hashindex=0; hashindex<inst->hashsize; hashindex++) {		if(inst->hashtable[hashindex]) {			cur = inst->hashtable[hashindex];			pairlist_free(&cur);		}	}	free(inst->compat_mode);	free(inst->hashtable);	pairlist_free(&inst->defaults);	pairlist_free(&inst->acctusers);	free(inst->usersfile);	free(inst->acctusersfile);	free(inst);	return 0;}/* *	This function is unused */static int fastuser_accounting(void *instance UNUSED, REQUEST *request UNUSED){	/*	 * FIXME: should re rather return RLM_MODULE_NOOP here?	 */	return RLM_MODULE_FAIL;}/* globally exported name */module_t rlm_fastusers = {	"fastusers",	0,				/* type: reserved */	NULL,				/* initialization */	fastuser_instantiate,		/* instantiation */	{		fastuser_authenticate,	/* authentication */		fastuser_authorize,	/* authorization */		fastuser_preacct,	/* preaccounting */		fastuser_accounting,	/* accounting */		NULL,			/* checksimul */		NULL,			/* pre-proxy */		NULL,			/* post-proxy */		NULL			/* post-auth */	},	fastuser_detach,		/* detach */	NULL				/* destroy */};

⌨️ 快捷键说明

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