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

📄 rlm_python.c

📁 free radius编程。完成AAA的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	if ((PyTuple_SetItem(pArgs, 0, pValuePairContainer)) != 0) {	    radlog(L_ERR, "%s: could not set tuple item", function_name);	    return -1;	}	if ((pValue = PyObject_CallObject(pFunc, pArgs)) == NULL) {	    radlog(L_ERR, "%s: function call failed", function_name);	    python_error();	    return -1;	}	/* The function returns either:	 *  1. tuple containing the integer return value,	 *  then the integer reply code (or None to not set),	 *  then the string tuples to build the reply with.	 *     (returnvalue, (p1, s1), (p2, s2))	 *	 *  2. the function return value alone	 *	 *  3. None - default return value is set	 *	 * xxx This code is messy!	 */	if (PyTuple_Check(pValue)) {	    PyObject *pTupleInt;	    if (PyTuple_Size(pValue) != 3) {		radlog(L_ERR, "%s: tuple must be " \		       "(return, replyTuple, configTuple)",		       function_name);	    }	    else {		pTupleInt = PyTuple_GetItem(pValue, 0);		if ((pTupleInt == NULL) || !PyInt_Check(pTupleInt)) {		    radlog(L_ERR, "%s: first tuple element not an integer",			   function_name);		}		else {		    /* Now have the return value */		    return_value = PyInt_AsLong(pTupleInt);		    /* Reply item tuple */		    add_vp_tuple(&request->reply->vps,				 PyTuple_GetItem(pValue, 1), function_name);		    /* Config item tuple */		    add_vp_tuple(&request->config_items,				 PyTuple_GetItem(pValue, 2), function_name);		}	    }	}	else if (PyInt_Check(pValue)) {	    /* Just an integer */	    return_value = PyInt_AsLong(pValue);	}	else if (pValue == Py_None) {	    /* returned 'None', return value defaults to "OK, continue." */	    return_value = RLM_MODULE_OK;	}	else {	    /* Not tuple or None */	    radlog(L_ERR, "%s function did not return a tuple or None\n",		   function_name);	}	/* Decrease reference counts for the argument and return tuple */	Py_DECREF(pArgs);	Py_DECREF(pValue);    }    /* Decrease reference count for the tuples passed, the     * container tuple, and the return value.     */    pValueHolderPtr = pValueHolder;    i = n_tuple;    while (i--) {	/* Can't write as pValueHolderPtr since Py_DECREF is a macro */	Py_DECREF(*pValueHolderPtr);	pValueHolderPtr++;    }    free(pValueHolder);    Py_DECREF(pValuePairContainer);    /* pDict and pFunc are borrowed and must not be Py_DECREF-ed */    /* Free pairs if we are rejecting.     * xxx Shouldn't the core do that?     */    if ((return_value == RLM_MODULE_REJECT) && (request != NULL)) {	pairfree(&(request->reply->vps));    }    /* Return the specified by the Python module */    return return_value;}static struct varlookup {	const char*	name;	int		value;} constants[] = {	{ "L_DBG",		L_DBG			},	{ "L_AUTH",		L_AUTH			},	{ "L_INFO",		L_INFO			},	{ "L_ERR",		L_ERR			},	{ "L_PROXY",		L_PROXY			},	{ "L_CONS",		L_CONS			},	{ "RLM_MODULE_REJECT",	RLM_MODULE_REJECT	},	{ "RLM_MODULE_FAIL",	RLM_MODULE_FAIL		},	{ "RLM_MODULE_OK",	RLM_MODULE_OK		},	{ "RLM_MODULE_HANDLED",	RLM_MODULE_HANDLED	},	{ "RLM_MODULE_INVALID",	RLM_MODULE_INVALID	},	{ "RLM_MODULE_USERLOCK",RLM_MODULE_USERLOCK	},	{ "RLM_MODULE_NOTFOUND",RLM_MODULE_NOTFOUND	},	{ "RLM_MODULE_NOOP",	RLM_MODULE_NOOP		},	{ "RLM_MODULE_UPDATED",	RLM_MODULE_UPDATED	},	{ "RLM_MODULE_NUMCODES",RLM_MODULE_NUMCODES	},	{ NULL, 0 },};/* * Import a user module and load a function from it */static int load_python_function(const char* module, const char* func,				PyObject** pyModule, PyObject** pyFunc) {    if ((module==NULL) || (func==NULL)) {	*pyFunc=NULL;	*pyModule=NULL;    } else {	PyObject *pName;	pName = PyString_FromString(module);	Py_INCREF(pName);	*pyModule = PyImport_Import(pName);	Py_DECREF(pName);	if (*pyModule != NULL) {	    PyObject *pDict;	    pDict = PyModule_GetDict(*pyModule);	    /* pDict: borrowed reference */	    *pyFunc = PyDict_GetItemString(pDict, func);	    /* pFunc: Borrowed reference */	} else {	    python_error();	    radlog(L_ERR, "Failed to import python module \"%s\"\n", module);	    return -1;	}    }    return 0;}/* *	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){    rlm_python_t *data;    PyObject *module;    int idx;    /*	 *	Set up a storage area for instance data	 */    data = rad_malloc(sizeof(*data));    if (!data) {      return -1;    }    memset(data, 0, sizeof(*data));    /*	 *	If the configuration parameters can't be parsed, then	 *	fail.	 */    if (cf_section_parse(conf, data, module_config) < 0) {	free(data);	return -1;    }    /*     * Setup our 'radiusd' module.     */    /* Code */    if ((module = data->pModule_builtin =	 Py_InitModule3("radiusd", radiusd_methods,			"FreeRADIUS Module.")) == NULL) {	radlog(L_ERR, "Python Py_InitModule3 failed");	free(data);	return -1;    }    /*     * Load constants into module     */    for (idx=0; constants[idx].name; idx++)	if ((PyModule_AddIntConstant(module, constants[idx].name, constants[idx].value)) == -1) {	    radlog(L_ERR, "Python AddIntConstant failed");	}    /*     * Import user modules.     */    if (load_python_function(data->mod_instantiate, data->func_instantiate,		&data->pModule_instantiate, &data->pFunc_instantiate)==-1) {	/* TODO: check if we need to cleanup data */	return -1;    }    if (load_python_function(data->mod_authenticate, data->func_authenticate,		&data->pModule_authenticate, &data->pFunc_authenticate)==-1) {	/* TODO: check if we need to cleanup data */	return -1;    }    if (load_python_function(data->mod_authorize, data->func_authorize,		&data->pModule_authorize, &data->pFunc_authorize)==-1) {	/* TODO: check if we need to cleanup data */	return -1;    }    if (load_python_function(data->mod_preacct, data->func_preacct,		&data->pModule_preacct, &data->pFunc_preacct)==-1) {	/* TODO: check if we need to cleanup data */	return -1;    }    if (load_python_function(data->mod_accounting, data->func_accounting,		&data->pModule_accounting, &data->pFunc_accounting)==-1) {	/* TODO: check if we need to cleanup data */	return -1;    }    if (load_python_function(data->mod_checksimul, data->func_checksimul,		&data->pModule_checksimul, &data->pFunc_checksimul)==-1) {	/* TODO: check if we need to cleanup data */	return -1;    }    if (load_python_function(data->mod_detach, data->func_detach,		&data->pModule_detach, &data->pFunc_detach)==-1) {	/* TODO: check if we need to cleanup data */	return -1;    }    *instance=data;    /* Call the instantiate function.  No request.  Use the return value. */    return python_function(NULL, data->pFunc_instantiate, "instantiate");}/* Wrapper functions */static int python_authorize(void *instance, REQUEST *request){    return python_function(request,			   ((struct rlm_python_t *)instance)->pFunc_authorize,			   "authorize");}static int python_authenticate(void *instance, REQUEST *request){    return python_function(	request,	((struct rlm_python_t *)instance)->pFunc_authenticate,	"authenticate");}static int python_preacct(void *instance, REQUEST *request){    return python_function(	request,	((struct rlm_python_t *)instance)->pFunc_preacct,	"preacct");}static int python_accounting(void *instance, REQUEST *request){    return python_function(	request,	((struct rlm_python_t *)instance)->pFunc_accounting,	"accounting");}static int python_checksimul(void *instance, REQUEST *request){    return python_function(	request,	((struct rlm_python_t *)instance)->pFunc_checksimul,	"checksimul");}static int python_detach(void *instance){    int return_value;    /* Default return value is failure */    return_value = -1;    if (((rlm_python_t *)instance)->pFunc_detach &&	PyCallable_Check(((rlm_python_t *)instance)->pFunc_detach)) {	PyObject *pArgs, *pValue;	/* call the function with an empty tuple */	pArgs = PyTuple_New(0);	pValue = PyObject_CallObject(((rlm_python_t *)instance)->pFunc_detach,				     pArgs);	if (pValue == NULL) {	    python_error();	    return -1;	}	else {	    if (!PyInt_Check(pValue)) {		radlog(L_ERR, "detach: return value not an integer");	    }	    else {		return_value = PyInt_AsLong(pValue);	    }	}	/* Decrease reference counts for the argument and return tuple */	Py_DECREF(pArgs);	Py_DECREF(pValue);    }    free(instance);#if 0    /* xxx test delete module object so it will be reloaded later.     * xxx useless since we can't SIGHUP reliably, anyway.     */    PyObject_Del(((struct rlm_python_t *)instance)->pModule_accounting);#endif    radlog(L_DBG, "python_detach done");    /* Return the specified by the Python module */    return return_value;}/* *	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 = {	"python",	RLM_TYPE_THREAD_SAFE,		/* type */	python_init,			/* initialization */	python_instantiate,		/* instantiation */	{		python_authenticate,	/* authentication */		python_authorize,	/* authorization */		python_preacct,		/* preaccounting */		python_accounting,	/* accounting */		python_checksimul,	/* checksimul */		NULL,			/* pre-proxy */		NULL,			/* post-proxy */		NULL			/* post-auth */	},	python_detach,			/* detach */	NULL,				/* destroy */};

⌨️ 快捷键说明

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