[Freeipa-devel] [PATCHES 134-136] extdom: handle ERANGE return code for getXXYYY_r()

Sumit Bose sbose at redhat.com
Mon Mar 2 17:45:07 UTC 2015


Hi,

the attached patches add ERANGE handling to getpwnam(), getpwuid(),
getgrnam() and getgrgid().

I added a configurable limit to the buffer allocation which defaults to
128MB. If you think this limit should be change or there should be no
limit at all please let me know.

bye,
Sumit
-------------- next part --------------
From 0b4e302866f734b93176d9104bd78a2e55702c40 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 24 Feb 2015 15:29:00 +0100
Subject: [PATCH 134/136] Add configure check for cwrap libraries

Currently only nss-wrapper is checked, checks for other crwap libraries
can be added e.g. as

AM_CHECK_WRAPPER(uid_wrapper, HAVE_UID_WRAPPER)
---
 daemons/configure.ac | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/daemons/configure.ac b/daemons/configure.ac
index 97cd25115f371e9e549d209401df9325c7e112c1..7c979fe2d0b91e9d71fe4ca5a50ad78a4de79298 100644
--- a/daemons/configure.ac
+++ b/daemons/configure.ac
@@ -236,6 +236,30 @@ PKG_CHECK_EXISTS(cmocka,
 )
 AM_CONDITIONAL([HAVE_CMOCKA], [test x$have_cmocka = xyes])
 
