
On each plugin initialization we create a separate python interpreter which gets stored in the plugin_ctx. The main interpreter is stored in py_ctx and is used for creating more interpreters (if more plugins get loaded) and final python deinitialization. The "traceback" module import and the ImportBlocker initialization was moved, because it has to happen inside the plugin specific interpreters.
115 lines
3.8 KiB
C
115 lines
3.8 KiB
C
/*
|
|
* SPDX-License-Identifier: ISC
|
|
*
|
|
* Copyright (c) 2019 Robert Manner <robert.manner@oneidentity.com>
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
/*
|
|
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
|
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
|
*/
|
|
|
|
#include "python_plugin_common.h"
|
|
|
|
static struct PluginContext plugin_ctx;
|
|
|
|
extern struct sudoers_group_plugin group_plugin;
|
|
|
|
#define PY_GROUP_PLUGIN_VERSION SUDO_API_MKVERSION(1, 0)
|
|
|
|
#define CALLBACK_PLUGINFUNC(func_name) group_plugin.func_name
|
|
#define CALLBACK_CFUNC(func_name) python_plugin_group_ ## func_name
|
|
|
|
// This also verifies compile time that the name matches the sudo plugin API.
|
|
#define CALLBACK_PYNAME(func_name) ((void)CALLBACK_PLUGINFUNC(func_name), #func_name)
|
|
|
|
|
|
int
|
|
python_plugin_group_init(int version, sudo_printf_t sudo_printf, char *const plugin_options[])
|
|
{
|
|
debug_decl(python_plugin_group_init, PYTHON_DEBUG_CALLBACKS);
|
|
|
|
if (version < SUDO_API_MKVERSION(1, 0)) {
|
|
sudo_printf(SUDO_CONV_ERROR_MSG,
|
|
"Error: Python group plugin requires at least plugin API version 1.0\n");
|
|
debug_return_int(SUDO_RC_ERROR);
|
|
}
|
|
|
|
int rc = SUDO_RC_ERROR;
|
|
|
|
rc = python_plugin_register_logging(NULL, sudo_printf, NULL);
|
|
if (rc != SUDO_RC_OK)
|
|
debug_return_int(rc);
|
|
|
|
rc = python_plugin_init(&plugin_ctx, plugin_options);
|
|
if (rc != SUDO_RC_OK)
|
|
debug_return_int(rc);
|
|
|
|
PyObject *py_version = NULL,
|
|
*py_plugin_options = NULL,
|
|
*py_kwargs = NULL;
|
|
|
|
if ((py_kwargs = PyDict_New()) == NULL ||
|
|
(py_version = py_create_version(PY_GROUP_PLUGIN_VERSION)) == NULL ||
|
|
(py_plugin_options = py_str_array_to_tuple(plugin_options)) == NULL ||
|
|
PyDict_SetItemString(py_kwargs, "args", py_plugin_options) != 0 ||
|
|
PyDict_SetItemString(py_kwargs, "version", py_version))
|
|
{
|
|
py_log_last_error("Failed to construct arguments for plugin constructor call.");
|
|
rc = SUDO_RC_ERROR;
|
|
} else {
|
|
rc = python_plugin_construct_custom(&plugin_ctx, py_kwargs);
|
|
}
|
|
|
|
Py_XDECREF(py_version);
|
|
Py_XDECREF(py_plugin_options);
|
|
Py_XDECREF(py_kwargs);
|
|
debug_return_int(rc);
|
|
}
|
|
|
|
void
|
|
python_plugin_group_cleanup(void)
|
|
{
|
|
debug_decl(python_plugin_group_cleanup, PYTHON_DEBUG_CALLBACKS);
|
|
PyThreadState_Swap(plugin_ctx.py_interpreter);
|
|
python_plugin_deinit(&plugin_ctx);
|
|
}
|
|
|
|
int
|
|
python_plugin_group_query(const char *user, const char *group, const struct passwd *pwd)
|
|
{
|
|
debug_decl(python_plugin_group_query, PYTHON_DEBUG_CALLBACKS);
|
|
|
|
PyThreadState_Swap(plugin_ctx.py_interpreter);
|
|
|
|
PyObject *py_pwd = py_from_passwd(pwd);
|
|
if (py_pwd == NULL) {
|
|
debug_return_int(SUDO_RC_ERROR);
|
|
}
|
|
|
|
int rc = python_plugin_api_rc_call(&plugin_ctx, CALLBACK_PYNAME(query),
|
|
Py_BuildValue("(zzO)", user, group, py_pwd));
|
|
Py_XDECREF(py_pwd);
|
|
|
|
debug_return_int(rc);
|
|
}
|
|
|
|
__dso_public struct sudoers_group_plugin group_plugin = {
|
|
GROUP_API_VERSION,
|
|
CALLBACK_CFUNC(init),
|
|
CALLBACK_CFUNC(cleanup),
|
|
CALLBACK_CFUNC(query)
|
|
};
|