summaryrefslogtreecommitdiff
path: root/python/libmu_py/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'python/libmu_py/auth.c')
-rw-r--r--python/libmu_py/auth.c601
1 files changed, 601 insertions, 0 deletions
diff --git a/python/libmu_py/auth.c b/python/libmu_py/auth.c
new file mode 100644
index 000000000..322e9f76b
--- /dev/null
+++ b/python/libmu_py/auth.c
@@ -0,0 +1,601 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2009-2024 Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include "libmu_py.h"
+#include <mailutils/pam.h>
+
+#define PY_MODULE "auth"
+#define PY_CSNAME1 "AuthorityType"
+#define PY_CSNAME2 "TicketType"
+#define PY_CSNAME3 "WicketType"
+#define PY_CSNAME4 "AuthDataType"
+
+static PyObject *
+_repr1 (PyObject *self)
+{
+ char buf[80];
+ sprintf (buf, "<" PY_MODULE "." PY_CSNAME1 " instance at %p>", self);
+ return PyUnicode_FromString (buf);
+}
+
+static PyObject *
+_repr2 (PyObject *self)
+{
+ char buf[80];
+ sprintf (buf, "<" PY_MODULE "." PY_CSNAME2 " instance at %p>", self);
+ return PyUnicode_FromString (buf);
+}
+
+static PyObject *
+_repr3 (PyObject *self)
+{
+ char buf[80];
+ sprintf (buf, "<" PY_MODULE "." PY_CSNAME3 " instance at %p>", self);
+ return PyUnicode_FromString (buf);
+}
+
+static PyObject *
+_repr4 (PyObject *self)
+{
+ char buf[80];
+ sprintf (buf, "<" PY_MODULE "." PY_CSNAME4 " instance at %p>", self);
+ return PyUnicode_FromString (buf);
+}
+
+
+static PyTypeObject PyAuthorityType = {
+ .ob_base = { PyObject_HEAD_INIT(NULL) },
+ .tp_name = PY_MODULE "." PY_CSNAME1,
+ .tp_basicsize = sizeof (PyAuthority),
+ .tp_dealloc = (destructor)_py_dealloc,
+ .tp_repr = _repr1,
+ .tp_str = _repr1,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_doc = "",
+};
+
+static PyTypeObject PyTicketType = {
+ .ob_base = { PyObject_HEAD_INIT(NULL) },
+ .tp_name = PY_MODULE "." PY_CSNAME2,
+ .tp_basicsize = sizeof (PyTicket),
+ .tp_dealloc = (destructor)_py_dealloc,
+ .tp_repr = _repr2,
+ .tp_str = _repr2,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_doc = "",
+};
+
+static PyTypeObject PyWicketType = {
+ .ob_base = { PyObject_HEAD_INIT(NULL) },
+ .tp_name = PY_MODULE "." PY_CSNAME3,
+ .tp_basicsize = sizeof (PyWicket),
+ .tp_dealloc = (destructor)_py_dealloc,
+ .tp_repr = _repr3,
+ .tp_str = _repr3,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_doc = "",
+};
+
+void
+_dealloc4 (PyObject *self)
+{
+ PyAuthData *py_ad = (PyAuthData *)self;
+ if (py_ad->auth_data)
+ mu_auth_data_free (py_ad->auth_data);
+ self->ob_type->tp_free (self);
+}
+
+static PyObject *
+_getattr4 (PyObject *self, char *name)
+{
+ PyAuthData *py_ad = (PyAuthData *)self;
+ struct mu_auth_data *ad = py_ad->auth_data;
+
+ if (!ad)
+ return NULL;
+
+ if (strcmp (name, "name") == 0)
+ return PyUnicode_FromString (ad->name);
+ else if (strcmp (name, "passwd") == 0)
+ return PyUnicode_FromString (ad->passwd);
+
+ /* FIXME: The use of PyLong_FromSize_t to convert uid_t and gid_t is
+ a bit dubious, but so far there's no other feasible way in Python,
+ save for converting uid (gid) to string and using PyLong_FromString. */
+ else if (strcmp (name, "uid") == 0)
+ return PyLong_FromSize_t (ad->uid);
+ else if (strcmp (name, "gid") == 0)
+ return PyLong_FromSize_t (ad->gid);
+ else if (strcmp (name, "gecos") == 0)
+ return PyUnicode_FromString (ad->gecos);
+ else if (strcmp (name, "dir") == 0)
+ return PyUnicode_FromString (ad->dir);
+ else if (strcmp (name, "shell") == 0)
+ return PyUnicode_FromString (ad->shell);
+ else if (strcmp (name, "mailbox") == 0)
+ return PyUnicode_FromString (ad->mailbox);
+ else if (strcmp (name, "source") == 0)
+ return PyUnicode_FromString (ad->source);
+ else if (strcmp (name, "quota") == 0)
+ /* FIXME: quota is mu_off_t rather than size_t. See comment for uid
+ above */
+ return PyLong_FromSize_t (ad->quota);
+ else if (strcmp (name, "flags") == 0)
+ return PyLong_FromLong (ad->flags);
+ else if (strcmp (name, "change_uid") == 0)
+ return PyLong_FromLong (ad->change_uid);
+ return NULL;
+}
+
+static PyTypeObject PyAuthDataType = {
+ .ob_base = { PyObject_HEAD_INIT(NULL) },
+ .tp_name = PY_MODULE "." PY_CSNAME4,
+ .tp_basicsize = sizeof (PyAuthData),
+ .tp_dealloc = (destructor)_dealloc4,
+ .tp_getattr = _getattr4,
+ .tp_repr = _repr4,
+ .tp_str = _repr4,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_doc = "",
+};
+
+PyAuthority *
+PyAuthority_NEW ()
+{
+ return (PyAuthority *)PyObject_NEW (PyAuthority, &PyAuthorityType);
+}
+
+int
+PyAuthority_Check (PyObject *x)
+{
+ return x->ob_type == &PyAuthorityType;
+}
+
+PyTicket *
+PyTicket_NEW ()
+{
+ return (PyTicket *)PyObject_NEW (PyTicket, &PyTicketType);
+}
+
+int
+PyTicket_Check (PyObject *x)
+{
+ return x->ob_type == &PyTicketType;
+}
+
+PyWicket *
+PyWicket_NEW ()
+{
+ return (PyWicket *)PyObject_NEW (PyWicket, &PyWicketType);
+}
+
+int
+PyWicket_Check (PyObject *x)
+{
+ return x->ob_type == &PyWicketType;
+}
+
+PyAuthData *
+PyAuthData_NEW ()
+{
+ return (PyAuthData *)PyObject_NEW (PyAuthData, &PyAuthDataType);
+}
+
+int
+PyAuthData_Check (PyObject *x)
+{
+ return x->ob_type == &PyAuthDataType;
+}
+
+/*
+ * Authority
+ */
+
+static PyObject *
+api_authority_create (PyObject *self, PyObject *args)
+{
+ int status;
+ PyAuthority *py_auth;
+ PyTicket *py_ticket;
+
+ if (!PyArg_ParseTuple (args, "O!O!",
+ &PyAuthorityType, &py_auth,
+ &PyTicketType, &py_ticket))
+ return NULL;
+
+ status = mu_authority_create (&py_auth->auth, py_ticket->ticket, NULL);
+ return _ro (PyLong_FromLong (status));
+}
+
+static PyObject *
+api_authority_destroy (PyObject *self, PyObject *args)
+{
+ PyAuthority *py_auth;
+
+ if (!PyArg_ParseTuple (args, "O!", &PyAuthorityType, &py_auth))
+ return NULL;
+
+ mu_authority_destroy (&py_auth->auth, NULL);
+ return _ro (Py_None);
+}
+
+static PyObject *
+api_authority_get_ticket (PyObject *self, PyObject *args)
+{
+ int status;
+ PyAuthority *py_auth;
+ PyTicket *py_ticket = PyTicket_NEW ();
+
+ if (!PyArg_ParseTuple (args, "O!", &PyAuthorityType, &py_auth))
+ return NULL;
+
+ Py_INCREF (py_ticket);
+
+ status = mu_authority_get_ticket (py_auth->auth, &py_ticket->ticket);
+ return status_object (status, (PyObject *)py_ticket);
+}
+
+static PyObject *
+api_authority_set_ticket (PyObject *self, PyObject *args)
+{
+ int status;
+ PyAuthority *py_auth;
+ PyTicket *py_ticket;
+
+ if (!PyArg_ParseTuple (args, "O!O!",
+ &PyAuthorityType, &py_auth,
+ &PyTicketType, &py_ticket))
+ return NULL;
+
+ status = mu_authority_set_ticket (py_auth->auth, py_ticket->ticket);
+ return _ro (PyLong_FromLong (status));
+}
+
+static PyObject *
+api_authority_authenticate (PyObject *self, PyObject *args)
+{
+ int status;
+ PyAuthority *py_auth;
+
+ if (!PyArg_ParseTuple (args, "O!", &PyAuthorityType, &py_auth))
+ return NULL;
+
+ status = mu_authority_authenticate (py_auth->auth);
+ return _ro (PyLong_FromLong (status));
+}
+
+/*
+ * Ticket
+ */
+
+static PyObject *
+api_ticket_create (PyObject *self, PyObject *args)
+{
+ int status;
+ PyTicket *py_ticket;
+
+ if (!PyArg_ParseTuple (args, "O!", &PyTicketType, &py_ticket))
+ return NULL;
+
+ status = mu_ticket_create (&py_ticket->ticket, NULL);
+ return _ro (PyLong_FromLong (status));
+}
+
+static PyObject *
+api_ticket_destroy (PyObject *self, PyObject *args)
+{
+ PyTicket *py_ticket;
+
+ if (!PyArg_ParseTuple (args, "O!", &PyTicketType, &py_ticket))
+ return NULL;
+
+ mu_ticket_destroy (&py_ticket->ticket);
+ return _ro (Py_None);
+}
+
+static PyObject *
+api_ticket_set_secret (PyObject *self, PyObject *args)
+{
+ int status;
+ PyTicket *py_ticket;
+ PySecret *py_secret;
+
+ if (!PyArg_ParseTuple (args, "O!O", &PyTicketType, &py_ticket, &py_secret))
+ return NULL;
+
+ if (!PySecret_Check ((PyObject *)py_secret))
+ {
+ PyErr_SetString (PyExc_TypeError, "");
+ return NULL;
+ }
+
+ status = mu_ticket_set_secret (py_ticket->ticket,
+ py_secret->secret);
+ return _ro (PyLong_FromLong (status));
+}
+
+/*
+ * Wicket
+ */
+
+static PyObject *
+api_wicket_create (PyObject *self, PyObject *args)
+{
+ int status;
+ char *filename;
+ PyWicket *py_wicket;
+
+ if (!PyArg_ParseTuple (args, "O!s", &PyWicketType, &py_wicket, &filename))
+ return NULL;
+
+ status = mu_file_wicket_create (&py_wicket->wicket, filename);
+ return _ro (PyLong_FromLong (status));
+}
+
+static PyObject *
+api_wicket_destroy (PyObject *self, PyObject *args)
+{
+ PyWicket *py_wicket;
+
+ if (!PyArg_ParseTuple (args, "O!", &PyWicketType, &py_wicket))
+ return NULL;
+
+ mu_wicket_destroy (&py_wicket->wicket);
+ return _ro (Py_None);
+}
+
+static PyObject *
+api_wicket_get_ticket (PyObject *self, PyObject *args)
+{
+ int status;
+ char *user;
+ PyWicket *py_wicket;
+ PyTicket *py_ticket = PyTicket_NEW ();
+
+ if (!PyArg_ParseTuple (args, "O!s", &PyWicketType, &py_wicket, &user))
+ return NULL;
+
+ Py_INCREF (py_ticket);
+
+ status = mu_wicket_get_ticket (py_wicket->wicket, user,
+ &py_ticket->ticket);
+ return status_object (status, (PyObject *)py_ticket);
+}
+
+/*
+ * mu_auth
+ */
+
+struct module_record {
+ char *name;
+ struct mu_auth_module *module;
+};
+
+static struct module_record module_table[] = {
+ { "system", &mu_auth_system_module },
+ { "generic", &mu_auth_generic_module },
+ { "pam", &mu_auth_pam_module },
+ { "sql", &mu_auth_sql_module },
+ { "virtual", &mu_auth_virtual_module },
+ { "radius", &mu_auth_radius_module },
+ { "ldap", &mu_auth_ldap_module },
+ { NULL, NULL },
+};
+
+static struct mu_auth_module *
+find_module (const struct module_record *table, const char *name)
+{
+ for (; table->name; table++)
+ if (strcmp (table->name, name) == 0)
+ break;
+ return table->module;
+}
+
+static int
+register_module (const char *name)
+{
+ int status = 0;
+
+ if (!name)
+ {
+ struct module_record *table;
+ for (table = module_table; table->name; table++)
+ mu_auth_register_module (table->module);
+ }
+ else
+ {
+ struct mu_auth_module *module = find_module (module_table, name);
+ if (module)
+ mu_auth_register_module (module);
+ else
+ status = EINVAL;
+ }
+ return status;
+}
+
+static PyObject *
+api_register_module (PyObject *self, PyObject *args)
+{
+ int status;
+ char *name = NULL;
+
+ if (!PyArg_ParseTuple (args, "|s", &name))
+ return NULL;
+
+ status = register_module (name);
+ return _ro (PyLong_FromLong (status));
+}
+
+static PyObject *
+api_get_auth_by_name (PyObject *self, PyObject *args)
+{
+ char *username;
+ PyAuthData *py_ad = PyAuthData_NEW ();
+
+ if (!PyArg_ParseTuple (args, "s", &username))
+ return NULL;
+
+ Py_INCREF (py_ad);
+
+ py_ad->auth_data = mu_get_auth_by_name (username);
+ if (!py_ad->auth_data)
+ return _ro (Py_None);
+
+ return _ro ((PyObject *)py_ad);
+}
+
+static PyObject *
+api_get_auth_by_uid (PyObject *self, PyObject *args)
+{
+ uid_t uid;
+ Py_ssize_t n;
+ PyAuthData *py_ad = PyAuthData_NEW ();
+
+ if (!PyArg_ParseTuple (args, "n", &n))
+ return NULL;
+ uid = (uid_t) n;
+ Py_INCREF (py_ad);
+
+ py_ad->auth_data = mu_get_auth_by_uid (uid);
+ if (!py_ad->auth_data)
+ return _ro (Py_None);
+
+ return _ro ((PyObject *)py_ad);
+}
+
+static PyObject *
+api_authenticate (PyObject *self, PyObject *args)
+{
+ int status;
+ char *pass;
+ PyAuthData *py_ad;
+
+ if (!PyArg_ParseTuple (args, "O!s", &PyAuthDataType, &py_ad, &pass))
+ return NULL;
+
+ status = mu_authenticate (py_ad->auth_data, pass);
+ return _ro (PyLong_FromLong (status));
+}
+
+static PyObject *
+api_set_pam_service (PyObject *self, PyObject *args)
+{
+ char *pam_service;
+
+ if (!PyArg_ParseTuple (args, "s", &pam_service))
+ return NULL;
+
+ mu_pam_service = pam_service;
+ return _ro (Py_None);
+}
+
+static PyMethodDef methods[] = {
+ { "authority_create", (PyCFunction) api_authority_create, METH_VARARGS,
+ "" },
+
+ { "authority_destroy", (PyCFunction) api_authority_destroy, METH_VARARGS,
+ "" },
+
+ { "authority_get_ticket", (PyCFunction) api_authority_get_ticket,
+ METH_VARARGS, "" },
+
+ { "authority_set_ticket", (PyCFunction) api_authority_set_ticket,
+ METH_VARARGS, "" },
+
+ { "authority_authenticate", (PyCFunction) api_authority_authenticate,
+ METH_VARARGS, "" },
+
+ { "ticket_create", (PyCFunction) api_ticket_create, METH_VARARGS,
+ "" },
+
+ { "ticket_destroy", (PyCFunction) api_ticket_destroy, METH_VARARGS,
+ "" },
+
+ { "ticket_set_secret", (PyCFunction) api_ticket_set_secret, METH_VARARGS,
+ "" },
+
+ { "wicket_create", (PyCFunction) api_wicket_create, METH_VARARGS,
+ "" },
+
+ { "wicket_destroy", (PyCFunction) api_wicket_destroy, METH_VARARGS,
+ "" },
+
+ { "wicket_get_ticket", (PyCFunction) api_wicket_get_ticket, METH_VARARGS,
+ "" },
+
+ { "register_module", (PyCFunction) api_register_module, METH_VARARGS,
+ "" },
+
+ { "get_auth_by_name", (PyCFunction) api_get_auth_by_name, METH_VARARGS,
+ "" },
+
+ { "get_auth_by_uid", (PyCFunction) api_get_auth_by_uid, METH_VARARGS,
+ "" },
+
+ { "authenticate", (PyCFunction) api_authenticate, METH_VARARGS,
+ "" },
+
+ { "set_pam_service", (PyCFunction) api_set_pam_service, METH_VARARGS,
+ "" },
+
+ { NULL, NULL, 0, NULL }
+};
+
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ PY_MODULE,
+ NULL,
+ -1,
+ methods
+};
+
+int
+mu_py_init_auth (void)
+{
+ PyAuthorityType.tp_new = PyType_GenericNew;
+ PyTicketType.tp_new = PyType_GenericNew;
+ PyWicketType.tp_new = PyType_GenericNew;
+ PyAuthDataType.tp_new = PyType_GenericNew;
+
+ if (PyType_Ready (&PyAuthorityType) < 0)
+ return -1;
+ if (PyType_Ready (&PyTicketType) < 0)
+ return -1;
+ if (PyType_Ready (&PyWicketType) < 0)
+ return -1;
+ if (PyType_Ready (&PyAuthDataType) < 0)
+ return -1;
+ return 0;
+}
+
+void
+_mu_py_attach_auth (void)
+{
+ PyObject *m;
+ if ((m = _mu_py_attach_module (&moduledef)))
+ {
+ Py_INCREF (&PyAuthorityType);
+ Py_INCREF (&PyTicketType);
+ Py_INCREF (&PyWicketType);
+ Py_INCREF (&PyAuthDataType);
+
+ PyModule_AddObject (m, PY_CSNAME1, (PyObject *)&PyAuthorityType);
+ PyModule_AddObject (m, PY_CSNAME2, (PyObject *)&PyTicketType);
+ PyModule_AddObject (m, PY_CSNAME3, (PyObject *)&PyWicketType);
+ PyModule_AddObject (m, PY_CSNAME4, (PyObject *)&PyAuthDataType);
+ }
+}

Return to:

Send suggestions and report system problems to the System administrator.