+dnl A macro to check presence of a cwrap (http://cwrap.org) wrapper on the system
+dnl Usage:
+dnl     AM_CHECK_WRAPPER(name, conditional)
+dnl If the cwrap library is found, sets the HAVE_$name conditional
+AC_DEFUN([AM_CHECK_WRAPPER],
+[
+    FOUND_WRAPPER=0
+
+    AC_MSG_CHECKING([for $1])
+    PKG_CHECK_EXISTS([$1],
+                     [
+                        AC_MSG_RESULT([yes])
+                        FOUND_WRAPPER=1
+                     ],
+                     [
+                        AC_MSG_RESULT([no])
+                        AC_MSG_WARN([cwrap library $1 not found, some tests will not run])
+                     ])
+
+    AM_CONDITIONAL($2, [ test x$FOUND_WRAPPER = x1])
+])
+
+AM_CHECK_WRAPPER(nss_wrapper, HAVE_NSS_WRAPPER)
+
 dnl -- dirsrv is needed for the extdom unit tests --
 PKG_CHECK_MODULES([DIRSRV], [dirsrv  >= 1.3.0])
 dnl -- sss_idmap is needed by the extdom exop --
-- 
2.1.0

-------------- next part --------------
From 9960f8f87bfedaaa72db9b27adfc3f86fce88cf8 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 24 Feb 2015 15:33:39 +0100
Subject: [PATCH 135/136] extdom: handle ERANGE return code for getXXYYY_r()
 calls

The getXXYYY_r() calls require a buffer to store the variable data of
the passwd and group structs. If the provided buffer is too small ERANGE
is returned and the caller can try with a larger buffer again.

Cmocka/cwrap based unit-tests for get*_r_wrapper() are added.

Resolves https://fedorahosted.org/freeipa/ticket/4908
---
 .../ipa-slapi-plugins/ipa-extdom-extop/Makefile.am |  31 +-
 .../ipa-extdom-extop/ipa_extdom.h                  |   8 +
 .../ipa-extdom-extop/ipa_extdom_cmocka_tests.c     | 186 ++++++++++++
 .../ipa-extdom-extop/ipa_extdom_common.c           | 327 ++++++++++++++-------
 .../ipa-extdom-extop/test_data/group               |   2 +
 .../ipa-extdom-extop/test_data/passwd              |   2 +
 .../ipa-extdom-extop/test_data/test_setup.sh       |   3 +
 7 files changed, 456 insertions(+), 103 deletions(-)
 create mode 100644 daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_cmocka_tests.c
 create mode 100644 daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/group
 create mode 100644 daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/passwd
 create mode 100644 daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/test_setup.sh

diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/Makefile.am b/daemons/ipa-slapi-plugins/ipa-extdom-extop/Makefile.am
index 0008476796f5b20f62f2c32e7b291b787fa7a6fc..a1679812ef3c5de8c6e18433cbb991a99ad0b6c8 100644
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/Makefile.am
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/Makefile.am
@@ -35,9 +35,20 @@ libipa_extdom_extop_la_LIBADD = 	\
 	$(SSSNSSIDMAP_LIBS)	\
 	$(NULL)
 
+TESTS =
+check_PROGRAMS =
+
 if HAVE_CHECK
-TESTS = extdom_tests
-check_PROGRAMS = extdom_tests
+TESTS += extdom_tests
+check_PROGRAMS += extdom_tests
+endif
+
+if HAVE_CMOCKA
+if HAVE_NSS_WRAPPER
+TESTS_ENVIRONMENT = . ./test_data/test_setup.sh;
+TESTS += extdom_cmocka_tests
+check_PROGRAMS += extdom_cmocka_tests
+endif
 endif
 
 extdom_tests_SOURCES = 	\
@@ -55,6 +66,22 @@ extdom_tests_LDADD = 		\
 	$(SSSNSSIDMAP_LIBS)	\
 	$(NULL)
 
+extdom_cmocka_tests_SOURCES = 		\
+	ipa_extdom_cmocka_tests.c	\
+	ipa_extdom_common.c		\
+	$(NULL)
+extdom_cmocka_tests_CFLAGS = $(CMOCKA_CFLAGS)
+extdom_cmocka_tests_LDFLAGS = 	\
+	-rpath $(shell pkg-config --libs-only-L dirsrv | sed -e 's/-L//') \
+	$(NULL)
+extdom_cmocka_tests_LDADD = 	\
+	$(CMOCKA_LIBS)		\
+	$(LDAP_LIBS)		\
+	$(DIRSRV_LIBS)		\
+	$(SSSNSSIDMAP_LIBS)	\
+	$(NULL)
+
+
 appdir = $(IPA_DATA_DIR)
 app_DATA =				\
 	ipa-extdom-extop-conf.ldif	\
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
index 56ca5009b1aa427f6c059b78ac392c768e461e2e..3231ee224f159545bb92a5c7433bae09869ad17e 100644
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
@@ -174,4 +174,12 @@ int check_request(struct extdom_req *req, enum extdom_version version);
 int handle_request(struct ipa_extdom_ctx *ctx, struct extdom_req *req,
                    struct berval **berval);
 int pack_response(struct extdom_res *res, struct berval **ret_val);
+int getpwnam_r_wrapper(size_t buf_max, const char *name,
+                       struct passwd *pwd, char **_buf, size_t *_buf_len);
+int getpwuid_r_wrapper(size_t buf_max, uid_t uid,
+                       struct passwd *pwd, char **_buf, size_t *_buf_len);
+int getgrnam_r_wrapper(size_t buf_max, const char *name,
+                       struct group *grp, char **_buf, size_t *_buf_len);
+int getgrgid_r_wrapper(size_t buf_max, gid_t gid,
+                       struct group *grp, char **_buf, size_t *_buf_len);
 #endif /* _IPA_EXTDOM_H_ */
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_cmocka_tests.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_cmocka_tests.c
new file mode 100644
index 0000000000000000000000000000000000000000..2143f4a90a1ca61cf4612774f77a520b3793443b
--- /dev/null
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_cmocka_tests.c
@@ -0,0 +1,186 @@
+/*
+    Authors:
+        Sumit Bose <sbose at redhat.com>
+
+    Copyright (C) 2015 Red Hat
+
+    Extdom tests
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <sys/types.h>
+#include <pwd.h>
+
+
+#include "ipa_extdom.h"
+
+#define MAX_BUF (1024*1024*1024)
+
+void test_getpwnam_r_wrapper(void **state)
+{
+    int ret;
+    struct passwd pwd;
+    char *buf;
+    size_t buf_len;
+
+    ret = getpwnam_r_wrapper(MAX_BUF, "non_exisiting_user", &pwd, &buf,
+                             &buf_len);
+    assert_int_equal(ret, ENOENT);
+
+    ret = getpwnam_r_wrapper(MAX_BUF, "user", &pwd, &buf, &buf_len);
+    assert_int_equal(ret, 0);
+    assert_string_equal(pwd.pw_name, "user");
+    assert_string_equal(pwd.pw_passwd, "x");
+    assert_int_equal(pwd.pw_uid, 12345);
+    assert_int_equal(pwd.pw_gid, 23456);
+    assert_string_equal(pwd.pw_gecos, "gecos");
+    assert_string_equal(pwd.pw_dir, "/home/user");
+    assert_string_equal(pwd.pw_shell, "/bin/shell");
+    free(buf);
+
+    ret = getpwnam_r_wrapper(MAX_BUF, "user_big", &pwd, &buf, &buf_len);
+    assert_int_equal(ret, 0);
+    assert_string_equal(pwd.pw_name, "user_big");
+    assert_string_equal(pwd.pw_passwd, "x");
+    assert_int_equal(pwd.pw_uid, 12346);
+    assert_int_equal(pwd.pw_gid, 23457);
+    assert_int_equal(strlen(pwd.pw_gecos), 1000 * strlen("gecos"));
+    assert_string_equal(pwd.pw_dir, "/home/user_big");
+    assert_string_equal(pwd.pw_shell, "/bin/shell");
+    free(buf);
+
+    ret = getpwnam_r_wrapper(1024, "user_big", &pwd, &buf, &buf_len);
+    assert_int_equal(ret, ENOMEM);
+}
+
+void test_getpwuid_r_wrapper(void **state)
+{
+    int ret;
+    struct passwd pwd;
+    char *buf;
+    size_t buf_len;
+
+    ret = getpwuid_r_wrapper(MAX_BUF, 99999, &pwd, &buf, &buf_len);
+    assert_int_equal(ret, ENOENT);
+
+    ret = getpwuid_r_wrapper(MAX_BUF, 12345, &pwd, &buf, &buf_len);
+    assert_int_equal(ret, 0);
+    assert_string_equal(pwd.pw_name, "user");
+    assert_string_equal(pwd.pw_passwd, "x");
+    assert_int_equal(pwd.pw_uid, 12345);
+    assert_int_equal(pwd.pw_gid, 23456);
+    assert_string_equal(pwd.pw_gecos, "gecos");
+    assert_string_equal(pwd.pw_dir, "/home/user");
+    assert_string_equal(pwd.pw_shell, "/bin/shell");
+    free(buf);
+
+    ret = getpwuid_r_wrapper(MAX_BUF, 12346, &pwd, &buf, &buf_len);
+    assert_int_equal(ret, 0);
+    assert_string_equal(pwd.pw_name, "user_big");
+    assert_string_equal(pwd.pw_passwd, "x");
+    assert_int_equal(pwd.pw_uid, 12346);
+    assert_int_equal(pwd.pw_gid, 23457);
+    assert_int_equal(strlen(pwd.pw_gecos), 1000 * strlen("gecos"));
+    assert_string_equal(pwd.pw_dir, "/home/user_big");
+    assert_string_equal(pwd.pw_shell, "/bin/shell");
+    free(buf);
+
+    ret = getpwuid_r_wrapper(1024, 12346, &pwd, &buf, &buf_len);
+    assert_int_equal(ret, ENOMEM);
+}
+
+void test_getgrnam_r_wrapper(void **state)
+{
+    int ret;
+    struct group grp;
+    char *buf;
+    size_t buf_len;
+
+    ret = getgrnam_r_wrapper(MAX_BUF, "non_exisiting_group", &grp, &buf, &buf_len);
+    assert_int_equal(ret, ENOENT);
+
+    ret = getgrnam_r_wrapper(MAX_BUF, "group", &grp, &buf, &buf_len);
+    assert_int_equal(ret, 0);
+    assert_string_equal(grp.gr_name, "group");
+    assert_string_equal(grp.gr_passwd, "x");
+    assert_int_equal(grp.gr_gid, 11111);
+    assert_string_equal(grp.gr_mem[0], "member0001");
+    assert_string_equal(grp.gr_mem[1], "member0002");
+    assert_null(grp.gr_mem[2]);
+    free(buf);
+
+    ret = getgrnam_r_wrapper(MAX_BUF, "group_big", &grp, &buf, &buf_len);
+    assert_int_equal(ret, 0);
+    assert_string_equal(grp.gr_name, "group_big");
+    assert_string_equal(grp.gr_passwd, "x");
+    assert_int_equal(grp.gr_gid, 22222);
+    assert_string_equal(grp.gr_mem[0], "member0001");
+    assert_string_equal(grp.gr_mem[1], "member0002");
+    free(buf);
+
+    ret = getgrnam_r_wrapper(1024, "group_big", &grp, &buf, &buf_len);
+    assert_int_equal(ret, ENOMEM);
+}
+
+void test_getgrgid_r_wrapper(void **state)
+{
+    int ret;
+    struct group grp;
+    char *buf;
+    size_t buf_len;
+
+    ret = getgrgid_r_wrapper(MAX_BUF, 99999, &grp, &buf, &buf_len);
+    assert_int_equal(ret, ENOENT);
+
+    ret = getgrgid_r_wrapper(MAX_BUF, 11111, &grp, &buf, &buf_len);
+    assert_int_equal(ret, 0);
+    assert_string_equal(grp.gr_name, "group");
+    assert_string_equal(grp.gr_passwd, "x");
+    assert_int_equal(grp.gr_gid, 11111);
+    assert_string_equal(grp.gr_mem[0], "member0001");
+    assert_string_equal(grp.gr_mem[1], "member0002");
+    assert_null(grp.gr_mem[2]);
+    free(buf);
+
+    ret = getgrgid_r_wrapper(MAX_BUF, 22222, &grp, &buf, &buf_len);
+    assert_int_equal(ret, 0);
+    assert_string_equal(grp.gr_name, "group_big");
+    assert_string_equal(grp.gr_passwd, "x");
+    assert_int_equal(grp.gr_gid, 22222);
+    assert_string_equal(grp.gr_mem[0], "member0001");
+    assert_string_equal(grp.gr_mem[1], "member0002");
+    free(buf);
+
+    ret = getgrgid_r_wrapper(1024, 22222, &grp, &buf, &buf_len);
+    assert_int_equal(ret, ENOMEM);
+}
+
+int main(int argc, const char *argv[])
+{
+    const UnitTest tests[] = {
+        unit_test(test_getpwnam_r_wrapper),
+        unit_test(test_getpwuid_r_wrapper),
+        unit_test(test_getgrnam_r_wrapper),
+        unit_test(test_getgrgid_r_wrapper),
+    };
+
+    return run_tests(tests);
+}
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
index 20fdd62b20f28f5384cf83b8be5819f721c6c3db..84aeb28066f25f05a89d0c2d42e8b060e2399501 100644
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
@@ -49,6 +49,220 @@
 
 #define MAX(a,b) (((a)>(b))?(a):(b))
 #define SSSD_DOMAIN_SEPARATOR '@'
+#define MAX_BUF (1024*1024*1024)
+
+
+
+static int get_buffer(size_t *_buf_len, char **_buf)
+{
+    long pw_max;
+    long gr_max;
+    size_t buf_len;
+    char *buf;
+
+    pw_max = sysconf(_SC_GETPW_R_SIZE_MAX);
+    gr_max = sysconf(_SC_GETGR_R_SIZE_MAX);
+
+    if (pw_max == -1 && gr_max == -1) {
+        buf_len = 16384;
+    } else {
+        buf_len = MAX(pw_max, gr_max);
+    }
+
+    buf = malloc(sizeof(char) * buf_len);
+    if (buf == NULL) {
+        return LDAP_OPERATIONS_ERROR;
+    }
+
+    *_buf_len = buf_len;
+    *_buf = buf;
+
+    return LDAP_SUCCESS;
+}
+
+int getpwnam_r_wrapper(size_t buf_max, const char *name,
+                       struct passwd *pwd, char **_buf, size_t *_buf_len)
+{
+    char *buf = NULL;
+    char *tmp_buf;
+    size_t buf_len = 0;
+    int ret;
+    struct passwd *result = NULL;
+
+    ret = get_buffer(&buf_len, &buf);
+    if (ret != LDAP_SUCCESS) {
+        return ENOMEM;
+    }
+
+    while (buf != NULL
+            && (ret = getpwnam_r(name, pwd, buf, buf_len, &result)) == ERANGE) {
+        buf_len *= 2;
+        if (buf_len > buf_max) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        tmp_buf = realloc(buf, buf_len);
+        if (tmp_buf == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        buf = tmp_buf;
+    }
+
+    if (ret == 0 && result == NULL) {
+        ret = ENOENT;
+    }
+
+done:
+    if (ret == 0) {
+        *_buf = buf;
+        *_buf_len = buf_len;
+    } else {
+        free(buf);
+    }
+
+    return ret;
+}
+
+int getpwuid_r_wrapper(size_t buf_max, uid_t uid,
+                       struct passwd *pwd, char **_buf, size_t *_buf_len)
+{
+    char *buf = NULL;
+    char *tmp_buf;
+    size_t buf_len = 0;
+    int ret;
+    struct passwd *result = NULL;
+
+    ret = get_buffer(&buf_len, &buf);
+    if (ret != LDAP_SUCCESS) {
+        return ENOMEM;
+    }
+
+    while (buf != NULL
+            && (ret = getpwuid_r(uid, pwd, buf, buf_len, &result)) == ERANGE) {
+        buf_len *= 2;
+        if (buf_len > buf_max) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        tmp_buf = realloc(buf, buf_len);
+        if (tmp_buf == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        buf = tmp_buf;
+    }
+
+    if (ret == 0 && result == NULL) {
+        ret = ENOENT;
+    }
+
+done:
+    if (ret == 0) {
+        *_buf = buf;
+        *_buf_len = buf_len;
+    } else {
+        free(buf);
+    }
+
+    return ret;
+}
+
+int getgrnam_r_wrapper(size_t buf_max, const char *name,
+                       struct group *grp, char **_buf, size_t *_buf_len)
+{
+    char *buf = NULL;
+    char *tmp_buf;
+    size_t buf_len = 0;
+    int ret;
+    struct group *result = NULL;
+
+    ret = get_buffer(&buf_len, &buf);
+    if (ret != LDAP_SUCCESS) {
+        return ENOMEM;
+    }
+
+    while (buf != NULL
+            && (ret = getgrnam_r(name, grp, buf, buf_len, &result)) == ERANGE) {
+        buf_len *= 2;
+        if (buf_len > buf_max) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        tmp_buf = realloc(buf, buf_len);
+        if (tmp_buf == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        buf = tmp_buf;
+    }
+
+    if (ret == 0 && result == NULL) {
+        ret = ENOENT;
+    }
+
+done:
+    if (ret == 0) {
+        *_buf = buf;
+        *_buf_len = buf_len;
+    } else {
+        free(buf);
+    }
+
+    return ret;
+}
+
+int getgrgid_r_wrapper(size_t buf_max, gid_t gid,
+                       struct group *grp, char **_buf, size_t *_buf_len)
+{
+    char *buf = NULL;
+    char *tmp_buf;
+    size_t buf_len = 0;
+    int ret;
+    struct group *result = NULL;
+
+    ret = get_buffer(&buf_len, &buf);
+    if (ret != LDAP_SUCCESS) {
+        return ENOMEM;
+    }
+
+    while (buf != NULL
+            && (ret = getgrgid_r(gid, grp, buf, buf_len, &result)) == ERANGE) {
+        buf_len *= 2;
+        if (buf_len > buf_max) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        tmp_buf = realloc(buf, buf_len);
+        if (tmp_buf == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
+
+        buf = tmp_buf;
+    }
+
+    if (ret == 0 && result == NULL) {
+        ret = ENOENT;
+    }
+
+done:
+    if (ret == 0) {
+        *_buf = buf;
+        *_buf_len = buf_len;
+    } else {
+        free(buf);
+    }
+
+    return ret;
+}
 
 int parse_request_data(struct berval *req_val, struct extdom_req **_req)
 {
@@ -191,33 +405,6 @@ int check_request(struct extdom_req *req, enum extdom_version version)
     return LDAP_SUCCESS;
 }
 
-static int get_buffer(size_t *_buf_len, char **_buf)
-{
-    long pw_max;
-    long gr_max;
-    size_t buf_len;
-    char *buf;
-
-    pw_max = sysconf(_SC_GETPW_R_SIZE_MAX);
-    gr_max = sysconf(_SC_GETGR_R_SIZE_MAX);
-
-    if (pw_max == -1 && gr_max == -1) {
-        buf_len = 16384;
-    } else {
-        buf_len = MAX(pw_max, gr_max);
-    }
-
-    buf = malloc(sizeof(char) * buf_len);
-    if (buf == NULL) {
-        return LDAP_OPERATIONS_ERROR;
-    }
-
-    *_buf_len = buf_len;
-    *_buf = buf;
-
-    return LDAP_SUCCESS;
-}
-
 static int get_user_grouplist(const char *name, gid_t gid,
                               size_t *_ngroups, gid_t **_groups )
 {
@@ -323,7 +510,6 @@ static int pack_ber_user(enum response_types response_type,
     size_t buf_len;
     char *buf = NULL;
     struct group grp;
-    struct group *grp_result;
     size_t c;
     char *locat;
     char *short_user_name = NULL;
@@ -357,11 +543,6 @@ static int pack_ber_user(enum response_types response_type,
             goto done;
         }
 
-        ret = get_buffer(&buf_len, &buf);
-        if (ret != LDAP_SUCCESS) {
-            goto done;
-        }
-
         ret = ber_printf(ber,"sss", gecos, homedir, shell);
         if (ret == -1) {
             ret = LDAP_OPERATIONS_ERROR;
@@ -375,15 +556,11 @@ static int pack_ber_user(enum response_types response_type,
         }
 
         for (c = 0; c < ngroups; c++) {
-            ret = getgrgid_r(groups[c], &grp, buf, buf_len, &grp_result);
+            ret = getgrgid_r_wrapper(MAX_BUF, groups[c], &grp, &buf, &buf_len);
             if (ret != 0) {
                 ret = LDAP_NO_SUCH_OBJECT;
                 goto done;
             }
-            if (grp_result == NULL) {
-                ret = LDAP_NO_SUCH_OBJECT;
-                goto done;
-            }
 
             ret = ber_printf(ber, "s", grp.gr_name);
             if (ret == -1) {
@@ -542,18 +719,12 @@ static int handle_uid_request(enum request_types request_type, uid_t uid,
 {
     int ret;
     struct passwd pwd;
-    struct passwd *pwd_result = NULL;
     char *sid_str = NULL;
     enum sss_id_type id_type;
     size_t buf_len;
     char *buf = NULL;
     struct sss_nss_kv *kv_list = NULL;
 
-    ret = get_buffer(&buf_len, &buf);
-    if (ret != LDAP_SUCCESS) {
-        return ret;
-    }
-
     if (request_type == REQ_SIMPLE) {
         ret = sss_nss_getsidbyid(uid, &sid_str, &id_type);
         if (ret != 0 || !(id_type == SSS_ID_TYPE_UID
@@ -568,15 +739,11 @@ static int handle_uid_request(enum request_types request_type, uid_t uid,
 
         ret = pack_ber_sid(sid_str, berval);
     } else {
-        ret = getpwuid_r(uid, &pwd, buf, buf_len, &pwd_result);
+        ret = getpwuid_r_wrapper(MAX_BUF, uid, &pwd, &buf, &buf_len);
         if (ret != 0) {
             ret = LDAP_NO_SUCH_OBJECT;
             goto done;
         }
-        if (pwd_result == NULL) {
-            ret = LDAP_NO_SUCH_OBJECT;
-            goto done;
-        }
 
         if (request_type == REQ_FULL_WITH_GROUPS) {
             ret = sss_nss_getorigbyname(pwd.pw_name, &kv_list, &id_type);
@@ -610,18 +777,12 @@ static int handle_gid_request(enum request_types request_type, gid_t gid,
 {
     int ret;
     struct group grp;
-    struct group *grp_result = NULL;
     char *sid_str = NULL;
     enum sss_id_type id_type;
     size_t buf_len;
     char *buf = NULL;
     struct sss_nss_kv *kv_list = NULL;
 
-    ret = get_buffer(&buf_len, &buf);
-    if (ret != LDAP_SUCCESS) {
-        return ret;
-    }
-
     if (request_type == REQ_SIMPLE) {
         ret = sss_nss_getsidbyid(gid, &sid_str, &id_type);
         if (ret != 0 || id_type != SSS_ID_TYPE_GID) {
@@ -635,15 +796,11 @@ static int handle_gid_request(enum request_types request_type, gid_t gid,
 
         ret = pack_ber_sid(sid_str, berval);
     } else {
-        ret = getgrgid_r(gid, &grp, buf, buf_len, &grp_result);
+        ret = getgrgid_r_wrapper(MAX_BUF, gid, &grp, &buf, &buf_len);
         if (ret != 0) {
             ret = LDAP_NO_SUCH_OBJECT;
             goto done;
         }
-        if (grp_result == NULL) {
-            ret = LDAP_NO_SUCH_OBJECT;
-            goto done;
-        }
 
         if (request_type == REQ_FULL_WITH_GROUPS) {
             ret = sss_nss_getorigbyname(grp.gr_name, &kv_list, &id_type);
@@ -676,9 +833,7 @@ static int handle_sid_request(enum request_types request_type, const char *sid,
 {
     int ret;
     struct passwd pwd;
-    struct passwd *pwd_result = NULL;
     struct group grp;
-    struct group *grp_result = NULL;
     char *domain_name = NULL;
     char *fq_name = NULL;
     char *object_name = NULL;
@@ -716,25 +871,15 @@ static int handle_sid_request(enum request_types request_type, const char *sid,
         goto done;
     }
 
-    ret = get_buffer(&buf_len, &buf);
-    if (ret != LDAP_SUCCESS) {
-        goto done;
-    }
-
     switch(id_type) {
     case SSS_ID_TYPE_UID:
     case SSS_ID_TYPE_BOTH:
-        ret = getpwnam_r(fq_name, &pwd, buf, buf_len, &pwd_result);
+        ret = getpwnam_r_wrapper(MAX_BUF, fq_name, &pwd, &buf, &buf_len);
         if (ret != 0) {
             ret = LDAP_NO_SUCH_OBJECT;
             goto done;
         }
 
-        if (pwd_result == NULL) {
-            ret = LDAP_NO_SUCH_OBJECT;
-            goto done;
-        }
-
         if (request_type == REQ_FULL_WITH_GROUPS) {
             ret = sss_nss_getorigbyname(pwd.pw_name, &kv_list, &id_type);
             if (ret != 0 || !(id_type == SSS_ID_TYPE_UID
@@ -755,17 +900,12 @@ static int handle_sid_request(enum request_types request_type, const char *sid,
                             pwd.pw_shell, kv_list, berval);
         break;
     case SSS_ID_TYPE_GID:
-        ret = getgrnam_r(fq_name, &grp, buf, buf_len, &grp_result);
+        ret = getgrnam_r_wrapper(MAX_BUF, fq_name, &grp, &buf, &buf_len);
         if (ret != 0) {
             ret = LDAP_NO_SUCH_OBJECT;
             goto done;
         }
 
-        if (grp_result == NULL) {
-            ret = LDAP_NO_SUCH_OBJECT;
-            goto done;
-        }
-
         if (request_type == REQ_FULL_WITH_GROUPS) {
             ret = sss_nss_getorigbyname(grp.gr_name, &kv_list, &id_type);
             if (ret != 0 || !(id_type == SSS_ID_TYPE_GID
@@ -806,9 +946,7 @@ static int handle_name_request(enum request_types request_type,
     int ret;
     char *fq_name = NULL;
     struct passwd pwd;
-    struct passwd *pwd_result = NULL;
     struct group grp;
-    struct group *grp_result = NULL;
     char *sid_str = NULL;
     enum sss_id_type id_type;
     size_t buf_len;
@@ -837,20 +975,8 @@ static int handle_name_request(enum request_types request_type,
 
         ret = pack_ber_sid(sid_str, berval);
     } else {
-        ret = get_buffer(&buf_len, &buf);
-        if (ret != LDAP_SUCCESS) {
-            goto done;
-        }
-
-        ret = getpwnam_r(fq_name, &pwd, buf, buf_len, &pwd_result);
-        if (ret != 0) {
-            /* according to the man page there are a couple of error codes
-             * which can indicate that the user was not found. To be on the
-             * safe side we fail back to the group lookup on all errors. */
-            pwd_result = NULL;
-        }
-
-        if (pwd_result != NULL) {
+        ret = getpwnam_r_wrapper(MAX_BUF, fq_name, &pwd, &buf, &buf_len);
+        if (ret == 0) {
             if (request_type == REQ_FULL_WITH_GROUPS) {
                 ret = sss_nss_getorigbyname(pwd.pw_name, &kv_list, &id_type);
                 if (ret != 0 || !(id_type == SSS_ID_TYPE_UID
@@ -869,17 +995,16 @@ static int handle_name_request(enum request_types request_type,
                                 pwd.pw_gid, pwd.pw_gecos, pwd.pw_dir,
                                 pwd.pw_shell, kv_list, berval);
         } else { /* no user entry found */
-            ret = getgrnam_r(fq_name, &grp, buf, buf_len, &grp_result);
+            /* according to the getpwnam() man page there are a couple of
+             * error codes which can indicate that the user was not found. To
+             * be on the safe side we fail back to the group lookup on all
+             * errors. */
+            ret = getgrnam_r_wrapper(MAX_BUF, fq_name, &grp, &buf, &buf_len);
             if (ret != 0) {
                 ret = LDAP_NO_SUCH_OBJECT;
                 goto done;
             }
 
-            if (grp_result == NULL) {
-                ret = LDAP_NO_SUCH_OBJECT;
-                goto done;
-            }
-
             if (request_type == REQ_FULL_WITH_GROUPS) {
                 ret = sss_nss_getorigbyname(grp.gr_name, &kv_list, &id_type);
                 if (ret != 0 || !(id_type == SSS_ID_TYPE_GID
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/group b/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/group
new file mode 100644
index 0000000000000000000000000000000000000000..972a6ef390aceeee2e29dccb1fddef2f4ad10fb9
--- /dev/null
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/group
@@ -0,0 +1,2 @@
+group:x:11111:member0001,member0002
+group_big:x:22222:member0001,member0002,member0003,member0004,member0005,member0006,member0007,member0008,member0009,member0010,member0011,member0012,member0013,member0014,member0015,member0016,member0017,member0018,member0019,member0020,member0021,member0022,member0023,member0024,member0025,member0026,member0027,member0028,member0029,member0030,member0031,member0032,member0033,member0034,member0035,member0036,member0037,member0038,member0039,member0040,member0041,member0042,member0043,member0044,member0045,member0046,member0047,member0048,member0049,member0050,member0051,member0052,member0053,member0054,member0055,member0056,member0057,member0058,member0059,member0060,member0061,member0062,member0063,member0064,member0065,member0066,member0067,member0068,member0069,member0070,member0071,member0072,member0073,member0074,member0075,member0076,member0077,member0078,member0079,member0080,member0081,member0082,member0083,member0084,member0085,member0086,member0087,member0088,member0089,member0090,member0091,member0092,member0093,member0094,member0095,member0096,member0097,member0098,member0099,member0100,member0101,member0102,member0103,member0104,member0105,member0106,member0107,member0108,member0109,member0110,member0111,member0112,member0113,member0114,member0115,member0116,member0117,member0118,member0119,member0120,member0121,member0122,member0123,member0124,member0125,member0126,member0127,member0128,member0129,member0130,member0131,member0132,member0133,member0134,member0135,member0136,member0137,member0138,member0139,member0140,member0141,member0142,member0143,member0144,member0145,member0146,member0147,member0148,member0149,member0150,member0151,member0152,member0153,member0154,member0155,member0156,member0157,member0158,member0159,member0160,member0161,member0162,member0163,member0164,member0165,member0166,member0167,member0168,member0169,member0170,member0171,member0172,member0173,member0174,member0175,member0176,member0177,member0178,member0179,member0180,member0181,member0182,member0183,member0184,member0185,member0186,member0187,member0188,member0189,member0190,member0191,member0192,member0193,member0194,member0195,member0196,member0197,member0198,member0199,member0200,member0201,member0202,member0203,member0204,member0205,member0206,member0207,member0208,member0209,member0210,member0211,member0212,member0213,member0214,member0215,member0216,member0217,member0218,member0219,member0220,member0221,member0222,member0223,member0224,member0225,member0226,member0227,member0228,member0229,member0230,member0231,member0232,member0233,member0234,member0235,member0236,member0237,member0238,member0239,member0240,member0241,member0242,member0243,member0244,member0245,member0246,member0247,member0248,member0249,member0250,member0251,member0252,member0253,member0254,member0255,member0256,member0257,member0258,member0259,member0260,member0261,member0262,member0263,member0264,member0265,member0266,member0267,member0268,member0269,member0270,member0271,member0272,member0273,member0274,member0275,member0276,member0277,member0278,member0279,member0280,member0281,member0282,member0283,member0284,member0285,member0286,member0287,member0288,member0289,member0290,member0291,member0292,member0293,member0294,member0295,member0296,member0297,member0298,member0299,member0300,member0301,member0302,member0303,member0304,member0305,member0306,member0307,member0308,member0309,member0310,member0311,member0312,member0313,member0314,member0315,member0316,member0317,member0318,member0319,member0320,member0321,member0322,member0323,member0324,member0325,member0326,member0327,member0328,member0329,member0330,member0331,member0332,member0333,member0334,member0335,member0336,member0337,member0338,member0339,member0340,member0341,member0342,member0343,member0344,member0345,member0346,member0347,member0348,member0349,member0350,member0351,member0352,member0353,member0354,member0355,member0356,member0357,member0358,member0359,member0360,member0361,member0362,member0363,member0364,member0365,member0366,member0367,member0368,member0369,member0370,member0371,member0372,member0373,member0374,member0375,member0376,member0377,member0378,member0379,member0380,member0381,member0382,member0383,member0384,member0385,member0386,member0387,member0388,member0389,member0390,member0391,member0392,member0393,member0394,member0395,member0396,member0397,member0398,member0399,member0400,member0401,member0402,member0403,member0404,member0405,member0406,member0407,member0408,member0409,member0410,member0411,member0412,member0413,member0414,member0415,member0416,member0417,member0418,member0419,member0420,member0421,member0422,member0423,member0424,member0425,member0426,member0427,member0428,member0429,member0430,member0431,member0432,member0433,member0434,member0435,member0436,member0437,member0438,member0439,member0440,member0441,member0442,member0443,member0444,member0445,member0446,member0447,member0448,member0449,member0450,member0451,member0452,member0453,member0454,member0455,member0456,member0457,member0458,member0459,member0460,member0461,member0462,member0463,member0464,member0465,member0466,member0467,member0468,member0469,member0470,member0471,member0472,member0473,member0474,member0475,member0476,member0477,member0478,member0479,member0480,member0481,member0482,member0483,member0484,member0485,member0486,member0487,member0488,member0489,member0490,member0491,member0492,member0493,member0494,member0495,member0496,member0497,member0498,member0499,member0500,member0501,member0502,member0503,member0504,member0505,member0506,member0507,member0508,member0509,member0510,member0511,member0512,member0513,member0514,member0515,member0516,member0517,member0518,member0519,member0520,member0521,member0522,member0523,member0524,member0525,member0526,member0527,member0528,member0529,member0530,member0531,member0532,member0533,member0534,member0535,member0536,member0537,member0538,member0539,member0540,member0541,member0542,member0543,member0544,member0545,member0546,member0547,member0548,member0549,member0550,member0551,member0552,member0553,member0554,member0555,member0556,member0557,member0558,member0559,member0560,member0561,member0562,member0563,member0564,member0565,member0566,member0567,member0568,member0569,member0570,member0571,member0572,member0573,member0574,member0575,member0576,member0577,member0578,member0579,member0580,member0581,member0582,member0583,member0584,member0585,member0586,member0587,member0588,member0589,member0590,member0591,member0592,member0593,member0594,member0595,member0596,member0597,member0598,member0599,member0600,member0601,member0602,member0603,member0604,member0605,member0606,member0607,member0608,member0609,member0610,member0611,member0612,member0613,member0614,member0615,member0616,member0617,member0618,member0619,member0620,member0621,member0622,member0623,member0624,member0625,member0626,member0627,member0628,member0629,member0630,member0631,member0632,member0633,member0634,member0635,member0636,member0637,member0638,member0639,member0640,member0641,member0642,member0643,member0644,member0645,member0646,member0647,member0648,member0649,member0650,member0651,member0652,member0653,member0654,member0655,member0656,member0657,member0658,member0659,member0660,member0661,member0662,member0663,member0664,member0665,member0666,member0667,member0668,member0669,member0670,member0671,member0672,member0673,member0674,member0675,member0676,member0677,member0678,member0679,member0680,member0681,member0682,member0683,member0684,member0685,member0686,member0687,member0688,member0689,member0690,member0691,member0692,member0693,member0694,member0695,member0696,member0697,member0698,member0699,member0700,member0701,member0702,member0703,member0704,member0705,member0706,member0707,member0708,member0709,member0710,member0711,member0712,member0713,member0714,member0715,member0716,member0717,member0718,member0719,member0720,member0721,member0722,member0723,member0724,member0725,member0726,member0727,member0728,member0729,member0730,member0731,member0732,member0733,member0734,member0735,member0736,member0737,member0738,member0739,member0740,member0741,member0742,member0743,member0744,member0745,member0746,member0747,member0748,member0749,member0750,member0751,member0752,member0753,member0754,member0755,member0756,member0757,member0758,member0759,member0760,member0761,member0762,member0763,member0764,member0765,member0766,member0767,member0768,member0769,member0770,member0771,member0772,member0773,member0774,member0775,member0776,member0777,member0778,member0779,member0780,member0781,member0782,member0783,member0784,member0785,member0786,member0787,member0788,member0789,member0790,member0791,member0792,member0793,member0794,member0795,member0796,member0797,member0798,member0799,member0800,member0801,member0802,member0803,member0804,member0805,member0806,member0807,member0808,member0809,member0810,member0811,member0812,member0813,member0814,member0815,member0816,member0817,member0818,member0819,member0820,member0821,member0822,member0823,member0824,member0825,member0826,member0827,member0828,member0829,member0830,member0831,member0832,member0833,member0834,member0835,member0836,member0837,member0838,member0839,member0840,member0841,member0842,member0843,member0844,member0845,member0846,member0847,member0848,member0849,member0850,member0851,member0852,member0853,member0854,member0855,member0856,member0857,member0858,member0859,member0860,member0861,member0862,member0863,member0864,member0865,member0866,member0867,member0868,member0869,member0870,member0871,member0872,member0873,member0874,member0875,member0876,member0877,member0878,member0879,member0880,member0881,member0882,member0883,member0884,member0885,member0886,member0887,member0888,member0889,member0890,member0891,member0892,member0893,member0894,member0895,member0896,member0897,member0898,member0899,member0900,member0901,member0902,member0903,member0904,member0905,member0906,member0907,member0908,member0909,member0910,member0911,member0912,member0913,member0914,member0915,member0916,member0917,member0918,member0919,member0920,member0921,member0922,member0923,member0924,member0925,member0926,member0927,member0928,member0929,member0930,member0931,member0932,member0933,member0934,member0935,member0936,member0937,member0938,member0939,member0940,member0941,member0942,member0943,member0944,member0945,member0946,member0947,member0948,member0949,member0950,member0951,member0952,member0953,member0954,member0955,member0956,member0957,member0958,member0959,member0960,member0961,member0962,member0963,member0964,member0965,member0966,member0967,member0968,member0969,member0970,member0971,member0972,member0973,member0974,member0975,member0976,member0977,member0978,member0979,member0980,member0981,member0982,member0983,member0984,member0985,member0986,member0987,member0988,member0989,member0990,member0991,member0992,member0993,member0994,member0995,member0996,member0997,member0998,member0999,member1000,
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/passwd b/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/passwd
new file mode 100644
index 0000000000000000000000000000000000000000..5962ad57178ed4bc28df27bda8537b970dedee15
--- /dev/null
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/passwd
@@ -0,0 +1,2 @@
+user:x:12345:23456:gecos:/home/user:/bin/shell
+user_big:x:12346:23457:gecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecosgecos:/home/user_big:/bin/shell
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/test_setup.sh b/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/test_setup.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ad839f340efe989a91cd6902f59c9a41483f68e0
--- /dev/null
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/test_data/test_setup.sh
@@ -0,0 +1,3 @@
+export LD_PRELOAD=$(pkg-config --libs nss_wrapper)
+export NSS_WRAPPER_PASSWD=./test_data/passwd
+export NSS_WRAPPER_GROUP=./test_data/group
-- 
2.1.0

-------------- next part --------------
From 39fcf6c01f8f7b50a4b03456fb7c7b7033d7f704 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Mon, 2 Mar 2015 10:59:34 +0100
Subject: [PATCH 136/136] extdom: make nss buffer configurable

The get*_r_wrapper() calls expect a maximum buffer size to avoid memory
shortage if too many threads try to allocate buffers e.g. for large
groups. With this patch this size can be configured by setting
ipaExtdomMaxNssBufSize in the plugin config object
cn=ipa_extdom_extop,cn=plugins,cn=config.

Related to https://fedorahosted.org/freeipa/ticket/4908
---
 .../ipa-extdom-extop/ipa_extdom.h                  |  1 +
 .../ipa-extdom-extop/ipa_extdom_common.c           | 59 ++++++++++++++--------
 .../ipa-extdom-extop/ipa_extdom_extop.c            | 10 ++++
 3 files changed, 48 insertions(+), 22 deletions(-)

diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
index 3231ee224f159545bb92a5c7433bae09869ad17e..512633f045cba21d3593faa898739684da94b7a4 100644
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom.h
@@ -150,6 +150,7 @@ struct extdom_res {
 struct ipa_extdom_ctx {
     Slapi_ComponentId *plugin_id;
     char *base_dn;
+    size_t max_nss_buf_size;
 };
 
 struct domain_info {
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
index 84aeb28066f25f05a89d0c2d42e8b060e2399501..ea609d1d5d5a1d384ec9fbdb5e5469a90930df17 100644
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
@@ -49,9 +49,6 @@
 
 #define MAX(a,b) (((a)>(b))?(a):(b))
 #define SSSD_DOMAIN_SEPARATOR '@'
-#define MAX_BUF (1024*1024*1024)
-
-
 
 static int get_buffer(size_t *_buf_len, char **_buf)
 {
@@ -496,7 +493,8 @@ static int pack_ber_sid(const char *sid, struct berval **berval)
 
 #define SSSD_SYSDB_SID_STR "objectSIDString"
 
-static int pack_ber_user(enum response_types response_type,
+static int pack_ber_user(struct ipa_extdom_ctx *ctx,
+                         enum response_types response_type,
                          const char *domain_name, const char *user_name,
                          uid_t uid, gid_t gid,
                          const char *gecos, const char *homedir,
@@ -556,7 +554,8 @@ static int pack_ber_user(enum response_types response_type,
         }
 
         for (c = 0; c < ngroups; c++) {
-            ret = getgrgid_r_wrapper(MAX_BUF, groups[c], &grp, &buf, &buf_len);
+            ret = getgrgid_r_wrapper(ctx->max_nss_buf_size,
+                                     groups[c], &grp, &buf, &buf_len);
             if (ret != 0) {
                 ret = LDAP_NO_SUCH_OBJECT;
                 goto done;
@@ -714,7 +713,8 @@ static int pack_ber_name(const char *domain_name, const char *name,
     return LDAP_SUCCESS;
 }
 
-static int handle_uid_request(enum request_types request_type, uid_t uid,
+static int handle_uid_request(struct ipa_extdom_ctx *ctx,
+                              enum request_types request_type, uid_t uid,
                               const char *domain_name, struct berval **berval)
 {
     int ret;
@@ -739,7 +739,8 @@ static int handle_uid_request(enum request_types request_type, uid_t uid,
 
         ret = pack_ber_sid(sid_str, berval);
     } else {
-        ret = getpwuid_r_wrapper(MAX_BUF, uid, &pwd, &buf, &buf_len);
+        ret = getpwuid_r_wrapper(ctx->max_nss_buf_size, uid, &pwd, &buf,
+                                 &buf_len);
         if (ret != 0) {
             ret = LDAP_NO_SUCH_OBJECT;
             goto done;
@@ -758,7 +759,8 @@ static int handle_uid_request(enum request_types request_type, uid_t uid,
             }
         }
 
-        ret = pack_ber_user((request_type == REQ_FULL ? RESP_USER
+        ret = pack_ber_user(ctx,
+                            (request_type == REQ_FULL ? RESP_USER
                                                       : RESP_USER_GROUPLIST),
                             domain_name, pwd.pw_name, pwd.pw_uid,
                             pwd.pw_gid, pwd.pw_gecos, pwd.pw_dir,
@@ -772,7 +774,8 @@ done:
     return ret;
 }
 
-static int handle_gid_request(enum request_types request_type, gid_t gid,
+static int handle_gid_request(struct ipa_extdom_ctx *ctx,
+                              enum request_types request_type, gid_t gid,
                               const char *domain_name, struct berval **berval)
 {
     int ret;
@@ -796,7 +799,8 @@ static int handle_gid_request(enum request_types request_type, gid_t gid,
 
         ret = pack_ber_sid(sid_str, berval);
     } else {
-        ret = getgrgid_r_wrapper(MAX_BUF, gid, &grp, &buf, &buf_len);
+        ret = getgrgid_r_wrapper(ctx->max_nss_buf_size, gid, &grp, &buf,
+                                 &buf_len);
         if (ret != 0) {
             ret = LDAP_NO_SUCH_OBJECT;
             goto done;
@@ -828,7 +832,8 @@ done:
     return ret;
 }
 
-static int handle_sid_request(enum request_types request_type, const char *sid,
+static int handle_sid_request(struct ipa_extdom_ctx *ctx,
+                              enum request_types request_type, const char *sid,
                               struct berval **berval)
 {
     int ret;
@@ -874,7 +879,8 @@ static int handle_sid_request(enum request_types request_type, const char *sid,
     switch(id_type) {
     case SSS_ID_TYPE_UID:
     case SSS_ID_TYPE_BOTH:
-        ret = getpwnam_r_wrapper(MAX_BUF, fq_name, &pwd, &buf, &buf_len);
+        ret = getpwnam_r_wrapper(ctx->max_nss_buf_size, fq_name, &pwd, &buf,
+                                 &buf_len);
         if (ret != 0) {
             ret = LDAP_NO_SUCH_OBJECT;
             goto done;
@@ -893,14 +899,16 @@ static int handle_sid_request(enum request_types request_type, const char *sid,
             }
         }
 
-        ret = pack_ber_user((request_type == REQ_FULL ? RESP_USER
+        ret = pack_ber_user(ctx,
+                            (request_type == REQ_FULL ? RESP_USER
                                                       : RESP_USER_GROUPLIST),
                             domain_name, pwd.pw_name, pwd.pw_uid,
                             pwd.pw_gid, pwd.pw_gecos, pwd.pw_dir,
                             pwd.pw_shell, kv_list, berval);
         break;
     case SSS_ID_TYPE_GID:
-        ret = getgrnam_r_wrapper(MAX_BUF, fq_name, &grp, &buf, &buf_len);
+        ret = getgrnam_r_wrapper(ctx->max_nss_buf_size, fq_name, &grp, &buf,
+                                 &buf_len);
         if (ret != 0) {
             ret = LDAP_NO_SUCH_OBJECT;
             goto done;
@@ -939,7 +947,8 @@ done:
     return ret;
 }
 
-static int handle_name_request(enum request_types request_type,
+static int handle_name_request(struct ipa_extdom_ctx *ctx,
+                               enum request_types request_type,
                                const char *name, const char *domain_name,
                                struct berval **berval)
 {
@@ -975,7 +984,8 @@ static int handle_name_request(enum request_types request_type,
 
         ret = pack_ber_sid(sid_str, berval);
     } else {
-        ret = getpwnam_r_wrapper(MAX_BUF, fq_name, &pwd, &buf, &buf_len);
+        ret = getpwnam_r_wrapper(ctx->max_nss_buf_size, fq_name, &pwd, &buf,
+                                 &buf_len);
         if (ret == 0) {
             if (request_type == REQ_FULL_WITH_GROUPS) {
                 ret = sss_nss_getorigbyname(pwd.pw_name, &kv_list, &id_type);
@@ -989,7 +999,8 @@ static int handle_name_request(enum request_types request_type,
                     goto done;
                 }
             }
-            ret = pack_ber_user((request_type == REQ_FULL ? RESP_USER
+            ret = pack_ber_user(ctx,
+                                (request_type == REQ_FULL ? RESP_USER
                                                           : RESP_USER_GROUPLIST),
                                 domain_name, pwd.pw_name, pwd.pw_uid,
                                 pwd.pw_gid, pwd.pw_gecos, pwd.pw_dir,
@@ -999,7 +1010,8 @@ static int handle_name_request(enum request_types request_type,
              * error codes which can indicate that the user was not found. To
              * be on the safe side we fail back to the group lookup on all
              * errors. */
-            ret = getgrnam_r_wrapper(MAX_BUF, fq_name, &grp, &buf, &buf_len);
+            ret = getgrnam_r_wrapper(ctx->max_nss_buf_size, fq_name, &grp, &buf,
+                                     &buf_len);
             if (ret != 0) {
                 ret = LDAP_NO_SUCH_OBJECT;
                 goto done;
@@ -1041,20 +1053,23 @@ int handle_request(struct ipa_extdom_ctx *ctx, struct extdom_req *req,
 
     switch (req->input_type) {
     case INP_POSIX_UID:
-        ret = handle_uid_request(req->request_type, req->data.posix_uid.uid,
+        ret = handle_uid_request(ctx, req->request_type,
+                                 req->data.posix_uid.uid,
                                  req->data.posix_uid.domain_name, berval);
 
         break;
     case INP_POSIX_GID:
-        ret = handle_gid_request(req->request_type, req->data.posix_gid.gid,
+        ret = handle_gid_request(ctx, req->request_type,
+                                 req->data.posix_gid.gid,
                                  req->data.posix_uid.domain_name, berval);
 
         break;
     case INP_SID:
-        ret = handle_sid_request(req->request_type, req->data.sid, berval);
+        ret = handle_sid_request(ctx, req->request_type, req->data.sid, berval);
         break;
     case INP_NAME:
-        ret = handle_name_request(req->request_type, req->data.name.object_name,
+        ret = handle_name_request(ctx, req->request_type,
+                                  req->data.name.object_name,
                                   req->data.name.domain_name, berval);
 
         break;
diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c
index aa66c145bc6cf2b77fdfe37be18da67588dc0439..e53f968db040a37fbd6a193f87b3671eeabda89d 100644
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_extop.c
@@ -40,6 +40,8 @@
 #include "ipa_extdom.h"
 #include "util.h"
 
+#define DEFAULT_MAX_NSS_BUFFER (128*1024*1024)
+
 Slapi_PluginDesc ipa_extdom_plugin_desc = {
     IPA_EXTDOM_FEATURE_DESC,
     "FreeIPA project",
@@ -185,6 +187,14 @@ static int ipa_extdom_init_ctx(Slapi_PBlock *pb, struct ipa_extdom_ctx **_ctx)
         goto done;
     }
 
+    ctx->max_nss_buf_size = slapi_entry_attr_get_uint(e,
+                                                      "ipaExtdomMaxNssBufSize");
+    if (ctx->max_nss_buf_size == 0) {
+        ctx->max_nss_buf_size = DEFAULT_MAX_NSS_BUFFER;
+    }
+    LOG("Maximal nss buffer size set to [%d]!\n", ctx->max_nss_buf_size);
+
+    ret = 0;
 
 done:
     if (ret) {
-- 
2.1.0



More information about the Freeipa-devel mailing list