summaryrefslogtreecommitdiffstats
path: root/plugins/python/python_plugin_group.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/python/python_plugin_group.c')
-rw-r--r--plugins/python/python_plugin_group.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/plugins/python/python_plugin_group.c b/plugins/python/python_plugin_group.c
new file mode 100644
index 0000000..b1514c7
--- /dev/null
+++ b/plugins/python/python_plugin_group.c
@@ -0,0 +1,114 @@
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 2019-2020 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)
+
+
+static 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, (unsigned int)version);
+ 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);
+}
+
+static 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);
+}
+
+static 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);
+}
+
+sudo_dso_public struct sudoers_group_plugin group_plugin = {
+ GROUP_API_VERSION,
+ CALLBACK_CFUNC(init),
+ CALLBACK_CFUNC(cleanup),
+ CALLBACK_CFUNC(query)
+};