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

📄 rlm_python.c

📁 freeradius-server-2.1.3.tar.gz安装源文件
💻 C
📖 第 1 页 / 共 2 页
字号:
{	VALUE_PAIR      *vp;	PyObject        *pRet = NULL;	PyObject        *pArgs = NULL;	int             tuplelen;	int             ret;		PyGILState_STATE gstate;		/* Return with "OK, continue" if the function is not defined. */	if (pFunc == NULL)		return RLM_MODULE_OK;		/* Default return value is "OK, continue" */	ret = RLM_MODULE_OK;		/*	 *	We will pass a tuple containing (name, value) tuples	 *	We can safely use the Python function to build up a	 *	tuple, since the tuple is not used elsewhere.	 *	 *	Determine the size of our tuple by walking through the packet.	 *	If request is NULL, pass None.	 */	tuplelen = 0;	if (request != NULL) {		for (vp = request->packet->vps; vp; vp = vp->next)			tuplelen++;	}	gstate = PyGILState_Ensure();		if (tuplelen == 0) {		Py_INCREF(Py_None);		pArgs = Py_None;	} else {		int i = 0;		if ((pArgs = PyTuple_New(tuplelen)) == NULL)			goto failed;		for (vp = request->packet->vps;		     vp != NULL;		     vp = vp->next, i++) {			PyObject *pPair;						/* The inside tuple has two only: */			if ((pPair = PyTuple_New(2)) == NULL)				goto failed;						if (python_populate_vptuple(pPair, vp) == 0) {				/* Put the tuple inside the container */				PyTuple_SET_ITEM(pArgs, i, pPair);			} else {				Py_INCREF(Py_None);				PyTuple_SET_ITEM(pArgs, i, Py_None);				Py_DECREF(pPair);			}		}	}		/* Call Python function. */	pRet = PyObject_CallFunctionObjArgs(pFunc, pArgs, NULL);		if (pRet == NULL)		goto failed;		if (request == NULL)		goto okay;	/*	 *	The function returns either:	 *  1. (returnvalue, replyTuple, configTuple), where	 *   - returnvalue is one of the constants RLM_*	 *   - replyTuple and configTuple are tuples of string	 *      tuples of size 2	 *	 *  2. the function return value alone	 *	 *  3. None - default return value is set	 *	 * xxx This code is messy!	 */	if (PyTuple_CheckExact(pRet)) {		PyObject *pTupleInt;				if (PyTuple_GET_SIZE(pRet) != 3) {			radlog(L_ERR, "rlm_python:%s: tuple must be (return, replyTuple, configTuple)", funcname);			goto failed;		}				pTupleInt = PyTuple_GET_ITEM(pRet, 0);		if (!PyInt_CheckExact(pTupleInt)) {			radlog(L_ERR, "rlm_python:%s: first tuple element not an integer", funcname);			goto failed;		}		/* Now have the return value */		ret = PyInt_AsLong(pTupleInt);		/* Reply item tuple */		python_vptuple(&request->reply->vps,			       PyTuple_GET_ITEM(pRet, 1), funcname);		/* Config item tuple */		python_vptuple(&request->config_items,			       PyTuple_GET_ITEM(pRet, 2), funcname);	} else if (PyInt_CheckExact(pRet)) {		/* Just an integer */		ret = PyInt_AsLong(pRet);	} else if (pRet == Py_None) {		/* returned 'None', return value defaults to "OK, continue." */		ret = RLM_MODULE_OK;	} else {		/* Not tuple or None */		radlog(L_ERR, "rlm_python:%s: function did not return a tuple or None", funcname);		goto failed;	} okay:	Py_DECREF(pArgs);	Py_DECREF(pRet);	PyGILState_Release(gstate);	return ret;	 failed:	python_error();	Py_XDECREF(pArgs);	Py_XDECREF(pRet);	PyGILState_Release(gstate);		return -1;}/* *	Import a user module and load a function from it */static int python_load_function(struct py_function_def *def){	const char *funcname = "python_load_function";	PyGILState_STATE gstate;		gstate = PyGILState_Ensure();		if (def->module_name != NULL && def->function_name != NULL) {		if ((def->module = PyImport_ImportModule(def->module_name)) == NULL) {			radlog(L_ERR, "rlm_python:%s: module '%s' is not found", funcname, def->module_name);			goto failed;		}				if ((def->function = PyObject_GetAttrString(def->module, def->function_name)) == NULL) {			radlog(L_ERR, "rlm_python:%s: function '%s.%s' is not found", funcname, def->module_name, def->function_name);			goto failed;		}				if (!PyCallable_Check(def->function)) {			radlog(L_ERR, "rlm_python:%s: function '%s.%s' is not callable", funcname, def->module_name, def->function_name);			goto failed;		}	}	PyGILState_Release(gstate);	return 0;	 failed:	python_error();	radlog(L_ERR, "rlm_python:%s: failed to import python function '%s.%s'", funcname, def->module_name, def->function_name);	Py_XDECREF(def->function);	def->function = NULL;	Py_XDECREF(def->module);	def->module = NULL;	PyGILState_Release(gstate);	return -1;}static void python_objclear(PyObject **ob){	if (*ob != NULL) {		Pyx_BLOCK_THREADS		Py_DECREF(*ob);		Pyx_UNBLOCK_THREADS	        *ob = NULL;	}}static void free_and_null(char **p){	if (*p != NULL) {		free(*p);		*p = NULL;	}}static void python_funcdef_clear(struct py_function_def *def){	python_objclear(&def->function);	python_objclear(&def->module);	free_and_null(&def->function_name);	free_and_null(&def->module_name);}static void python_instance_clear(struct rlm_python_t *data){#define A(x) python_funcdef_clear(&data->x)		A(instantiate);	A(authorize);	A(authenticate);	A(preacct);	A(accounting);	A(checksimul);	A(detach);#undef A}/* *	Do any per-module initialization that is separate to each *	configured instance of the module.  e.g. set up connections *	to external databases, read configuration files, set up *	dictionary entries, etc. * *	If configuration information is given in the config section *	that must be referenced in later calls, store a handle to it *	in *instance otherwise put a null pointer there. * */static int python_instantiate(CONF_SECTION *conf, void **instance){        struct rlm_python_t    *data = NULL;        /*         *      Set up a storage area for instance data         */        if ((data = malloc(sizeof(*data))) == NULL)                return -1;        memset(data, 0, sizeof(*data));        if (python_init() != 0) {		free(data);		return -1;        }        /*         *      If the configuration parameters can't be parsed, then         *      fail.         */        if (cf_section_parse(conf, data, module_config) < 0) {                free(data);                return -1;        }#define A(x) if (python_load_function(&data->x) < 0) goto failed        A(instantiate);        A(authenticate);        A(authorize);        A(preacct);        A(accounting);        A(checksimul);        A(detach);#undef A        *instance = data;        /*	 *	Call the instantiate function.  No request.  Use the	 *	return value.	 */	return python_function(NULL, data->instantiate.function,			       "instantiate"); failed:        python_error();        python_instance_clear(data);        free(data);        return -1;}static int python_detach(void *instance){        struct rlm_python_t    *data = (struct rlm_python_t *) instance;        int             ret;	        ret = python_function(NULL, data->detach.function, "detach");	        python_instance_clear(data);	        free(data);        return ret;}#define A(x) static int python_##x(void *instance, REQUEST *request) { \  return python_function(request, ((struct rlm_python_t *)instance)->x.function, #x); \}A(authenticate)A(authorize)A(preacct)A(accounting)A(checksimul)#undef A/* *	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_python = {	RLM_MODULE_INIT,	"python",	RLM_TYPE_THREAD_SAFE,		/* type */	python_instantiate,		/* instantiation */        python_detach,	{		python_authenticate,	/* authentication */		python_authorize,	/* authorization */		python_preacct,		/* preaccounting */		python_accounting,	/* accounting */		python_checksimul,	/* checksimul */		NULL,			/* pre-proxy */		NULL,			/* post-proxy */		NULL			/* post-auth */	}};

⌨️ 快捷键说明

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