Ejemplo n.º 1
0
static int mod_init(void)
{
	int i;
	static char name[] = "radiusd";

	if (radiusd_module) return 0;
	
	Py_SetProgramName(name);
	Py_Initialize();
	PyEval_InitThreads(); /* This also grabs a lock */
	
	if ((radiusd_module = Py_InitModule3("radiusd", radiusd_methods,
					     "FreeRADIUS Module.")) == NULL)
		goto failed;
	
	for (i = 0; radiusd_constants[i].name; i++)
		if ((PyModule_AddIntConstant(radiusd_module,
					     radiusd_constants[i].name,
					     radiusd_constants[i].value)) < 0)
			goto failed;
	
	PyEval_ReleaseLock(); /* Drop lock grabbed by InitThreads */
	
	DEBUG("mod_init done");
	return 0;
	
failed:
	mod_error();
	Py_XDECREF(radiusd_module);
	radiusd_module = NULL;
	Py_Finalize();
	return -1;
}
Ejemplo n.º 2
0
static int mod_init(rlm_python_t *inst)
{
	int i;
	static char name[] = "radiusd";

	if (radiusd_module) return 0;

	/*
	 *	Explicitly load libpython, so symbols will be available to lib-dynload modules
	 */
	inst->libpython = dlopen("libpython" STRINGIFY(PY_MAJOR_VERSION) "." STRINGIFY(PY_MINOR_VERSION) ".so",
				 RTLD_NOW | RTLD_GLOBAL);
	if (!inst->libpython) {
	 	WARN("Failed loading libpython symbols into global symbol table: %s", dlerror());
	}

	Py_SetProgramName(name);
#ifdef HAVE_PTHREAD_H
	Py_InitializeEx(0);				/* Don't override signal handlers */
	PyEval_InitThreads(); 				/* This also grabs a lock */
	inst->main_thread_state = PyThreadState_Get();	/* We need this for setting up thread local stuff */
#endif
	if (inst->python_path) {
		PySys_SetPath(inst->python_path);
	}

	if ((radiusd_module = Py_InitModule3("radiusd", radiusd_methods,
					     "FreeRADIUS Module.")) == NULL)
		goto failed;

	for (i = 0; radiusd_constants[i].name; i++) {
		if ((PyModule_AddIntConstant(radiusd_module, radiusd_constants[i].name,
					     radiusd_constants[i].value)) < 0) {
			goto failed;
		}
	}

#ifdef HAVE_PTHREAD_H
	PyThreadState_Swap(NULL);	/* We have to swap out the current thread else we get deadlocks */
	PyEval_ReleaseLock();		/* Drop lock grabbed by InitThreads */
#endif
	DEBUG("mod_init done");
	return 0;

failed:
	Py_XDECREF(radiusd_module);

#ifdef HAVE_PTHREAD_H
	PyEval_ReleaseLock();
#endif

	Pyx_BLOCK_THREADS
	mod_error();
	Pyx_UNBLOCK_THREADS

	radiusd_module = NULL;

	Py_Finalize();
	return -1;
}
Ejemplo n.º 3
0
static int mod_init(rlm_python_t *inst)
{
	int i;
	static char name[] = "radiusd";

	if (radiusd_module) return 0;

	Py_SetProgramName(name);
#ifdef HAVE_PTHREAD_H
	Py_InitializeEx(0);				/* Don't override signal handlers */
	PyEval_InitThreads(); 				/* This also grabs a lock */
	inst->main_thread_state = PyThreadState_Get();	/* We need this for setting up thread local stuff */
#endif
	if (inst->python_path) {
		PySys_SetPath(inst->python_path);
	}
	
	if ((radiusd_module = Py_InitModule3("radiusd", radiusd_methods,
					     "FreeRADIUS Module.")) == NULL)
		goto failed;

	for (i = 0; radiusd_constants[i].name; i++) {
		if ((PyModule_AddIntConstant(radiusd_module, radiusd_constants[i].name,
					     radiusd_constants[i].value)) < 0) {
			goto failed;
		}
	}

#ifdef HAVE_PTHREAD_H
	PyThreadState_Swap(NULL);	/* We have to swap out the current thread else we get deadlocks */
	PyEval_ReleaseLock();		/* Drop lock grabbed by InitThreads */
#endif
	DEBUG("mod_init done");
	return 0;

failed:
	Py_XDECREF(radiusd_module);

#ifdef HAVE_PTHREAD_H
	PyEval_ReleaseLock();
#endif

	Pyx_BLOCK_THREADS
	mod_error();
	Pyx_UNBLOCK_THREADS

	radiusd_module = NULL;

	Py_Finalize();
	return -1;
}
Ejemplo n.º 4
0
/* uam_load. uams must have a uam_setup function. */
struct uam_mod *uam_load(const char *path, const char *name)
{
    char buf[MAXPATHLEN + 1], *p;
    struct uam_mod *mod;
    void *module;

