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

📄 rlm_perl.c

📁 新的radius程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	}}/* * *     Verify that a Perl SV is a string and save it in FreeRadius *     Value Pair Format * */static int pairadd_sv(VALUE_PAIR **vp, char *key, SV *sv, int operator) {       char            *val;       VALUE_PAIR      *vpp;       if (SvOK(sv)) {               val = SvPV_nolen(sv);               vpp = pairmake(key, val, operator);               if (vpp != NULL) {                       pairadd(vp, vpp);                       radlog(L_DBG,                         "rlm_perl: Added pair %s = %s", key, val);		       return 1;               } else {                       radlog(L_DBG,                         "rlm_perl: ERROR: Failed to create pair %s = %s",                         key, val);               }        }       return 0;}/*  *     Boyan :  *     Gets the content from hashes  */static int get_hv_content(HV *my_hv, VALUE_PAIR **vp){       SV		*res_sv, **av_sv;       AV		*av;       char		*key;       I32		key_len, len, i, j;       int		ret=0;       for (i = hv_iterinit(my_hv); i > 0; i--) {               res_sv = hv_iternextsv(my_hv,&key,&key_len);               if (SvROK(res_sv) && (SvTYPE(SvRV(res_sv)) == SVt_PVAV)) {                       av = (AV*)SvRV(res_sv);                       len = av_len(av);                       for (j = 0; j <= len; j++) {                               av_sv = av_fetch(av, j, 0);                               ret = pairadd_sv(vp, key, *av_sv, T_OP_ADD) + ret;                       }               } else ret = pairadd_sv(vp, key, res_sv, T_OP_EQ) + ret;        }        return ret;}/* * 	Call the function_name inside the module * 	Store all vps in hashes %RAD_CHECK %RAD_REPLY %RAD_REQUEST * */static int rlmperl_call(void *instance, REQUEST *request, char *function_name){	PERL_INST	*inst = instance;	VALUE_PAIR	*vp;	int		exitstatus=0, count;	STRLEN		n_a;	HV		*rad_reply_hv;	HV		*rad_check_hv;	HV		*rad_request_hv;	HV		*rad_request_proxy_hv;	HV		*rad_request_proxy_reply_hv;#ifdef USE_ITHREADS	POOL_HANDLE	*handle;	if ((handle = pool_pop(instance)) == NULL) {		return RLM_MODULE_FAIL;	}	radlog(L_DBG,"found interpetator at address 0x%lx",(unsigned long) handle->clone);	{	dTHXa(handle->clone);	PERL_SET_CONTEXT(handle->clone);	}#else	PERL_SET_CONTEXT(inst->perl);	radlog(L_DBG,"Using perl at 0x%lx",(unsigned long) inst->perl);#endif	{	dSP;	ENTER;	SAVETMPS;	/*	 *	Radius has told us to call this function, but none	 *	is defined.	 */	if (!function_name) {		return RLM_MODULE_FAIL;	}	rad_reply_hv = get_hv("RAD_REPLY",1);	rad_check_hv = get_hv("RAD_CHECK",1);	rad_request_hv = get_hv("RAD_REQUEST",1);	rad_request_proxy_hv = get_hv("RAD_REQUEST_PROXY",1);	rad_request_proxy_reply_hv = get_hv("RAD_REQUEST_PROXY_REPLY",1);	perl_store_vps(request->reply->vps, rad_reply_hv);	perl_store_vps(request->config_items, rad_check_hv);	perl_store_vps(request->packet->vps, rad_request_hv);		if (request->proxy != NULL) {		perl_store_vps(request->proxy->vps, rad_request_proxy_hv);	} else {		hv_undef(rad_request_proxy_hv);	}	if (request->proxy_reply !=NULL) {		perl_store_vps(request->proxy_reply->vps, rad_request_proxy_reply_hv);	} else {		hv_undef(rad_request_proxy_reply_hv);	}			vp = NULL;	PUSHMARK(SP);	/*	* This way %RAD_xx can be pushed onto stack as sub parameters.	* XPUSHs( newRV_noinc((SV *)rad_request_hv) );	* XPUSHs( newRV_noinc((SV *)rad_reply_hv) );	* XPUSHs( newRV_noinc((SV *)rad_check_hv) );	* PUTBACK;	*/	count = call_pv(function_name, G_SCALAR | G_EVAL | G_NOARGS);	SPAGAIN;	if (SvTRUE(ERRSV)) {		radlog(L_ERR, "rlm_perl: perl_embed:: module = %s , func = %s exit status= %s\n",		       inst->module,		       function_name, SvPV(ERRSV,n_a));		POPs;	}	if (count == 1) {		exitstatus = POPi;		if (exitstatus >= 100 || exitstatus < 0) {			exitstatus = RLM_MODULE_FAIL;		}	}		PUTBACK;	FREETMPS;	LEAVE;	if ((get_hv_content(rad_reply_hv, &vp)) > 0 ) {		pairmove(&request->reply->vps, &vp);		pairfree(&vp);	}	if ((get_hv_content(rad_check_hv, &vp)) > 0 ) {		pairmove(&request->config_items, &vp);		pairfree(&vp);	}		if ((get_hv_content(rad_request_proxy_reply_hv, &vp)) > 0 && request->proxy_reply != NULL) {		pairfree(&request->proxy_reply->vps);		pairmove(&request->proxy_reply->vps, &vp);		pairfree(&vp);	}	}#ifdef USE_ITHREADS	pool_release(handle,instance);	radlog(L_DBG,"Unreserve perl at address 0x%lx", (unsigned long) handle->clone);#endif	return exitstatus;}/* *	Find the named user in this modules database.  Create the set *	of attribute-value pairs to check and reply with for this user *	from the database. The authentication code only needs to check *	the password, the rest is done here. */static int perl_authorize(void *instance, REQUEST *request){	return rlmperl_call(instance, request,			    ((PERL_INST *)instance)->func_authorize);}/* *	Authenticate the user with the given password. */static int perl_authenticate(void *instance, REQUEST *request){	return rlmperl_call(instance, request,			    ((PERL_INST *)instance)->func_authenticate);}/* *	Massage the request before recording it or proxying it */static int perl_preacct(void *instance, REQUEST *request){	return rlmperl_call(instance, request,			    ((PERL_INST *)instance)->func_preacct);}/* *	Write accounting information to this modules database. */static int perl_accounting(void *instance, REQUEST *request){	VALUE_PAIR	*pair;	int 		acctstatustype=0;	if ((pair = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) != NULL) {                acctstatustype = pair->lvalue;        } else {                radlog(L_ERR, "Invalid Accounting Packet");                return RLM_MODULE_INVALID;        }	switch (acctstatustype) {		case PW_STATUS_START:			if (((PERL_INST *)instance)->func_start_accounting) {				return rlmperl_call(instance, request,					    ((PERL_INST *)instance)->func_start_accounting);			} else {				return rlmperl_call(instance, request,					    ((PERL_INST *)instance)->func_accounting);			}			break;		case PW_STATUS_STOP:			if (((PERL_INST *)instance)->func_stop_accounting) {				return rlmperl_call(instance, request,					    ((PERL_INST *)instance)->func_stop_accounting);			} else {				return rlmperl_call(instance, request,					    ((PERL_INST *)instance)->func_accounting);			}			break;		default:			return rlmperl_call(instance, request,					    ((PERL_INST *)instance)->func_accounting);	}}/* *	Check for simultaneouse-use */static int perl_checksimul(void *instance, REQUEST *request){	return rlmperl_call(instance, request,			((PERL_INST *)instance)->func_checksimul);}/* *	Pre-Proxy request */static int perl_pre_proxy(void *instance, REQUEST *request){	return rlmperl_call(instance, request,			((PERL_INST *)instance)->func_pre_proxy);}/* *	Post-Proxy request */static int perl_post_proxy(void *instance, REQUEST *request){	return rlmperl_call(instance, request,			((PERL_INST *)instance)->func_post_proxy);}/* *	Pre-Auth request */static int perl_post_auth(void *instance, REQUEST *request){	return rlmperl_call(instance, request,			((PERL_INST *)instance)->func_post_auth);}/* * Detach a instance give a chance to a module to make some internal setup ... */static int perl_detach(void *instance){	PERL_INST	*inst = (PERL_INST *) instance;	int 		exitstatus=0,count=0;#ifdef USE_ITHREADS	POOL_HANDLE	*handle, *tmp, *tmp2;	MUTEX_LOCK(&inst->perl_pool->mutex);	inst->perl_pool->detach = yes;	MUTEX_UNLOCK(&inst->perl_pool->mutex);	for (handle = inst->perl_pool->head; handle != NULL; handle = handle->next) {		radlog(L_DBG,"Detach perl 0x%lx", (unsigned long) handle->clone);		/*		 * Wait until clone becomes idle		 */		MUTEX_LOCK(&handle->lock);		/*		 * Give a clones chance to run detach function		 */		{		dTHXa(handle->clone);		PERL_SET_CONTEXT(handle->clone);		{		dSP; ENTER; SAVETMPS; PUSHMARK(SP);		count = call_pv(inst->func_detach, G_SCALAR | G_EVAL );		SPAGAIN;		if (count == 1) {			exitstatus = POPi;			/*			 * FIXME: bug in perl			 *			 */			if (exitstatus >= 100 || exitstatus < 0) {				exitstatus = RLM_MODULE_FAIL;			}		}		PUTBACK;		FREETMPS;		LEAVE;		radlog(L_DBG,"detach at 0x%lx returned status %d",				(unsigned long) handle->clone, exitstatus);		}		}		MUTEX_UNLOCK(&handle->lock);	}	/*	 * Free handles	 */	for (tmp = inst->perl_pool->head; tmp !=NULL  ; tmp = tmp2) {		tmp2 = tmp->next;		radlog(L_DBG,"rlm_perl:: Destroy perl");		rlm_perl_destruct(tmp->clone);		delete_pool_handle(tmp,inst);	}	{	dTHXa(inst->perl);#endif /* USE_ITHREADS */	PERL_SET_CONTEXT(inst->perl);	{	dSP; ENTER; SAVETMPS;	PUSHMARK(SP);	count = call_pv(inst->func_detach, G_SCALAR | G_EVAL );	SPAGAIN;	if (count == 1) {		exitstatus = POPi;		if (exitstatus >= 100 || exitstatus < 0) {			exitstatus = RLM_MODULE_FAIL;		}	}	PUTBACK;	FREETMPS;	LEAVE;	}#ifdef USE_ITHREADS	}#endif	xlat_unregister(inst->xlat_name, perl_xlat);	free(inst->xlat_name);	if (inst->func_authorize) free(inst->func_authorize);	if (inst->func_authenticate) free(inst->func_authenticate);	if (inst->func_accounting) free(inst->func_accounting);	if (inst->func_preacct) free(inst->func_preacct);	if (inst->func_checksimul) free(inst->func_checksimul);	if (inst->func_pre_proxy) free(inst->func_pre_proxy);	if (inst->func_post_proxy) free(inst->func_post_proxy);	if (inst->func_post_auth) free(inst->func_post_auth);	if (inst->func_detach) free(inst->func_detach);#ifdef USE_ITHREADS	free(inst->perl_pool->head);	free(inst->perl_pool->tail);	MUTEX_DESTROY(&inst->perl_pool->mutex);	free(inst->perl_pool);	rlm_perl_destruct(inst->perl);#else	perl_destruct(inst->perl);	perl_free(inst->perl);#endif	free(inst);	return exitstatus;}/* *	The module name should be the only globally exported symbol. *	That is, everything else should be 'static'. * *	If the module needs to temporarily modify it's instantiation *	data, the type should be changed to RLM_TYPE_THREAD_UNSAFE. *	The server will then take care of ensuring that the module *	is single-threaded. */module_t rlm_perl = {	"perl",				/* Name */#ifdef USE_ITHREADS	RLM_TYPE_THREAD_SAFE,		/* type */#else	RLM_TYPE_THREAD_UNSAFE,#endif	perl_init,			/* initialization */	perl_instantiate,		/* instantiation */	{		perl_authenticate,		perl_authorize,		perl_preacct,		perl_accounting,		perl_checksimul,      	/* check simul */		perl_pre_proxy,	 /* pre-proxy */		perl_post_proxy,	/* post-proxy */		perl_post_auth	  /* post-auth */	},	perl_detach,			/* detach */	NULL,				/* destroy */};

⌨️ 快捷键说明

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