Backport extended NSS API from upstream master branch
This commit is contained in:
parent
b5c435b10b
commit
7781c9e992
142
0002-sss_client-create-nss_common.h.patch
Normal file
142
0002-sss_client-create-nss_common.h.patch
Normal file
@ -0,0 +1,142 @@
|
||||
From 7449b236523409cc8766fb957d6cba051fdfb483 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Fri, 29 Sep 2017 21:38:54 +0200
|
||||
Subject: [PATCH 02/11] sss_client: create nss_common.h
|
||||
|
||||
This patch makes sss_nss_getpw_readrep() and sss_nss_getgr_readrep()
|
||||
calls which parse SSSD's replies for user and group requests available
|
||||
to other components.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/2478
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
Makefile.am | 1 +
|
||||
src/sss_client/nss_common.h | 43 +++++++++++++++++++++++++++++++++++++++++++
|
||||
src/sss_client/nss_group.c | 10 +++-------
|
||||
src/sss_client/nss_passwd.c | 11 +++--------
|
||||
4 files changed, 50 insertions(+), 15 deletions(-)
|
||||
create mode 100644 src/sss_client/nss_common.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 5483375167d99568e8313c9a0488900419be6ec3..dc2f4b1857ce5bd376544488348731be29b6b293 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -3623,6 +3623,7 @@ libnss_sss_la_SOURCES = \
|
||||
src/sss_client/nss_services.c \
|
||||
src/sss_client/sss_cli.h \
|
||||
src/sss_client/nss_compat.h \
|
||||
+ src/sss_client/nss_common.h \
|
||||
src/sss_client/nss_mc_common.c \
|
||||
src/util/io.c \
|
||||
src/util/murmurhash3.c \
|
||||
diff --git a/src/sss_client/nss_common.h b/src/sss_client/nss_common.h
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e83b4f95a3136b5aa711194a4d37389eebfb607a
|
||||
--- /dev/null
|
||||
+++ b/src/sss_client/nss_common.h
|
||||
@@ -0,0 +1,43 @@
|
||||
+/*
|
||||
+ SSSD
|
||||
+
|
||||
+ Common routines for classical and enhanced NSS interface
|
||||
+
|
||||
+ Authors:
|
||||
+ Sumit Bose <sbose@redhat.com>
|
||||
+
|
||||
+ Copyright (C) Red Hat, Inc 2007
|
||||
+
|
||||
+ This program 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 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 Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public License
|
||||
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+*/
|
||||
+
|
||||
+
|
||||
+
|
||||
+struct sss_nss_pw_rep {
|
||||
+ struct passwd *result;
|
||||
+ char *buffer;
|
||||
+ size_t buflen;
|
||||
+};
|
||||
+
|
||||
+int sss_nss_getpw_readrep(struct sss_nss_pw_rep *pr,
|
||||
+ uint8_t *buf, size_t *len);
|
||||
+
|
||||
+struct sss_nss_gr_rep {
|
||||
+ struct group *result;
|
||||
+ char *buffer;
|
||||
+ size_t buflen;
|
||||
+};
|
||||
+
|
||||
+int sss_nss_getgr_readrep(struct sss_nss_gr_rep *pr,
|
||||
+ uint8_t *buf, size_t *len);
|
||||
diff --git a/src/sss_client/nss_group.c b/src/sss_client/nss_group.c
|
||||
index 0e686af43aeb84a5938315e3922e9fcf2fef4e83..42fba6242d23fc1d52cfd7be10cf10383010f091 100644
|
||||
--- a/src/sss_client/nss_group.c
|
||||
+++ b/src/sss_client/nss_group.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "sss_cli.h"
|
||||
#include "nss_mc.h"
|
||||
+#include "nss_common.h"
|
||||
|
||||
static struct sss_nss_getgrent_data {
|
||||
size_t len;
|
||||
@@ -190,14 +191,9 @@ done:
|
||||
*
|
||||
* FIXME: do we need to pad so that each result is 32 bit aligned ?
|
||||
*/
|
||||
-struct sss_nss_gr_rep {
|
||||
- struct group *result;
|
||||
- char *buffer;
|
||||
- size_t buflen;
|
||||
-};
|
||||
|
||||
-static int sss_nss_getgr_readrep(struct sss_nss_gr_rep *pr,
|
||||
- uint8_t *buf, size_t *len)
|
||||
+int sss_nss_getgr_readrep(struct sss_nss_gr_rep *pr,
|
||||
+ uint8_t *buf, size_t *len)
|
||||
{
|
||||
errno_t ret;
|
||||
size_t i, l, slen, ptmem, pad, dlen, glen;
|
||||
diff --git a/src/sss_client/nss_passwd.c b/src/sss_client/nss_passwd.c
|
||||
index c43f9bc50f43599b541e97f5a5aa60de036a5cdf..61e2a567e684fbc7664b5d425e81cfa28a98e845 100644
|
||||
--- a/src/sss_client/nss_passwd.c
|
||||
+++ b/src/sss_client/nss_passwd.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <string.h>
|
||||
#include "sss_cli.h"
|
||||
#include "nss_mc.h"
|
||||
+#include "nss_common.h"
|
||||
|
||||
static struct sss_nss_getpwent_data {
|
||||
size_t len;
|
||||
@@ -63,14 +64,8 @@ static void sss_nss_getpwent_data_clean(void) {
|
||||
* 8-X: sequence of 5, 0 terminated, strings (name, passwd, gecos, dir, shell)
|
||||
*/
|
||||
|
||||
-struct sss_nss_pw_rep {
|
||||
- struct passwd *result;
|
||||
- char *buffer;
|
||||
- size_t buflen;
|
||||
-};
|
||||
-
|
||||
-static int sss_nss_getpw_readrep(struct sss_nss_pw_rep *pr,
|
||||
- uint8_t *buf, size_t *len)
|
||||
+int sss_nss_getpw_readrep(struct sss_nss_pw_rep *pr,
|
||||
+ uint8_t *buf, size_t *len)
|
||||
{
|
||||
errno_t ret;
|
||||
size_t i, slen, dlen;
|
||||
--
|
||||
2.14.3
|
||||
|
900
0003-nss-idmap-add-nss-like-calls-with-timeout-and-flags.patch
Normal file
900
0003-nss-idmap-add-nss-like-calls-with-timeout-and-flags.patch
Normal file
@ -0,0 +1,900 @@
|
||||
From 5e6622722e84d594298a8324f3685a1bda2b5868 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Fri, 29 Sep 2017 16:16:01 +0200
|
||||
Subject: [PATCH 03/11] nss-idmap: add nss like calls with timeout and flags
|
||||
|
||||
This patch adds new calls to libsss_nss_idmap to get NSS like user and
|
||||
group information directly from SSSD without using the system's NSS
|
||||
interfaces.
|
||||
|
||||
Additionally a timeout and a flags options are added which are not
|
||||
available for system's NSS.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/2478
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
Makefile.am | 22 +-
|
||||
configure.ac | 13 +
|
||||
src/sss_client/common.c | 9 +-
|
||||
src/sss_client/common_private.h | 41 +++
|
||||
src/sss_client/idmap/common_ex.c | 105 +++++++
|
||||
src/sss_client/idmap/sss_nss_ex.c | 402 +++++++++++++++++++++++++++
|
||||
src/sss_client/idmap/sss_nss_idmap.exports | 10 +
|
||||
src/sss_client/idmap/sss_nss_idmap.h | 135 +++++++++
|
||||
src/sss_client/idmap/sss_nss_idmap_private.h | 30 ++
|
||||
9 files changed, 757 insertions(+), 10 deletions(-)
|
||||
create mode 100644 src/sss_client/common_private.h
|
||||
create mode 100644 src/sss_client/idmap/common_ex.c
|
||||
create mode 100644 src/sss_client/idmap/sss_nss_ex.c
|
||||
create mode 100644 src/sss_client/idmap/sss_nss_idmap_private.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index dc2f4b1857ce5bd376544488348731be29b6b293..dd25d1f7ea1be66388aa1b393bac290c4d7501a2 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -1159,13 +1159,28 @@ pkgconfig_DATA += src/sss_client/idmap/sss_nss_idmap.pc
|
||||
libsss_nss_idmap_la_DEPENDENCIES = src/sss_client/idmap/sss_nss_idmap.exports
|
||||
libsss_nss_idmap_la_SOURCES = \
|
||||
src/sss_client/idmap/sss_nss_idmap.c \
|
||||
+ src/sss_client/idmap/sss_nss_ex.c \
|
||||
+ src/sss_client/idmap/sss_nss_idmap_private.h \
|
||||
src/sss_client/common.c \
|
||||
- src/util/strtonum.c
|
||||
+ src/sss_client/idmap/common_ex.c \
|
||||
+ src/sss_client/nss_mc_passwd.c \
|
||||
+ src/sss_client/nss_passwd.c \
|
||||
+ src/sss_client/nss_mc_group.c \
|
||||
+ src/sss_client/nss_group.c \
|
||||
+ src/sss_client/nss_mc_initgr.c \
|
||||
+ src/sss_client/nss_mc_common.c \
|
||||
+ src/util/strtonum.c \
|
||||
+ src/util/murmurhash3.c \
|
||||
+ src/util/io.c \
|
||||
+ $(NULL)
|
||||
libsss_nss_idmap_la_LIBADD = \
|
||||
- $(CLIENT_LIBS)
|
||||
+ $(LIBCLOCK_GETTIME) \
|
||||
+ $(CLIENT_LIBS) \
|
||||
+ -lpthread \
|
||||
+ $(NULL)
|
||||
libsss_nss_idmap_la_LDFLAGS = \
|
||||
-Wl,--version-script,$(srcdir)/src/sss_client/idmap/sss_nss_idmap.exports \
|
||||
- -version-info 3:0:3
|
||||
+ -version-info 4:0:4
|
||||
|
||||
dist_noinst_DATA += src/sss_client/idmap/sss_nss_idmap.exports
|
||||
|
||||
@@ -3624,6 +3639,7 @@ libnss_sss_la_SOURCES = \
|
||||
src/sss_client/sss_cli.h \
|
||||
src/sss_client/nss_compat.h \
|
||||
src/sss_client/nss_common.h \
|
||||
+ src/sss_client/common_private.h \
|
||||
src/sss_client/nss_mc_common.c \
|
||||
src/util/io.c \
|
||||
src/util/murmurhash3.c \
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 7037927b5f7045b29d3774c85758e00e35e6def6..7e699d33e342c70d210d3f320c8a29a99e0c78a6 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -75,6 +75,19 @@ AC_SEARCH_LIBS([timer_create], [rt posix4],
|
||||
AC_SUBST([LIBADD_TIMER])
|
||||
LIBS=$SAVE_LIBS
|
||||
|
||||
+# Check library for the clock_gettime function
|
||||
+SAVE_LIBS=$LIBS
|
||||
+LIBS=
|
||||
+LIBCLOCK_GETTIME=
|
||||
+AC_SEARCH_LIBS([clock_gettime], [rt posix4],
|
||||
+ [AC_DEFINE([HAVE_LIBRT], [1],
|
||||
+ [Define if you have the librt library or equivalent.])
|
||||
+ LIBCLOCK_GETTIME="$LIBS"],
|
||||
+ [AC_MSG_ERROR([unable to find library for the clock_gettime() function])])
|
||||
+
|
||||
+AC_SUBST([LIBCLOCK_GETTIME])
|
||||
+LIBS=$SAVE_LIBS
|
||||
+
|
||||
# Check for presence of modern functions for setting file timestamps
|
||||
AC_CHECK_FUNCS([ utimensat \
|
||||
futimens ])
|
||||
diff --git a/src/sss_client/common.c b/src/sss_client/common.c
|
||||
index e5e0cbf854e4c977c03f9b1ca1ac90bfd8cbdb77..40252a35281dc4e94c712c3e7f8253af8b19b35a 100644
|
||||
--- a/src/sss_client/common.c
|
||||
+++ b/src/sss_client/common.c
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <libintl.h>
|
||||
#define _(STRING) dgettext (PACKAGE, STRING)
|
||||
#include "sss_cli.h"
|
||||
+#include "common_private.h"
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
#include <pthread.h>
|
||||
@@ -1113,13 +1114,7 @@ errno_t sss_strnlen(const char *str, size_t maxlen, size_t *len)
|
||||
#if HAVE_PTHREAD
|
||||
typedef void (*sss_mutex_init)(void);
|
||||
|
||||
-struct sss_mutex {
|
||||
- pthread_mutex_t mtx;
|
||||
-
|
||||
- int old_cancel_state;
|
||||
-};
|
||||
-
|
||||
-static struct sss_mutex sss_nss_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER };
|
||||
+struct sss_mutex sss_nss_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER };
|
||||
|
||||
static struct sss_mutex sss_pam_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER };
|
||||
|
||||
diff --git a/src/sss_client/common_private.h b/src/sss_client/common_private.h
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a98d2c062caeecdbab02ecdaa6ae44d688a791bb
|
||||
--- /dev/null
|
||||
+++ b/src/sss_client/common_private.h
|
||||
@@ -0,0 +1,41 @@
|
||||
+/*
|
||||
+ SSSD
|
||||
+
|
||||
+ SSS client - private calls
|
||||
+
|
||||
+ Authors:
|
||||
+ Sumit Bose <sbose@redhat.com>
|
||||
+
|
||||
+ Copyright (C) 2017 Red Hat
|
||||
+
|
||||
+ 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/>.
|
||||
+*/
|
||||
+
|
||||
+#ifndef COMMON_PRIVATE_H_
|
||||
+#define COMMON_PRIVATE_H_
|
||||
+
|
||||
+#include "config.h"
|
||||
+
|
||||
+#if HAVE_PTHREAD
|
||||
+#include <pthread.h>
|
||||
+
|
||||
+struct sss_mutex {
|
||||
+ pthread_mutex_t mtx;
|
||||
+
|
||||
+ int old_cancel_state;
|
||||
+};
|
||||
+
|
||||
+#endif /* HAVE_PTHREAD */
|
||||
+
|
||||
+#endif /* COMMON_PRIVATE_H_ */
|
||||
diff --git a/src/sss_client/idmap/common_ex.c b/src/sss_client/idmap/common_ex.c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5efe9fabed7896ce674615472dbb256c4eae2144
|
||||
--- /dev/null
|
||||
+++ b/src/sss_client/idmap/common_ex.c
|
||||
@@ -0,0 +1,105 @@
|
||||
+/*
|
||||
+ Authors:
|
||||
+ Sumit Bose <sbose@redhat.com>
|
||||
+
|
||||
+ Copyright (C) 2017 Red Hat
|
||||
+
|
||||
+ SSSD's enhanced NSS API
|
||||
+
|
||||
+ 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 <time.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include "sss_cli.h"
|
||||
+#include "common_private.h"
|
||||
+
|
||||
+extern struct sss_mutex sss_nss_mtx;
|
||||
+
|
||||
+#define SEC_FROM_MSEC(ms) ((ms) / 1000)
|
||||
+#define NSEC_FROM_MSEC(ms) (((ms) % 1000) * 1000 * 1000)
|
||||
+
|
||||
+/* adopted from timersub() defined in /usr/include/sys/time.h */
|
||||
+#define TIMESPECSUB(a, b, result) \
|
||||
+ do { \
|
||||
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
|
||||
+ (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \
|
||||
+ if ((result)->tv_nsec < 0) { \
|
||||
+ --(result)->tv_sec; \
|
||||
+ (result)->tv_nsec += 1000000000; \
|
||||
+ } \
|
||||
+ } while (0)
|
||||
+
|
||||
+#define TIMESPEC_TO_MS(ts) ( ((ts)->tv_sec * 1000) \
|
||||
+ + ((ts)->tv_nsec) / (1000 * 1000) )
|
||||
+
|
||||
+static int sss_mt_timedlock(struct sss_mutex *m, struct timespec *endtime)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = pthread_mutex_timedlock(&m->mtx, endtime);
|
||||
+ if (ret != 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &m->old_cancel_state);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int sss_nss_timedlock(unsigned int timeout_ms, int *time_left_ms)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int left;
|
||||
+ struct timespec starttime;
|
||||
+ struct timespec endtime;
|
||||
+ struct timespec diff;
|
||||
+
|
||||
+ /* make sure there is no overrun when calculating the time left */
|
||||
+ if (timeout_ms > INT_MAX) {
|
||||
+ timeout_ms = INT_MAX;
|
||||
+ }
|
||||
+
|
||||
+ ret = clock_gettime(CLOCK_REALTIME, &starttime);
|
||||
+ if (ret != 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ endtime.tv_sec = starttime.tv_sec + SEC_FROM_MSEC(timeout_ms);
|
||||
+ endtime.tv_nsec = starttime.tv_nsec + NSEC_FROM_MSEC(timeout_ms);
|
||||
+
|
||||
+ ret = sss_mt_timedlock(&sss_nss_mtx, &endtime);
|
||||
+
|
||||
+ if (ret == 0) {
|
||||
+ ret = clock_gettime(CLOCK_REALTIME, &endtime);
|
||||
+ if (ret != 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (timeout_ms == 0) {
|
||||
+ *time_left_ms = 0;
|
||||
+ } else {
|
||||
+ TIMESPECSUB(&endtime, &starttime, &diff);
|
||||
+ left = timeout_ms - TIMESPEC_TO_MS(&diff);
|
||||
+ if (left <= 0) {
|
||||
+ return EIO;
|
||||
+ } else if (left > SSS_CLI_SOCKET_TIMEOUT) {
|
||||
+ *time_left_ms = SSS_CLI_SOCKET_TIMEOUT;
|
||||
+ } else {
|
||||
+ *time_left_ms = left;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..582d1373ec35305cf128e04fd3d705457d304789
|
||||
--- /dev/null
|
||||
+++ b/src/sss_client/idmap/sss_nss_ex.c
|
||||
@@ -0,0 +1,402 @@
|
||||
+/*
|
||||
+ SSSD
|
||||
+
|
||||
+ Extended NSS Responder Interface
|
||||
+
|
||||
+ Authors:
|
||||
+ Sumit Bose <sbose@redhat.com>
|
||||
+
|
||||
+ Copyright (C) 2017 Red Hat
|
||||
+
|
||||
+ 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 <stdlib.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include <sys/param.h> /* for MIN() */
|
||||
+
|
||||
+#include "sss_client/sss_cli.h"
|
||||
+#include "sss_client/nss_mc.h"
|
||||
+#include "sss_client/nss_common.h"
|
||||
+#include "sss_client/idmap/sss_nss_idmap.h"
|
||||
+#include "sss_client/idmap/sss_nss_idmap_private.h"
|
||||
+
|
||||
+#ifndef discard_const
|
||||
+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
|
||||
+#endif
|
||||
+
|
||||
+struct sss_nss_initgr_rep {
|
||||
+ gid_t *groups;
|
||||
+ long int *ngroups;
|
||||
+ long int *start;
|
||||
+};
|
||||
+
|
||||
+struct nss_input {
|
||||
+ union {
|
||||
+ const char *name;
|
||||
+ uid_t uid;
|
||||
+ gid_t gid;
|
||||
+ } input;
|
||||
+ struct sss_cli_req_data rd;
|
||||
+ enum sss_cli_command cmd;
|
||||
+ union {
|
||||
+ struct sss_nss_pw_rep pwrep;
|
||||
+ struct sss_nss_gr_rep grrep;
|
||||
+ struct sss_nss_initgr_rep initgrrep;
|
||||
+ } result;
|
||||
+};
|
||||
+
|
||||
+errno_t sss_nss_mc_get(struct nss_input *inp)
|
||||
+{
|
||||
+ switch(inp->cmd) {
|
||||
+ case SSS_NSS_GETPWNAM:
|
||||
+ return sss_nss_mc_getpwnam(inp->input.name, (inp->rd.len - 1),
|
||||
+ inp->result.pwrep.result,
|
||||
+ inp->result.pwrep.buffer,
|
||||
+ inp->result.pwrep.buflen);
|
||||
+ break;
|
||||
+ case SSS_NSS_GETPWUID:
|
||||
+ return sss_nss_mc_getpwuid(inp->input.uid,
|
||||
+ inp->result.pwrep.result,
|
||||
+ inp->result.pwrep.buffer,
|
||||
+ inp->result.pwrep.buflen);
|
||||
+ break;
|
||||
+ case SSS_NSS_GETGRNAM:
|
||||
+ return sss_nss_mc_getgrnam(inp->input.name, (inp->rd.len - 1),
|
||||
+ inp->result.grrep.result,
|
||||
+ inp->result.grrep.buffer,
|
||||
+ inp->result.grrep.buflen);
|
||||
+ break;
|
||||
+ case SSS_NSS_GETGRGID:
|
||||
+ return sss_nss_mc_getgrgid(inp->input.gid,
|
||||
+ inp->result.grrep.result,
|
||||
+ inp->result.grrep.buffer,
|
||||
+ inp->result.grrep.buflen);
|
||||
+ break;
|
||||
+ case SSS_NSS_INITGR:
|
||||
+ return sss_nss_mc_initgroups_dyn(inp->input.name, (inp->rd.len - 1),
|
||||
+ -1 /* currently ignored */,
|
||||
+ inp->result.initgrrep.start,
|
||||
+ inp->result.initgrrep.ngroups,
|
||||
+ &(inp->result.initgrrep.groups),
|
||||
+ *(inp->result.initgrrep.ngroups));
|
||||
+ break;
|
||||
+ default:
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
|
||||
+{
|
||||
+ uint8_t *repbuf = NULL;
|
||||
+ size_t replen;
|
||||
+ size_t len;
|
||||
+ uint32_t num_results;
|
||||
+ int ret;
|
||||
+ int time_left;
|
||||
+ int errnop;
|
||||
+ size_t c;
|
||||
+ gid_t *new_groups;
|
||||
+ size_t idx;
|
||||
+
|
||||
+ ret = sss_nss_mc_get(inp);
|
||||
+ switch (ret) {
|
||||
+ case 0:
|
||||
+ return 0;
|
||||
+ case ERANGE:
|
||||
+ return ERANGE;
|
||||
+ case ENOENT:
|
||||
+ /* fall through, we need to actively ask the parent
|
||||
+ * if no entry is found */
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* if using the mmaped cache failed,
|
||||
+ * fall back to socket based comms */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ sss_nss_timedlock(timeout, &time_left);
|
||||
+
|
||||
+ /* previous thread might already initialize entry in mmap cache */
|
||||
+ ret = sss_nss_mc_get(inp);
|
||||
+ switch (ret) {
|
||||
+ case 0:
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
+ case ERANGE:
|
||||
+ ret = ERANGE;
|
||||
+ goto out;
|
||||
+ case ENOENT:
|
||||
+ /* fall through, we need to actively ask the parent
|
||||
+ * if no entry is found */
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* if using the mmaped cache failed,
|
||||
+ * fall back to socket based comms */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_nss_make_request_timeout(inp->cmd, &inp->rd, time_left,
|
||||
+ &repbuf, &replen, &errnop);
|
||||
+ if (ret != NSS_STATUS_SUCCESS) {
|
||||
+ ret = errnop != 0 ? errnop : EIO;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* Get number of results from repbuf. */
|
||||
+ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL);
|
||||
+
|
||||
+ /* no results if not found */
|
||||
+ if (num_results == 0) {
|
||||
+ ret = ENOENT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (inp->cmd == SSS_NSS_INITGR) {
|
||||
+ if ((*(inp->result.initgrrep.ngroups) - *(inp->result.initgrrep.start))
|
||||
+ < num_results) {
|
||||
+ new_groups = realloc(inp->result.initgrrep.groups,
|
||||
+ (num_results + *(inp->result.initgrrep.start))
|
||||
+ * sizeof(gid_t));
|
||||
+ if (new_groups == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ inp->result.initgrrep.groups = new_groups;
|
||||
+ }
|
||||
+ *(inp->result.initgrrep.ngroups) = num_results
|
||||
+ + *(inp->result.initgrrep.start);
|
||||
+
|
||||
+ idx = 2 * sizeof(uint32_t);
|
||||
+ for (c = 0; c < num_results; c++) {
|
||||
+ SAFEALIGN_COPY_UINT32(
|
||||
+ &(inp->result.initgrrep.groups[*(inp->result.initgrrep.start)]),
|
||||
+ repbuf + idx, &idx);
|
||||
+ *(inp->result.initgrrep.start) += 1;
|
||||
+ }
|
||||
+
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* only 1 result is accepted for this function */
|
||||
+ if (num_results != 1) {
|
||||
+ ret = EBADMSG;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ len = replen - 8;
|
||||
+ if (inp->cmd == SSS_NSS_GETPWNAM || inp->cmd == SSS_NSS_GETPWUID) {
|
||||
+ ret = sss_nss_getpw_readrep(&(inp->result.pwrep), repbuf+8, &len);
|
||||
+ } else if (inp->cmd == SSS_NSS_GETGRNAM || inp->cmd == SSS_NSS_GETGRGID) {
|
||||
+ ret = sss_nss_getgr_readrep(&(inp->result.grrep), repbuf+8, &len);
|
||||
+ } else {
|
||||
+ ret = EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (ret) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (len == 0) {
|
||||
+ /* no extra data */
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ free(repbuf);
|
||||
+
|
||||
+ sss_nss_unlock();
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd,
|
||||
+ char *buffer, size_t buflen,
|
||||
+ struct passwd **result,
|
||||
+ uint32_t flags, unsigned int timeout)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct nss_input inp = {
|
||||
+ .input.name = name,
|
||||
+ .cmd = SSS_NSS_GETPWNAM,
|
||||
+ .rd.data = name,
|
||||
+ .result.pwrep.result = pwd,
|
||||
+ .result.pwrep.buffer = buffer,
|
||||
+ .result.pwrep.buflen = buflen};
|
||||
+
|
||||
+ if (buffer == NULL || buflen == 0) {
|
||||
+ return ERANGE;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len);
|
||||
+ if (ret != 0) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+ inp.rd.len++;
|
||||
+
|
||||
+ *result = NULL;
|
||||
+
|
||||
+ ret = sss_get_ex(&inp, flags, timeout);
|
||||
+ if (ret == 0) {
|
||||
+ *result = inp.result.pwrep.result;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd,
|
||||
+ char *buffer, size_t buflen,
|
||||
+ struct passwd **result,
|
||||
+ uint32_t flags, unsigned int timeout)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint32_t user_uid = uid;
|
||||
+ struct nss_input inp = {
|
||||
+ .input.uid = uid,
|
||||
+ .cmd = SSS_NSS_GETPWUID,
|
||||
+ .rd.len = sizeof(uint32_t),
|
||||
+ .rd.data = &user_uid,
|
||||
+ .result.pwrep.result = pwd,
|
||||
+ .result.pwrep.buffer = buffer,
|
||||
+ .result.pwrep.buflen = buflen};
|
||||
+
|
||||
+ if (buffer == NULL || buflen == 0) {
|
||||
+ return ERANGE;
|
||||
+ }
|
||||
+
|
||||
+ *result = NULL;
|
||||
+
|
||||
+ ret = sss_get_ex(&inp, flags, timeout);
|
||||
+ if (ret == 0) {
|
||||
+ *result = inp.result.pwrep.result;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int sss_nss_getgrnam_timeout(const char *name, struct group *grp,
|
||||
+ char *buffer, size_t buflen, struct group **result,
|
||||
+ uint32_t flags, unsigned int timeout)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct nss_input inp = {
|
||||
+ .input.name = name,
|
||||
+ .cmd = SSS_NSS_GETGRNAM,
|
||||
+ .rd.data = name,
|
||||
+ .result.grrep.result = grp,
|
||||
+ .result.grrep.buffer = buffer,
|
||||
+ .result.grrep.buflen = buflen};
|
||||
+
|
||||
+ if (buffer == NULL || buflen == 0) {
|
||||
+ return ERANGE;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len);
|
||||
+ if (ret != 0) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+ inp.rd.len++;
|
||||
+
|
||||
+ *result = NULL;
|
||||
+
|
||||
+ ret = sss_get_ex(&inp, flags, timeout);
|
||||
+ if (ret == 0) {
|
||||
+ *result = inp.result.grrep.result;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp,
|
||||
+ char *buffer, size_t buflen, struct group **result,
|
||||
+ uint32_t flags, unsigned int timeout)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint32_t group_gid = gid;
|
||||
+ struct nss_input inp = {
|
||||
+ .input.gid = gid,
|
||||
+ .cmd = SSS_NSS_GETGRGID,
|
||||
+ .rd.len = sizeof(uint32_t),
|
||||
+ .rd.data = &group_gid,
|
||||
+ .result.grrep.result = grp,
|
||||
+ .result.grrep.buffer = buffer,
|
||||
+ .result.grrep.buflen = buflen};
|
||||
+
|
||||
+ if (buffer == NULL || buflen == 0) {
|
||||
+ return ERANGE;
|
||||
+ }
|
||||
+
|
||||
+ *result = NULL;
|
||||
+
|
||||
+ ret = sss_get_ex(&inp, flags, timeout);
|
||||
+ if (ret == 0) {
|
||||
+ *result = inp.result.grrep.result;
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int sss_nss_getgrouplist_timeout(const char *name, gid_t group,
|
||||
+ gid_t *groups, int *ngroups,
|
||||
+ uint32_t flags, unsigned int timeout)
|
||||
+{
|
||||
+ int ret;
|
||||
+ gid_t *new_groups;
|
||||
+ long int new_ngroups;
|
||||
+ long int start = 1;
|
||||
+ struct nss_input inp = {
|
||||
+ .input.name = name,
|
||||
+ .cmd = SSS_NSS_INITGR,
|
||||
+ .rd.data = name};
|
||||
+
|
||||
+ if (groups == NULL || ngroups == NULL || *ngroups == 0) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len);
|
||||
+ if (ret != 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ inp.rd.len++;
|
||||
+
|
||||
+ new_ngroups = MAX(1, *ngroups);
|
||||
+ new_groups = malloc(new_ngroups * sizeof(gid_t));
|
||||
+ if (new_groups == NULL) {
|
||||
+ free(discard_const(inp.rd.data));
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+ new_groups[0] = group;
|
||||
+
|
||||
+ inp.result.initgrrep.groups = new_groups,
|
||||
+ inp.result.initgrrep.ngroups = &new_ngroups;
|
||||
+ inp.result.initgrrep.start = &start;
|
||||
+
|
||||
+
|
||||
+ ret = sss_get_ex(&inp, flags, timeout);
|
||||
+ free(discard_const(inp.rd.data));
|
||||
+ if (ret != 0) {
|
||||
+ free(new_groups);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(groups, new_groups, MIN(*ngroups, start) * sizeof(gid_t));
|
||||
+ free(new_groups);
|
||||
+
|
||||
+ if (start > *ngroups) {
|
||||
+ ret = ERANGE;
|
||||
+ } else {
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ *ngroups = start;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/src/sss_client/idmap/sss_nss_idmap.exports b/src/sss_client/idmap/sss_nss_idmap.exports
|
||||
index 49dac6fc9351b0ca98cd46e83b85ec8ef0075a0d..788d05ecc3bd56fa88e68a98b9c8096cf7140a09 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_idmap.exports
|
||||
+++ b/src/sss_client/idmap/sss_nss_idmap.exports
|
||||
@@ -31,3 +31,13 @@ SSS_NSS_IDMAP_0.3.0 {
|
||||
global:
|
||||
sss_nss_getlistbycert;
|
||||
} SSS_NSS_IDMAP_0.2.0;
|
||||
+
|
||||
+SSS_NSS_IDMAP_0.4.0 {
|
||||
+ # public functions
|
||||
+ global:
|
||||
+ sss_nss_getpwnam_timeout;
|
||||
+ sss_nss_getpwuid_timeout;
|
||||
+ sss_nss_getgrnam_timeout;
|
||||
+ sss_nss_getgrgid_timeout;
|
||||
+ sss_nss_getgrouplist_timeout;
|
||||
+} SSS_NSS_IDMAP_0.3.0;
|
||||
diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h
|
||||
index cbf19479ff9ec6e0d6e07e1f7e48a1571e147740..2334b6cb3fb8ef62e4ce3a7187c7affaeaa034e7 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_idmap.h
|
||||
+++ b/src/sss_client/idmap/sss_nss_idmap.h
|
||||
@@ -26,6 +26,9 @@
|
||||
#define SSS_NSS_IDMAP_H_
|
||||
|
||||
#include <stdint.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <pwd.h>
|
||||
+#include <grp.h>
|
||||
|
||||
/**
|
||||
* Object types
|
||||
@@ -159,4 +162,136 @@ int sss_nss_getlistbycert(const char *cert, char ***fq_name,
|
||||
* @param[in] kv_list Key-value list returned by sss_nss_getorigbyname().
|
||||
*/
|
||||
void sss_nss_free_kv(struct sss_nss_kv *kv_list);
|
||||
+
|
||||
+/**
|
||||
+ * Flags to control the behavior and the results for sss_*_ex() calls
|
||||
+ */
|
||||
+
|
||||
+#define SSS_NSS_EX_FLAG_NO_FLAGS 0
|
||||
+
|
||||
+#ifdef IPA_389DS_PLUGIN_HELPER_CALLS
|
||||
+
|
||||
+/**
|
||||
+ * @brief Return user information based on the user name
|
||||
+ *
|
||||
+ * @param[in] name same as for getpwnam_r(3)
|
||||
+ * @param[in] pwd same as for getpwnam_r(3)
|
||||
+ * @param[in] buffer same as for getpwnam_r(3)
|
||||
+ * @param[in] buflen same as for getpwnam_r(3)
|
||||
+ * @param[out] result same as for getpwnam_r(3)
|
||||
+ * @param[in] flags flags to control the behavior and the results of the
|
||||
+ * call
|
||||
+ * @param[in] timeout timeout in milliseconds
|
||||
+ *
|
||||
+ * @return
|
||||
+ * - 0:
|
||||
+ * - ENOENT: no user with the given name found
|
||||
+ * - ERANGE: Insufficient buffer space supplied
|
||||
+ * - ETIME: request timed out but was send to SSSD
|
||||
+ * - ETIMEDOUT: request timed out but was not send to SSSD
|
||||
+ */
|
||||
+int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd,
|
||||
+ char *buffer, size_t buflen,
|
||||
+ struct passwd **result,
|
||||
+ uint32_t flags, unsigned int timeout);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Return user information based on the user uid
|
||||
+ *
|
||||
+ * @param[in] uid same as for getpwuid_r(3)
|
||||
+ * @param[in] pwd same as for getpwuid_r(3)
|
||||
+ * @param[in] buffer same as for getpwuid_r(3)
|
||||
+ * @param[in] buflen same as for getpwuid_r(3)
|
||||
+ * @param[out] result same as for getpwuid_r(3)
|
||||
+ * @param[in] flags flags to control the behavior and the results of the
|
||||
+ * call
|
||||
+ * @param[in] timeout timeout in milliseconds
|
||||
+ *
|
||||
+ * @return
|
||||
+ * - 0:
|
||||
+ * - ENOENT: no user with the given uid found
|
||||
+ * - ERANGE: Insufficient buffer space supplied
|
||||
+ * - ETIME: request timed out but was send to SSSD
|
||||
+ * - ETIMEDOUT: request timed out but was not send to SSSD
|
||||
+ */
|
||||
+int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd,
|
||||
+ char *buffer, size_t buflen,
|
||||
+ struct passwd **result,
|
||||
+ uint32_t flags, unsigned int timeout);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Return group information based on the group name
|
||||
+ *
|
||||
+ * @param[in] name same as for getgrnam_r(3)
|
||||
+ * @param[in] pwd same as for getgrnam_r(3)
|
||||
+ * @param[in] buffer same as for getgrnam_r(3)
|
||||
+ * @param[in] buflen same as for getgrnam_r(3)
|
||||
+ * @param[out] result same as for getgrnam_r(3)
|
||||
+ * @param[in] flags flags to control the behavior and the results of the
|
||||
+ * call
|
||||
+ * @param[in] timeout timeout in milliseconds
|
||||
+ *
|
||||
+ * @return
|
||||
+ * - 0:
|
||||
+ * - ENOENT: no group with the given name found
|
||||
+ * - ERANGE: Insufficient buffer space supplied
|
||||
+ * - ETIME: request timed out but was send to SSSD
|
||||
+ * - ETIMEDOUT: request timed out but was not send to SSSD
|
||||
+ */
|
||||
+int sss_nss_getgrnam_timeout(const char *name, struct group *grp,
|
||||
+ char *buffer, size_t buflen, struct group **result,
|
||||
+ uint32_t flags, unsigned int timeout);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Return group information based on the group gid
|
||||
+ *
|
||||
+ * @param[in] gid same as for getgrgid_r(3)
|
||||
+ * @param[in] pwd same as for getgrgid_r(3)
|
||||
+ * @param[in] buffer same as for getgrgid_r(3)
|
||||
+ * @param[in] buflen same as for getgrgid_r(3)
|
||||
+ * @param[out] result same as for getgrgid_r(3)
|
||||
+ * @param[in] flags flags to control the behavior and the results of the
|
||||
+ * call
|
||||
+ * @param[in] timeout timeout in milliseconds
|
||||
+ *
|
||||
+ * @return
|
||||
+ * - 0:
|
||||
+ * - ENOENT: no group with the given gid found
|
||||
+ * - ERANGE: Insufficient buffer space supplied
|
||||
+ * - ETIME: request timed out but was send to SSSD
|
||||
+ * - ETIMEDOUT: request timed out but was not send to SSSD
|
||||
+ */
|
||||
+int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp,
|
||||
+ char *buffer, size_t buflen, struct group **result,
|
||||
+ uint32_t flags, unsigned int timeout);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Return a list of groups to which a user belongs
|
||||
+ *
|
||||
+ * @param[in] name name of the user
|
||||
+ * @param[in] group same as second argument of getgrouplist(3)
|
||||
+ * @param[in] groups array of gid_t of size ngroups, will be filled
|
||||
+ * with GIDs of groups the user belongs to
|
||||
+ * @param[in,out] ngroups size of the groups array on input. On output it
|
||||
+ * will contain the actual number of groups the
|
||||
+ * user belongs to. With a return value of 0 the
|
||||
+ * groups array was large enough to hold all group.
|
||||
+ * With a return valu of ERANGE the array was not
|
||||
+ * large enough and ngroups will have the needed
|
||||
+ * size.
|
||||
+ * @param[in] flags flags to control the behavior and the results of
|
||||
+ * the call
|
||||
+ * @param[in] timeout timeout in milliseconds
|
||||
+ *
|
||||
+ * @return
|
||||
+ * - 0: success
|
||||
+ * - ENOENT: no user with the given name found
|
||||
+ * - ERANGE: Insufficient buffer space supplied
|
||||
+ * - ETIME: request timed out but was send to SSSD
|
||||
+ * - ETIMEDOUT: request timed out but was not send to SSSD
|
||||
+ */
|
||||
+int sss_nss_getgrouplist_timeout(const char *name, gid_t group,
|
||||
+ gid_t *groups, int *ngroups,
|
||||
+ uint32_t flags, unsigned int timeout);
|
||||
+#endif /* IPA_389DS_PLUGIN_HELPER_CALLS */
|
||||
#endif /* SSS_NSS_IDMAP_H_ */
|
||||
diff --git a/src/sss_client/idmap/sss_nss_idmap_private.h b/src/sss_client/idmap/sss_nss_idmap_private.h
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..afcd8e355981b9a2dc29a62bab143756b39ed654
|
||||
--- /dev/null
|
||||
+++ b/src/sss_client/idmap/sss_nss_idmap_private.h
|
||||
@@ -0,0 +1,30 @@
|
||||
+/*
|
||||
+ SSSD
|
||||
+
|
||||
+ NSS Responder ID-mapping interface - private calls
|
||||
+
|
||||
+ Authors:
|
||||
+ Sumit Bose <sbose@redhat.com>
|
||||
+
|
||||
+ Copyright (C) 2017 Red Hat
|
||||
+
|
||||
+ 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/>.
|
||||
+*/
|
||||
+
|
||||
+#ifndef SSS_NSS_IDMAP_PRIVATE_H_
|
||||
+#define SSS_NSS_IDMAP_PRIVATE_H_
|
||||
+
|
||||
+int sss_nss_timedlock(unsigned int timeout_ms, int *time_left_ms);
|
||||
+
|
||||
+#endif /* SSS_NSS_IDMAP_PRIVATE_H_ */
|
||||
--
|
||||
2.14.3
|
||||
|
605
0004-NSS-add-_EX-version-of-some-requests.patch
Normal file
605
0004-NSS-add-_EX-version-of-some-requests.patch
Normal file
@ -0,0 +1,605 @@
|
||||
From cf93f7c2f2031078bbbff095dae01eb4f8deff85 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Wed, 11 Oct 2017 14:54:54 +0200
|
||||
Subject: [PATCH 04/11] NSS: add *_EX version of some requests
|
||||
|
||||
To be able to send the flags to the SSSD responder new request types
|
||||
with an _EX postfix are added which expect and additional 32bit flag
|
||||
field after the name or the id of the requested object.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/2478
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/responder/nss/nss_cmd.c | 76 +++++++++++++++++++++-----
|
||||
src/responder/nss/nss_protocol.c | 81 ++++++++++++++++++++++++++++
|
||||
src/responder/nss/nss_protocol.h | 8 +++
|
||||
src/sss_client/idmap/sss_nss_ex.c | 110 +++++++++++++++++++++++++++-----------
|
||||
src/sss_client/sss_cli.h | 7 +++
|
||||
5 files changed, 237 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c
|
||||
index ebf66dfe0444b83aed20d58d36ddf70d2f4fa1f9..974eaccc93cea3a330007735676da69eb9b84141 100644
|
||||
--- a/src/responder/nss/nss_cmd.c
|
||||
+++ b/src/responder/nss/nss_cmd.c
|
||||
@@ -54,6 +54,7 @@ static void nss_getby_done(struct tevent_req *subreq);
|
||||
static void nss_getlistby_done(struct tevent_req *subreq);
|
||||
|
||||
static errno_t nss_getby_name(struct cli_ctx *cli_ctx,
|
||||
+ bool ex_version,
|
||||
enum cache_req_type type,
|
||||
const char **attrs,
|
||||
enum sss_mc_type memcache,
|
||||
@@ -64,6 +65,7 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx,
|
||||
struct tevent_req *subreq;
|
||||
const char *rawname;
|
||||
errno_t ret;
|
||||
+ uint32_t flags = 0;
|
||||
|
||||
cmd_ctx = nss_cmd_ctx_create(cli_ctx, cli_ctx, type, fill_fn);
|
||||
if (cmd_ctx == NULL) {
|
||||
@@ -71,7 +73,11 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- ret = nss_protocol_parse_name(cli_ctx, &rawname);
|
||||
+ if (ex_version) {
|
||||
+ ret = nss_protocol_parse_name_ex(cli_ctx, &rawname, &flags);
|
||||
+ } else {
|
||||
+ ret = nss_protocol_parse_name(cli_ctx, &rawname);
|
||||
+ }
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request message!\n");
|
||||
goto done;
|
||||
@@ -108,6 +114,7 @@ done:
|
||||
}
|
||||
|
||||
static errno_t nss_getby_id(struct cli_ctx *cli_ctx,
|
||||
+ bool ex_version,
|
||||
enum cache_req_type type,
|
||||
const char **attrs,
|
||||
enum sss_mc_type memcache,
|
||||
@@ -118,6 +125,7 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx,
|
||||
struct tevent_req *subreq;
|
||||
uint32_t id;
|
||||
errno_t ret;
|
||||
+ uint32_t flags = 0;
|
||||
|
||||
cmd_ctx = nss_cmd_ctx_create(cli_ctx, cli_ctx, type, fill_fn);
|
||||
if (cmd_ctx == NULL) {
|
||||
@@ -125,7 +133,11 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- ret = nss_protocol_parse_id(cli_ctx, &id);
|
||||
+ if (ex_version) {
|
||||
+ ret = nss_protocol_parse_id_ex(cli_ctx, &id, &flags);
|
||||
+ } else {
|
||||
+ ret = nss_protocol_parse_id(cli_ctx, &id);
|
||||
+ }
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request message!\n");
|
||||
goto done;
|
||||
@@ -766,14 +778,26 @@ static errno_t nss_endent(struct cli_ctx *cli_ctx,
|
||||
|
||||
static errno_t nss_cmd_getpwnam(struct cli_ctx *cli_ctx)
|
||||
{
|
||||
- return nss_getby_name(cli_ctx, CACHE_REQ_USER_BY_NAME, NULL, SSS_MC_PASSWD,
|
||||
- nss_protocol_fill_pwent);
|
||||
+ return nss_getby_name(cli_ctx, false, CACHE_REQ_USER_BY_NAME, NULL,
|
||||
+ SSS_MC_PASSWD, nss_protocol_fill_pwent);
|
||||
}
|
||||
|
||||
static errno_t nss_cmd_getpwuid(struct cli_ctx *cli_ctx)
|
||||
{
|
||||
- return nss_getby_id(cli_ctx, CACHE_REQ_USER_BY_ID, NULL, SSS_MC_PASSWD,
|
||||
- nss_protocol_fill_pwent);
|
||||
+ return nss_getby_id(cli_ctx, false, CACHE_REQ_USER_BY_ID, NULL,
|
||||
+ SSS_MC_PASSWD, nss_protocol_fill_pwent);
|
||||
+}
|
||||
+
|
||||
+static errno_t nss_cmd_getpwnam_ex(struct cli_ctx *cli_ctx)
|
||||
+{
|
||||
+ return nss_getby_name(cli_ctx, true, CACHE_REQ_USER_BY_NAME, NULL,
|
||||
+ SSS_MC_PASSWD, nss_protocol_fill_pwent);
|
||||
+}
|
||||
+
|
||||
+static errno_t nss_cmd_getpwuid_ex(struct cli_ctx *cli_ctx)
|
||||
+{
|
||||
+ return nss_getby_id(cli_ctx, true, CACHE_REQ_USER_BY_ID, NULL,
|
||||
+ SSS_MC_PASSWD, nss_protocol_fill_pwent);
|
||||
}
|
||||
|
||||
static errno_t nss_cmd_setpwent(struct cli_ctx *cli_ctx)
|
||||
@@ -809,16 +833,29 @@ static errno_t nss_cmd_endpwent(struct cli_ctx *cli_ctx)
|
||||
|
||||
static errno_t nss_cmd_getgrnam(struct cli_ctx *cli_ctx)
|
||||
{
|
||||
- return nss_getby_name(cli_ctx, CACHE_REQ_GROUP_BY_NAME, NULL, SSS_MC_GROUP,
|
||||
- nss_protocol_fill_grent);
|
||||
+ return nss_getby_name(cli_ctx, false, CACHE_REQ_GROUP_BY_NAME, NULL,
|
||||
+ SSS_MC_GROUP, nss_protocol_fill_grent);
|
||||
}
|
||||
|
||||
static errno_t nss_cmd_getgrgid(struct cli_ctx *cli_ctx)
|
||||
{
|
||||
- return nss_getby_id(cli_ctx, CACHE_REQ_GROUP_BY_ID, NULL, SSS_MC_GROUP,
|
||||
- nss_protocol_fill_grent);
|
||||
+ return nss_getby_id(cli_ctx, false, CACHE_REQ_GROUP_BY_ID, NULL,
|
||||
+ SSS_MC_GROUP, nss_protocol_fill_grent);
|
||||
}
|
||||
|
||||
+static errno_t nss_cmd_getgrnam_ex(struct cli_ctx *cli_ctx)
|
||||
+{
|
||||
+ return nss_getby_name(cli_ctx, true, CACHE_REQ_GROUP_BY_NAME, NULL,
|
||||
+ SSS_MC_GROUP, nss_protocol_fill_grent);
|
||||
+}
|
||||
+
|
||||
+static errno_t nss_cmd_getgrgid_ex(struct cli_ctx *cli_ctx)
|
||||
+{
|
||||
+ return nss_getby_id(cli_ctx, true, CACHE_REQ_GROUP_BY_ID, NULL,
|
||||
+ SSS_MC_GROUP, nss_protocol_fill_grent);
|
||||
+}
|
||||
+
|
||||
+
|
||||
static errno_t nss_cmd_setgrent(struct cli_ctx *cli_ctx)
|
||||
{
|
||||
struct nss_ctx *nss_ctx;
|
||||
@@ -852,7 +889,13 @@ static errno_t nss_cmd_endgrent(struct cli_ctx *cli_ctx)
|
||||
|
||||
static errno_t nss_cmd_initgroups(struct cli_ctx *cli_ctx)
|
||||
{
|
||||
- return nss_getby_name(cli_ctx, CACHE_REQ_INITGROUPS, NULL,
|
||||
+ return nss_getby_name(cli_ctx, false, CACHE_REQ_INITGROUPS, NULL,
|
||||
+ SSS_MC_INITGROUPS, nss_protocol_fill_initgr);
|
||||
+}
|
||||
+
|
||||
+static errno_t nss_cmd_initgroups_ex(struct cli_ctx *cli_ctx)
|
||||
+{
|
||||
+ return nss_getby_name(cli_ctx, true, CACHE_REQ_INITGROUPS, NULL,
|
||||
SSS_MC_INITGROUPS, nss_protocol_fill_initgr);
|
||||
}
|
||||
|
||||
@@ -943,7 +986,7 @@ static errno_t nss_cmd_getsidbyname(struct cli_ctx *cli_ctx)
|
||||
{
|
||||
const char *attrs[] = { SYSDB_SID_STR, NULL };
|
||||
|
||||
- return nss_getby_name(cli_ctx, CACHE_REQ_OBJECT_BY_NAME, attrs,
|
||||
+ return nss_getby_name(cli_ctx, false, CACHE_REQ_OBJECT_BY_NAME, attrs,
|
||||
SSS_MC_NONE, nss_protocol_fill_sid);
|
||||
}
|
||||
|
||||
@@ -951,7 +994,7 @@ static errno_t nss_cmd_getsidbyid(struct cli_ctx *cli_ctx)
|
||||
{
|
||||
const char *attrs[] = { SYSDB_SID_STR, NULL };
|
||||
|
||||
- return nss_getby_id(cli_ctx, CACHE_REQ_OBJECT_BY_ID, attrs,
|
||||
+ return nss_getby_id(cli_ctx, false, CACHE_REQ_OBJECT_BY_ID, attrs,
|
||||
SSS_MC_NONE, nss_protocol_fill_sid);
|
||||
}
|
||||
|
||||
@@ -1006,7 +1049,7 @@ static errno_t nss_cmd_getorigbyname(struct cli_ctx *cli_ctx)
|
||||
attrs = defattrs;
|
||||
}
|
||||
|
||||
- return nss_getby_name(cli_ctx, CACHE_REQ_OBJECT_BY_NAME, attrs,
|
||||
+ return nss_getby_name(cli_ctx, false, CACHE_REQ_OBJECT_BY_NAME, attrs,
|
||||
SSS_MC_NONE, nss_protocol_fill_orig);
|
||||
}
|
||||
|
||||
@@ -1051,6 +1094,11 @@ struct sss_cmd_table *get_nss_cmds(void)
|
||||
{ SSS_NSS_GETORIGBYNAME, nss_cmd_getorigbyname },
|
||||
{ SSS_NSS_GETNAMEBYCERT, nss_cmd_getnamebycert },
|
||||
{ SSS_NSS_GETLISTBYCERT, nss_cmd_getlistbycert },
|
||||
+ { SSS_NSS_GETPWNAM_EX, nss_cmd_getpwnam_ex },
|
||||
+ { SSS_NSS_GETPWUID_EX, nss_cmd_getpwuid_ex },
|
||||
+ { SSS_NSS_GETGRNAM_EX, nss_cmd_getgrnam_ex },
|
||||
+ { SSS_NSS_GETGRGID_EX, nss_cmd_getgrgid_ex },
|
||||
+ { SSS_NSS_INITGR_EX, nss_cmd_initgroups_ex },
|
||||
{ SSS_CLI_NULL, NULL }
|
||||
};
|
||||
|
||||
diff --git a/src/responder/nss/nss_protocol.c b/src/responder/nss/nss_protocol.c
|
||||
index 06fc4d00a7877a7990402f4f2633ddc0bd640b41..17bfc4f4e71960a72e9e04622eac95b94a865ec7 100644
|
||||
--- a/src/responder/nss/nss_protocol.c
|
||||
+++ b/src/responder/nss/nss_protocol.c
|
||||
@@ -133,6 +133,61 @@ nss_protocol_parse_name(struct cli_ctx *cli_ctx, const char **_rawname)
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+errno_t
|
||||
+nss_protocol_parse_name_ex(struct cli_ctx *cli_ctx, const char **_rawname,
|
||||
+ uint32_t *_flags)
|
||||
+{
|
||||
+ struct cli_protocol *pctx;
|
||||
+ const char *rawname;
|
||||
+ uint8_t *body;
|
||||
+ size_t blen;
|
||||
+ uint8_t *p;
|
||||
+ uint32_t flags;
|
||||
+
|
||||
+ pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
|
||||
+
|
||||
+ sss_packet_get_body(pctx->creq->in, &body, &blen);
|
||||
+
|
||||
+ if (blen < 1 + sizeof(uint32_t)) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Body too short!\n");
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* If first argument not terminated fail. */
|
||||
+ if (body[blen - 1 - sizeof(uint32_t)] != '\0') {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated!\n");
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ p = memchr(body, '\0', blen);
|
||||
+
|
||||
+ /* If the body isn't valid UTF-8, fail */
|
||||
+ if (!sss_utf8_check(body, (p - body))) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "First argument is not UTF-8 string!\n");
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ rawname = (const char *)body;
|
||||
+ if (rawname[0] == '\0') {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "An empty name was provided!\n");
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ p++;
|
||||
+ if ((p - body) + sizeof(uint32_t) != blen) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Body has unexpected size!\n");
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ SAFEALIGN_COPY_UINT32(&flags, p, NULL);
|
||||
+ p += sizeof(uint32_t);
|
||||
+
|
||||
+ *_rawname = rawname;
|
||||
+ *_flags = flags;
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
errno_t
|
||||
nss_protocol_parse_id(struct cli_ctx *cli_ctx, uint32_t *_id)
|
||||
{
|
||||
@@ -156,6 +211,32 @@ nss_protocol_parse_id(struct cli_ctx *cli_ctx, uint32_t *_id)
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+errno_t
|
||||
+nss_protocol_parse_id_ex(struct cli_ctx *cli_ctx, uint32_t *_id,
|
||||
+ uint32_t *_flags)
|
||||
+{
|
||||
+ struct cli_protocol *pctx;
|
||||
+ uint8_t *body;
|
||||
+ size_t blen;
|
||||
+ uint32_t id;
|
||||
+ uint32_t flags;
|
||||
+
|
||||
+ pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
|
||||
+
|
||||
+ sss_packet_get_body(pctx->creq->in, &body, &blen);
|
||||
+
|
||||
+ if (blen != 2 * sizeof(uint32_t)) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ SAFEALIGN_COPY_UINT32(&id, body, NULL);
|
||||
+ SAFEALIGN_COPY_UINT32(&flags, body + sizeof(uint32_t), NULL);
|
||||
+
|
||||
+ *_id = id;
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
errno_t
|
||||
nss_protocol_parse_limit(struct cli_ctx *cli_ctx, uint32_t *_limit)
|
||||
{
|
||||
diff --git a/src/responder/nss/nss_protocol.h b/src/responder/nss/nss_protocol.h
|
||||
index 417b0891615dcb8771d49f7b2f4d276342ca3150..ca5b040237dc18acdca9a7a3a7a7dbb64265aa95 100644
|
||||
--- a/src/responder/nss/nss_protocol.h
|
||||
+++ b/src/responder/nss/nss_protocol.h
|
||||
@@ -88,9 +88,17 @@ void nss_protocol_reply(struct cli_ctx *cli_ctx,
|
||||
errno_t
|
||||
nss_protocol_parse_name(struct cli_ctx *cli_ctx, const char **_rawname);
|
||||
|
||||
+errno_t
|
||||
+nss_protocol_parse_name_ex(struct cli_ctx *cli_ctx, const char **_rawname,
|
||||
+ uint32_t *_flags);
|
||||
+
|
||||
errno_t
|
||||
nss_protocol_parse_id(struct cli_ctx *cli_ctx, uint32_t *_id);
|
||||
|
||||
+errno_t
|
||||
+nss_protocol_parse_id_ex(struct cli_ctx *cli_ctx, uint32_t *_id,
|
||||
+ uint32_t *_flags);
|
||||
+
|
||||
errno_t
|
||||
nss_protocol_parse_limit(struct cli_ctx *cli_ctx, uint32_t *_limit);
|
||||
|
||||
diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c
|
||||
index 582d1373ec35305cf128e04fd3d705457d304789..dc7610a4e528b5126f0d25d84cd3c1a22f683b75 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_ex.c
|
||||
+++ b/src/sss_client/idmap/sss_nss_ex.c
|
||||
@@ -61,31 +61,37 @@ errno_t sss_nss_mc_get(struct nss_input *inp)
|
||||
{
|
||||
switch(inp->cmd) {
|
||||
case SSS_NSS_GETPWNAM:
|
||||
- return sss_nss_mc_getpwnam(inp->input.name, (inp->rd.len - 1),
|
||||
+ case SSS_NSS_GETPWNAM_EX:
|
||||
+ return sss_nss_mc_getpwnam(inp->input.name, strlen(inp->input.name),
|
||||
inp->result.pwrep.result,
|
||||
inp->result.pwrep.buffer,
|
||||
inp->result.pwrep.buflen);
|
||||
break;
|
||||
case SSS_NSS_GETPWUID:
|
||||
+ case SSS_NSS_GETPWUID_EX:
|
||||
return sss_nss_mc_getpwuid(inp->input.uid,
|
||||
inp->result.pwrep.result,
|
||||
inp->result.pwrep.buffer,
|
||||
inp->result.pwrep.buflen);
|
||||
break;
|
||||
case SSS_NSS_GETGRNAM:
|
||||
- return sss_nss_mc_getgrnam(inp->input.name, (inp->rd.len - 1),
|
||||
+ case SSS_NSS_GETGRNAM_EX:
|
||||
+ return sss_nss_mc_getgrnam(inp->input.name, strlen(inp->input.name),
|
||||
inp->result.grrep.result,
|
||||
inp->result.grrep.buffer,
|
||||
inp->result.grrep.buflen);
|
||||
break;
|
||||
case SSS_NSS_GETGRGID:
|
||||
+ case SSS_NSS_GETGRGID_EX:
|
||||
return sss_nss_mc_getgrgid(inp->input.gid,
|
||||
inp->result.grrep.result,
|
||||
inp->result.grrep.buffer,
|
||||
inp->result.grrep.buflen);
|
||||
break;
|
||||
case SSS_NSS_INITGR:
|
||||
- return sss_nss_mc_initgroups_dyn(inp->input.name, (inp->rd.len - 1),
|
||||
+ case SSS_NSS_INITGR_EX:
|
||||
+ return sss_nss_mc_initgroups_dyn(inp->input.name,
|
||||
+ strlen(inp->input.name),
|
||||
-1 /* currently ignored */,
|
||||
inp->result.initgrrep.start,
|
||||
inp->result.initgrrep.ngroups,
|
||||
@@ -163,7 +169,7 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (inp->cmd == SSS_NSS_INITGR) {
|
||||
+ if (inp->cmd == SSS_NSS_INITGR || inp->cmd == SSS_NSS_INITGR_EX) {
|
||||
if ((*(inp->result.initgrrep.ngroups) - *(inp->result.initgrrep.start))
|
||||
< num_results) {
|
||||
new_groups = realloc(inp->result.initgrrep.groups,
|
||||
@@ -198,15 +204,24 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
|
||||
}
|
||||
|
||||
len = replen - 8;
|
||||
- if (inp->cmd == SSS_NSS_GETPWNAM || inp->cmd == SSS_NSS_GETPWUID) {
|
||||
+
|
||||
+ switch(inp->cmd) {
|
||||
+ case SSS_NSS_GETPWNAM:
|
||||
+ case SSS_NSS_GETPWUID:
|
||||
+ case SSS_NSS_GETPWNAM_EX:
|
||||
+ case SSS_NSS_GETPWUID_EX:
|
||||
ret = sss_nss_getpw_readrep(&(inp->result.pwrep), repbuf+8, &len);
|
||||
- } else if (inp->cmd == SSS_NSS_GETGRNAM || inp->cmd == SSS_NSS_GETGRGID) {
|
||||
+ break;
|
||||
+ case SSS_NSS_GETGRNAM:
|
||||
+ case SSS_NSS_GETGRGID:
|
||||
+ case SSS_NSS_GETGRNAM_EX:
|
||||
+ case SSS_NSS_GETGRGID_EX:
|
||||
ret = sss_nss_getgr_readrep(&(inp->result.grrep), repbuf+8, &len);
|
||||
- } else {
|
||||
+ break;
|
||||
+ default:
|
||||
ret = EINVAL;
|
||||
- goto out;
|
||||
}
|
||||
- if (ret) {
|
||||
+ if (ret != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -223,6 +238,39 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int make_name_flag_req_data(const char *name, uint32_t flags,
|
||||
+ struct sss_cli_req_data *rd)
|
||||
+{
|
||||
+ size_t len;
|
||||
+ size_t name_len;
|
||||
+ uint8_t *data;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (name == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_strnlen(name, SSS_NAME_MAX, &name_len);
|
||||
+ if (ret != 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ name_len++;
|
||||
+
|
||||
+ len = name_len + sizeof(uint32_t);
|
||||
+ data = malloc(len);
|
||||
+ if (data == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(data, name, name_len);
|
||||
+ SAFEALIGN_COPY_UINT32(data + name_len, &flags, NULL);
|
||||
+
|
||||
+ rd->len = len;
|
||||
+ rd->data = data;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd,
|
||||
char *buffer, size_t buflen,
|
||||
struct passwd **result,
|
||||
@@ -231,8 +279,7 @@ int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd,
|
||||
int ret;
|
||||
struct nss_input inp = {
|
||||
.input.name = name,
|
||||
- .cmd = SSS_NSS_GETPWNAM,
|
||||
- .rd.data = name,
|
||||
+ .cmd = SSS_NSS_GETPWNAM_EX,
|
||||
.result.pwrep.result = pwd,
|
||||
.result.pwrep.buffer = buffer,
|
||||
.result.pwrep.buflen = buflen};
|
||||
@@ -241,15 +288,15 @@ int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd,
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
- ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len);
|
||||
+ ret = make_name_flag_req_data(name, flags, &inp.rd);
|
||||
if (ret != 0) {
|
||||
- return EINVAL;
|
||||
+ return ret;
|
||||
}
|
||||
- inp.rd.len++;
|
||||
|
||||
*result = NULL;
|
||||
|
||||
ret = sss_get_ex(&inp, flags, timeout);
|
||||
+ free(discard_const(inp.rd.data));
|
||||
if (ret == 0) {
|
||||
*result = inp.result.pwrep.result;
|
||||
}
|
||||
@@ -262,12 +309,12 @@ int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd,
|
||||
uint32_t flags, unsigned int timeout)
|
||||
{
|
||||
int ret;
|
||||
- uint32_t user_uid = uid;
|
||||
+ uint32_t req_data[2];
|
||||
struct nss_input inp = {
|
||||
.input.uid = uid,
|
||||
- .cmd = SSS_NSS_GETPWUID,
|
||||
- .rd.len = sizeof(uint32_t),
|
||||
- .rd.data = &user_uid,
|
||||
+ .cmd = SSS_NSS_GETPWUID_EX,
|
||||
+ .rd.len = 2 * sizeof(uint32_t),
|
||||
+ .rd.data = &req_data,
|
||||
.result.pwrep.result = pwd,
|
||||
.result.pwrep.buffer = buffer,
|
||||
.result.pwrep.buflen = buflen};
|
||||
@@ -276,6 +323,8 @@ int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd,
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
+ SAFEALIGN_COPY_UINT32(&req_data[0], &uid, NULL);
|
||||
+ SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL);
|
||||
*result = NULL;
|
||||
|
||||
ret = sss_get_ex(&inp, flags, timeout);
|
||||
@@ -292,8 +341,7 @@ int sss_nss_getgrnam_timeout(const char *name, struct group *grp,
|
||||
int ret;
|
||||
struct nss_input inp = {
|
||||
.input.name = name,
|
||||
- .cmd = SSS_NSS_GETGRNAM,
|
||||
- .rd.data = name,
|
||||
+ .cmd = SSS_NSS_GETGRNAM_EX,
|
||||
.result.grrep.result = grp,
|
||||
.result.grrep.buffer = buffer,
|
||||
.result.grrep.buflen = buflen};
|
||||
@@ -302,15 +350,15 @@ int sss_nss_getgrnam_timeout(const char *name, struct group *grp,
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
- ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len);
|
||||
+ ret = make_name_flag_req_data(name, flags, &inp.rd);
|
||||
if (ret != 0) {
|
||||
- return EINVAL;
|
||||
+ return ret;
|
||||
}
|
||||
- inp.rd.len++;
|
||||
|
||||
*result = NULL;
|
||||
|
||||
ret = sss_get_ex(&inp, flags, timeout);
|
||||
+ free(discard_const(inp.rd.data));
|
||||
if (ret == 0) {
|
||||
*result = inp.result.grrep.result;
|
||||
}
|
||||
@@ -322,12 +370,12 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp,
|
||||
uint32_t flags, unsigned int timeout)
|
||||
{
|
||||
int ret;
|
||||
- uint32_t group_gid = gid;
|
||||
+ uint32_t req_data[2];
|
||||
struct nss_input inp = {
|
||||
.input.gid = gid,
|
||||
- .cmd = SSS_NSS_GETGRGID,
|
||||
- .rd.len = sizeof(uint32_t),
|
||||
- .rd.data = &group_gid,
|
||||
+ .cmd = SSS_NSS_GETGRGID_EX,
|
||||
+ .rd.len = 2 * sizeof(uint32_t),
|
||||
+ .rd.data = &req_data,
|
||||
.result.grrep.result = grp,
|
||||
.result.grrep.buffer = buffer,
|
||||
.result.grrep.buflen = buflen};
|
||||
@@ -336,6 +384,8 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp,
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
+ SAFEALIGN_COPY_UINT32(&req_data[0], &gid, NULL);
|
||||
+ SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL);
|
||||
*result = NULL;
|
||||
|
||||
ret = sss_get_ex(&inp, flags, timeout);
|
||||
@@ -355,18 +405,16 @@ int sss_nss_getgrouplist_timeout(const char *name, gid_t group,
|
||||
long int start = 1;
|
||||
struct nss_input inp = {
|
||||
.input.name = name,
|
||||
- .cmd = SSS_NSS_INITGR,
|
||||
- .rd.data = name};
|
||||
+ .cmd = SSS_NSS_INITGR_EX};
|
||||
|
||||
if (groups == NULL || ngroups == NULL || *ngroups == 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
- ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len);
|
||||
+ ret = make_name_flag_req_data(name, flags, &inp.rd);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
- inp.rd.len++;
|
||||
|
||||
new_ngroups = MAX(1, *ngroups);
|
||||
new_groups = malloc(new_ngroups * sizeof(gid_t));
|
||||
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
|
||||
index 5329651a9385d138b8ea7237cb5cf4e2b8e5f371..9d2cc00c9957f5680548461129e3e6b777da5091 100644
|
||||
--- a/src/sss_client/sss_cli.h
|
||||
+++ b/src/sss_client/sss_cli.h
|
||||
@@ -79,6 +79,9 @@ enum sss_cli_command {
|
||||
SSS_NSS_GETPWENT = 0x0014,
|
||||
SSS_NSS_ENDPWENT = 0x0015,
|
||||
|
||||
+ SSS_NSS_GETPWNAM_EX = 0x0019,
|
||||
+ SSS_NSS_GETPWUID_EX = 0x001A,
|
||||
+
|
||||
/* group */
|
||||
|
||||
SSS_NSS_GETGRNAM = 0x0021,
|
||||
@@ -88,6 +91,10 @@ enum sss_cli_command {
|
||||
SSS_NSS_ENDGRENT = 0x0025,
|
||||
SSS_NSS_INITGR = 0x0026,
|
||||
|
||||
+ SSS_NSS_GETGRNAM_EX = 0x0029,
|
||||
+ SSS_NSS_GETGRGID_EX = 0x002A,
|
||||
+ SSS_NSS_INITGR_EX = 0x002E,
|
||||
+
|
||||
#if 0
|
||||
/* aliases */
|
||||
|
||||
--
|
||||
2.14.3
|
||||
|
148
0005-NSS-add-support-for-SSS_NSS_EX_FLAG_NO_CACHE.patch
Normal file
148
0005-NSS-add-support-for-SSS_NSS_EX_FLAG_NO_CACHE.patch
Normal file
@ -0,0 +1,148 @@
|
||||
From ac6b267ff3df6d0417062a128ec16b184ea2c1b7 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Thu, 12 Oct 2017 10:42:41 +0200
|
||||
Subject: [PATCH 05/11] NSS: add support for SSS_NSS_EX_FLAG_NO_CACHE
|
||||
|
||||
If SSS_NSS_EX_FLAG_NO_CACHE is set the object is refresh by directly
|
||||
looking it up in the backend.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/2478
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/responder/nss/nss_cmd.c | 8 ++++
|
||||
src/sss_client/idmap/sss_nss_ex.c | 71 ++++++++++++++++++++----------------
|
||||
src/sss_client/idmap/sss_nss_idmap.h | 4 ++
|
||||
3 files changed, 52 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c
|
||||
index 974eaccc93cea3a330007735676da69eb9b84141..c5ddd2f2cc2122cd169ea991b94a14eb5bad095f 100644
|
||||
--- a/src/responder/nss/nss_cmd.c
|
||||
+++ b/src/responder/nss/nss_cmd.c
|
||||
@@ -92,6 +92,10 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) {
|
||||
+ cache_req_data_set_bypass_cache(data, true);
|
||||
+ }
|
||||
+
|
||||
subreq = nss_get_object_send(cmd_ctx, cli_ctx->ev, cli_ctx,
|
||||
data, memcache, rawname, 0);
|
||||
if (subreq == NULL) {
|
||||
@@ -152,6 +156,10 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) {
|
||||
+ cache_req_data_set_bypass_cache(data, true);
|
||||
+ }
|
||||
+
|
||||
subreq = nss_get_object_send(cmd_ctx, cli_ctx->ev, cli_ctx,
|
||||
data, memcache, NULL, id);
|
||||
if (subreq == NULL) {
|
||||
diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c
|
||||
index dc7610a4e528b5126f0d25d84cd3c1a22f683b75..edb3ea652ef7032b76c8f815b9f83fe185a669ea 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_ex.c
|
||||
+++ b/src/sss_client/idmap/sss_nss_ex.c
|
||||
@@ -115,42 +115,51 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
|
||||
size_t c;
|
||||
gid_t *new_groups;
|
||||
size_t idx;
|
||||
+ bool skip_mc = false;
|
||||
|
||||
- ret = sss_nss_mc_get(inp);
|
||||
- switch (ret) {
|
||||
- case 0:
|
||||
- return 0;
|
||||
- case ERANGE:
|
||||
- return ERANGE;
|
||||
- case ENOENT:
|
||||
- /* fall through, we need to actively ask the parent
|
||||
- * if no entry is found */
|
||||
- break;
|
||||
- default:
|
||||
- /* if using the mmaped cache failed,
|
||||
- * fall back to socket based comms */
|
||||
- break;
|
||||
+ if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) {
|
||||
+ skip_mc = true;
|
||||
+ }
|
||||
+
|
||||
+ if (!skip_mc) {
|
||||
+ ret = sss_nss_mc_get(inp);
|
||||
+ switch (ret) {
|
||||
+ case 0:
|
||||
+ return 0;
|
||||
+ case ERANGE:
|
||||
+ return ERANGE;
|
||||
+ case ENOENT:
|
||||
+ /* fall through, we need to actively ask the parent
|
||||
+ * if no entry is found */
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* if using the mmaped cache failed,
|
||||
+ * fall back to socket based comms */
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
sss_nss_timedlock(timeout, &time_left);
|
||||
|
||||
- /* previous thread might already initialize entry in mmap cache */
|
||||
- ret = sss_nss_mc_get(inp);
|
||||
- switch (ret) {
|
||||
- case 0:
|
||||
- ret = 0;
|
||||
- goto out;
|
||||
- case ERANGE:
|
||||
- ret = ERANGE;
|
||||
- goto out;
|
||||
- case ENOENT:
|
||||
- /* fall through, we need to actively ask the parent
|
||||
- * if no entry is found */
|
||||
- break;
|
||||
- default:
|
||||
- /* if using the mmaped cache failed,
|
||||
- * fall back to socket based comms */
|
||||
- break;
|
||||
+ if (!skip_mc) {
|
||||
+ /* previous thread might already initialize entry in mmap cache */
|
||||
+ ret = sss_nss_mc_get(inp);
|
||||
+ switch (ret) {
|
||||
+ case 0:
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
+ case ERANGE:
|
||||
+ ret = ERANGE;
|
||||
+ goto out;
|
||||
+ case ENOENT:
|
||||
+ /* fall through, we need to actively ask the parent
|
||||
+ * if no entry is found */
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* if using the mmaped cache failed,
|
||||
+ * fall back to socket based comms */
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
ret = sss_nss_make_request_timeout(inp->cmd, &inp->rd, time_left,
|
||||
diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h
|
||||
index 2334b6cb3fb8ef62e4ce3a7187c7affaeaa034e7..1649830afbb80c617fd339f054aef8bc8e585fb9 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_idmap.h
|
||||
+++ b/src/sss_client/idmap/sss_nss_idmap.h
|
||||
@@ -169,6 +169,10 @@ void sss_nss_free_kv(struct sss_nss_kv *kv_list);
|
||||
|
||||
#define SSS_NSS_EX_FLAG_NO_FLAGS 0
|
||||
|
||||
+/** Always request data from the server side, client must be privileged to do
|
||||
+ * so, see nss_trusted_users option in man sssd.conf for details */
|
||||
+#define SSS_NSS_EX_FLAG_NO_CACHE (1 << 0)
|
||||
+
|
||||
#ifdef IPA_389DS_PLUGIN_HELPER_CALLS
|
||||
|
||||
/**
|
||||
--
|
||||
2.14.3
|
||||
|
111
0006-CACHE_REQ-Add-cache_req_data_set_bypass_dp.patch
Normal file
111
0006-CACHE_REQ-Add-cache_req_data_set_bypass_dp.patch
Normal file
@ -0,0 +1,111 @@
|
||||
From 52e675ec4b160720515c81ae8c0e5a95feb50c57 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Mon, 23 Oct 2017 18:26:55 +0200
|
||||
Subject: [PATCH 06/11] CACHE_REQ: Add cache_req_data_set_bypass_dp()
|
||||
|
||||
Similar to cache_req_data_set_bypass_cache()
|
||||
cache_req_data_set_bypass_dp() can be used to control how the cache_req
|
||||
framework performs the lookup. If cache_req_data_set_bypass_dp() is used
|
||||
with 'true' only a cache lookup is performed and no request is send to
|
||||
the backend even if no entry was found.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/2478
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/responder/common/cache_req/cache_req.c | 15 +++++++++++++++
|
||||
src/responder/common/cache_req/cache_req.h | 3 +++
|
||||
src/responder/common/cache_req/cache_req_data.c | 12 ++++++++++++
|
||||
src/responder/common/cache_req/cache_req_private.h | 2 ++
|
||||
4 files changed, 32 insertions(+)
|
||||
|
||||
diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c
|
||||
index 5fed7a2ab8beded2fee91f679a12f9a0ff6013ec..110df561101be538e3f0496addfa2e14e42ea918 100644
|
||||
--- a/src/responder/common/cache_req/cache_req.c
|
||||
+++ b/src/responder/common/cache_req/cache_req.c
|
||||
@@ -142,6 +142,13 @@ cache_req_create(TALLOC_CTX *mem_ctx,
|
||||
|
||||
cr->cache_first = rctx->cache_first;
|
||||
cr->bypass_cache = cr->plugin->bypass_cache || cr->data->bypass_cache;
|
||||
+ cr->bypass_dp = cr->data->bypass_dp;
|
||||
+ if (cr->bypass_cache && cr->bypass_dp) {
|
||||
+ CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr,
|
||||
+ "Cannot bypass cache and dp at the same time!");
|
||||
+ talloc_free(cr);
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
return cr;
|
||||
}
|
||||
@@ -658,6 +665,14 @@ static bool cache_req_search_schema(struct cache_req *cr,
|
||||
bypass_cache = true;
|
||||
bypass_dp = false;
|
||||
|
||||
+ if (!first_iteration) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ } else if (cr->bypass_dp) {
|
||||
+ /* The caller wants to lookup only in the cache */
|
||||
+ bypass_cache = false;
|
||||
+ bypass_dp = true;
|
||||
+
|
||||
if (!first_iteration) {
|
||||
return false;
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/cache_req.h b/src/responder/common/cache_req/cache_req.h
|
||||
index c04b2fba6f0445dcfcc9cfe1b5963ac975c39118..2c88853887fc816bba2182d9d9beaa32fa384158 100644
|
||||
--- a/src/responder/common/cache_req/cache_req.h
|
||||
+++ b/src/responder/common/cache_req/cache_req.h
|
||||
@@ -127,6 +127,9 @@ void
|
||||
cache_req_data_set_bypass_cache(struct cache_req_data *data,
|
||||
bool bypass_cache);
|
||||
|
||||
+void
|
||||
+cache_req_data_set_bypass_dp(struct cache_req_data *data,
|
||||
+ bool bypass_dp);
|
||||
/* Output data. */
|
||||
|
||||
struct cache_req_result {
|
||||
diff --git a/src/responder/common/cache_req/cache_req_data.c b/src/responder/common/cache_req/cache_req_data.c
|
||||
index 48264a321dc603f9708ba71c44542363b11a71ba..ed378274a9a0a68ede8ac99805f3ea4a041382e6 100644
|
||||
--- a/src/responder/common/cache_req/cache_req_data.c
|
||||
+++ b/src/responder/common/cache_req/cache_req_data.c
|
||||
@@ -365,3 +365,15 @@ cache_req_data_set_bypass_cache(struct cache_req_data *data,
|
||||
|
||||
data->bypass_cache = bypass_cache;
|
||||
}
|
||||
+
|
||||
+void
|
||||
+cache_req_data_set_bypass_dp(struct cache_req_data *data,
|
||||
+ bool bypass_dp)
|
||||
+{
|
||||
+ if (data == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "cache_req_data should never be NULL\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ data->bypass_dp = bypass_dp;
|
||||
+}
|
||||
diff --git a/src/responder/common/cache_req/cache_req_private.h b/src/responder/common/cache_req/cache_req_private.h
|
||||
index 9b706ff7d678f543effb77089857a7e8a42a9c51..0f630542d38a277d1819063fa4134bd7d2525c90 100644
|
||||
--- a/src/responder/common/cache_req/cache_req_private.h
|
||||
+++ b/src/responder/common/cache_req/cache_req_private.h
|
||||
@@ -42,6 +42,7 @@ struct cache_req {
|
||||
struct sss_domain_info *domain;
|
||||
bool cache_first;
|
||||
bool bypass_cache;
|
||||
+ bool bypass_dp;
|
||||
/* Only contact domains with this type */
|
||||
enum cache_req_dom_type req_dom_type;
|
||||
|
||||
@@ -90,6 +91,7 @@ struct cache_req_data {
|
||||
} svc;
|
||||
|
||||
bool bypass_cache;
|
||||
+ bool bypass_dp;
|
||||
};
|
||||
|
||||
struct tevent_req *
|
||||
--
|
||||
2.14.3
|
||||
|
48
0007-nss-make-memcache_delete_entry-public.patch
Normal file
48
0007-nss-make-memcache_delete_entry-public.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From a7d6ca275d6b2e5d396cbefb18d0ee880011e271 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Tue, 24 Oct 2017 12:50:43 +0200
|
||||
Subject: [PATCH 07/11] nss: make memcache_delete_entry() public
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/2478
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/responder/nss/nss_get_object.c | 2 +-
|
||||
src/responder/nss/nss_private.h | 8 ++++++++
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/responder/nss/nss_get_object.c b/src/responder/nss/nss_get_object.c
|
||||
index e56480af5e3369963d2e8bb17d74d1603af8e014..15faced006f754134415e766284377f0c86af0ac 100644
|
||||
--- a/src/responder/nss/nss_get_object.c
|
||||
+++ b/src/responder/nss/nss_get_object.c
|
||||
@@ -86,7 +86,7 @@ memcache_delete_entry_by_id(struct nss_ctx *nss_ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static errno_t
|
||||
+errno_t
|
||||
memcache_delete_entry(struct nss_ctx *nss_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_domain_info *domain,
|
||||
diff --git a/src/responder/nss/nss_private.h b/src/responder/nss/nss_private.h
|
||||
index a0b573d6ecba2d8ba6f55db0adcd7ee29cbec991..5fc19d26be9adda4d967086e7b239e49a78866ee 100644
|
||||
--- a/src/responder/nss/nss_private.h
|
||||
+++ b/src/responder/nss/nss_private.h
|
||||
@@ -92,6 +92,14 @@ struct sss_cmd_table *get_nss_cmds(void);
|
||||
|
||||
int nss_connection_setup(struct cli_ctx *cli_ctx);
|
||||
|
||||
+errno_t
|
||||
+memcache_delete_entry(struct nss_ctx *nss_ctx,
|
||||
+ struct resp_ctx *rctx,
|
||||
+ struct sss_domain_info *domain,
|
||||
+ const char *name,
|
||||
+ uint32_t id,
|
||||
+ enum sss_mc_type type);
|
||||
+
|
||||
struct tevent_req *
|
||||
nss_get_object_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
--
|
||||
2.14.3
|
||||
|
364
0008-NSS-add-support-for-SSS_NSS_EX_FLAG_INVALIDATE_CACHE.patch
Normal file
364
0008-NSS-add-support-for-SSS_NSS_EX_FLAG_INVALIDATE_CACHE.patch
Normal file
@ -0,0 +1,364 @@
|
||||
From 55f7d8034d783c01789d76a2b9ffc901045e8af8 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Tue, 24 Oct 2017 14:10:53 +0200
|
||||
Subject: [PATCH 08/11] NSS: add support for SSS_NSS_EX_FLAG_INVALIDATE_CACHE
|
||||
|
||||
The patch adds support for the SSS_NSS_EX_FLAG_INVALIDATE_CACHE flag and
|
||||
makes the existing code more flexible and handle additional flags.
|
||||
|
||||
If SSS_NSS_EX_FLAG_INVALIDATE_CACHE is set the requested object is only
|
||||
looked up in the cache and if it was found on-disk and memory cache
|
||||
entries will be invalidated.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/2478
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/responder/nss/nss_cmd.c | 141 +++++++++++++++++++++++++++++++--
|
||||
src/responder/nss/nss_protocol.c | 1 +
|
||||
src/responder/nss/nss_protocol.h | 1 +
|
||||
src/responder/nss/nss_protocol_grent.c | 9 ++-
|
||||
src/responder/nss/nss_protocol_pwent.c | 6 +-
|
||||
src/sss_client/idmap/sss_nss_ex.c | 20 ++++-
|
||||
src/sss_client/idmap/sss_nss_idmap.h | 8 +-
|
||||
7 files changed, 171 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c
|
||||
index c5ddd2f2cc2122cd169ea991b94a14eb5bad095f..545257a0be7e91e9de767a57848bb77c5791db4e 100644
|
||||
--- a/src/responder/nss/nss_cmd.c
|
||||
+++ b/src/responder/nss/nss_cmd.c
|
||||
@@ -50,6 +50,26 @@ nss_cmd_ctx_create(TALLOC_CTX *mem_ctx,
|
||||
return cmd_ctx;
|
||||
}
|
||||
|
||||
+static errno_t eval_flags(struct nss_cmd_ctx *cmd_ctx,
|
||||
+ struct cache_req_data *data)
|
||||
+{
|
||||
+ if ((cmd_ctx->flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
|
||||
+ && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Flags SSS_NSS_EX_FLAG_NO_CACHE and "
|
||||
+ "SSS_NSS_EX_FLAG_INVALIDATE_CACHE are "
|
||||
+ "mutually exclusive.\n");
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if ((cmd_ctx->flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) {
|
||||
+ cache_req_data_set_bypass_cache(data, true);
|
||||
+ } else if ((cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
|
||||
+ cache_req_data_set_bypass_dp(data, true);
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
static void nss_getby_done(struct tevent_req *subreq);
|
||||
static void nss_getlistby_done(struct tevent_req *subreq);
|
||||
|
||||
@@ -65,7 +85,6 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx,
|
||||
struct tevent_req *subreq;
|
||||
const char *rawname;
|
||||
errno_t ret;
|
||||
- uint32_t flags = 0;
|
||||
|
||||
cmd_ctx = nss_cmd_ctx_create(cli_ctx, cli_ctx, type, fill_fn);
|
||||
if (cmd_ctx == NULL) {
|
||||
@@ -73,8 +92,9 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ cmd_ctx->flags = 0;
|
||||
if (ex_version) {
|
||||
- ret = nss_protocol_parse_name_ex(cli_ctx, &rawname, &flags);
|
||||
+ ret = nss_protocol_parse_name_ex(cli_ctx, &rawname, &cmd_ctx->flags);
|
||||
} else {
|
||||
ret = nss_protocol_parse_name(cli_ctx, &rawname);
|
||||
}
|
||||
@@ -92,8 +112,10 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) {
|
||||
- cache_req_data_set_bypass_cache(data, true);
|
||||
+ ret = eval_flags(cmd_ctx, data);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "eval_flags failed.\n");
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
subreq = nss_get_object_send(cmd_ctx, cli_ctx->ev, cli_ctx,
|
||||
@@ -129,7 +151,6 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx,
|
||||
struct tevent_req *subreq;
|
||||
uint32_t id;
|
||||
errno_t ret;
|
||||
- uint32_t flags = 0;
|
||||
|
||||
cmd_ctx = nss_cmd_ctx_create(cli_ctx, cli_ctx, type, fill_fn);
|
||||
if (cmd_ctx == NULL) {
|
||||
@@ -138,7 +159,7 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx,
|
||||
}
|
||||
|
||||
if (ex_version) {
|
||||
- ret = nss_protocol_parse_id_ex(cli_ctx, &id, &flags);
|
||||
+ ret = nss_protocol_parse_id_ex(cli_ctx, &id, &cmd_ctx->flags);
|
||||
} else {
|
||||
ret = nss_protocol_parse_id(cli_ctx, &id);
|
||||
}
|
||||
@@ -156,8 +177,10 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) {
|
||||
- cache_req_data_set_bypass_cache(data, true);
|
||||
+ ret = eval_flags(cmd_ctx, data);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "eval_flags failed.\n");
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
subreq = nss_get_object_send(cmd_ctx, cli_ctx->ev, cli_ctx,
|
||||
@@ -425,6 +448,98 @@ done:
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+static errno_t invalidate_cache(struct nss_cmd_ctx *cmd_ctx,
|
||||
+ struct cache_req_result *result)
|
||||
+{
|
||||
+ int ret;
|
||||
+ enum sss_mc_type memcache_type;
|
||||
+ const char *name;
|
||||
+ char *output_name = NULL;
|
||||
+ bool is_user;
|
||||
+ struct sysdb_attrs *attrs = NULL;
|
||||
+
|
||||
+ switch (cmd_ctx->type) {
|
||||
+ case CACHE_REQ_INITGROUPS:
|
||||
+ case CACHE_REQ_INITGROUPS_BY_UPN:
|
||||
+ memcache_type = SSS_MC_INITGROUPS;
|
||||
+ is_user = true;
|
||||
+ break;
|
||||
+ case CACHE_REQ_USER_BY_NAME:
|
||||
+ case CACHE_REQ_USER_BY_ID:
|
||||
+ memcache_type = SSS_MC_PASSWD;
|
||||
+ is_user = true;
|
||||
+ break;
|
||||
+ case CACHE_REQ_GROUP_BY_NAME:
|
||||
+ case CACHE_REQ_GROUP_BY_ID:
|
||||
+ memcache_type = SSS_MC_GROUP;
|
||||
+ is_user = false;
|
||||
+ break;
|
||||
+ default:
|
||||
+ /* nothing to do */
|
||||
+ return EOK;
|
||||
+ }
|
||||
+
|
||||
+ /* Find output name to invalidate memory cache entry*/
|
||||
+ name = sss_get_name_from_msg(result->domain, result->msgs[0]);
|
||||
+ if (name == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Found object has no name.\n");
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+ ret = sss_output_fqname(cmd_ctx, result->domain, name,
|
||||
+ cmd_ctx->nss_ctx->rctx->override_space,
|
||||
+ &output_name);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sss_output_fqname failed.\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ memcache_delete_entry(cmd_ctx->nss_ctx, cmd_ctx->nss_ctx->rctx, NULL,
|
||||
+ output_name, 0, memcache_type);
|
||||
+ if (memcache_type == SSS_MC_INITGROUPS) {
|
||||
+ /* Invalidate the passwd data as well */
|
||||
+ memcache_delete_entry(cmd_ctx->nss_ctx, cmd_ctx->nss_ctx->rctx,
|
||||
+ result->domain, output_name, 0, SSS_MC_PASSWD);
|
||||
+ }
|
||||
+ talloc_free(output_name);
|
||||
+
|
||||
+ /* Use sysdb name to invalidate disk cache entry */
|
||||
+ name = ldb_msg_find_attr_as_string(result->msgs[0], SYSDB_NAME, NULL);
|
||||
+ if (name == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Found object has no name.\n");
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (memcache_type == SSS_MC_INITGROUPS) {
|
||||
+ attrs = sysdb_new_attrs(cmd_ctx);
|
||||
+ if (attrs == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n");
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, 1);
|
||||
+ if (ret != EOK) {
|
||||
+ talloc_free(attrs);
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_time_t failed.\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_set_user_attr(result->domain, name, attrs, SYSDB_MOD_REP);
|
||||
+ talloc_free(attrs);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_user_attr failed.\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_invalidate_cache_entry(result->domain, name, is_user);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_invalidate_cache_entry failed.\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
static void nss_getby_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct cache_req_result *result;
|
||||
@@ -440,6 +555,16 @@ static void nss_getby_done(struct tevent_req *subreq)
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ if ((cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
|
||||
+ ret = invalidate_cache(cmd_ctx, result);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to invalidate cache for [%s].\n",
|
||||
+ cmd_ctx->rawname);
|
||||
+ nss_protocol_done(cmd_ctx->cli_ctx, ret);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
nss_protocol_reply(cmd_ctx->cli_ctx, cmd_ctx->nss_ctx, cmd_ctx,
|
||||
result, cmd_ctx->fill_fn);
|
||||
|
||||
diff --git a/src/responder/nss/nss_protocol.c b/src/responder/nss/nss_protocol.c
|
||||
index 17bfc4f4e71960a72e9e04622eac95b94a865ec7..2655386498754c46fbb363bdd1f976f9ded6a434 100644
|
||||
--- a/src/responder/nss/nss_protocol.c
|
||||
+++ b/src/responder/nss/nss_protocol.c
|
||||
@@ -233,6 +233,7 @@ nss_protocol_parse_id_ex(struct cli_ctx *cli_ctx, uint32_t *_id,
|
||||
SAFEALIGN_COPY_UINT32(&flags, body + sizeof(uint32_t), NULL);
|
||||
|
||||
*_id = id;
|
||||
+ *_flags = flags;
|
||||
|
||||
return EOK;
|
||||
}
|
||||
diff --git a/src/responder/nss/nss_protocol.h b/src/responder/nss/nss_protocol.h
|
||||
index ca5b040237dc18acdca9a7a3a7a7dbb64265aa95..76724d2b2db7b11c9147fa927e39abab731328b2 100644
|
||||
--- a/src/responder/nss/nss_protocol.h
|
||||
+++ b/src/responder/nss/nss_protocol.h
|
||||
@@ -50,6 +50,7 @@ struct nss_cmd_ctx {
|
||||
struct nss_ctx *nss_ctx;
|
||||
struct nss_state_ctx *state_ctx;
|
||||
nss_protocol_fill_packet_fn fill_fn;
|
||||
+ uint32_t flags;
|
||||
|
||||
/* For initgroups- */
|
||||
const char *rawname;
|
||||
diff --git a/src/responder/nss/nss_protocol_grent.c b/src/responder/nss/nss_protocol_grent.c
|
||||
index ee228c722a153a1ba7aa8a1b30a1e551108424bb..6f6ae57dd97b000ad3cf174b0f649d46981563e2 100644
|
||||
--- a/src/responder/nss/nss_protocol_grent.c
|
||||
+++ b/src/responder/nss/nss_protocol_grent.c
|
||||
@@ -274,8 +274,10 @@ nss_protocol_fill_grent(struct nss_ctx *nss_ctx,
|
||||
|
||||
num_results++;
|
||||
|
||||
- /* Do not store entry in memory cache during enumeration. */
|
||||
- if (!cmd_ctx->enumeration) {
|
||||
+ /* Do not store entry in memory cache during enumeration or when
|
||||
+ * requested. */
|
||||
+ if (!cmd_ctx->enumeration
|
||||
+ && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) {
|
||||
members = (char *)&body[rp_members];
|
||||
members_size = body_len - rp_members;
|
||||
ret = sss_mmap_cache_gr_store(&nss_ctx->grp_mc_ctx, name, &pwfield,
|
||||
@@ -390,7 +392,8 @@ nss_protocol_fill_initgr(struct nss_ctx *nss_ctx,
|
||||
num_results++;
|
||||
}
|
||||
|
||||
- if (nss_ctx->initgr_mc_ctx) {
|
||||
+ if (nss_ctx->initgr_mc_ctx
|
||||
+ && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) {
|
||||
to_sized_string(&rawname, cmd_ctx->rawname);
|
||||
to_sized_string(&unique_name, result->lookup_name);
|
||||
|
||||
diff --git a/src/responder/nss/nss_protocol_pwent.c b/src/responder/nss/nss_protocol_pwent.c
|
||||
index db5c071e2ff172a2267c08c9817fecfbcc7cabc3..f449ec69b6a86a6db2aaed368e217c1a791faaa2 100644
|
||||
--- a/src/responder/nss/nss_protocol_pwent.c
|
||||
+++ b/src/responder/nss/nss_protocol_pwent.c
|
||||
@@ -295,8 +295,10 @@ nss_protocol_fill_pwent(struct nss_ctx *nss_ctx,
|
||||
|
||||
num_results++;
|
||||
|
||||
- /* Do not store entry in memory cache during enumeration. */
|
||||
- if (!cmd_ctx->enumeration) {
|
||||
+ /* Do not store entry in memory cache during enumeration or when
|
||||
+ * requested. */
|
||||
+ if (!cmd_ctx->enumeration
|
||||
+ && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) {
|
||||
ret = sss_mmap_cache_pw_store(&nss_ctx->pwd_mc_ctx, name, &pwfield,
|
||||
uid, gid, &gecos, &homedir, &shell);
|
||||
if (ret != EOK) {
|
||||
diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c
|
||||
index edb3ea652ef7032b76c8f815b9f83fe185a669ea..148eb7b35ec236b6272dd203a0035399cfdef73d 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_ex.c
|
||||
+++ b/src/sss_client/idmap/sss_nss_ex.c
|
||||
@@ -103,6 +103,18 @@ errno_t sss_nss_mc_get(struct nss_input *inp)
|
||||
}
|
||||
}
|
||||
|
||||
+static int check_flags(uint32_t flags)
|
||||
+{
|
||||
+ /* SSS_NSS_EX_FLAG_NO_CACHE and SSS_NSS_EX_FLAG_INVALIDATE_CACHE are
|
||||
+ * mutually exclusive */
|
||||
+ if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
|
||||
+ && (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
|
||||
{
|
||||
uint8_t *repbuf = NULL;
|
||||
@@ -117,7 +129,13 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
|
||||
size_t idx;
|
||||
bool skip_mc = false;
|
||||
|
||||
- if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) {
|
||||
+ ret = check_flags(flags);
|
||||
+ if (ret != 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
|
||||
+ || (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
|
||||
skip_mc = true;
|
||||
}
|
||||
|
||||
diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h
|
||||
index 1649830afbb80c617fd339f054aef8bc8e585fb9..3755643312f05a31d1cf1aa76dfc22848ef1e3ec 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_idmap.h
|
||||
+++ b/src/sss_client/idmap/sss_nss_idmap.h
|
||||
@@ -170,9 +170,15 @@ void sss_nss_free_kv(struct sss_nss_kv *kv_list);
|
||||
#define SSS_NSS_EX_FLAG_NO_FLAGS 0
|
||||
|
||||
/** Always request data from the server side, client must be privileged to do
|
||||
- * so, see nss_trusted_users option in man sssd.conf for details */
|
||||
+ * so, see nss_trusted_users option in man sssd.conf for details.
|
||||
+ * This flag cannot be used together with SSS_NSS_EX_FLAG_INVALIDATE_CACHE */
|
||||
#define SSS_NSS_EX_FLAG_NO_CACHE (1 << 0)
|
||||
|
||||
+/** Invalidate the data in the caches, client must be privileged to do
|
||||
+ * so, see nss_trusted_users option in man sssd.conf for details.
|
||||
+ * This flag cannot be used together with SSS_NSS_EX_FLAG_NO_CACHE */
|
||||
+#define SSS_NSS_EX_FLAG_INVALIDATE_CACHE (1 << 1)
|
||||
+
|
||||
#ifdef IPA_389DS_PLUGIN_HELPER_CALLS
|
||||
|
||||
/**
|
||||
--
|
||||
2.14.3
|
||||
|
589
0009-NSS-TESTS-add-unit-tests-for-_EX-requests.patch
Normal file
589
0009-NSS-TESTS-add-unit-tests-for-_EX-requests.patch
Normal file
@ -0,0 +1,589 @@
|
||||
From 85da8a5e90bffc8b0fef5e0ea364a8d3cb50de86 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Wed, 25 Oct 2017 21:31:54 +0200
|
||||
Subject: [PATCH 09/11] NSS/TESTS: add unit tests for *_EX requests
|
||||
|
||||
The patch adds unit tests for the new *_EX requests with different input
|
||||
types and flags.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/2478
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/tests/cmocka/test_nss_srv.c | 539 ++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 539 insertions(+)
|
||||
|
||||
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
|
||||
index ccedf96beaecfaa4232bbe456d5e5a8394098483..6aa726153183b5a871a75d398727ea7132358ca6 100644
|
||||
--- a/src/tests/cmocka/test_nss_srv.c
|
||||
+++ b/src/tests/cmocka/test_nss_srv.c
|
||||
@@ -255,6 +255,45 @@ static void mock_input_user_or_group(const char *input)
|
||||
mock_parse_inp(shortname, domname, EOK);
|
||||
}
|
||||
|
||||
+static void mock_input_user_or_group_ex(bool do_parse_inp, const char *input,
|
||||
+ uint32_t flags)
|
||||
+{
|
||||
+ const char *copy;
|
||||
+ const char *shortname;
|
||||
+ const char *domname;
|
||||
+ char *separator;
|
||||
+ uint8_t *data;
|
||||
+ size_t len;
|
||||
+
|
||||
+ len = strlen(input);
|
||||
+ len++;
|
||||
+ data = talloc_size(nss_test_ctx, len + sizeof(uint32_t));
|
||||
+ assert_non_null(data);
|
||||
+ memcpy(data, input, len);
|
||||
+ SAFEALIGN_COPY_UINT32(data + len, &flags, NULL);
|
||||
+
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
|
||||
+ will_return(__wrap_sss_packet_get_body, data);
|
||||
+ will_return(__wrap_sss_packet_get_body, len + sizeof(uint32_t));
|
||||
+
|
||||
+ if (do_parse_inp) {
|
||||
+ copy = talloc_strdup(nss_test_ctx, input);
|
||||
+ assert_non_null(copy);
|
||||
+
|
||||
+ separator = strrchr(copy, '@');
|
||||
+ if (separator == NULL) {
|
||||
+ shortname = input;
|
||||
+ domname = NULL;
|
||||
+ } else {
|
||||
+ *separator = '\0';
|
||||
+ shortname = copy;
|
||||
+ domname = separator + 1;
|
||||
+ }
|
||||
+
|
||||
+ mock_parse_inp(shortname, domname, EOK);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void mock_input_upn(const char *upn)
|
||||
{
|
||||
will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
|
||||
@@ -291,6 +330,20 @@ static void mock_input_id(TALLOC_CTX *mem_ctx, uint32_t id)
|
||||
will_return(__wrap_sss_packet_get_body, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
+static void mock_input_id_ex(TALLOC_CTX *mem_ctx, uint32_t id, uint32_t flags)
|
||||
+{
|
||||
+ uint8_t *body;
|
||||
+
|
||||
+ body = talloc_zero_array(mem_ctx, uint8_t, 8);
|
||||
+ if (body == NULL) return;
|
||||
+
|
||||
+ SAFEALIGN_SETMEM_UINT32(body, id, NULL);
|
||||
+ SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), flags, NULL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
|
||||
+ will_return(__wrap_sss_packet_get_body, body);
|
||||
+ will_return(__wrap_sss_packet_get_body, 2 * sizeof(uint32_t));
|
||||
+}
|
||||
+
|
||||
static void mock_fill_user(void)
|
||||
{
|
||||
/* One packet for the entry and one for num entries */
|
||||
@@ -4143,6 +4196,482 @@ void test_nss_getsidbyname_neg(void **state)
|
||||
assert_int_equal(ret, ENOENT);
|
||||
}
|
||||
|
||||
+static int test_nss_EINVAL_check(uint32_t status, uint8_t *body, size_t blen)
|
||||
+{
|
||||
+ assert_int_equal(status, EINVAL);
|
||||
+ assert_int_equal(blen, 0);
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+#define RESET_TCTX do { \
|
||||
+ nss_test_ctx->tctx->done = false; \
|
||||
+ nss_test_ctx->tctx->error = EIO; \
|
||||
+} while (0)
|
||||
+
|
||||
+void test_nss_getpwnam_ex(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom,
|
||||
+ &getpwnam_usr, NULL, 0);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ mock_input_user_or_group_ex(true, "testuser", 0);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM_EX);
|
||||
+ mock_fill_user();
|
||||
+
|
||||
+ /* Query for that user, call a callback when command finishes */
|
||||
+ set_cmd_cb(test_nss_getpwnam_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use old input format, expect EINVAL */
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
|
||||
+ will_return(__wrap_sss_packet_get_body, "testuser");
|
||||
+ will_return(__wrap_sss_packet_get_body, 0);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM_EX);
|
||||
+
|
||||
+ set_cmd_cb(test_nss_EINVAL_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use unsupported flag combination, expect EINVAL */
|
||||
+ mock_input_user_or_group_ex(false, "testuser",
|
||||
+ SSS_NSS_EX_FLAG_NO_CACHE
|
||||
+ |SSS_NSS_EX_FLAG_INVALIDATE_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM_EX);
|
||||
+
|
||||
+ set_cmd_cb(test_nss_EINVAL_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use flag SSS_NSS_EX_FLAG_NO_CACHE,
|
||||
+ * will cause a backend lookup -> mock_account_recv_simple() */
|
||||
+ mock_input_user_or_group_ex(true, "testuser", SSS_NSS_EX_FLAG_NO_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM_EX);
|
||||
+ mock_fill_user();
|
||||
+ mock_account_recv_simple();
|
||||
+
|
||||
+ set_cmd_cb(test_nss_getpwnam_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use flag SSS_NSS_EX_FLAG_INVALIDATE_CACHE */
|
||||
+ mock_input_user_or_group_ex(true, "testuser",
|
||||
+ SSS_NSS_EX_FLAG_INVALIDATE_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM_EX);
|
||||
+ mock_fill_user();
|
||||
+
|
||||
+ set_cmd_cb(test_nss_getpwnam_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+}
|
||||
+
|
||||
+void test_nss_getpwuid_ex(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ uint32_t id = 101;
|
||||
+
|
||||
+ /* Prime the cache with a valid user */
|
||||
+ ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom,
|
||||
+ &getpwuid_usr, NULL, 0);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ mock_input_id_ex(nss_test_ctx, id, 0);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID_EX);
|
||||
+ mock_fill_user();
|
||||
+
|
||||
+ /* Query for that id, call a callback when command finishes */
|
||||
+ set_cmd_cb(test_nss_getpwuid_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use old input format, expect failure */
|
||||
+ mock_input_id(nss_test_ctx, id);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID_EX);
|
||||
+
|
||||
+ set_cmd_cb(test_nss_EINVAL_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use unsupported flag combination, expect EINVAL */
|
||||
+ mock_input_id_ex(nss_test_ctx, id, SSS_NSS_EX_FLAG_NO_CACHE
|
||||
+ |SSS_NSS_EX_FLAG_INVALIDATE_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID_EX);
|
||||
+
|
||||
+ set_cmd_cb(test_nss_EINVAL_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use flag SSS_NSS_EX_FLAG_NO_CACHE,
|
||||
+ * will cause a backend lookup -> mock_account_recv_simple() */
|
||||
+ mock_input_id_ex(nss_test_ctx, id, SSS_NSS_EX_FLAG_NO_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID_EX);
|
||||
+ mock_fill_user();
|
||||
+ mock_account_recv_simple();
|
||||
+
|
||||
+ set_cmd_cb(test_nss_getpwuid_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use flag SSS_NSS_EX_FLAG_INVALIDATE_CACHE */
|
||||
+ mock_input_id_ex(nss_test_ctx, id, SSS_NSS_EX_FLAG_INVALIDATE_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID_EX);
|
||||
+ mock_fill_user();
|
||||
+
|
||||
+ set_cmd_cb(test_nss_getpwuid_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+}
|
||||
+
|
||||
+void test_nss_getgrnam_ex_no_members(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ /* Test group is still in the cache */
|
||||
+
|
||||
+ mock_input_user_or_group_ex(true, getgrnam_no_members.gr_name, 0);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM_EX);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+
|
||||
+ /* Query for that group, call a callback when command finishes */
|
||||
+ set_cmd_cb(test_nss_getgrnam_no_members_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use old input format, expect failure */
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
|
||||
+ will_return(__wrap_sss_packet_get_body, "testgroup");
|
||||
+ will_return(__wrap_sss_packet_get_body, 0);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM_EX);
|
||||
+
|
||||
+ set_cmd_cb(test_nss_EINVAL_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use unsupported flag combination, expect EINVAL */
|
||||
+ mock_input_user_or_group_ex(false, getgrnam_no_members.gr_name,
|
||||
+ SSS_NSS_EX_FLAG_NO_CACHE
|
||||
+ |SSS_NSS_EX_FLAG_INVALIDATE_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM_EX);
|
||||
+
|
||||
+ set_cmd_cb(test_nss_EINVAL_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use flag SSS_NSS_EX_FLAG_NO_CACHE,
|
||||
+ * will cause a backend lookup -> mock_account_recv_simple() */
|
||||
+ mock_input_user_or_group_ex(true, getgrnam_no_members.gr_name,
|
||||
+ SSS_NSS_EX_FLAG_NO_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM_EX);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ mock_account_recv_simple();
|
||||
+
|
||||
+ set_cmd_cb(test_nss_getgrnam_no_members_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use flag SSS_NSS_EX_FLAG_INVALIDATE_CACHE */
|
||||
+ mock_input_user_or_group_ex(true, getgrnam_no_members.gr_name,
|
||||
+ SSS_NSS_EX_FLAG_INVALIDATE_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM_EX);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+
|
||||
+ set_cmd_cb(test_nss_getgrnam_no_members_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+}
|
||||
+
|
||||
+void test_nss_getgrgid_ex_no_members(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ /* Test group is still in the cache */
|
||||
+
|
||||
+ mock_input_id_ex(nss_test_ctx, getgrnam_no_members.gr_gid, 0);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRGID_EX);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ mock_account_recv_simple();
|
||||
+
|
||||
+ /* Query for that group, call a callback when command finishes */
|
||||
+ set_cmd_cb(test_nss_getgrnam_no_members_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRGID_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use old input format, expect failure */
|
||||
+ mock_input_id(nss_test_ctx, getgrnam_no_members.gr_gid);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRGID_EX);
|
||||
+
|
||||
+ set_cmd_cb(test_nss_EINVAL_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRGID_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use unsupported flag combination, expect EINVAL */
|
||||
+ mock_input_id_ex(nss_test_ctx, getgrnam_no_members.gr_gid,
|
||||
+ SSS_NSS_EX_FLAG_NO_CACHE
|
||||
+ |SSS_NSS_EX_FLAG_INVALIDATE_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRGID_EX);
|
||||
+
|
||||
+ set_cmd_cb(test_nss_EINVAL_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRGID_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use flag SSS_NSS_EX_FLAG_NO_CACHE,
|
||||
+ * will cause a backend lookup -> mock_account_recv_simple() */
|
||||
+ mock_input_id_ex(nss_test_ctx, getgrnam_no_members.gr_gid,
|
||||
+ SSS_NSS_EX_FLAG_NO_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRGID_EX);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ mock_account_recv_simple();
|
||||
+ mock_account_recv_simple();
|
||||
+
|
||||
+ set_cmd_cb(test_nss_getgrnam_no_members_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRGID_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use flag SSS_NSS_EX_FLAG_INVALIDATE_CACHE */
|
||||
+ mock_input_id_ex(nss_test_ctx, getgrnam_no_members.gr_gid,
|
||||
+ SSS_NSS_EX_FLAG_INVALIDATE_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRGID_EX);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+
|
||||
+ set_cmd_cb(test_nss_getgrnam_no_members_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRGID_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+}
|
||||
+
|
||||
+void test_nss_initgroups_ex(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ struct sysdb_attrs *attrs;
|
||||
+
|
||||
+ attrs = sysdb_new_attrs(nss_test_ctx);
|
||||
+ assert_non_null(attrs);
|
||||
+
|
||||
+ ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE,
|
||||
+ time(NULL) + 300);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, "upninitgr@upndomain.test");
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom,
|
||||
+ &testinitgr_usr, attrs, 0);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ mock_input_user_or_group_ex(true, "testinitgr", 0);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR_EX);
|
||||
+ mock_fill_user();
|
||||
+
|
||||
+ /* Query for that user, call a callback when command finishes */
|
||||
+ set_cmd_cb(test_nss_initgr_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use old input format, expect failure */
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER);
|
||||
+ will_return(__wrap_sss_packet_get_body, "testinitgr");
|
||||
+ will_return(__wrap_sss_packet_get_body, 0);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR_EX);
|
||||
+
|
||||
+ set_cmd_cb(test_nss_EINVAL_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use unsupported flag combination, expect EINVAL */
|
||||
+ mock_input_user_or_group_ex(false, "testinitgr",
|
||||
+ SSS_NSS_EX_FLAG_NO_CACHE
|
||||
+ |SSS_NSS_EX_FLAG_INVALIDATE_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR_EX);
|
||||
+
|
||||
+ set_cmd_cb(test_nss_EINVAL_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use flag SSS_NSS_EX_FLAG_NO_CACHE,
|
||||
+ * will cause a backend lookup -> mock_account_recv_simple() */
|
||||
+ mock_input_user_or_group_ex(true, "testinitgr",
|
||||
+ SSS_NSS_EX_FLAG_NO_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR_EX);
|
||||
+ mock_fill_user();
|
||||
+ mock_account_recv_simple();
|
||||
+
|
||||
+ set_cmd_cb(test_nss_initgr_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ RESET_TCTX;
|
||||
+
|
||||
+ /* Use flag SSS_NSS_EX_FLAG_INVALIDATE_CACHE */
|
||||
+ mock_input_user_or_group_ex(true, "testinitgr",
|
||||
+ SSS_NSS_EX_FLAG_INVALIDATE_CACHE);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR_EX);
|
||||
+ mock_fill_user();
|
||||
+
|
||||
+ set_cmd_cb(test_nss_initgr_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR_EX,
|
||||
+ nss_test_ctx->nss_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+}
|
||||
+
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
int rv;
|
||||
@@ -4288,6 +4817,16 @@ int main(int argc, const char *argv[])
|
||||
nss_test_setup, nss_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getsidbyname_neg,
|
||||
nss_test_setup, nss_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_nss_getpwnam_ex,
|
||||
+ nss_test_setup, nss_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_nss_getpwuid_ex,
|
||||
+ nss_test_setup, nss_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_nss_getgrnam_ex_no_members,
|
||||
+ nss_test_setup, nss_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_nss_getgrgid_ex_no_members,
|
||||
+ nss_test_setup, nss_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_nss_initgroups_ex,
|
||||
+ nss_test_setup, nss_test_teardown),
|
||||
};
|
||||
|
||||
/* Set debug level to invalid value so we can deside if -d 0 was used. */
|
||||
--
|
||||
2.14.3
|
||||
|
493
0010-nss-idmap-add-timeout-version-of-old-sss_nss_-calls.patch
Normal file
493
0010-nss-idmap-add-timeout-version-of-old-sss_nss_-calls.patch
Normal file
@ -0,0 +1,493 @@
|
||||
From e54db68cbb9c12d8a6867f2c7766fb2115ab0997 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Thu, 2 Nov 2017 10:32:41 +0100
|
||||
Subject: [PATCH 10/11] nss-idmap: add timeout version of old sss_nss_* calls
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
src/sss_client/idmap/sss_nss_idmap.c | 126 ++++++++++++++++++--------
|
||||
src/sss_client/idmap/sss_nss_idmap.exports | 7 ++
|
||||
src/sss_client/idmap/sss_nss_idmap.h | 124 +++++++++++++++++++++++++
|
||||
src/sss_client/idmap/sss_nss_idmap.unit_tests | 2 +-
|
||||
src/tests/cmocka/sss_nss_idmap-tests.c | 13 +--
|
||||
6 files changed, 229 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index dd25d1f7ea1be66388aa1b393bac290c4d7501a2..286ba47e3c421864362717be5258de960efca9f2 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -2974,7 +2974,6 @@ test_sysdb_domain_resolution_order_LDADD = \
|
||||
|
||||
test_wbc_calls_SOURCES = \
|
||||
src/tests/cmocka/test_wbc_calls.c \
|
||||
- src/sss_client/idmap/sss_nss_idmap.c \
|
||||
src/sss_client/libwbclient/wbc_sid_sssd.c \
|
||||
src/sss_client/libwbclient/wbclient_common.c \
|
||||
src/sss_client/libwbclient/wbc_sid_common.c \
|
||||
@@ -2993,6 +2992,7 @@ test_wbc_calls_LDADD = \
|
||||
$(TALLOC_LIBS) \
|
||||
$(SSSD_INTERNAL_LTLIBS) \
|
||||
libsss_test_common.la \
|
||||
+ libsss_nss_idmap.la \
|
||||
$(NULL)
|
||||
|
||||
test_be_ptask_SOURCES = \
|
||||
diff --git a/src/sss_client/idmap/sss_nss_idmap.c b/src/sss_client/idmap/sss_nss_idmap.c
|
||||
index 6f3af267a1e763e7dce77e3862be377ae2bfe984..6e7685d2b1d80956b6a6668e9bbb146abd9e86ed 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_idmap.c
|
||||
+++ b/src/sss_client/idmap/sss_nss_idmap.c
|
||||
@@ -28,10 +28,13 @@
|
||||
|
||||
#include "sss_client/sss_cli.h"
|
||||
#include "sss_client/idmap/sss_nss_idmap.h"
|
||||
+#include "sss_client/idmap/sss_nss_idmap_private.h"
|
||||
#include "util/strtonum.h"
|
||||
|
||||
#define DATA_START (3 * sizeof(uint32_t))
|
||||
#define LIST_START (2 * sizeof(uint32_t))
|
||||
+#define NO_TIMEOUT ((unsigned int) -1)
|
||||
+
|
||||
union input {
|
||||
const char *str;
|
||||
uint32_t id;
|
||||
@@ -198,8 +201,8 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd ,
|
||||
- struct output *out)
|
||||
+static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd,
|
||||
+ unsigned int timeout, struct output *out)
|
||||
{
|
||||
int ret;
|
||||
size_t inp_len;
|
||||
@@ -215,6 +218,7 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd ,
|
||||
struct sss_nss_kv *kv_list;
|
||||
char **names;
|
||||
enum sss_id_type *types;
|
||||
+ int time_left = SSS_CLI_SOCKET_TIMEOUT;
|
||||
|
||||
switch (cmd) {
|
||||
case SSS_NSS_GETSIDBYNAME:
|
||||
@@ -250,9 +254,14 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd ,
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
- sss_nss_lock();
|
||||
+ if (timeout == NO_TIMEOUT) {
|
||||
+ sss_nss_lock();
|
||||
+ } else {
|
||||
+ sss_nss_timedlock(timeout, &time_left);
|
||||
+ }
|
||||
|
||||
- nret = sss_nss_make_request(cmd, &rd, &repbuf, &replen, &errnop);
|
||||
+ nret = sss_nss_make_request_timeout(cmd, &rd, time_left, &repbuf, &replen,
|
||||
+ &errnop);
|
||||
if (nret != NSS_STATUS_SUCCESS) {
|
||||
ret = nss_status_to_errno(nret);
|
||||
goto done;
|
||||
@@ -347,8 +356,8 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int sss_nss_getsidbyname(const char *fq_name, char **sid,
|
||||
- enum sss_id_type *type)
|
||||
+int sss_nss_getsidbyname_timeout(const char *fq_name, unsigned int timeout,
|
||||
+ char **sid, enum sss_id_type *type)
|
||||
{
|
||||
int ret;
|
||||
union input inp;
|
||||
@@ -360,7 +369,7 @@ int sss_nss_getsidbyname(const char *fq_name, char **sid,
|
||||
|
||||
inp.str = fq_name;
|
||||
|
||||
- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYNAME, &out);
|
||||
+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYNAME, timeout, &out);
|
||||
if (ret == EOK) {
|
||||
*sid = out.d.str;
|
||||
*type = out.type;
|
||||
@@ -369,7 +378,14 @@ int sss_nss_getsidbyname(const char *fq_name, char **sid,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type)
|
||||
+int sss_nss_getsidbyname(const char *fq_name, char **sid,
|
||||
+ enum sss_id_type *type)
|
||||
+{
|
||||
+ return sss_nss_getsidbyname_timeout(fq_name, NO_TIMEOUT, sid, type);
|
||||
+}
|
||||
+
|
||||
+int sss_nss_getsidbyid_timeout(uint32_t id, unsigned int timeout,
|
||||
+ char **sid, enum sss_id_type *type)
|
||||
{
|
||||
int ret;
|
||||
union input inp;
|
||||
@@ -381,7 +397,7 @@ int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type)
|
||||
|
||||
inp.id = id;
|
||||
|
||||
- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYID, &out);
|
||||
+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYID, timeout, &out);
|
||||
if (ret == EOK) {
|
||||
*sid = out.d.str;
|
||||
*type = out.type;
|
||||
@@ -390,8 +406,13 @@ int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int sss_nss_getnamebysid(const char *sid, char **fq_name,
|
||||
- enum sss_id_type *type)
|
||||
+int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type)
|
||||
+{
|
||||
+ return sss_nss_getsidbyid_timeout(id, NO_TIMEOUT, sid, type);
|
||||
+}
|
||||
+
|
||||
+int sss_nss_getnamebysid_timeout(const char *sid, unsigned int timeout,
|
||||
+ char **fq_name, enum sss_id_type *type)
|
||||
{
|
||||
int ret;
|
||||
union input inp;
|
||||
@@ -403,7 +424,7 @@ int sss_nss_getnamebysid(const char *sid, char **fq_name,
|
||||
|
||||
inp.str = sid;
|
||||
|
||||
- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYSID, &out);
|
||||
+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYSID, timeout, &out);
|
||||
if (ret == EOK) {
|
||||
*fq_name = out.d.str;
|
||||
*type = out.type;
|
||||
@@ -412,7 +433,14 @@ int sss_nss_getnamebysid(const char *sid, char **fq_name,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type)
|
||||
+int sss_nss_getnamebysid(const char *sid, char **fq_name,
|
||||
+ enum sss_id_type *type)
|
||||
+{
|
||||
+ return sss_nss_getnamebysid_timeout(sid, NO_TIMEOUT, fq_name, type);
|
||||
+}
|
||||
+
|
||||
+int sss_nss_getidbysid_timeout(const char *sid, unsigned int timeout,
|
||||
+ uint32_t *id, enum sss_id_type *id_type)
|
||||
{
|
||||
int ret;
|
||||
union input inp;
|
||||
@@ -424,7 +452,7 @@ int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type)
|
||||
|
||||
inp.str = sid;
|
||||
|
||||
- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETIDBYSID, &out);
|
||||
+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETIDBYSID, timeout, &out);
|
||||
if (ret == EOK) {
|
||||
*id = out.d.id;
|
||||
*id_type = out.type;
|
||||
@@ -433,8 +461,14 @@ int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list,
|
||||
- enum sss_id_type *type)
|
||||
+int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type)
|
||||
+{
|
||||
+ return sss_nss_getidbysid_timeout(sid, NO_TIMEOUT, id, id_type);
|
||||
+}
|
||||
+
|
||||
+int sss_nss_getorigbyname_timeout(const char *fq_name, unsigned int timeout,
|
||||
+ struct sss_nss_kv **kv_list,
|
||||
+ enum sss_id_type *type)
|
||||
{
|
||||
int ret;
|
||||
union input inp;
|
||||
@@ -446,7 +480,7 @@ int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list,
|
||||
|
||||
inp.str = fq_name;
|
||||
|
||||
- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETORIGBYNAME, &out);
|
||||
+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETORIGBYNAME, timeout, &out);
|
||||
if (ret == EOK) {
|
||||
*kv_list = out.d.kv_list;
|
||||
*type = out.type;
|
||||
@@ -455,30 +489,42 @@ int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list,
|
||||
+ enum sss_id_type *type)
|
||||
+{
|
||||
+ return sss_nss_getorigbyname_timeout(fq_name, NO_TIMEOUT, kv_list, type);
|
||||
+}
|
||||
+
|
||||
+int sss_nss_getnamebycert_timeout(const char *cert, unsigned int timeout,
|
||||
+ char **fq_name, enum sss_id_type *type)
|
||||
+{
|
||||
+ int ret;
|
||||
+ union input inp;
|
||||
+ struct output out;
|
||||
+
|
||||
+ if (fq_name == NULL || cert == NULL || *cert == '\0') {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ inp.str = cert;
|
||||
+
|
||||
+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYCERT, timeout, &out);
|
||||
+ if (ret == EOK) {
|
||||
+ *fq_name = out.d.str;
|
||||
+ *type = out.type;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int sss_nss_getnamebycert(const char *cert, char **fq_name,
|
||||
enum sss_id_type *type)
|
||||
{
|
||||
- int ret;
|
||||
- union input inp;
|
||||
- struct output out;
|
||||
-
|
||||
- if (fq_name == NULL || cert == NULL || *cert == '\0') {
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- inp.str = cert;
|
||||
-
|
||||
- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYCERT, &out);
|
||||
- if (ret == EOK) {
|
||||
- *fq_name = out.d.str;
|
||||
- *type = out.type;
|
||||
- }
|
||||
-
|
||||
- return ret;
|
||||
+ return sss_nss_getnamebycert_timeout(cert, NO_TIMEOUT, fq_name, type);
|
||||
}
|
||||
|
||||
-int sss_nss_getlistbycert(const char *cert, char ***fq_name,
|
||||
- enum sss_id_type **type)
|
||||
+int sss_nss_getlistbycert_timeout(const char *cert, unsigned int timeout,
|
||||
+ char ***fq_name, enum sss_id_type **type)
|
||||
{
|
||||
int ret;
|
||||
union input inp;
|
||||
@@ -490,7 +536,7 @@ int sss_nss_getlistbycert(const char *cert, char ***fq_name,
|
||||
|
||||
inp.str = cert;
|
||||
|
||||
- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETLISTBYCERT, &out);
|
||||
+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETLISTBYCERT, timeout, &out);
|
||||
if (ret == EOK) {
|
||||
*fq_name = out.d.names;
|
||||
*type = out.types;
|
||||
@@ -498,3 +544,9 @@ int sss_nss_getlistbycert(const char *cert, char ***fq_name,
|
||||
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+int sss_nss_getlistbycert(const char *cert, char ***fq_name,
|
||||
+ enum sss_id_type **type)
|
||||
+{
|
||||
+ return sss_nss_getlistbycert_timeout(cert, NO_TIMEOUT, fq_name, type);
|
||||
+}
|
||||
diff --git a/src/sss_client/idmap/sss_nss_idmap.exports b/src/sss_client/idmap/sss_nss_idmap.exports
|
||||
index 788d05ecc3bd56fa88e68a98b9c8096cf7140a09..8d0a24f42aa3fb3dd9c2ed125bf79e2c7792993f 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_idmap.exports
|
||||
+++ b/src/sss_client/idmap/sss_nss_idmap.exports
|
||||
@@ -40,4 +40,11 @@ SSS_NSS_IDMAP_0.4.0 {
|
||||
sss_nss_getgrnam_timeout;
|
||||
sss_nss_getgrgid_timeout;
|
||||
sss_nss_getgrouplist_timeout;
|
||||
+ sss_nss_getsidbyname_timeout;
|
||||
+ sss_nss_getsidbyid_timeout;
|
||||
+ sss_nss_getnamebysid_timeout;
|
||||
+ sss_nss_getidbysid_timeout;
|
||||
+ sss_nss_getorigbyname_timeout;
|
||||
+ sss_nss_getnamebycert_timeout;
|
||||
+ sss_nss_getlistbycert_timeout;
|
||||
} SSS_NSS_IDMAP_0.3.0;
|
||||
diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h
|
||||
index 3755643312f05a31d1cf1aa76dfc22848ef1e3ec..125e72a6486f5916f90d37f27e1743d181bfa3e5 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_idmap.h
|
||||
+++ b/src/sss_client/idmap/sss_nss_idmap.h
|
||||
@@ -303,5 +303,129 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp,
|
||||
int sss_nss_getgrouplist_timeout(const char *name, gid_t group,
|
||||
gid_t *groups, int *ngroups,
|
||||
uint32_t flags, unsigned int timeout);
|
||||
+/**
|
||||
+ * @brief Find SID by fully qualified name with timeout
|
||||
+ *
|
||||
+ * @param[in] fq_name Fully qualified name of a user or a group
|
||||
+ * @param[in] timeout timeout in milliseconds
|
||||
+ * @param[out] sid String representation of the SID of the requested user
|
||||
+ * or group, must be freed by the caller
|
||||
+ * @param[out] type Type of the object related to the given name
|
||||
+ *
|
||||
+ * @return
|
||||
+ * - 0 (EOK): success, sid contains the requested SID
|
||||
+ * - ENOENT: requested object was not found in the domain extracted from the given name
|
||||
+ * - ENETUNREACH: SSSD does not know how to handle the domain extracted from the given name
|
||||
+ * - ENOSYS: this call is not supported by the configured provider
|
||||
+ * - EINVAL: input cannot be parsed
|
||||
+ * - EIO: remote servers cannot be reached
|
||||
+ * - EFAULT: any other error
|
||||
+ * - ETIME: request timed out but was send to SSSD
|
||||
+ * - ETIMEDOUT: request timed out but was not send to SSSD
|
||||
+ */
|
||||
+int sss_nss_getsidbyname_timeout(const char *fq_name, unsigned int timeout,
|
||||
+ char **sid, enum sss_id_type *type);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Find SID by a POSIX UID or GID with timeout
|
||||
+ *
|
||||
+ * @param[in] id POSIX UID or GID
|
||||
+ * @param[in] timeout timeout in milliseconds
|
||||
+ * @param[out] sid String representation of the SID of the requested user
|
||||
+ * or group, must be freed by the caller
|
||||
+ * @param[out] type Type of the object related to the given ID
|
||||
+ *
|
||||
+ * @return
|
||||
+ * - see #sss_nss_getsidbyname_timeout
|
||||
+ */
|
||||
+int sss_nss_getsidbyid_timeout(uint32_t id, unsigned int timeout,
|
||||
+ char **sid, enum sss_id_type *type);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Return the fully qualified name for the given SID with timeout
|
||||
+ *
|
||||
+ * @param[in] sid String representation of the SID
|
||||
+ * @param[in] timeout timeout in milliseconds
|
||||
+ * @param[out] fq_name Fully qualified name of a user or a group,
|
||||
+ * must be freed by the caller
|
||||
+ * @param[out] type Type of the object related to the SID
|
||||
+ *
|
||||
+ * @return
|
||||
+ * - see #sss_nss_getsidbyname_timeout
|
||||
+ */
|
||||
+int sss_nss_getnamebysid_timeout(const char *sid, unsigned int timeout,
|
||||
+ char **fq_name, enum sss_id_type *type);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Return the POSIX ID for the given SID with timeout
|
||||
+ *
|
||||
+ * @param[in] sid String representation of the SID
|
||||
+ * @param[in] timeout timeout in milliseconds
|
||||
+ * @param[out] id POSIX ID related to the SID
|
||||
+ * @param[out] id_type Type of the object related to the SID
|
||||
+ *
|
||||
+ * @return
|
||||
+ * - see #sss_nss_getsidbyname_timeout
|
||||
+ */
|
||||
+int sss_nss_getidbysid_timeout(const char *sid, unsigned int timeout,
|
||||
+ uint32_t *id, enum sss_id_type *id_type);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Find original data by fully qualified name with timeout
|
||||
+ *
|
||||
+ * @param[in] fq_name Fully qualified name of a user or a group
|
||||
+ * @param[in] timeout timeout in milliseconds
|
||||
+ * @param[out] kv_list A NULL terminate list of key-value pairs where the key
|
||||
+ * is the attribute name in the cache of SSSD,
|
||||
+ * must be freed by the caller with sss_nss_free_kv()
|
||||
+ * @param[out] type Type of the object related to the given name
|
||||
+ *
|
||||
+ * @return
|
||||
+ * - 0 (EOK): success, sid contains the requested SID
|
||||
+ * - ENOENT: requested object was not found in the domain extracted from the given name
|
||||
+ * - ENETUNREACH: SSSD does not know how to handle the domain extracted from the given name
|
||||
+ * - ENOSYS: this call is not supported by the configured provider
|
||||
+ * - EINVAL: input cannot be parsed
|
||||
+ * - EIO: remote servers cannot be reached
|
||||
+ * - EFAULT: any other error
|
||||
+ * - ETIME: request timed out but was send to SSSD
|
||||
+ * - ETIMEDOUT: request timed out but was not send to SSSD
|
||||
+ */
|
||||
+int sss_nss_getorigbyname_timeout(const char *fq_name, unsigned int timeout,
|
||||
+ struct sss_nss_kv **kv_list,
|
||||
+ enum sss_id_type *type);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Return the fully qualified name for the given base64 encoded
|
||||
+ * X.509 certificate in DER format with timeout
|
||||
+ *
|
||||
+ * @param[in] cert base64 encoded certificate
|
||||
+ * @param[in] timeout timeout in milliseconds
|
||||
+ * @param[out] fq_name Fully qualified name of a user or a group,
|
||||
+ * must be freed by the caller
|
||||
+ * @param[out] type Type of the object related to the cert
|
||||
+ *
|
||||
+ * @return
|
||||
+ * - see #sss_nss_getsidbyname_timeout
|
||||
+ */
|
||||
+int sss_nss_getnamebycert_timeout(const char *cert, unsigned int timeout,
|
||||
+ char **fq_name, enum sss_id_type *type);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Return a list of fully qualified names for the given base64 encoded
|
||||
+ * X.509 certificate in DER format with timeout
|
||||
+ *
|
||||
+ * @param[in] cert base64 encoded certificate
|
||||
+ * @param[in] timeout timeout in milliseconds
|
||||
+ * @param[out] fq_name List of fully qualified name of users or groups,
|
||||
+ * must be freed by the caller
|
||||
+ * @param[out] type List of types of the objects related to the cert
|
||||
+ *
|
||||
+ * @return
|
||||
+ * - see #sss_nss_getsidbyname_timeout
|
||||
+ */
|
||||
+int sss_nss_getlistbycert_timeout(const char *cert, unsigned int timeout,
|
||||
+ char ***fq_name, enum sss_id_type **type);
|
||||
+
|
||||
#endif /* IPA_389DS_PLUGIN_HELPER_CALLS */
|
||||
#endif /* SSS_NSS_IDMAP_H_ */
|
||||
diff --git a/src/sss_client/idmap/sss_nss_idmap.unit_tests b/src/sss_client/idmap/sss_nss_idmap.unit_tests
|
||||
index 361cc3b134ead52cf458afe27c055739d6728441..05c474f008e1d59aae5976acfd81613c3c3e6540 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_idmap.unit_tests
|
||||
+++ b/src/sss_client/idmap/sss_nss_idmap.unit_tests
|
||||
@@ -2,5 +2,5 @@
|
||||
UNIT_TEST_ONLY {
|
||||
# should not be part of installed library
|
||||
global:
|
||||
- sss_nss_make_request;
|
||||
+ sss_nss_make_request_timeout;
|
||||
};
|
||||
diff --git a/src/tests/cmocka/sss_nss_idmap-tests.c b/src/tests/cmocka/sss_nss_idmap-tests.c
|
||||
index 8807eca619d7b07d919168e5629042cf38f654ac..2e37040d2d3523bea157804706685fa0b36df16a 100644
|
||||
--- a/src/tests/cmocka/sss_nss_idmap-tests.c
|
||||
+++ b/src/tests/cmocka/sss_nss_idmap-tests.c
|
||||
@@ -61,10 +61,11 @@ uint8_t buf_orig1[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0
|
||||
#error "unknow endianess"
|
||||
#endif
|
||||
|
||||
-enum nss_status sss_nss_make_request(enum sss_cli_command cmd,
|
||||
- struct sss_cli_req_data *rd,
|
||||
- uint8_t **repbuf, size_t *replen,
|
||||
- int *errnop)
|
||||
+enum nss_status sss_nss_make_request_timeout(enum sss_cli_command cmd,
|
||||
+ struct sss_cli_req_data *rd,
|
||||
+ int timeout,
|
||||
+ uint8_t **repbuf, size_t *replen,
|
||||
+ int *errnop)
|
||||
{
|
||||
struct sss_nss_make_request_test_data *d;
|
||||
|
||||
@@ -114,7 +115,7 @@ void test_getsidbyname(void **state)
|
||||
sid = NULL;
|
||||
|
||||
for (c = 0; d[c].d.repbuf != NULL; c++) {
|
||||
- will_return(sss_nss_make_request, &d[0].d);
|
||||
+ will_return(sss_nss_make_request_timeout, &d[0].d);
|
||||
|
||||
ret = sss_nss_getsidbyname("test", &sid, &type);
|
||||
assert_int_equal(ret, d[0].ret);
|
||||
@@ -134,7 +135,7 @@ void test_getorigbyname(void **state)
|
||||
enum sss_id_type type;
|
||||
struct sss_nss_make_request_test_data d = {buf_orig1, sizeof(buf_orig1), 0, NSS_STATUS_SUCCESS};
|
||||
|
||||
- will_return(sss_nss_make_request, &d);
|
||||
+ will_return(sss_nss_make_request_timeout, &d);
|
||||
ret = sss_nss_getorigbyname("test", &kv_list, &type);
|
||||
assert_int_equal(ret, EOK);
|
||||
assert_int_equal(type, SSS_ID_TYPE_UID);
|
||||
--
|
||||
2.14.3
|
||||
|
183
0011-nss-idmap-allow-empty-buffer-with-SSS_NSS_EX_FLAG_IN.patch
Normal file
183
0011-nss-idmap-allow-empty-buffer-with-SSS_NSS_EX_FLAG_IN.patch
Normal file
@ -0,0 +1,183 @@
|
||||
From 859bddc2bf51dc426a3dc56bd9f365e9c5722b65 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Thu, 2 Nov 2017 11:09:20 +0100
|
||||
Subject: [PATCH 11/11] nss-idmap: allow empty buffer with
|
||||
SSS_NSS_EX_FLAG_INVALIDATE_CACHE
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/sss_client/idmap/sss_nss_ex.c | 89 ++++++++++++++++++++++++++-------------
|
||||
1 file changed, 60 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c
|
||||
index 148eb7b35ec236b6272dd203a0035399cfdef73d..dcd9619a8b07ced7498f61b7e809fa46ebffe09e 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_ex.c
|
||||
+++ b/src/sss_client/idmap/sss_nss_ex.c
|
||||
@@ -103,8 +103,11 @@ errno_t sss_nss_mc_get(struct nss_input *inp)
|
||||
}
|
||||
}
|
||||
|
||||
-static int check_flags(uint32_t flags)
|
||||
+static int check_flags(struct nss_input *inp, uint32_t flags,
|
||||
+ bool *skip_mc, bool *skip_data)
|
||||
{
|
||||
+ bool no_data = false;
|
||||
+
|
||||
/* SSS_NSS_EX_FLAG_NO_CACHE and SSS_NSS_EX_FLAG_INVALIDATE_CACHE are
|
||||
* mutually exclusive */
|
||||
if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
|
||||
@@ -112,6 +115,52 @@ static int check_flags(uint32_t flags)
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
+ *skip_mc = false;
|
||||
+ if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
|
||||
+ || (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
|
||||
+ *skip_mc = true;
|
||||
+ }
|
||||
+
|
||||
+ switch(inp->cmd) {
|
||||
+ case SSS_NSS_GETPWNAM:
|
||||
+ case SSS_NSS_GETPWNAM_EX:
|
||||
+ case SSS_NSS_GETPWUID:
|
||||
+ case SSS_NSS_GETPWUID_EX:
|
||||
+ if (inp->result.pwrep.buffer == NULL
|
||||
+ || inp->result.pwrep.buflen == 0) {
|
||||
+ no_data = true;
|
||||
+ }
|
||||
+ break;
|
||||
+ case SSS_NSS_GETGRNAM:
|
||||
+ case SSS_NSS_GETGRNAM_EX:
|
||||
+ case SSS_NSS_GETGRGID:
|
||||
+ case SSS_NSS_GETGRGID_EX:
|
||||
+ if (inp->result.grrep.buffer == NULL
|
||||
+ || inp->result.grrep.buflen == 0) {
|
||||
+ no_data = true;
|
||||
+ }
|
||||
+ break;
|
||||
+ case SSS_NSS_INITGR:
|
||||
+ case SSS_NSS_INITGR_EX:
|
||||
+ if (inp->result.initgrrep.ngroups == 0
|
||||
+ || inp->result.initgrrep.groups == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ *skip_data = false;
|
||||
+ /* Allow empty buffer with SSS_NSS_EX_FLAG_INVALIDATE_CACHE */
|
||||
+ if (no_data) {
|
||||
+ if ((flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
|
||||
+ *skip_data = true;
|
||||
+ } else {
|
||||
+ return ERANGE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -128,18 +177,14 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
|
||||
gid_t *new_groups;
|
||||
size_t idx;
|
||||
bool skip_mc = false;
|
||||
+ bool skip_data = false;
|
||||
|
||||
- ret = check_flags(flags);
|
||||
+ ret = check_flags(inp, flags, &skip_mc, &skip_data);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
- if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0
|
||||
- || (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) {
|
||||
- skip_mc = true;
|
||||
- }
|
||||
-
|
||||
- if (!skip_mc) {
|
||||
+ if (!skip_mc && !skip_data) {
|
||||
ret = sss_nss_mc_get(inp);
|
||||
switch (ret) {
|
||||
case 0:
|
||||
@@ -159,7 +204,7 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
|
||||
|
||||
sss_nss_timedlock(timeout, &time_left);
|
||||
|
||||
- if (!skip_mc) {
|
||||
+ if (!skip_mc && !skip_data) {
|
||||
/* previous thread might already initialize entry in mmap cache */
|
||||
ret = sss_nss_mc_get(inp);
|
||||
switch (ret) {
|
||||
@@ -196,6 +241,12 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if (skip_data) {
|
||||
+ /* No data requested, just return the return code */
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if (inp->cmd == SSS_NSS_INITGR || inp->cmd == SSS_NSS_INITGR_EX) {
|
||||
if ((*(inp->result.initgrrep.ngroups) - *(inp->result.initgrrep.start))
|
||||
< num_results) {
|
||||
@@ -311,10 +362,6 @@ int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd,
|
||||
.result.pwrep.buffer = buffer,
|
||||
.result.pwrep.buflen = buflen};
|
||||
|
||||
- if (buffer == NULL || buflen == 0) {
|
||||
- return ERANGE;
|
||||
- }
|
||||
-
|
||||
ret = make_name_flag_req_data(name, flags, &inp.rd);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
@@ -346,10 +393,6 @@ int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd,
|
||||
.result.pwrep.buffer = buffer,
|
||||
.result.pwrep.buflen = buflen};
|
||||
|
||||
- if (buffer == NULL || buflen == 0) {
|
||||
- return ERANGE;
|
||||
- }
|
||||
-
|
||||
SAFEALIGN_COPY_UINT32(&req_data[0], &uid, NULL);
|
||||
SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL);
|
||||
*result = NULL;
|
||||
@@ -373,10 +416,6 @@ int sss_nss_getgrnam_timeout(const char *name, struct group *grp,
|
||||
.result.grrep.buffer = buffer,
|
||||
.result.grrep.buflen = buflen};
|
||||
|
||||
- if (buffer == NULL || buflen == 0) {
|
||||
- return ERANGE;
|
||||
- }
|
||||
-
|
||||
ret = make_name_flag_req_data(name, flags, &inp.rd);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
@@ -407,10 +446,6 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp,
|
||||
.result.grrep.buffer = buffer,
|
||||
.result.grrep.buflen = buflen};
|
||||
|
||||
- if (buffer == NULL || buflen == 0) {
|
||||
- return ERANGE;
|
||||
- }
|
||||
-
|
||||
SAFEALIGN_COPY_UINT32(&req_data[0], &gid, NULL);
|
||||
SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL);
|
||||
*result = NULL;
|
||||
@@ -434,10 +469,6 @@ int sss_nss_getgrouplist_timeout(const char *name, gid_t group,
|
||||
.input.name = name,
|
||||
.cmd = SSS_NSS_INITGR_EX};
|
||||
|
||||
- if (groups == NULL || ngroups == NULL || *ngroups == 0) {
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
ret = make_name_flag_req_data(name, flags, &inp.rd);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
--
|
||||
2.14.3
|
||||
|
16
sssd.spec
16
sssd.spec
@ -29,7 +29,7 @@
|
||||
|
||||
Name: sssd
|
||||
Version: 1.16.0
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
Group: Applications/System
|
||||
Summary: System Security Services Daemon
|
||||
License: GPLv3+
|
||||
@ -39,6 +39,17 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
||||
|
||||
### Patches ###
|
||||
Patch0001: 0001-KCM-Fix-restart-during-after-upgrade.patch
|
||||
Patch0002: 0002-sss_client-create-nss_common.h.patch
|
||||
Patch0003: 0003-nss-idmap-add-nss-like-calls-with-timeout-and-flags.patch
|
||||
Patch0004: 0004-NSS-add-_EX-version-of-some-requests.patch
|
||||
Patch0005: 0005-NSS-add-support-for-SSS_NSS_EX_FLAG_NO_CACHE.patch
|
||||
Patch0006: 0006-CACHE_REQ-Add-cache_req_data_set_bypass_dp.patch
|
||||
Patch0007: 0007-nss-make-memcache_delete_entry-public.patch
|
||||
Patch0008: 0008-NSS-add-support-for-SSS_NSS_EX_FLAG_INVALIDATE_CACHE.patch
|
||||
Patch0009: 0009-NSS-TESTS-add-unit-tests-for-_EX-requests.patch
|
||||
Patch0010: 0010-nss-idmap-add-timeout-version-of-old-sss_nss_-calls.patch
|
||||
Patch0011: 0011-nss-idmap-allow-empty-buffer-with-SSS_NSS_EX_FLAG_IN.patch
|
||||
|
||||
Patch0502: 0502-SYSTEMD-Use-capabilities.patch
|
||||
Patch0503: 0503-Disable-stopping-idle-socket-activated-responders.patch
|
||||
Patch0600: 0600-tests-cmocka-Fix-unit-tests-with-libldb-1.3.0.patch
|
||||
@ -1251,6 +1262,9 @@ fi
|
||||
%{_libdir}/%{name}/modules/libwbclient.so
|
||||
|
||||
%changelog
|
||||
* Fri Nov 17 2017 Jakub Hrozek <jhrozek@redhat.com> - 1.16.0-3
|
||||
- Backport extended NSS API from upstream master branch
|
||||
|
||||
* Fri Nov 03 2017 Lukas Slebodnik <lslebodn@fedoraproject.org> - 1.16.0-2
|
||||
- Resolves: upstream#3529 - sssd-kcm Fix restart during/after upgrade
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user