Skip to content

Commit

Permalink
Add python_path_mode option to rlm_python3
Browse files Browse the repository at this point in the history
  • Loading branch information
ndptech committed Nov 26, 2024
1 parent f5ffff1 commit ca07473
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
7 changes: 7 additions & 0 deletions raddb/mods-available/python3
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ python3 {
#
# python_path="${modconfdir}/${.:name}:/another_path/to/python_files"

# How to use "python_path"
#
# - "append" - append to system path
# - "prepend" - prepend to the system path
# - "overwrite" - overwrite the system path
# python_path_mode = append

module = example

# Pass all VPS lists as a 6-tuple to the callbacks
Expand Down
42 changes: 39 additions & 3 deletions src/modules/rlm_python3/rlm_python3.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ static CONF_PARSER module_config[] = {
#undef A

{ "python_path", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_python_t, python_path), NULL },
{ "python_path_mode", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_python_t, python_path_mode_str), "append" },
{ "cext_compat", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_python_t, cext_compat), "yes" },
{ "pass_all_vps", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_python_t, pass_all_vps), "no" },
{ "pass_all_vps_dict", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_python_t, pass_all_vps_dict), "no" },
Expand Down Expand Up @@ -133,6 +134,19 @@ static struct {
{ NULL, 0 },
};

typedef enum {
PYTHON_PATH_MODE_APPEND,
PYTHON_PATH_MODE_PREPEND,
PYTHON_PATH_MODE_OVERWRITE
} py_path_mode;

FR_NAME_NUMBER const python_path_mode[] = {
{ "append", PYTHON_PATH_MODE_APPEND },
{ "prepend", PYTHON_PATH_MODE_PREPEND },
{ "overwrite", PYTHON_PATH_MODE_OVERWRITE },
{ NULL, -1 }
};

/*
* This allows us to initialise PyThreadState on a per thread basis
*/
Expand Down Expand Up @@ -1217,10 +1231,17 @@ static int python_interpreter_init(rlm_python_t *inst, CONF_SECTION *conf)
if (inst->python_path) {
char *p, *path;
PyObject *sys = PyImport_ImportModule("sys");
PyObject *sys_path = PyObject_GetAttrString(sys, "path");
PyObject *sys_path;
Py_ssize_t i = 0;

memcpy(&p, &inst->python_path, sizeof(path));

if (inst->python_path_mode == PYTHON_PATH_MODE_OVERWRITE) {
sys_path = PyList_New(0);
} else {
sys_path = PyObject_GetAttrString(sys, "path");
}

for (path = strtok(p, ":"); path != NULL; path = strtok(NULL, ":")) {
#if PY_VERSION_HEX > 0x03000000
wchar_t *py_path;
Expand All @@ -1230,10 +1251,18 @@ static int python_interpreter_init(rlm_python_t *inst, CONF_SECTION *conf)
#else
MEM(py_path = _Py_char2wchar(path, NULL));
#endif
PyList_Append(sys_path, PyUnicode_FromWideChar(py_path, -1));
if (inst->python_path_mode == PYTHON_PATH_MODE_PREPEND) {
PyList_Insert(sys_path, i++, PyUnicode_FromWideChar(py_path, -1));
} else {
PyList_Append(sys_path, PyUnicode_FromWideChar(py_path, -1));
}
PyMem_RawFree(py_path);
#else
PyList_Append(sys_path, PyLong_FromString(path));
if (inst->python_path_mode == PYTHON_PATH_PREPEND) {
PyList_Insert(sys_path, i++, PyLong_FromString(path));
} ekse {
PyList_Append(sys_path, PyLong_FromString(path));
}
#endif
}

Expand Down Expand Up @@ -1272,6 +1301,13 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
inst->name = cf_section_name2(conf);
if (!inst->name) inst->name = cf_section_name1(conf);

inst->python_path_mode = fr_str2int(python_path_mode, inst->python_path_mode_str, -1);
if (inst->python_path_mode < 0) {
cf_log_err_cs(conf, "Invalid 'python_path_mode' value \"%s\", expected 'append', "
"'prepend' or 'overwrite'", inst->python_path_mode_str);
return -1;
}

/*
* Load the python code required for this module instance
*/
Expand Down
2 changes: 2 additions & 0 deletions src/modules/rlm_python3/rlm_python3.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ typedef struct rlm_python_t {
char const *name; //!< Name of the module instance
PyThreadState *sub_interpreter; //!< The main interpreter/thread used for this instance.
char const *python_path; //!< Path to search for python files in.
char const *python_path_mode_str; //!< How to use the value of `python_path`.
int python_path_mode;
PyObject *module; //!< Local, interpreter specific module, containing
//!< FreeRADIUS functions.
bool cext_compat; //!< Whether or not to create sub-interpreters per module
Expand Down

0 comments on commit ca07473

Please sign in to comment.