Blame SOURCES/0058-PYSSS-Re-add-the-pysss.getgrouplist-interface.patch

71e593
From f0603645f5ea5f707875807b4f815400f4b79e41 Mon Sep 17 00:00:00 2001
71e593
From: Jakub Hrozek <jhrozek@redhat.com>
71e593
Date: Wed, 24 Oct 2018 09:41:44 +0200
71e593
Subject: [PATCH] PYSSS: Re-add the pysss.getgrouplist() interface
71e593
71e593
Related:
71e593
https://pagure.io/SSSD/sssd/issue/3493
71e593
71e593
Commit 0e211b8ba30c3adcdeef21ca1339b194cbfffb04 was supposed to remove
71e593
only the parts of the pysss API that relate to the local domain. But it
71e593
removed also the getgrouplist() method by accident. This method is very
71e593
important to IPA, so we need to add it back.
71e593
71e593
Reviewed-by: Alexander Bokovoy <abokovoy@redhat.com>
71e593
---
71e593
 src/python/pysss.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
71e593
 1 file changed, 83 insertions(+)
71e593
71e593
diff --git a/src/python/pysss.c b/src/python/pysss.c
71e593
index e92653a9e4cb4fdfef14b0ab3e297b1d469ad1dc..78b8de0739f8184bd5411e51d99c2baf5ce48057 100644
71e593
--- a/src/python/pysss.c
71e593
+++ b/src/python/pysss.c
71e593
@@ -215,12 +215,95 @@ static PyTypeObject pysss_password_type = {
71e593
     .tp_doc   = sss_py_const_p(char, "SSS password obfuscation"),
71e593
 };
71e593
 
71e593
+/*
71e593
+ * Get list of groups user belongs to
71e593
+ */
71e593
+PyDoc_STRVAR(py_sss_getgrouplist__doc__,
71e593
+    "Get list of groups user belongs to.\n\n"
71e593
+    "NOTE: The interface uses the system NSS calls and is not limited to "
71e593
+    "users served by the SSSD!\n"
71e593
+    ":param username: name of user to get list for\n");
71e593
+
71e593
+static PyObject *py_sss_getgrouplist(PyObject *self, PyObject *args)
71e593
+{
71e593
+    char *username = NULL;
71e593
+    gid_t *groups = NULL;
71e593
+    struct passwd *pw;
71e593
+    struct group *gr;
71e593
+    int ngroups;
71e593
+    int ret;
71e593
+    Py_ssize_t i, idx;
71e593
+    PyObject *groups_tuple;
71e593
+
71e593
+    if(!PyArg_ParseTuple(args, discard_const_p(char, "s"), &username)) {
71e593
+        goto fail;
71e593
+    }
71e593
+
71e593
+    pw = getpwnam(username);
71e593
+    if (pw == NULL) {
71e593
+        goto fail;
71e593
+    }
71e593
+
71e593
+    ngroups = 32;
71e593
+    groups = malloc(sizeof(gid_t) * ngroups);
71e593
+    if (groups == NULL) {
71e593
+        goto fail;
71e593
+    }
71e593
+
71e593
+    do {
71e593
+        ret = getgrouplist(username, pw->pw_gid, groups, &ngroups);
71e593
+        if (ret < ngroups) {
71e593
+            gid_t *tmp_groups = realloc(groups, ngroups * sizeof(gid_t));
71e593
+            if (tmp_groups == NULL) {
71e593
+                goto fail;
71e593
+            }
71e593
+            groups = tmp_groups;
71e593
+        }
71e593
+    } while (ret != ngroups);
71e593
+
71e593
+    groups_tuple = PyTuple_New((Py_ssize_t) ngroups);
71e593
+    if (groups_tuple == NULL) {
71e593
+        goto fail;
71e593
+    }
71e593
+
71e593
+    /* Populate a tuple with names of groups
71e593
+     * In unlikely case of group not being able to resolve, skip it
71e593
+     * We also need to resize resulting tuple to avoid empty elements there */
71e593
+    idx = 0;
71e593
+    for (i = 0; i < ngroups; i++) {
71e593
+        gr = getgrgid(groups[i]);
71e593
+        if (gr) {
71e593
+            PyTuple_SetItem(groups_tuple, idx,
71e593
+#ifdef IS_PY3K
71e593
+                    PyUnicode_FromString(gr->gr_name)
71e593
+#else
71e593
+                    PyString_FromString(gr->gr_name)
71e593
+#endif
71e593
+                    );
71e593
+            idx++;
71e593
+        }
71e593
+    }
71e593
+    free(groups);
71e593
+    groups = NULL;
71e593
+
71e593
+    if (i != idx) {
71e593
+        _PyTuple_Resize(&groups_tuple, idx);
71e593
+    }
71e593
+
71e593
+    return groups_tuple;
71e593
+
71e593
+fail:
71e593
+    free(groups);
71e593
+    return NULL;
71e593
+}
71e593
+
71e593
 /* ==================== the sss module initialization =======================*/
71e593
 
71e593
 /*
71e593
  * Module methods
71e593
  */
71e593
 static PyMethodDef module_methods[] = {
71e593
+        {"getgrouplist", py_sss_getgrouplist, METH_VARARGS, py_sss_getgrouplist__doc__},
71e593
         {NULL, NULL, 0, NULL}  /* Sentinel */
71e593
 };
71e593
 
71e593
-- 
71e593
2.14.4
71e593