    if ((module = mod_open(path)) == NULL) {
        LOG(log_error, logtype_afpd, "uam_load(%s): failed to load: %s", name, mod_error());
        return NULL;
    }

    if ((mod = (struct uam_mod *) malloc(sizeof(struct uam_mod))) == NULL) {
        LOG(log_error, logtype_afpd, "uam_load(%s): malloc failed", name);
        goto uam_load_fail;
    }

    strlcpy(buf, name, sizeof(buf));
    if ((p = strchr(buf, '.')))
        *p = '\0';

    if ((mod->uam_fcn = mod_symbol(module, buf)) == NULL) {
        LOG(log_error, logtype_afpd, "uam_load(%s): mod_symbol error for symbol %s",
            name,
            buf);
        goto uam_load_err;
    }

    if (mod->uam_fcn->uam_type != UAM_MODULE_SERVER) {
        LOG(log_error, logtype_afpd, "uam_load(%s): attempted to load a non-server module",
            name);
        goto uam_load_err;
    }

    /* version check would go here */

    if (!mod->uam_fcn->uam_setup ||
            ((*mod->uam_fcn->uam_setup)(name) < 0)) {
        LOG(log_error, logtype_afpd, "uam_load(%s): uam_setup failed", name);
        goto uam_load_err;
    }

    mod->uam_module = module;
    return mod;

uam_load_err:
    free(mod);
uam_load_fail:
    mod_close(module);
    return NULL;
}
Ejemplo n.º 5
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 mod_instantiate(UNUSED CONF_SECTION *conf, void *instance)
{
	rlm_python_t *inst = instance;

	if (mod_init(inst) != 0) {
		return -1;
	}

#define A(x) if (mod_load_function(&inst->x) < 0) goto failed

	A(instantiate);
	A(authenticate);
	A(authorize);
	A(preacct);
	A(accounting);
	A(checksimul);
	A(pre_proxy);
	A(post_proxy);
	A(post_auth);
#ifdef WITH_COA
	A(recv_coa);
	A(send_coa);
#endif
	A(detach);

#undef A

	/*
	 *	Call the instantiate function.  No request.  Use the
	 *	return value.
	 */
	return do_python(inst, NULL, inst->instantiate.function, "instantiate", false);
failed:
	Pyx_BLOCK_THREADS
	mod_error();
	Pyx_UNBLOCK_THREADS
	mod_instance_clear(inst);
	return -1;
}
Ejemplo n.º 6
0
static int mod_load_function(struct py_function_def *def)
{
	char const *funcname = "mod_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) {
			ERROR("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) {
			ERROR("rlm_python:%s: function '%s.%s' is not found", funcname, def->module_name, def->function_name);
			goto failed;
		}
		
		if (!PyCallable_Check(def->function)) {
			ERROR("rlm_python:%s: function '%s.%s' is not callable", funcname, def->module_name, def->function_name);
			goto failed;
		}
	}
	PyGILState_Release(gstate);
	return 0;
	
failed:
	mod_error();
	ERROR("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;
}
Ejemplo n.º 7
0
static int do_python(REQUEST *request, PyObject *pFunc,
		     char const *funcname)
{
	vp_cursor_t	cursor;
	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)
		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 = paircursor(&cursor, &request->packet->vps);
		     vp;
		     vp = pairnext(&cursor)) {
			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 = paircursor(&cursor, &request->packet->vps);
		     vp;
		     vp = pairnext(&cursor), i++) {
			PyObject *pPair;
			
			/* The inside tuple has two only: */
			if ((pPair = PyTuple_New(2)) == NULL)
				goto failed;
			
			if (mod_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)
		goto failed;
	
	if (!request)
		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) {
			ERROR("rlm_python:%s: tuple must be (return, replyTuple, configTuple)", funcname);
			goto failed;
		}
		
		pTupleInt = PyTuple_GET_ITEM(pRet, 0);
		if (!PyInt_CheckExact(pTupleInt)) {
			ERROR("rlm_python:%s: first tuple element not an integer", funcname);
			goto failed;
		}
		/* Now have the return value */
		ret = PyInt_AsLong(pTupleInt);
		/* Reply item tuple */
		mod_vptuple(request->reply, &request->reply->vps,
			    PyTuple_GET_ITEM(pRet, 1), funcname);
		/* Config item tuple */
		mod_vptuple(request, &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 */
		ERROR("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:
	mod_error();
	Py_XDECREF(pArgs);
	Py_XDECREF(pRet);
	PyGILState_Release(gstate);
	
	return -1;
}