mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-01-11 08:41:55 -06:00
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 Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
parent
cc6fc3728c
commit
5bd4b7a09d
@ -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 \
|
||||
|
@ -174,4 +174,13 @@ 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 get_buffer(size_t *_buf_len, char **_buf);
|
||||
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_ */
|
||||
|
@ -0,0 +1,226 @@
|
||||
/*
|
||||
Authors:
|
||||
Sumit Bose <sbose@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 = get_buffer(&buf_len, &buf);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
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 = get_buffer(&buf_len, &buf);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
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), 4000 * strlen("gecos"));
|
||||
assert_string_equal(pwd.pw_dir, "/home/user_big");
|
||||
assert_string_equal(pwd.pw_shell, "/bin/shell");
|
||||
free(buf);
|
||||
|
||||
ret = get_buffer(&buf_len, &buf);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
ret = getpwnam_r_wrapper(1024, "user_big", &pwd, &buf, &buf_len);
|
||||
assert_int_equal(ret, ERANGE);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void test_getpwuid_r_wrapper(void **state)
|
||||
{
|
||||
int ret;
|
||||
struct passwd pwd;
|
||||
char *buf;
|
||||
size_t buf_len;
|
||||
|
||||
ret = get_buffer(&buf_len, &buf);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
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 = get_buffer(&buf_len, &buf);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
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), 4000 * strlen("gecos"));
|
||||
assert_string_equal(pwd.pw_dir, "/home/user_big");
|
||||
assert_string_equal(pwd.pw_shell, "/bin/shell");
|
||||
free(buf);
|
||||
|
||||
ret = get_buffer(&buf_len, &buf);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
ret = getpwuid_r_wrapper(1024, 12346, &pwd, &buf, &buf_len);
|
||||
assert_int_equal(ret, ERANGE);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void test_getgrnam_r_wrapper(void **state)
|
||||
{
|
||||
int ret;
|
||||
struct group grp;
|
||||
char *buf;
|
||||
size_t buf_len;
|
||||
|
||||
ret = get_buffer(&buf_len, &buf);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
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 = get_buffer(&buf_len, &buf);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
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 = get_buffer(&buf_len, &buf);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
ret = getgrnam_r_wrapper(1024, "group_big", &grp, &buf, &buf_len);
|
||||
assert_int_equal(ret, ERANGE);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
void test_getgrgid_r_wrapper(void **state)
|
||||
{
|
||||
int ret;
|
||||
struct group grp;
|
||||
char *buf;
|
||||
size_t buf_len;
|
||||
|
||||
ret = get_buffer(&buf_len, &buf);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
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 = get_buffer(&buf_len, &buf);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
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 = get_buffer(&buf_len, &buf);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
ret = getgrgid_r_wrapper(1024, 22222, &grp, &buf, &buf_len);
|
||||
assert_int_equal(ret, ERANGE);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
@ -49,6 +49,188 @@
|
||||
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#define SSSD_DOMAIN_SEPARATOR '@'
|
||||
#define MAX_BUF (1024*1024*1024)
|
||||
|
||||
|
||||
|
||||
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);
|
||||
|
||||
buf_len = MAX(16384, 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 inc_buffer(size_t buf_max, size_t *_buf_len, char **_buf)
|
||||
{
|
||||
size_t tmp_len;
|
||||
char *tmp_buf;
|
||||
|
||||
tmp_buf = *_buf;
|
||||
tmp_len = *_buf_len;
|
||||
|
||||
tmp_len *= 2;
|
||||
if (tmp_len > buf_max) {
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
tmp_buf = realloc(tmp_buf, tmp_len);
|
||||
if (tmp_buf == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
*_buf_len = tmp_len;
|
||||
*_buf = tmp_buf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getpwnam_r_wrapper(size_t buf_max, const char *name,
|
||||
struct passwd *pwd, char **_buf, size_t *_buf_len)
|
||||
{
|
||||
char *buf = NULL;
|
||||
size_t buf_len = 0;
|
||||
int ret;
|
||||
struct passwd *result = NULL;
|
||||
|
||||
buf = *_buf;
|
||||
buf_len = *_buf_len;
|
||||
|
||||
while (buf != NULL
|
||||
&& (ret = getpwnam_r(name, pwd, buf, buf_len, &result)) == ERANGE) {
|
||||
ret = inc_buffer(buf_max, &buf_len, &buf);
|
||||
if (ret != 0) {
|
||||
if (ret == ERANGE) {
|
||||
LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0 && result == NULL) {
|
||||
ret = ENOENT;
|
||||
}
|
||||
|
||||
done:
|
||||
*_buf = buf;
|
||||
*_buf_len = buf_len;
|
||||
|
||||
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;
|
||||
size_t buf_len = 0;
|
||||
int ret;
|
||||
struct passwd *result = NULL;
|
||||
|
||||
buf = *_buf;
|
||||
buf_len = *_buf_len;
|
||||
|
||||
while (buf != NULL
|
||||
&& (ret = getpwuid_r(uid, pwd, buf, buf_len, &result)) == ERANGE) {
|
||||
ret = inc_buffer(buf_max, &buf_len, &buf);
|
||||
if (ret != 0) {
|
||||
if (ret == ERANGE) {
|
||||
LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0 && result == NULL) {
|
||||
ret = ENOENT;
|
||||
}
|
||||
|
||||
done:
|
||||
*_buf = buf;
|
||||
*_buf_len = buf_len;
|
||||
|
||||
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;
|
||||
size_t buf_len = 0;
|
||||
int ret;
|
||||
struct group *result = NULL;
|
||||
|
||||
buf = *_buf;
|
||||
buf_len = *_buf_len;
|
||||
|
||||
while (buf != NULL
|
||||
&& (ret = getgrnam_r(name, grp, buf, buf_len, &result)) == ERANGE) {
|
||||
ret = inc_buffer(buf_max, &buf_len, &buf);
|
||||
if (ret != 0) {
|
||||
if (ret == ERANGE) {
|
||||
LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0 && result == NULL) {
|
||||
ret = ENOENT;
|
||||
}
|
||||
|
||||
done:
|
||||
*_buf = buf;
|
||||
*_buf_len = buf_len;
|
||||
|
||||
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;
|
||||
size_t buf_len = 0;
|
||||
int ret;
|
||||
struct group *result = NULL;
|
||||
|
||||
buf = *_buf;
|
||||
buf_len = *_buf_len;
|
||||
|
||||
while (buf != NULL
|
||||
&& (ret = getgrgid_r(gid, grp, buf, buf_len, &result)) == ERANGE) {
|
||||
ret = inc_buffer(buf_max, &buf_len, &buf);
|
||||
if (ret != 0) {
|
||||
if (ret == ERANGE) {
|
||||
LOG("Buffer too small, increase ipaExtdomMaxNssBufSize.\n");
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0 && result == NULL) {
|
||||
ret = ENOENT;
|
||||
}
|
||||
|
||||
done:
|
||||
*_buf = buf;
|
||||
*_buf_len = buf_len;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int parse_request_data(struct berval *req_val, struct extdom_req **_req)
|
||||
{
|
||||
@ -191,33 +373,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 +478,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;
|
||||
@ -375,13 +529,13 @@ 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;
|
||||
if (ret == ENOMEM || ret == ERANGE) {
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
} else {
|
||||
ret = LDAP_NO_SUCH_OBJECT;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -542,7 +696,6 @@ 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;
|
||||
@ -568,13 +721,13 @@ 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;
|
||||
if (ret == ENOMEM || ret == ERANGE) {
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
} else {
|
||||
ret = LDAP_NO_SUCH_OBJECT;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -610,7 +763,6 @@ 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;
|
||||
@ -635,13 +787,13 @@ 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;
|
||||
if (ret == ENOMEM || ret == ERANGE) {
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
} else {
|
||||
ret = LDAP_NO_SUCH_OBJECT;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -676,9 +828,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;
|
||||
@ -724,14 +874,13 @@ 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(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;
|
||||
if (ret == ENOMEM || ret == ERANGE) {
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
} else {
|
||||
ret = LDAP_NO_SUCH_OBJECT;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -755,14 +904,13 @@ 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;
|
||||
if (ret == ENOMEM || ret == ERANGE) {
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
} else {
|
||||
ret = LDAP_NO_SUCH_OBJECT;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -806,9 +954,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;
|
||||
@ -842,15 +988,8 @@ static int handle_name_request(enum request_types request_type,
|
||||
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
|
||||
@ -868,15 +1007,21 @@ static int handle_name_request(enum request_types request_type,
|
||||
domain_name, pwd.pw_name, pwd.pw_uid,
|
||||
pwd.pw_gid, pwd.pw_gecos, pwd.pw_dir,
|
||||
pwd.pw_shell, kv_list, berval);
|
||||
} else if (ret == ENOMEM || ret == ERANGE) {
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
} 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;
|
||||
if (ret == ENOMEM || ret == ERANGE) {
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
} else {
|
||||
ret = LDAP_NO_SUCH_OBJECT;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -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
|
Loading…
Reference in New Issue
Block a user