New upstream release 1.15.3
https://docs.pagure.org/SSSD.sssd/users/relnotes/notes_1_15_3.html
This commit is contained in:
parent
ca67484fda
commit
6302a22355
1
.gitignore
vendored
1
.gitignore
vendored
@ -76,3 +76,4 @@ sssd-1.2.91.tar.gz
|
||||
/sssd-1.15.0.tar.gz
|
||||
/sssd-1.15.1.tar.gz
|
||||
/sssd-1.15.2.tar.gz
|
||||
/sssd-1.15.3.tar.gz
|
||||
|
@ -1,23 +0,0 @@
|
||||
From 012ee7c3fe24a5e75d9b0465268c1bb8187b8337 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 15 Mar 2017 18:00:37 +0100
|
||||
Subject: [PATCH 01/97] Updating the version for the 1.15.3 release
|
||||
|
||||
---
|
||||
version.m4 | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/version.m4 b/version.m4
|
||||
index 11e5e71b08b8af7c8d4f39410fea99d5d2ce3a00..da96ecd2e2d58e3e6079741f81a07f99259010b4 100644
|
||||
--- a/version.m4
|
||||
+++ b/version.m4
|
||||
@@ -1,5 +1,5 @@
|
||||
# Primary version number
|
||||
-m4_define([VERSION_NUMBER], [1.15.2])
|
||||
+m4_define([VERSION_NUMBER], [1.15.3])
|
||||
|
||||
# If the PRERELEASE_VERSION_NUMBER is set, we'll append
|
||||
# it to the release tag when creating an RPM or SRPM
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,29 +0,0 @@
|
||||
From 6fb643c75e59e093c8c52def162ce1f1956430c7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
|
||||
Date: Tue, 14 Mar 2017 18:20:43 +0100
|
||||
Subject: [PATCH 02/97] UTIL: Typo in comment
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/util/safe-format-string.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/util/safe-format-string.h b/src/util/safe-format-string.h
|
||||
index 2f4796de7cea66d9ff0cd808e9e7c33de053feb8..fdebcf966554bcce150ed531173e991973698da0 100644
|
||||
--- a/src/util/safe-format-string.h
|
||||
+++ b/src/util/safe-format-string.h
|
||||
@@ -42,7 +42,7 @@
|
||||
* Features:
|
||||
* - Only string 's' fields are supported
|
||||
* - All the varargs should be strings, followed by a NULL argument
|
||||
- * - Both positional '%$1s' and non-positional '%s' are supported
|
||||
+ * - Both positional '%1$s' and non-positional '%s' are supported
|
||||
* - Field widths '%8s' work as expected
|
||||
* - Precision '%.8s' works, but precision cannot be read from a field
|
||||
* - Left alignment flag is supported '%-8s'.
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 3c071c4d6ec0d8f798eb862ebc4584123ff44663 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Slebodnik <lslebodn@redhat.com>
|
||||
Date: Tue, 21 Mar 2017 12:27:16 +0100
|
||||
Subject: [PATCH 03/97] MAN: Mention sssd-secrets in "SEE ALSO" section
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Resolves:
|
||||
https://pagure.io/SSSD/sssd/issue/3344
|
||||
|
||||
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
---
|
||||
src/man/include/seealso.xml | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/src/man/include/seealso.xml b/src/man/include/seealso.xml
|
||||
index 25b421748fb19881552de8b6384af2c794063e11..2e9c646c475887bce3612472975ade375edbd819 100644
|
||||
--- a/src/man/include/seealso.xml
|
||||
+++ b/src/man/include/seealso.xml
|
||||
@@ -28,6 +28,12 @@
|
||||
<manvolnum>5</manvolnum>
|
||||
</citerefentry>,
|
||||
</phrase>
|
||||
+ <phrase condition="with_secrets">
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>sssd-secrets</refentrytitle>
|
||||
+ <manvolnum>5</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ </phrase>
|
||||
<citerefentry>
|
||||
<refentrytitle>sss_cache</refentrytitle><manvolnum>8</manvolnum>
|
||||
</citerefentry>,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,369 +0,0 @@
|
||||
From 843bc50c04afa6e4f4a4561d887bbbd5f7101ce1 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Wed, 8 Feb 2017 14:28:28 +0100
|
||||
Subject: [PATCH 04/97] split_on_separator: move to a separate file
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
To be able to include split_on_separator() without additional
|
||||
dependencies (only talloc), it is moved into a separate file.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
Makefile.am | 30 ++++++++++---
|
||||
src/util/util.c | 93 ----------------------------------------
|
||||
src/util/util_ext.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 144 insertions(+), 100 deletions(-)
|
||||
create mode 100644 src/util/util_ext.c
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 45b04de2638a745a189c0b4e5794ccd29913b10d..6dae4f2dd7f2dee501add82c7ab4f15fcbcc59ac 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -987,6 +987,7 @@ libsss_util_la_SOURCES = \
|
||||
src/sbus/sssd_dbus_common_signals.c \
|
||||
src/sbus/sssd_dbus_utils.c \
|
||||
src/util/util.c \
|
||||
+ src/util/util_ext.c \
|
||||
src/util/memory.c \
|
||||
src/util/safe-format-string.c \
|
||||
src/util/server.c \
|
||||
@@ -2355,19 +2356,23 @@ test_authtok_SOURCES = \
|
||||
src/tests/cmocka/test_authtok.c \
|
||||
src/util/authtok.c \
|
||||
src/util/authtok-utils.c \
|
||||
- src/util/util.c
|
||||
+ src/util/util.c \
|
||||
+ src/util/util_ext.c \
|
||||
+ $(NULL)
|
||||
test_authtok_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
$(TALLOC_CFLAGS) \
|
||||
$(POPT_CFLAGS) \
|
||||
- $(DHASH_CFLAGS)
|
||||
+ $(DHASH_CFLAGS) \
|
||||
+ $(NULL)
|
||||
test_authtok_LDADD = \
|
||||
$(TALLOC_LIBS) \
|
||||
$(CMOCKA_LIBS) \
|
||||
$(DHASH_LIBS) \
|
||||
$(POPT_LIBS) \
|
||||
libsss_test_common.la \
|
||||
- libsss_debug.la
|
||||
+ libsss_debug.la \
|
||||
+ $(NULL)
|
||||
|
||||
sss_nss_idmap_tests_SOURCES = \
|
||||
src/tests/cmocka/sss_nss_idmap-tests.c
|
||||
@@ -2839,6 +2844,7 @@ test_child_common_SOURCES = \
|
||||
src/util/atomic_io.c \
|
||||
src/util/util_errors.c \
|
||||
src/util/util.c \
|
||||
+ src/util/util_ext.c \
|
||||
$(NULL)
|
||||
test_child_common_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
@@ -3774,6 +3780,7 @@ krb5_child_SOURCES = \
|
||||
src/util/authtok.c \
|
||||
src/util/authtok-utils.c \
|
||||
src/util/util.c \
|
||||
+ src/util/util_ext.c \
|
||||
src/util/signal.c \
|
||||
src/util/strtonum.c \
|
||||
src/util/become_user.c \
|
||||
@@ -3807,6 +3814,7 @@ ldap_child_SOURCES = \
|
||||
src/util/authtok.c \
|
||||
src/util/authtok-utils.c \
|
||||
src/util/util.c \
|
||||
+ src/util/util_ext.c \
|
||||
src/util/signal.c \
|
||||
src/util/become_user.c \
|
||||
$(NULL)
|
||||
@@ -3827,6 +3835,7 @@ selinux_child_SOURCES = \
|
||||
src/util/sss_semanage.c \
|
||||
src/util/atomic_io.c \
|
||||
src/util/util.c \
|
||||
+ src/util/util_ext.c \
|
||||
$(NULL)
|
||||
selinux_child_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
@@ -3845,6 +3854,7 @@ gpo_child_SOURCES = \
|
||||
src/providers/ad/ad_gpo_child.c \
|
||||
src/util/atomic_io.c \
|
||||
src/util/util.c \
|
||||
+ src/util/util_ext.c \
|
||||
src/util/signal.c
|
||||
gpo_child_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
@@ -3876,6 +3886,7 @@ p11_child_SOURCES = \
|
||||
src/p11_child/p11_child_nss.c \
|
||||
src/util/atomic_io.c \
|
||||
src/util/util.c \
|
||||
+ src/util/util_ext.c \
|
||||
$(NULL)
|
||||
p11_child_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
@@ -3893,16 +3904,21 @@ p11_child_LDADD = \
|
||||
|
||||
memberof_la_SOURCES = \
|
||||
src/ldb_modules/memberof.c \
|
||||
- src/util/util.c
|
||||
+ src/util/util.c \
|
||||
+ src/util/util_ext.c \
|
||||
+ $(NULL)
|
||||
memberof_la_CFLAGS = \
|
||||
- $(AM_CFLAGS)
|
||||
+ $(AM_CFLAGS) \
|
||||
+ $(NULL)
|
||||
memberof_la_LIBADD = \
|
||||
libsss_debug.la \
|
||||
$(LDB_LIBS) \
|
||||
- $(DHASH_LIBS)
|
||||
+ $(DHASH_LIBS) \
|
||||
+ $(NULL)
|
||||
memberof_la_LDFLAGS = \
|
||||
-avoid-version \
|
||||
- -module
|
||||
+ -module \
|
||||
+ $(NULL)
|
||||
|
||||
if BUILD_KRB5_LOCATOR_PLUGIN
|
||||
sssd_krb5_locator_plugin_la_SOURCES = \
|
||||
diff --git a/src/util/util.c b/src/util/util.c
|
||||
index a528f0c0249c33bfc3d3275250e74d5edcef2e6f..9d6202f695d516f20d648621da81a2d5e746daa5 100644
|
||||
--- a/src/util/util.c
|
||||
+++ b/src/util/util.c
|
||||
@@ -35,99 +35,6 @@
|
||||
int socket_activated = 0;
|
||||
int dbus_activated = 0;
|
||||
|
||||
-int split_on_separator(TALLOC_CTX *mem_ctx, const char *str,
|
||||
- const char sep, bool trim, bool skip_empty,
|
||||
- char ***_list, int *size)
|
||||
-{
|
||||
- int ret;
|
||||
- const char *substr_end = str;
|
||||
- const char *substr_begin = str;
|
||||
- const char *sep_pos = NULL;
|
||||
- size_t substr_len;
|
||||
- char **list = NULL;
|
||||
- int num_strings = 0;
|
||||
- TALLOC_CTX *tmp_ctx = NULL;
|
||||
-
|
||||
- if (str == NULL || *str == '\0' || _list == NULL) {
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- tmp_ctx = talloc_new(NULL);
|
||||
- if (tmp_ctx == NULL) {
|
||||
- return ENOMEM;
|
||||
- }
|
||||
-
|
||||
- do {
|
||||
- substr_len = 0;
|
||||
-
|
||||
- /* If this is not the first substring, then move from the separator. */
|
||||
- if (sep_pos != NULL) {
|
||||
- substr_end = sep_pos + 1;
|
||||
- substr_begin = sep_pos + 1;
|
||||
- }
|
||||
-
|
||||
- /* Find end of the first substring */
|
||||
- while (*substr_end != sep && *substr_end != '\0') {
|
||||
- substr_end++;
|
||||
- substr_len++;
|
||||
- }
|
||||
-
|
||||
- sep_pos = substr_end;
|
||||
-
|
||||
- if (trim) {
|
||||
- /* Trim leading whitespace */
|
||||
- while (isspace(*substr_begin) && substr_begin < substr_end) {
|
||||
- substr_begin++;
|
||||
- substr_len--;
|
||||
- }
|
||||
-
|
||||
- /* Trim trailing whitespace */
|
||||
- while (substr_end - 1 > substr_begin && isspace(*(substr_end-1))) {
|
||||
- substr_end--;
|
||||
- substr_len--;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* Copy the substring to the output list of strings */
|
||||
- if (skip_empty == false || substr_len > 0) {
|
||||
- list = talloc_realloc(tmp_ctx, list, char*, num_strings + 2);
|
||||
- if (list == NULL) {
|
||||
- ret = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- /* empty string is stored for substr_len == 0 */
|
||||
- list[num_strings] = talloc_strndup(list, substr_begin, substr_len);
|
||||
- if (list[num_strings] == NULL) {
|
||||
- ret = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
- num_strings++;
|
||||
- }
|
||||
-
|
||||
- } while (*sep_pos != '\0');
|
||||
-
|
||||
- if (list == NULL) {
|
||||
- /* No allocations were done, make space for the NULL */
|
||||
- list = talloc(tmp_ctx, char *);
|
||||
- if (list == NULL) {
|
||||
- ret = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
- }
|
||||
- list[num_strings] = NULL;
|
||||
-
|
||||
- if (size) {
|
||||
- *size = num_strings;
|
||||
- }
|
||||
-
|
||||
- *_list = talloc_steal(mem_ctx, list);
|
||||
- ret = EOK;
|
||||
-done:
|
||||
- talloc_free(tmp_ctx);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
static void free_args(char **args)
|
||||
{
|
||||
int i;
|
||||
diff --git a/src/util/util_ext.c b/src/util/util_ext.c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fceb8c873a26471d476b39d5d4e567c445ed8d0b
|
||||
--- /dev/null
|
||||
+++ b/src/util/util_ext.c
|
||||
@@ -0,0 +1,121 @@
|
||||
+/*
|
||||
+ SSSD helper calls - can be used by libraries for external use as well
|
||||
+
|
||||
+ Authors:
|
||||
+ Simo Sorce <ssorce@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 <talloc.h>
|
||||
+#include <stdbool.h>
|
||||
+#include <errno.h>
|
||||
+#include <ctype.h>
|
||||
+
|
||||
+#define EOK 0
|
||||
+
|
||||
+int split_on_separator(TALLOC_CTX *mem_ctx, const char *str,
|
||||
+ const char sep, bool trim, bool skip_empty,
|
||||
+ char ***_list, int *size)
|
||||
+{
|
||||
+ int ret;
|
||||
+ const char *substr_end = str;
|
||||
+ const char *substr_begin = str;
|
||||
+ const char *sep_pos = NULL;
|
||||
+ size_t substr_len;
|
||||
+ char **list = NULL;
|
||||
+ int num_strings = 0;
|
||||
+ TALLOC_CTX *tmp_ctx = NULL;
|
||||
+
|
||||
+ if (str == NULL || *str == '\0' || _list == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ do {
|
||||
+ substr_len = 0;
|
||||
+
|
||||
+ /* If this is not the first substring, then move from the separator. */
|
||||
+ if (sep_pos != NULL) {
|
||||
+ substr_end = sep_pos + 1;
|
||||
+ substr_begin = sep_pos + 1;
|
||||
+ }
|
||||
+
|
||||
+ /* Find end of the first substring */
|
||||
+ while (*substr_end != sep && *substr_end != '\0') {
|
||||
+ substr_end++;
|
||||
+ substr_len++;
|
||||
+ }
|
||||
+
|
||||
+ sep_pos = substr_end;
|
||||
+
|
||||
+ if (trim) {
|
||||
+ /* Trim leading whitespace */
|
||||
+ while (isspace(*substr_begin) && substr_begin < substr_end) {
|
||||
+ substr_begin++;
|
||||
+ substr_len--;
|
||||
+ }
|
||||
+
|
||||
+ /* Trim trailing whitespace */
|
||||
+ while (substr_end - 1 > substr_begin && isspace(*(substr_end-1))) {
|
||||
+ substr_end--;
|
||||
+ substr_len--;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Copy the substring to the output list of strings */
|
||||
+ if (skip_empty == false || substr_len > 0) {
|
||||
+ list = talloc_realloc(tmp_ctx, list, char*, num_strings + 2);
|
||||
+ if (list == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* empty string is stored for substr_len == 0 */
|
||||
+ list[num_strings] = talloc_strndup(list, substr_begin, substr_len);
|
||||
+ if (list[num_strings] == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ num_strings++;
|
||||
+ }
|
||||
+
|
||||
+ } while (*sep_pos != '\0');
|
||||
+
|
||||
+ if (list == NULL) {
|
||||
+ /* No allocations were done, make space for the NULL */
|
||||
+ list = talloc(tmp_ctx, char *);
|
||||
+ if (list == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+ list[num_strings] = NULL;
|
||||
+
|
||||
+ if (size) {
|
||||
+ *size = num_strings;
|
||||
+ }
|
||||
+
|
||||
+ *_list = talloc_steal(mem_ctx, list);
|
||||
+ ret = EOK;
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,91 +0,0 @@
|
||||
From 8b7548f65a0d812a47d26895671ec6f01b6813c1 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Mon, 20 Feb 2017 17:28:51 +0100
|
||||
Subject: [PATCH 05/97] util: move string_in_list to util_ext
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
To be able to include string_in_list() without additional
|
||||
dependencies it is moved into a separate file.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/util/util.c | 20 --------------------
|
||||
src/util/util_ext.c | 22 ++++++++++++++++++++++
|
||||
2 files changed, 22 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/src/util/util.c b/src/util/util.c
|
||||
index 9d6202f695d516f20d648621da81a2d5e746daa5..f0e8f9dd6a4bceed6befb74c57aa066b19a72bb7 100644
|
||||
--- a/src/util/util.c
|
||||
+++ b/src/util/util.c
|
||||
@@ -617,26 +617,6 @@ errno_t add_string_to_list(TALLOC_CTX *mem_ctx, const char *string,
|
||||
return EOK;
|
||||
}
|
||||
|
||||
-bool string_in_list(const char *string, char **list, bool case_sensitive)
|
||||
-{
|
||||
- size_t c;
|
||||
- int(*compare)(const char *s1, const char *s2);
|
||||
-
|
||||
- if (string == NULL || list == NULL || *list == NULL) {
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- compare = case_sensitive ? strcmp : strcasecmp;
|
||||
-
|
||||
- for (c = 0; list[c] != NULL; c++) {
|
||||
- if (compare(string, list[c]) == 0) {
|
||||
- return true;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
void safezero(void *data, size_t size)
|
||||
{
|
||||
volatile uint8_t *p = data;
|
||||
diff --git a/src/util/util_ext.c b/src/util/util_ext.c
|
||||
index fceb8c873a26471d476b39d5d4e567c445ed8d0b..04dc02a8adf32bd0590fe6eba230658e67d0a362 100644
|
||||
--- a/src/util/util_ext.c
|
||||
+++ b/src/util/util_ext.c
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
+#include <string.h>
|
||||
+#include <strings.h>
|
||||
|
||||
#define EOK 0
|
||||
|
||||
@@ -119,3 +121,23 @@ done:
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+bool string_in_list(const char *string, char **list, bool case_sensitive)
|
||||
+{
|
||||
+ size_t c;
|
||||
+ int(*compare)(const char *s1, const char *s2);
|
||||
+
|
||||
+ if (string == NULL || list == NULL || *list == NULL) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ compare = case_sensitive ? strcmp : strcasecmp;
|
||||
+
|
||||
+ for (c = 0; list[c] != NULL; c++) {
|
||||
+ if (compare(string, list[c]) == 0) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
--
|
||||
2.12.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,151 +0,0 @@
|
||||
From 31a6661ff2a640fbcf97460df2415fd1bab309b5 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Wed, 15 Mar 2017 10:57:09 +0100
|
||||
Subject: [PATCH 07/97] certmap: add placeholder for OpenSSL implementation
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
Makefile.am | 30 +++++++++++++++++++++--------
|
||||
src/lib/certmap/sss_cert_content_crypto.c | 32 +++++++++++++++++++++++++++++++
|
||||
src/lib/certmap/sss_certmap_int.h | 8 +++++---
|
||||
3 files changed, 59 insertions(+), 11 deletions(-)
|
||||
create mode 100644 src/lib/certmap/sss_cert_content_crypto.c
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 8ca12c10d2713b6a72361d84b25486500c79f407..7947b7a5fbe3ca1034baac1c13c53300994b1bf8 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -278,9 +278,12 @@ if HAVE_CMOCKA
|
||||
simple-access-tests \
|
||||
krb5_common_test \
|
||||
test_iobuf \
|
||||
- sss_certmap_test \
|
||||
$(NULL)
|
||||
|
||||
+if HAVE_NSS
|
||||
+non_interactive_cmocka_based_tests += sss_certmap_test
|
||||
+endif #HAVE_NSS
|
||||
+
|
||||
if HAVE_LIBRESOLV
|
||||
non_interactive_cmocka_based_tests += test_resolv_fake
|
||||
endif # HAVE_LIBRESOLV
|
||||
@@ -1715,7 +1718,6 @@ sssd_check_socket_activated_responders_LDADD = \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
-if HAVE_NSS
|
||||
pkgconfig_DATA += src/lib/certmap/sss_certmap.pc
|
||||
libsss_certmap_la_DEPENDENCIES = src/lib/certmap/sss_certmap.exports
|
||||
libsss_certmap_la_SOURCES = \
|
||||
@@ -1726,26 +1728,38 @@ libsss_certmap_la_SOURCES = \
|
||||
src/lib/certmap/sss_certmap_ldap_mapping.c \
|
||||
src/util/util_ext.c \
|
||||
src/util/cert/cert_common.c \
|
||||
- src/util/crypto/nss/nss_base64.c \
|
||||
- src/util/cert/nss/cert.c \
|
||||
- src/util/crypto/nss/nss_util.c \
|
||||
$(NULL)
|
||||
libsss_certmap_la_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
$(TALLOC_CFLAGS) \
|
||||
- $(NSS_CFLAGS) \
|
||||
$(NULL)
|
||||
libsss_certmap_la_LIBADD = \
|
||||
$(TALLOC_LIBS) \
|
||||
- $(NSS_LIBS) \
|
||||
$(NULL)
|
||||
libsss_certmap_la_LDFLAGS = \
|
||||
-Wl,--version-script,$(srcdir)/src/lib/certmap/sss_certmap.exports \
|
||||
-version-info 0:0:0
|
||||
|
||||
+if HAVE_NSS
|
||||
+libsss_certmap_la_SOURCES += \
|
||||
+ src/util/crypto/nss/nss_base64.c \
|
||||
+ src/util/cert/nss/cert.c \
|
||||
+ src/util/crypto/nss/nss_util.c \
|
||||
+ $(NULL)
|
||||
+libsss_certmap_la_CFLAGS += $(NSS_CFLAGS)
|
||||
+libsss_certmap_la_LIBADD += $(NSS_LIBS)
|
||||
+else
|
||||
+libsss_certmap_la_SOURCES += \
|
||||
+ src/util/crypto/libcrypto/crypto_base64.c \
|
||||
+ src/util/cert/libcrypto/cert.c \
|
||||
+ $(NULL)
|
||||
+
|
||||
+libsss_certmap_la_CFLAGS += $(CRYPTO_CFLAGS)
|
||||
+libsss_certmap_la_LIBADD += $(CRYPTO_LIBS)
|
||||
+endif
|
||||
+
|
||||
dist_noinst_DATA += src/lib/certmap/sss_certmap.exports
|
||||
dist_noinst_HEADERS += src/lib/certmap/sss_certmap_int.h
|
||||
-endif
|
||||
|
||||
#################
|
||||
# Feature Tests #
|
||||
diff --git a/src/lib/certmap/sss_cert_content_crypto.c b/src/lib/certmap/sss_cert_content_crypto.c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bddcf9bce986bd986aa0aa5f16a0744a97ab36d6
|
||||
--- /dev/null
|
||||
+++ b/src/lib/certmap/sss_cert_content_crypto.c
|
||||
@@ -0,0 +1,32 @@
|
||||
+/*
|
||||
+ SSSD - certificate handling utils - OpenSSL version
|
||||
+ The calls defined here should be useable outside of SSSD as well, e.g. in
|
||||
+ libsss_certmap.
|
||||
+
|
||||
+ Copyright (C) Sumit Bose <sbose@redhat.com> 2017
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU General Public License as published by
|
||||
+ the Free Software Foundation; either version 3 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+*/
|
||||
+
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include "lib/certmap/sss_certmap.h"
|
||||
+#include "lib/certmap/sss_certmap_int.h"
|
||||
+
|
||||
+int sss_cert_get_content(TALLOC_CTX *mem_ctx,
|
||||
+ const uint8_t *der_blob, size_t der_size,
|
||||
+ struct sss_cert_content **content)
|
||||
+{
|
||||
+ return EINVAL;
|
||||
+}
|
||||
diff --git a/src/lib/certmap/sss_certmap_int.h b/src/lib/certmap/sss_certmap_int.h
|
||||
index 28f1c596cfb5e78077b6a8e9baefa88b4900a022..0b4cda73639be9b323ac3388f97be90bc1a771f2 100644
|
||||
--- a/src/lib/certmap/sss_certmap_int.h
|
||||
+++ b/src/lib/certmap/sss_certmap_int.h
|
||||
@@ -22,12 +22,14 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
-#include <sys/types.h>
|
||||
-#include <regex.h>
|
||||
-
|
||||
#ifndef __SSS_CERTMAP_INT_H__
|
||||
#define __SSS_CERTMAP_INT_H__
|
||||
|
||||
+#include <sys/types.h>
|
||||
+#include <regex.h>
|
||||
+#include <stdint.h>
|
||||
+#include <talloc.h>
|
||||
+
|
||||
#define CM_DEBUG(cm_ctx, format, ...) do { \
|
||||
if (cm_ctx != NULL && cm_ctx->debug != NULL) { \
|
||||
cm_ctx->debug(cm_ctx->debug_priv, __FILE__, __LINE__, __FUNCTION__, \
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,173 +0,0 @@
|
||||
From 3994e8779d16db3e9fb30f03e5ecf5e811095ac2 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Mon, 21 Sep 2015 12:32:48 +0200
|
||||
Subject: [PATCH 08/97] sysdb: add sysdb_attrs_copy()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/db/sysdb.c | 24 ++++++++++++++
|
||||
src/db/sysdb.h | 1 +
|
||||
src/tests/sysdb-tests.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 112 insertions(+)
|
||||
|
||||
diff --git a/src/db/sysdb.c b/src/db/sysdb.c
|
||||
index 5160e3df3810a113d4ec1371350e51a074aaa146..98b7afbfab5141fa9b63a4aab31c620545b3c1f2 100644
|
||||
--- a/src/db/sysdb.c
|
||||
+++ b/src/db/sysdb.c
|
||||
@@ -752,6 +752,30 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+errno_t sysdb_attrs_copy(struct sysdb_attrs *src, struct sysdb_attrs *dst)
|
||||
+{
|
||||
+ int ret;
|
||||
+ size_t c;
|
||||
+ size_t d;
|
||||
+
|
||||
+ if (src == NULL || dst == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ for (c = 0; c < src->num; c++) {
|
||||
+ for (d = 0; d < src->a[c].num_values; d++) {
|
||||
+ ret = sysdb_attrs_add_val_safe(dst, src->a[c].name,
|
||||
+ &src->a[c].values[d]);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_val failed.\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
int sysdb_attrs_users_from_str_list(struct sysdb_attrs *attrs,
|
||||
const char *attr_name,
|
||||
const char *domain,
|
||||
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
|
||||
index 83d0d794c737c094d1fd52e7cc7f2113b5d9a7a0..c677957bb639e40db2f985205160612094302e78 100644
|
||||
--- a/src/db/sysdb.h
|
||||
+++ b/src/db/sysdb.h
|
||||
@@ -352,6 +352,7 @@ int sysdb_attrs_add_lc_name_alias_safe(struct sysdb_attrs *attrs,
|
||||
int sysdb_attrs_copy_values(struct sysdb_attrs *src,
|
||||
struct sysdb_attrs *dst,
|
||||
const char *name);
|
||||
+errno_t sysdb_attrs_copy(struct sysdb_attrs *src, struct sysdb_attrs *dst);
|
||||
int sysdb_attrs_get_el(struct sysdb_attrs *attrs, const char *name,
|
||||
struct ldb_message_element **el);
|
||||
int sysdb_attrs_get_el_ext(struct sysdb_attrs *attrs, const char *name,
|
||||
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
|
||||
index 013b01a9a68d9de87d796d3aff41d98cef8cccc3..c343c734a27a335303974b6866a5d9e88d4c307e 100644
|
||||
--- a/src/tests/sysdb-tests.c
|
||||
+++ b/src/tests/sysdb-tests.c
|
||||
@@ -4997,6 +4997,92 @@ START_TEST(test_sysdb_attrs_add_string_safe)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
+START_TEST(test_sysdb_attrs_copy)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct sysdb_attrs *src;
|
||||
+ struct sysdb_attrs *dst;
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ const char *val;
|
||||
+ const char **array;
|
||||
+
|
||||
+ ret = sysdb_attrs_copy(NULL, NULL);
|
||||
+ fail_unless(ret == EINVAL, "Wrong return code");
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ fail_unless(tmp_ctx != NULL, "talloc_new failed");
|
||||
+
|
||||
+ src = sysdb_new_attrs(tmp_ctx);
|
||||
+ fail_unless(src != NULL, "sysdb_new_attrs failed");
|
||||
+
|
||||
+ ret = sysdb_attrs_copy(src, NULL);
|
||||
+ fail_unless(ret == EINVAL, "Wrong return code");
|
||||
+
|
||||
+ dst = sysdb_new_attrs(tmp_ctx);
|
||||
+ fail_unless(dst != NULL, "sysdb_new_attrs failed");
|
||||
+
|
||||
+ ret = sysdb_attrs_copy(NULL, dst);
|
||||
+ fail_unless(ret == EINVAL, "Wrong return code");
|
||||
+
|
||||
+ ret = sysdb_attrs_copy(src, dst);
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_copy failed");
|
||||
+ fail_unless(dst->num == 0, "Wrong number of elements");
|
||||
+
|
||||
+ ret = sysdb_attrs_add_string(src, TEST_ATTR_NAME, TEST_ATTR_VALUE);
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_add_val failed.");
|
||||
+
|
||||
+ ret = sysdb_attrs_copy(src, dst);
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_copy failed");
|
||||
+ fail_unless(dst->num == 1, "Wrong number of elements");
|
||||
+ ret = sysdb_attrs_get_string(dst, TEST_ATTR_NAME, &val);
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_get_string failed.\n");
|
||||
+ fail_unless(strcmp(val, TEST_ATTR_VALUE) == 0, "Wrong attribute value.");
|
||||
+
|
||||
+ /* Make sure the same entry is not copied twice */
|
||||
+ ret = sysdb_attrs_copy(src, dst);
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_copy failed");
|
||||
+ fail_unless(dst->num == 1, "Wrong number of elements");
|
||||
+ ret = sysdb_attrs_get_string(dst, TEST_ATTR_NAME, &val);
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_get_string failed.\n");
|
||||
+ fail_unless(strcmp(val, TEST_ATTR_VALUE) == 0, "Wrong attribute value.");
|
||||
+
|
||||
+ /* Add new value to existing attribute */
|
||||
+ ret = sysdb_attrs_add_string(src, TEST_ATTR_NAME, TEST_ATTR_VALUE"_2nd");
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_add_val failed.");
|
||||
+
|
||||
+ ret = sysdb_attrs_copy(src, dst);
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_copy failed");
|
||||
+ fail_unless(dst->num == 1, "Wrong number of elements");
|
||||
+ ret = sysdb_attrs_get_string_array(dst, TEST_ATTR_NAME, tmp_ctx, &array);
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_get_string_array failed.\n");
|
||||
+ fail_unless(strcmp(array[0], TEST_ATTR_VALUE) == 0,
|
||||
+ "Wrong attribute value.");
|
||||
+ fail_unless(strcmp(array[1], TEST_ATTR_VALUE"_2nd") == 0,
|
||||
+ "Wrong attribute value.");
|
||||
+ fail_unless(array[2] == NULL, "Wrong number of values.");
|
||||
+
|
||||
+ /* Add new attribute */
|
||||
+ ret = sysdb_attrs_add_string(src, TEST_ATTR_NAME"_2nd", TEST_ATTR_VALUE);
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_add_val failed.");
|
||||
+
|
||||
+ ret = sysdb_attrs_copy(src, dst);
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_copy failed");
|
||||
+ fail_unless(dst->num == 2, "Wrong number of elements");
|
||||
+ ret = sysdb_attrs_get_string_array(dst, TEST_ATTR_NAME, tmp_ctx, &array);
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_get_string_array failed.\n");
|
||||
+ fail_unless(strcmp(array[0], TEST_ATTR_VALUE) == 0,
|
||||
+ "Wrong attribute value.");
|
||||
+ fail_unless(strcmp(array[1], TEST_ATTR_VALUE"_2nd") == 0,
|
||||
+ "Wrong attribute value.");
|
||||
+ fail_unless(array[2] == NULL, "Wrong number of values.");
|
||||
+ ret = sysdb_attrs_get_string(dst, TEST_ATTR_NAME"_2nd", &val);
|
||||
+ fail_unless(ret == EOK, "sysdb_attrs_get_string failed.\n");
|
||||
+ fail_unless(strcmp(val, TEST_ATTR_VALUE) == 0, "Wrong attribute value.");
|
||||
+
|
||||
+ talloc_free(tmp_ctx);
|
||||
+}
|
||||
+END_TEST
|
||||
+
|
||||
START_TEST (test_sysdb_search_return_ENOENT)
|
||||
{
|
||||
struct sysdb_test_ctx *test_ctx;
|
||||
@@ -6995,6 +7081,7 @@ Suite *create_sysdb_suite(void)
|
||||
tcase_add_test(tc_sysdb, test_sysdb_attrs_add_val);
|
||||
tcase_add_test(tc_sysdb, test_sysdb_attrs_add_val_safe);
|
||||
tcase_add_test(tc_sysdb, test_sysdb_attrs_add_string_safe);
|
||||
+ tcase_add_test(tc_sysdb, test_sysdb_attrs_copy);
|
||||
|
||||
/* ===== Test search return empty result ===== */
|
||||
tcase_add_test(tc_sysdb, test_sysdb_search_return_ENOENT);
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,316 +0,0 @@
|
||||
From 70c0648f021ded3d31313eb962e1ad140f242673 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Sun, 12 Mar 2017 18:31:03 +0100
|
||||
Subject: [PATCH 09/97] sdap_get_users_send(): new argument mapped_attrs
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
mapped_attrs can be a list of sysdb_attrs which are not available on
|
||||
the server side but should be store with the cached user entry. This is
|
||||
needed e.g. when the input to look up the user in LDAP is not an
|
||||
attribute which is stored in LDAP but some data where LDAP attributes
|
||||
are extracted from. The current use case is the certificate mapping
|
||||
library which can create LDAP search filters based on content of the
|
||||
certificate. To allow upcoming cache lookup to use the input directly it
|
||||
is stored in the user object in the cache.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/db/sysdb.h | 3 ++
|
||||
src/db/sysdb_ops.c | 61 ++++++++++++++++++++++++++++++
|
||||
src/providers/ldap/ldap_id.c | 4 +-
|
||||
src/providers/ldap/sdap_async.h | 3 +-
|
||||
src/providers/ldap/sdap_async_enum.c | 2 +-
|
||||
src/providers/ldap/sdap_async_initgroups.c | 2 +-
|
||||
src/providers/ldap/sdap_async_private.h | 1 +
|
||||
src/providers/ldap/sdap_async_users.c | 41 +++++++++++++++++++-
|
||||
src/providers/ldap/sdap_users.h | 1 +
|
||||
9 files changed, 111 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
|
||||
index c677957bb639e40db2f985205160612094302e78..098f47f91187aac75c58c02f0af738c344765762 100644
|
||||
--- a/src/db/sysdb.h
|
||||
+++ b/src/db/sysdb.h
|
||||
@@ -1246,6 +1246,9 @@ errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx,
|
||||
errno_t sysdb_remove_cert(struct sss_domain_info *domain,
|
||||
const char *cert);
|
||||
|
||||
+errno_t sysdb_remove_mapped_data(struct sss_domain_info *domain,
|
||||
+ struct sysdb_attrs *mapped_attr);
|
||||
+
|
||||
/* === Functions related to GPOs === */
|
||||
|
||||
#define SYSDB_GPO_CONTAINER "cn=gpos,cn=ad,cn=custom"
|
||||
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
|
||||
index 242d3ce3bb795691e329790a07c3493672e8f523..6c2254df2b75d3d3419528523103ad9cddb40c9d 100644
|
||||
--- a/src/db/sysdb_ops.c
|
||||
+++ b/src/db/sysdb_ops.c
|
||||
@@ -4685,6 +4685,67 @@ errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx,
|
||||
return sysdb_search_object_by_cert(mem_ctx, domain, cert, user_attrs, res);
|
||||
}
|
||||
|
||||
+errno_t sysdb_remove_mapped_data(struct sss_domain_info *domain,
|
||||
+ struct sysdb_attrs *mapped_attr)
|
||||
+{
|
||||
+ int ret;
|
||||
+ char *val;
|
||||
+ char *filter;
|
||||
+ const char *attrs[] = {SYSDB_NAME, NULL};
|
||||
+ struct ldb_result *res = NULL;
|
||||
+ size_t c;
|
||||
+ bool all_ok = true;
|
||||
+
|
||||
+ if (mapped_attr->num != 1 || mapped_attr->a[0].num_values != 1) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "Unsupported number of attributes.\n");
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = bin_to_ldap_filter_value(NULL, mapped_attr->a[0].values[0].data,
|
||||
+ mapped_attr->a[0].values[0].length, &val);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "bin_to_ldap_filter_value failed.\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ filter = talloc_asprintf(NULL, "(&("SYSDB_UC")(%s=%s))",
|
||||
+ mapped_attr->a[0].name, val);
|
||||
+ talloc_free(val);
|
||||
+ if (filter == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_search_object_attr(NULL, domain, filter, attrs, false, &res);
|
||||
+ talloc_free(filter);
|
||||
+ if (ret == ENOENT || res == NULL) {
|
||||
+ DEBUG(SSSDBG_TRACE_ALL, "Mapped data not found.\n");
|
||||
+ talloc_free(res);
|
||||
+ return EOK;
|
||||
+ } else if (ret != EOK) {
|
||||
+ talloc_free(res);
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_object_attr failed.\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ for (c = 0; c < res->count; c++) {
|
||||
+ DEBUG(SSSDBG_TRACE_ALL, "Removing mapped data from [%s].\n",
|
||||
+ ldb_dn_get_linearized(res->msgs[c]->dn));
|
||||
+ /* The timestamp cache is skipped on purpose here. */
|
||||
+ ret = sysdb_set_cache_entry_attr(domain->sysdb->ldb, res->msgs[c]->dn,
|
||||
+ mapped_attr, SYSDB_MOD_DEL);
|
||||
+ if (ret != EOK) {
|
||||
+ all_ok = false;
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Failed to remove mapped data from [%s], skipping.\n",
|
||||
+ ldb_dn_get_linearized(res->msgs[c]->dn));
|
||||
+ }
|
||||
+ }
|
||||
+ talloc_free(res);
|
||||
+
|
||||
+ return (all_ok ? EOK : EIO);
|
||||
+}
|
||||
+
|
||||
errno_t sysdb_remove_cert(struct sss_domain_info *domain,
|
||||
const char *cert)
|
||||
{
|
||||
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
|
||||
index e9455b538daa2d65d944dbb68022a2773623d7b7..898ddb18689d55fcc3fdf021b38df0e574003eb2 100644
|
||||
--- a/src/providers/ldap/ldap_id.c
|
||||
+++ b/src/providers/ldap/ldap_id.c
|
||||
@@ -442,7 +442,7 @@ static void users_get_search(struct tevent_req *req)
|
||||
state->attrs, state->filter,
|
||||
dp_opt_get_int(state->ctx->opts->basic,
|
||||
SDAP_SEARCH_TIMEOUT),
|
||||
- lookup_type);
|
||||
+ lookup_type, NULL);
|
||||
if (!subreq) {
|
||||
tevent_req_error(req, ENOMEM);
|
||||
return;
|
||||
@@ -507,7 +507,7 @@ static void users_get_done(struct tevent_req *subreq)
|
||||
ret = sdap_fallback_local_user(state, state->shortname, uid, &usr_attrs);
|
||||
if (ret == EOK) {
|
||||
ret = sdap_save_user(state, state->ctx->opts, state->domain,
|
||||
- usr_attrs[0], NULL, 0);
|
||||
+ usr_attrs[0], NULL, NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
|
||||
index 2ebde6b83646408e446c91cb324809cb767b2617..6e5800b42ba4a045fa7985b09a80b6b86b8c6055 100644
|
||||
--- a/src/providers/ldap/sdap_async.h
|
||||
+++ b/src/providers/ldap/sdap_async.h
|
||||
@@ -90,7 +90,8 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx,
|
||||
const char **attrs,
|
||||
const char *filter,
|
||||
int timeout,
|
||||
- enum sdap_entry_lookup_type lookup_type);
|
||||
+ enum sdap_entry_lookup_type lookup_type,
|
||||
+ struct sysdb_attrs *mapped_attrs);
|
||||
int sdap_get_users_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx, char **timestamp);
|
||||
|
||||
diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c
|
||||
index 387e53155b567ce106cc68009c7cb99e27d24a17..3f65059e18d5c8b548da0babec867d27c3a64198 100644
|
||||
--- a/src/providers/ldap/sdap_async_enum.c
|
||||
+++ b/src/providers/ldap/sdap_async_enum.c
|
||||
@@ -635,7 +635,7 @@ static struct tevent_req *enum_users_send(TALLOC_CTX *memctx,
|
||||
state->attrs, state->filter,
|
||||
dp_opt_get_int(state->ctx->opts->basic,
|
||||
SDAP_ENUM_SEARCH_TIMEOUT),
|
||||
- SDAP_LOOKUP_ENUMERATE);
|
||||
+ SDAP_LOOKUP_ENUMERATE, NULL);
|
||||
if (!subreq) {
|
||||
ret = ENOMEM;
|
||||
goto fail;
|
||||
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
|
||||
index 8c7a65bf36abf341e077cf9eac18a234d3a07c07..79af7a3eda3fe8533933535c98c2b4b4698dfda2 100644
|
||||
--- a/src/providers/ldap/sdap_async_initgroups.c
|
||||
+++ b/src/providers/ldap/sdap_async_initgroups.c
|
||||
@@ -2991,7 +2991,7 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
|
||||
DEBUG(SSSDBG_TRACE_ALL, "Storing the user\n");
|
||||
|
||||
ret = sdap_save_user(state, state->opts, state->dom, state->orig_user,
|
||||
- NULL, 0);
|
||||
+ NULL, NULL, 0);
|
||||
if (ret) {
|
||||
goto fail;
|
||||
}
|
||||
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
|
||||
index 266bc03115e2bdd6a283f5f7da565fd00d3a77be..72507442a9ffd5c0e24ccbd95d75d3ebf9bf0940 100644
|
||||
--- a/src/providers/ldap/sdap_async_private.h
|
||||
+++ b/src/providers/ldap/sdap_async_private.h
|
||||
@@ -94,6 +94,7 @@ int sdap_save_users(TALLOC_CTX *memctx,
|
||||
struct sdap_options *opts,
|
||||
struct sysdb_attrs **users,
|
||||
int num_users,
|
||||
+ struct sysdb_attrs *mapped_attrs,
|
||||
char **_usn_value);
|
||||
|
||||
int sdap_initgr_common_store(struct sysdb_ctx *sysdb,
|
||||
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
|
||||
index 87d91d8247c37a4c6a1d83b7189399056528fc90..3d957ab584865f74499bc732395388a78965fe5f 100644
|
||||
--- a/src/providers/ldap/sdap_async_users.c
|
||||
+++ b/src/providers/ldap/sdap_async_users.c
|
||||
@@ -117,6 +117,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
|
||||
struct sdap_options *opts,
|
||||
struct sss_domain_info *dom,
|
||||
struct sysdb_attrs *attrs,
|
||||
+ struct sysdb_attrs *mapped_attrs,
|
||||
char **_usn_value,
|
||||
time_t now)
|
||||
{
|
||||
@@ -511,6 +512,11 @@ int sdap_save_user(TALLOC_CTX *memctx,
|
||||
user_attrs, missing, cache_timeout, now);
|
||||
if (ret) goto done;
|
||||
|
||||
+ if (mapped_attrs != NULL) {
|
||||
+ ret = sysdb_set_user_attr(dom, user_name, mapped_attrs, SYSDB_MOD_ADD);
|
||||
+ if (ret) return ret;
|
||||
+ }
|
||||
+
|
||||
if (_usn_value) {
|
||||
*_usn_value = talloc_steal(memctx, usn_value);
|
||||
}
|
||||
@@ -537,6 +543,7 @@ int sdap_save_users(TALLOC_CTX *memctx,
|
||||
struct sdap_options *opts,
|
||||
struct sysdb_attrs **users,
|
||||
int num_users,
|
||||
+ struct sysdb_attrs *mapped_attrs,
|
||||
char **_usn_value)
|
||||
{
|
||||
TALLOC_CTX *tmpctx;
|
||||
@@ -565,11 +572,20 @@ int sdap_save_users(TALLOC_CTX *memctx,
|
||||
}
|
||||
in_transaction = true;
|
||||
|
||||
+ if (mapped_attrs != NULL) {
|
||||
+ ret = sysdb_remove_mapped_data(dom, mapped_attrs);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_remove_mapped_data failed, "
|
||||
+ "some cached entries might contain invalid mapping data.\n");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
now = time(NULL);
|
||||
for (i = 0; i < num_users; i++) {
|
||||
usn_value = NULL;
|
||||
|
||||
- ret = sdap_save_user(tmpctx, opts, dom, users[i], &usn_value, now);
|
||||
+ ret = sdap_save_user(tmpctx, opts, dom, users[i], mapped_attrs,
|
||||
+ &usn_value, now);
|
||||
|
||||
/* Do not fail completely on errors.
|
||||
* Just report the failure to save and go on */
|
||||
@@ -868,6 +884,7 @@ struct sdap_get_users_state {
|
||||
|
||||
char *higher_usn;
|
||||
struct sysdb_attrs **users;
|
||||
+ struct sysdb_attrs *mapped_attrs;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
@@ -883,7 +900,8 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx,
|
||||
const char **attrs,
|
||||
const char *filter,
|
||||
int timeout,
|
||||
- enum sdap_entry_lookup_type lookup_type)
|
||||
+ enum sdap_entry_lookup_type lookup_type,
|
||||
+ struct sysdb_attrs *mapped_attrs)
|
||||
{
|
||||
errno_t ret;
|
||||
struct tevent_req *req;
|
||||
@@ -900,6 +918,23 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx,
|
||||
state->filter = filter;
|
||||
PROBE(SDAP_SEARCH_USER_SEND, state->filter);
|
||||
|
||||
+ if (mapped_attrs == NULL) {
|
||||
+ state->mapped_attrs = NULL;
|
||||
+ } else {
|
||||
+ state->mapped_attrs = sysdb_new_attrs(state);
|
||||
+ if (state->mapped_attrs == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_attrs_copy(mapped_attrs, state->mapped_attrs);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_copy failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
subreq = sdap_search_user_send(state, ev, dom, opts, search_bases,
|
||||
sh, attrs, filter, timeout, lookup_type);
|
||||
if (subreq == NULL) {
|
||||
@@ -938,9 +973,11 @@ static void sdap_get_users_done(struct tevent_req *subreq)
|
||||
}
|
||||
|
||||
PROBE(SDAP_SEARCH_USER_SAVE_BEGIN, state->filter);
|
||||
+
|
||||
ret = sdap_save_users(state, state->sysdb,
|
||||
state->dom, state->opts,
|
||||
state->users, state->count,
|
||||
+ state->mapped_attrs,
|
||||
&state->higher_usn);
|
||||
PROBE(SDAP_SEARCH_USER_SAVE_END, state->filter);
|
||||
if (ret) {
|
||||
diff --git a/src/providers/ldap/sdap_users.h b/src/providers/ldap/sdap_users.h
|
||||
index 78dafb31a2a07e7289055daec77c5dc5da1bdeef..a6d088a6d7114db75b0f0ea22ef85c57da6fab0f 100644
|
||||
--- a/src/providers/ldap/sdap_users.h
|
||||
+++ b/src/providers/ldap/sdap_users.h
|
||||
@@ -34,6 +34,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
|
||||
struct sdap_options *opts,
|
||||
struct sss_domain_info *dom,
|
||||
struct sysdb_attrs *attrs,
|
||||
+ struct sysdb_attrs *mapped_attrs,
|
||||
char **_usn_value,
|
||||
time_t now);
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,178 +0,0 @@
|
||||
From 81c564a0692aa4b719af2219f52894e6cd4bdf9f Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Mon, 30 Nov 2015 12:14:55 +0100
|
||||
Subject: [PATCH 10/97] LDAP: always store the certificate from the request
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Store the certificate used to lookup a user as mapped attribute in the
|
||||
cached user object.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/db/sysdb.h | 1 +
|
||||
src/db/sysdb_ops.c | 4 ++--
|
||||
src/providers/ldap/ldap_id.c | 19 ++++++++++++++++++-
|
||||
src/tests/cmocka/test_nss_srv.c | 2 +-
|
||||
src/tests/cmocka/test_pam_srv.c | 6 +++---
|
||||
src/tests/sysdb-tests.c | 4 ++--
|
||||
6 files changed, 27 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
|
||||
index 098f47f91187aac75c58c02f0af738c344765762..3db22b3689bf6ffd9a48e29c229916e3fac9ca1b 100644
|
||||
--- a/src/db/sysdb.h
|
||||
+++ b/src/db/sysdb.h
|
||||
@@ -139,6 +139,7 @@
|
||||
|
||||
#define SYSDB_AUTH_TYPE "authType"
|
||||
#define SYSDB_USER_CERT "userCertificate"
|
||||
+#define SYSDB_USER_MAPPED_CERT "userMappedCertificate"
|
||||
#define SYSDB_USER_EMAIL "mail"
|
||||
|
||||
#define SYSDB_SUBDOMAIN_REALM "realmName"
|
||||
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
|
||||
index 6c2254df2b75d3d3419528523103ad9cddb40c9d..8ae25764478e522255b177f9e8de1d3ca1ad43fd 100644
|
||||
--- a/src/db/sysdb_ops.c
|
||||
+++ b/src/db/sysdb_ops.c
|
||||
@@ -4660,7 +4660,7 @@ errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx,
|
||||
int ret;
|
||||
char *user_filter;
|
||||
|
||||
- ret = sss_cert_derb64_to_ldap_filter(mem_ctx, cert, SYSDB_USER_CERT,
|
||||
+ ret = sss_cert_derb64_to_ldap_filter(mem_ctx, cert, SYSDB_USER_MAPPED_CERT,
|
||||
&user_filter);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n");
|
||||
@@ -4749,7 +4749,7 @@ errno_t sysdb_remove_mapped_data(struct sss_domain_info *domain,
|
||||
errno_t sysdb_remove_cert(struct sss_domain_info *domain,
|
||||
const char *cert)
|
||||
{
|
||||
- struct ldb_message_element el = { 0, SYSDB_USER_CERT, 0, NULL };
|
||||
+ struct ldb_message_element el = { 0, SYSDB_USER_MAPPED_CERT, 0, NULL };
|
||||
struct sysdb_attrs del_attrs = { 1, &el };
|
||||
const char *attrs[] = {SYSDB_NAME, NULL};
|
||||
struct ldb_result *res = NULL;
|
||||
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
|
||||
index 898ddb18689d55fcc3fdf021b38df0e574003eb2..a8b4bc2cfc6e9d4e0d74b0e3e036afbcbf7eb26e 100644
|
||||
--- a/src/providers/ldap/ldap_id.c
|
||||
+++ b/src/providers/ldap/ldap_id.c
|
||||
@@ -60,6 +60,7 @@ struct users_get_state {
|
||||
int dp_error;
|
||||
int sdap_ret;
|
||||
bool noexist_delete;
|
||||
+ struct sysdb_attrs *extra_attrs;
|
||||
};
|
||||
|
||||
static int users_get_retry(struct tevent_req *req);
|
||||
@@ -99,6 +100,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
||||
state->conn = conn;
|
||||
state->dp_error = DP_ERR_FATAL;
|
||||
state->noexist_delete = noexist_delete;
|
||||
+ state->extra_attrs = NULL;
|
||||
|
||||
state->op = sdap_id_op_create(state, state->conn->conn_cache);
|
||||
if (!state->op) {
|
||||
@@ -251,6 +253,21 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
||||
"sss_cert_derb64_to_ldap_filter failed.\n");
|
||||
goto done;
|
||||
}
|
||||
+
|
||||
+ state->extra_attrs = sysdb_new_attrs(state);
|
||||
+ if (state->extra_attrs == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_attrs_add_base64_blob(state->extra_attrs,
|
||||
+ SYSDB_USER_MAPPED_CERT, filter_value);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_base64_blob failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
break;
|
||||
default:
|
||||
ret = EINVAL;
|
||||
@@ -442,7 +459,7 @@ static void users_get_search(struct tevent_req *req)
|
||||
state->attrs, state->filter,
|
||||
dp_opt_get_int(state->ctx->opts->basic,
|
||||
SDAP_SEARCH_TIMEOUT),
|
||||
- lookup_type, NULL);
|
||||
+ lookup_type, state->extra_attrs);
|
||||
if (!subreq) {
|
||||
tevent_req_error(req, ENOMEM);
|
||||
return;
|
||||
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
|
||||
index 72bbaf9bf35ebb3fc4208afaa3c7af95922afcb0..76b9c6fb05673130de0957e93291919c263a28f3 100644
|
||||
--- a/src/tests/cmocka/test_nss_srv.c
|
||||
+++ b/src/tests/cmocka/test_nss_srv.c
|
||||
@@ -3508,7 +3508,7 @@ static void test_nss_getnamebycert(void **state)
|
||||
der = sss_base64_decode(nss_test_ctx, TEST_TOKEN_CERT, &der_size);
|
||||
assert_non_null(der);
|
||||
|
||||
- ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_CERT, der, der_size);
|
||||
+ ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_MAPPED_CERT, der, der_size);
|
||||
talloc_free(der);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
|
||||
index ae2e555f7024027d1c0063031f8882bf81a31905..847419658bb983e6548722d6fa6fb22c63ee86b8 100644
|
||||
--- a/src/tests/cmocka/test_pam_srv.c
|
||||
+++ b/src/tests/cmocka/test_pam_srv.c
|
||||
@@ -1598,7 +1598,7 @@ static int test_lookup_by_cert_cb(void *pvt)
|
||||
der = sss_base64_decode(pam_test_ctx, pvt, &der_size);
|
||||
assert_non_null(der);
|
||||
|
||||
- ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_CERT, der, der_size);
|
||||
+ ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_MAPPED_CERT, der, der_size);
|
||||
talloc_free(der);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
@@ -1630,7 +1630,7 @@ static int test_lookup_by_cert_double_cb(void *pvt)
|
||||
der = sss_base64_decode(pam_test_ctx, pvt, &der_size);
|
||||
assert_non_null(der);
|
||||
|
||||
- ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_CERT, der, der_size);
|
||||
+ ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_MAPPED_CERT, der, der_size);
|
||||
talloc_free(der);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
@@ -1658,7 +1658,7 @@ static int test_lookup_by_cert_wrong_user_cb(void *pvt)
|
||||
der = sss_base64_decode(pam_test_ctx, pvt, &der_size);
|
||||
assert_non_null(der);
|
||||
|
||||
- ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_CERT, der, der_size);
|
||||
+ ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_MAPPED_CERT, der, der_size);
|
||||
talloc_free(der);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
|
||||
index c343c734a27a335303974b6866a5d9e88d4c307e..5bdd631fbfa1b4463fb169e5f07b65fb2c784096 100644
|
||||
--- a/src/tests/sysdb-tests.c
|
||||
+++ b/src/tests/sysdb-tests.c
|
||||
@@ -5721,7 +5721,7 @@ START_TEST(test_sysdb_search_user_by_cert)
|
||||
val.data = sss_base64_decode(test_ctx, TEST_USER_CERT_DERB64, &val.length);
|
||||
fail_unless(val.data != NULL, "sss_base64_decode failed.");
|
||||
|
||||
- ret = sysdb_attrs_add_val(data->attrs, SYSDB_USER_CERT, &val);
|
||||
+ ret = sysdb_attrs_add_val(data->attrs, SYSDB_USER_MAPPED_CERT, &val);
|
||||
fail_unless(ret == EOK, "sysdb_attrs_add_val failed with [%d][%s].",
|
||||
ret, strerror(ret));
|
||||
|
||||
@@ -5750,7 +5750,7 @@ START_TEST(test_sysdb_search_user_by_cert)
|
||||
data2 = test_data_new_user(test_ctx, 2345671);
|
||||
fail_if(data2 == NULL);
|
||||
|
||||
- ret = sysdb_attrs_add_val(data2->attrs, SYSDB_USER_CERT, &val);
|
||||
+ ret = sysdb_attrs_add_val(data2->attrs, SYSDB_USER_MAPPED_CERT, &val);
|
||||
fail_unless(ret == EOK, "sysdb_attrs_add_val failed with [%d][%s].",
|
||||
ret, strerror(ret));
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,235 +0,0 @@
|
||||
From b341ee51cffd98b642b9c68a417f8a7504e303a1 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Thu, 2 Feb 2017 16:34:32 +0100
|
||||
Subject: [PATCH 11/97] sss_cert_derb64_to_ldap_filter: add sss_certmap support
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Use certificate mapping library if available to lookup a user by
|
||||
certificate in LDAP.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
Makefile.am | 1 +
|
||||
src/db/sysdb_ops.c | 2 +-
|
||||
src/db/sysdb_views.c | 4 +-
|
||||
src/providers/ipa/ipa_views.c | 2 +-
|
||||
src/providers/ldap/ldap_id.c | 2 +-
|
||||
src/tests/cmocka/test_cert_utils.c | 4 +-
|
||||
src/util/cert.h | 3 ++
|
||||
src/util/cert/cert_common.c | 76 ++++++++++++++++++++++++++++++++------
|
||||
8 files changed, 76 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 7947b7a5fbe3ca1034baac1c13c53300994b1bf8..f262cc24832358910dbb92ccd46f93c9eda8a295 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -952,6 +952,7 @@ libsss_cert_la_LIBADD = \
|
||||
$(TALLOC_LIBS) \
|
||||
libsss_crypt.la \
|
||||
libsss_debug.la \
|
||||
+ libsss_certmap.la \
|
||||
$(NULL)
|
||||
libsss_cert_la_LDFLAGS = \
|
||||
-avoid-version \
|
||||
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
|
||||
index 8ae25764478e522255b177f9e8de1d3ca1ad43fd..919f22370ff87eff2bf0bb569ca90f1ee699a61e 100644
|
||||
--- a/src/db/sysdb_ops.c
|
||||
+++ b/src/db/sysdb_ops.c
|
||||
@@ -4661,7 +4661,7 @@ errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx,
|
||||
char *user_filter;
|
||||
|
||||
ret = sss_cert_derb64_to_ldap_filter(mem_ctx, cert, SYSDB_USER_MAPPED_CERT,
|
||||
- &user_filter);
|
||||
+ NULL, NULL, &user_filter);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n");
|
||||
return ret;
|
||||
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
|
||||
index 9dc48f5b6c414bbc7c64bcd1fe73553f388588bd..1c416dd14049237e9f35d52f154035e3ff861469 100644
|
||||
--- a/src/db/sysdb_views.c
|
||||
+++ b/src/db/sysdb_views.c
|
||||
@@ -862,8 +862,8 @@ errno_t sysdb_search_override_by_cert(TALLOC_CTX *mem_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- ret = sss_cert_derb64_to_ldap_filter(tmp_ctx, cert, SYSDB_USER_CERT,
|
||||
- &cert_filter);
|
||||
+ ret = sss_cert_derb64_to_ldap_filter(tmp_ctx, cert, SYSDB_USER_CERT, NULL,
|
||||
+ NULL, &cert_filter);
|
||||
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n");
|
||||
diff --git a/src/providers/ipa/ipa_views.c b/src/providers/ipa/ipa_views.c
|
||||
index 29f589ec1fd05f59175dcc4592e6395941e6e034..5b6fcbc9b7c6f2ea7dbeecb01a5a3fd11b8a6854 100644
|
||||
--- a/src/providers/ipa/ipa_views.c
|
||||
+++ b/src/providers/ipa/ipa_views.c
|
||||
@@ -156,7 +156,7 @@ static errno_t dp_id_data_to_override_filter(TALLOC_CTX *mem_ctx,
|
||||
if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_BY_CERT) {
|
||||
ret = sss_cert_derb64_to_ldap_filter(mem_ctx, ar->filter_value,
|
||||
ipa_opts->override_map[IPA_AT_OVERRIDE_USER_CERT].name,
|
||||
- &cert_filter);
|
||||
+ NULL, NULL, &cert_filter);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
"sss_cert_derb64_to_ldap_filter failed.\n");
|
||||
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
|
||||
index a8b4bc2cfc6e9d4e0d74b0e3e036afbcbf7eb26e..8e60769d09383ac8ebe33e5f64fd4fd9788e82cd 100644
|
||||
--- a/src/providers/ldap/ldap_id.c
|
||||
+++ b/src/providers/ldap/ldap_id.c
|
||||
@@ -247,7 +247,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
||||
}
|
||||
|
||||
ret = sss_cert_derb64_to_ldap_filter(state, filter_value, attr_name,
|
||||
- &user_filter);
|
||||
+ NULL, NULL, &user_filter);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
"sss_cert_derb64_to_ldap_filter failed.\n");
|
||||
diff --git a/src/tests/cmocka/test_cert_utils.c b/src/tests/cmocka/test_cert_utils.c
|
||||
index 35e8cb7513968079861048a7e8b0631229f202c0..5830131754e4cf318273151b586ef36d6a349829 100644
|
||||
--- a/src/tests/cmocka/test_cert_utils.c
|
||||
+++ b/src/tests/cmocka/test_cert_utils.c
|
||||
@@ -297,11 +297,11 @@ void test_sss_cert_derb64_to_ldap_filter(void **state)
|
||||
struct test_state *ts = talloc_get_type_abort(*state, struct test_state);
|
||||
assert_non_null(ts);
|
||||
|
||||
- ret = sss_cert_derb64_to_ldap_filter(ts, NULL, NULL, NULL);
|
||||
+ ret = sss_cert_derb64_to_ldap_filter(ts, NULL, NULL, NULL, NULL, NULL);
|
||||
assert_int_equal(ret, EINVAL);
|
||||
|
||||
ret = sss_cert_derb64_to_ldap_filter(ts, "AAECAwQFBgcICQ==", "attrName",
|
||||
- &filter);
|
||||
+ NULL, NULL, &filter);
|
||||
assert_int_equal(ret, EOK);
|
||||
assert_string_equal(filter,
|
||||
"(attrName=\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09)");
|
||||
diff --git a/src/util/cert.h b/src/util/cert.h
|
||||
index bb64d0d7a0a48207df60f6e6e554da5e16a16b03..4598aa8df0cd860fed71d9cd2e4beec7f1910578 100644
|
||||
--- a/src/util/cert.h
|
||||
+++ b/src/util/cert.h
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <talloc.h>
|
||||
|
||||
#include "util/util.h"
|
||||
+#include "lib/certmap/sss_certmap.h"
|
||||
|
||||
#ifndef __CERT_H__
|
||||
#define __CERT_H__
|
||||
@@ -39,6 +40,8 @@ errno_t sss_cert_pem_to_derb64(TALLOC_CTX *mem_ctx, const char *pem,
|
||||
|
||||
errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64,
|
||||
const char *attr_name,
|
||||
+ struct sss_certmap_ctx *certmap_ctx,
|
||||
+ struct sss_domain_info *dom,
|
||||
char **ldap_filter);
|
||||
|
||||
errno_t bin_to_ldap_filter_value(TALLOC_CTX *mem_ctx,
|
||||
diff --git a/src/util/cert/cert_common.c b/src/util/cert/cert_common.c
|
||||
index a29696ed3cd9f2168f47323fac97d44e9b49f921..766877089429ff1c01000a3986316c74583e3fa4 100644
|
||||
--- a/src/util/cert/cert_common.c
|
||||
+++ b/src/util/cert/cert_common.c
|
||||
@@ -72,12 +72,17 @@ errno_t sss_cert_pem_to_derb64(TALLOC_CTX *mem_ctx, const char *pem,
|
||||
|
||||
errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64,
|
||||
const char *attr_name,
|
||||
+ struct sss_certmap_ctx *certmap_ctx,
|
||||
+ struct sss_domain_info *dom,
|
||||
char **ldap_filter)
|
||||
{
|
||||
int ret;
|
||||
unsigned char *der;
|
||||
size_t der_size;
|
||||
char *val;
|
||||
+ char *filter = NULL;
|
||||
+ char **domains = NULL;
|
||||
+ size_t c;
|
||||
|
||||
if (derb64 == NULL || attr_name == NULL) {
|
||||
return EINVAL;
|
||||
@@ -89,18 +94,67 @@ errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64,
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
- ret = bin_to_ldap_filter_value(mem_ctx, der, der_size, &val);
|
||||
- talloc_free(der);
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, "bin_to_ldap_filter_value failed.\n");
|
||||
- return ret;
|
||||
- }
|
||||
+ if (certmap_ctx == NULL) {
|
||||
+ ret = bin_to_ldap_filter_value(mem_ctx, der, der_size, &val);
|
||||
+ talloc_free(der);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "bin_to_ldap_filter_value failed.\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
- *ldap_filter = talloc_asprintf(mem_ctx, "(%s=%s)", attr_name, val);
|
||||
- talloc_free(val);
|
||||
- if (*ldap_filter == NULL) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
|
||||
- return ENOMEM;
|
||||
+ *ldap_filter = talloc_asprintf(mem_ctx, "(%s=%s)", attr_name, val);
|
||||
+ talloc_free(val);
|
||||
+ if (*ldap_filter == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+ } else {
|
||||
+ ret = sss_certmap_get_search_filter(certmap_ctx, der, der_size,
|
||||
+ &filter, &domains);
|
||||
+ talloc_free(der);
|
||||
+ if (ret != 0) {
|
||||
+ if (ret == ENOENT) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Certificate does not match matching-rules.\n");
|
||||
+ } else {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "sss_certmap_get_search_filter failed.\n");
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (domains == NULL) {
|
||||
+ if (IS_SUBDOMAIN(dom)) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ "Rule applies only to local domain.\n");
|
||||
+ ret = ENOENT;
|
||||
+ }
|
||||
+ } else {
|
||||
+ for (c = 0; domains[c] != NULL; c++) {
|
||||
+ if (strcasecmp(dom->name, domains[c]) == 0) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ "Rule applies to current domain [%s].\n",
|
||||
+ dom->name);
|
||||
+ ret = EOK;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (domains[c] == NULL) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ "Rule does not apply to current domain [%s].\n",
|
||||
+ dom->name);
|
||||
+ ret = ENOENT;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (ret == EOK) {
|
||||
+ *ldap_filter = talloc_strdup(mem_ctx, filter);
|
||||
+ if (*ldap_filter == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ }
|
||||
+ }
|
||||
+ sss_certmap_free_filter_and_domains(filter, domains);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,846 +0,0 @@
|
||||
From 49f8ec8e0a3723a748bdb043d6dc1fb2a3977a8a Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Mon, 6 Feb 2017 10:27:22 +0100
|
||||
Subject: [PATCH 12/97] sysdb: add certmap related calls
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add sysdb calls to write and read data for the certificate mapping
|
||||
library to the cache.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
Makefile.am | 17 ++
|
||||
src/db/sysdb.h | 27 +++
|
||||
src/db/sysdb_certmap.c | 425 ++++++++++++++++++++++++++++++++++
|
||||
src/tests/cmocka/test_sysdb_certmap.c | 260 +++++++++++++++++++++
|
||||
4 files changed, 729 insertions(+)
|
||||
create mode 100644 src/db/sysdb_certmap.c
|
||||
create mode 100644 src/tests/cmocka/test_sysdb_certmap.c
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index f262cc24832358910dbb92ccd46f93c9eda8a295..bd0ca0d303e1742ad26c7648cd24e2c0135af34e 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -254,6 +254,7 @@ if HAVE_CMOCKA
|
||||
test_sysdb_ts_cache \
|
||||
test_sysdb_views \
|
||||
test_sysdb_subdomains \
|
||||
+ test_sysdb_certmap \
|
||||
test_sysdb_sudo \
|
||||
test_sysdb_utils \
|
||||
test_wbc_calls \
|
||||
@@ -974,6 +975,7 @@ libsss_util_la_SOURCES = \
|
||||
src/db/sysdb_ranges.c \
|
||||
src/db/sysdb_idmap.c \
|
||||
src/db/sysdb_gpo.c \
|
||||
+ src/db/sysdb_certmap.c \
|
||||
src/monitor/monitor_sbus.c \
|
||||
src/providers/dp_auth_util.c \
|
||||
src/providers/dp_pam_data_util.c \
|
||||
@@ -2773,6 +2775,21 @@ test_sysdb_subdomains_LDADD = \
|
||||
libsss_test_common.la \
|
||||
$(NULL)
|
||||
|
||||
+test_sysdb_certmap_SOURCES = \
|
||||
+ src/tests/cmocka/test_sysdb_certmap.c \
|
||||
+ $(NULL)
|
||||
+test_sysdb_certmap_CFLAGS = \
|
||||
+ $(AM_CFLAGS) \
|
||||
+ $(NULL)
|
||||
+test_sysdb_certmap_LDADD = \
|
||||
+ $(CMOCKA_LIBS) \
|
||||
+ $(LDB_LIBS) \
|
||||
+ $(POPT_LIBS) \
|
||||
+ $(TALLOC_LIBS) \
|
||||
+ $(SSSD_INTERNAL_LTLIBS) \
|
||||
+ libsss_test_common.la \
|
||||
+ $(NULL)
|
||||
+
|
||||
test_sysdb_sudo_SOURCES = \
|
||||
src/tests/cmocka/test_sysdb_sudo.c \
|
||||
$(NULL)
|
||||
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
|
||||
index 3db22b3689bf6ffd9a48e29c229916e3fac9ca1b..0cbb2c5c02355e9e9a4e73b075f92d16e4855045 100644
|
||||
--- a/src/db/sysdb.h
|
||||
+++ b/src/db/sysdb.h
|
||||
@@ -39,6 +39,7 @@
|
||||
#define SYSDB_NETGROUP_CONTAINER "cn=Netgroups"
|
||||
#define SYSDB_RANGE_CONTAINER "cn=ranges"
|
||||
#define SYSDB_VIEW_CONTAINER "cn=views"
|
||||
+#define SYSDB_CERTMAP_CONTAINER "cn=certmap"
|
||||
#define SYSDB_TMPL_USER_BASE SYSDB_USERS_CONTAINER","SYSDB_DOM_BASE
|
||||
#define SYSDB_TMPL_GROUP_BASE SYSDB_GROUPS_CONTAINER","SYSDB_DOM_BASE
|
||||
#define SYSDB_TMPL_CUSTOM_BASE SYSDB_CUSTOM_CONTAINER","SYSDB_DOM_BASE
|
||||
@@ -46,6 +47,7 @@
|
||||
#define SYSDB_TMPL_RANGE_BASE SYSDB_RANGE_CONTAINER","SYSDB_BASE
|
||||
#define SYSDB_TMPL_VIEW_BASE SYSDB_VIEW_CONTAINER","SYSDB_BASE
|
||||
#define SYSDB_TMPL_VIEW_SEARCH_BASE "cn=%s,"SYSDB_TMPL_VIEW_BASE
|
||||
+#define SYSDB_TMPL_CERTMAP_BASE SYSDB_CERTMAP_CONTAINER","SYSDB_BASE
|
||||
|
||||
#define SYSDB_SUBDOMAIN_CLASS "subdomain"
|
||||
#define SYSDB_USER_CLASS "user"
|
||||
@@ -58,6 +60,7 @@
|
||||
#define SYSDB_ID_RANGE_CLASS "idRange"
|
||||
#define SYSDB_DOMAIN_ID_RANGE_CLASS "domainIDRange"
|
||||
#define SYSDB_TRUSTED_AD_DOMAIN_RANGE_CLASS "TrustedADDomainRange"
|
||||
+#define SYSDB_CERTMAP_CLASS "certificateMappingRule"
|
||||
|
||||
#define SYSDB_DN "dn"
|
||||
#define SYSDB_NAME "name"
|
||||
@@ -158,6 +161,12 @@
|
||||
#define SYSDB_DOMAIN_ID "domainID"
|
||||
#define SYSDB_ID_RANGE_TYPE "idRangeType"
|
||||
|
||||
+#define SYSDB_CERTMAP_PRIORITY "priority"
|
||||
+#define SYSDB_CERTMAP_MATCHING_RULE "matchingRule"
|
||||
+#define SYSDB_CERTMAP_MAPPING_RULE "mappingRule"
|
||||
+#define SYSDB_CERTMAP_DOMAINS "domains"
|
||||
+#define SYSDB_CERTMAP_USER_NAME_HINT "userNameHint"
|
||||
+
|
||||
#define ORIGINALAD_PREFIX "originalAD"
|
||||
#define OVERRIDE_PREFIX "override"
|
||||
#define SYSDB_DEFAULT_OVERRIDE_NAME "defaultOverrideName"
|
||||
@@ -264,6 +273,7 @@
|
||||
#define SYSDB_TMPL_CUSTOM SYSDB_NAME"=%s,cn=%s,"SYSDB_TMPL_CUSTOM_BASE
|
||||
#define SYSDB_TMPL_RANGE SYSDB_NAME"=%s,"SYSDB_TMPL_RANGE_BASE
|
||||
#define SYSDB_TMPL_OVERRIDE SYSDB_OVERRIDE_ANCHOR_UUID"=%s,"SYSDB_TMPL_VIEW_SEARCH_BASE
|
||||
+#define SYSDB_TMPL_CERTMAP SYSDB_NAME"=%s,"SYSDB_TMPL_CERTMAP_BASE
|
||||
|
||||
#define SYSDB_MOD_ADD LDB_FLAG_MOD_ADD
|
||||
#define SYSDB_MOD_DEL LDB_FLAG_MOD_DELETE
|
||||
@@ -320,6 +330,15 @@ struct range_info {
|
||||
char *range_type;
|
||||
};
|
||||
|
||||
+struct certmap_info {
|
||||
+ char *name;
|
||||
+ uint32_t priority;
|
||||
+ char *match_rule;
|
||||
+ char *map_rule;
|
||||
+ const char **domains;
|
||||
+};
|
||||
+
|
||||
+
|
||||
/* These attributes are stored in the timestamp cache */
|
||||
extern const char *sysdb_ts_cache_attrs[];
|
||||
|
||||
@@ -619,6 +638,14 @@ uint64_t sss_view_ldb_msg_find_attr_as_uint64(struct sss_domain_info *dom,
|
||||
const char *attr_name,
|
||||
uint64_t default_value);
|
||||
|
||||
+errno_t sysdb_update_certmap(struct sysdb_ctx *sysdb,
|
||||
+ struct certmap_info **certmaps,
|
||||
+ bool user_name_hint);
|
||||
+
|
||||
+errno_t sysdb_get_certmap(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
|
||||
+ struct certmap_info ***certmaps,
|
||||
+ bool *user_name_hint);
|
||||
+
|
||||
/* Sysdb initialization.
|
||||
* call this function *only* once to initialize the database and get
|
||||
* the sysdb ctx */
|
||||
diff --git a/src/db/sysdb_certmap.c b/src/db/sysdb_certmap.c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..4917796b11c3967b4d147ebee7c7e83f09b872ce
|
||||
--- /dev/null
|
||||
+++ b/src/db/sysdb_certmap.c
|
||||
@@ -0,0 +1,425 @@
|
||||
+/*
|
||||
+ SSSD
|
||||
+
|
||||
+ System Database - certificate mapping rules related calls
|
||||
+
|
||||
+ Copyright (C) 2017 Sumit Bose <sbose@redhat.com>
|
||||
+
|
||||
+ 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 "util/util.h"
|
||||
+#include "db/sysdb_private.h"
|
||||
+
|
||||
+static errno_t sysdb_create_certmap_container(struct sysdb_ctx *sysdb,
|
||||
+ bool user_name_hint)
|
||||
+{
|
||||
+ struct ldb_message *msg = NULL;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ msg = ldb_msg_new(sysdb);
|
||||
+ if (msg == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ msg->dn = ldb_dn_new(msg, sysdb->ldb, SYSDB_TMPL_CERTMAP_BASE);
|
||||
+ if (msg->dn == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ ret = ldb_msg_add_string(msg, "cn", "certmap");
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ ret = sysdb_error_to_errno(ret);
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = ldb_msg_add_string(msg, SYSDB_CERTMAP_USER_NAME_HINT,
|
||||
+ user_name_hint ? "TRUE" : "FALSE");
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ ret = sysdb_error_to_errno(ret);
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* do a synchronous add */
|
||||
+ ret = ldb_add(sysdb->ldb, msg);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
+ "Failed to add certmap container (%d, [%s])!\n",
|
||||
+ ret, ldb_errstring(sysdb->ldb));
|
||||
+ ret = EIO;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(msg);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static errno_t sysdb_certmap_add(struct sysdb_ctx *sysdb,
|
||||
+ struct certmap_info *certmap)
|
||||
+{
|
||||
+ struct ldb_message *msg;
|
||||
+ struct ldb_message_element *el;
|
||||
+ int ret;
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ size_t c;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed");
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ msg = ldb_msg_new(tmp_ctx);
|
||||
+ if (msg == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ msg->dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
|
||||
+ SYSDB_TMPL_CERTMAP, certmap->name);
|
||||
+ if (msg->dn == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_add_string(msg, SYSDB_OBJECTCLASS, SYSDB_CERTMAP_CLASS);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_string failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_add_string(msg, SYSDB_NAME, certmap->name);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_string failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (certmap->map_rule != NULL) {
|
||||
+ ret = sysdb_add_string(msg, SYSDB_CERTMAP_MAPPING_RULE,
|
||||
+ certmap->map_rule);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_string failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (certmap->match_rule != NULL) {
|
||||
+ ret = sysdb_add_string(msg, SYSDB_CERTMAP_MATCHING_RULE,
|
||||
+ certmap->match_rule);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_string failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (certmap->domains != NULL) {
|
||||
+ for (c = 0; certmap->domains[c] != NULL; c++);
|
||||
+ el = talloc_zero(tmp_ctx, struct ldb_message_element);
|
||||
+ if (el == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ el->name = talloc_strdup(el, SYSDB_CERTMAP_DOMAINS);
|
||||
+ if(el->name == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ el->num_values = c;
|
||||
+ el->values = talloc_zero_array(el, struct ldb_val, c + 1);
|
||||
+ if (el->values == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_array failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ for (c = 0; certmap->domains[c] != NULL; c++) {
|
||||
+ el->values[c].data = (uint8_t *) talloc_strdup(el->values,
|
||||
+ certmap->domains[c]);
|
||||
+ if (el->values[c].data == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ el->values[c].length = strlen(certmap->domains[c]);
|
||||
+ }
|
||||
+
|
||||
+ ret = ldb_msg_add(msg, el, LDB_FLAG_MOD_ADD);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add failed.\n");
|
||||
+ ret = sysdb_error_to_errno(ret);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_add_ulong(msg, SYSDB_CERTMAP_PRIORITY,
|
||||
+ (unsigned long)certmap->priority);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_ulong failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = ldb_add(sysdb->ldb, msg);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_add failed.\n");
|
||||
+ ret = sysdb_error_to_errno(ret);
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ if (ret) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, sss_strerror(ret));
|
||||
+ }
|
||||
+ talloc_zfree(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+errno_t sysdb_update_certmap(struct sysdb_ctx *sysdb,
|
||||
+ struct certmap_info **certmaps,
|
||||
+ bool user_name_hint)
|
||||
+{
|
||||
+ size_t c;
|
||||
+ struct ldb_dn *container_dn = NULL;
|
||||
+ bool in_transaction = false;
|
||||
+ int ret;
|
||||
+ int sret;
|
||||
+
|
||||
+ if (certmaps == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ container_dn = ldb_dn_new(sysdb, sysdb->ldb, SYSDB_TMPL_CERTMAP_BASE);
|
||||
+ if (container_dn == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_transaction_start(sysdb);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_start failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+ in_transaction = true;
|
||||
+
|
||||
+ ret = sysdb_delete_recursive(sysdb, container_dn, true);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_delete_recursive failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+ ret = sysdb_create_certmap_container(sysdb, user_name_hint);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_create_certmap_container failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ for (c = 0; certmaps[c] != NULL; c++) {
|
||||
+ ret = sysdb_certmap_add(sysdb, certmaps[c]);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_certmap_add failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_transaction_commit(sysdb);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_transaction_commit failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+ in_transaction = false;
|
||||
+
|
||||
+done:
|
||||
+ if (in_transaction) {
|
||||
+ sret = sysdb_transaction_cancel(sysdb);
|
||||
+ if (sret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction.\n");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ talloc_free(container_dn);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+errno_t sysdb_get_certmap(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
|
||||
+ struct certmap_info ***certmaps, bool *user_name_hint)
|
||||
+{
|
||||
+ size_t c;
|
||||
+ size_t d;
|
||||
+ struct ldb_dn *container_dn = NULL;
|
||||
+ int ret;
|
||||
+ struct certmap_info **maps;
|
||||
+ TALLOC_CTX *tmp_ctx = NULL;
|
||||
+ struct ldb_result *res;
|
||||
+ const char *tmp_str;
|
||||
+ uint64_t tmp_uint;
|
||||
+ struct ldb_message_element *tmp_el;
|
||||
+ const char *attrs[] = {SYSDB_NAME,
|
||||
+ SYSDB_CERTMAP_PRIORITY,
|
||||
+ SYSDB_CERTMAP_MATCHING_RULE,
|
||||
+ SYSDB_CERTMAP_MAPPING_RULE,
|
||||
+ SYSDB_CERTMAP_DOMAINS,
|
||||
+ NULL};
|
||||
+ const char *config_attrs[] = {SYSDB_CERTMAP_USER_NAME_HINT,
|
||||
+ NULL};
|
||||
+ size_t num_values;
|
||||
+ bool hint = false;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ container_dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_TMPL_CERTMAP_BASE);
|
||||
+ if (container_dn == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = ldb_search(sysdb->ldb, tmp_ctx, &res, container_dn, LDB_SCOPE_BASE,
|
||||
+ config_attrs, SYSDB_CERTMAP_USER_NAME_HINT"=*");
|
||||
+ if (ret != LDB_SUCCESS || res->count != 1) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Failed to read certmap config, skipping.\n");
|
||||
+ } else {
|
||||
+ hint = ldb_msg_find_attr_as_bool(res->msgs[0],
|
||||
+ SYSDB_CERTMAP_USER_NAME_HINT, false);
|
||||
+ }
|
||||
+
|
||||
+ ret = ldb_search(sysdb->ldb, tmp_ctx, &res,
|
||||
+ container_dn, LDB_SCOPE_SUBTREE,
|
||||
+ attrs, "objectclass=%s", SYSDB_CERTMAP_CLASS);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_search failed.\n");
|
||||
+ ret = EIO;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (res->count == 0) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "No certificate maps found.\n");
|
||||
+ ret = ENOENT;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ maps = talloc_zero_array(tmp_ctx, struct certmap_info *, res->count + 1);
|
||||
+ if (maps == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_array failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ for (c = 0; c < res->count; c++) {
|
||||
+ maps[c] = talloc_zero(maps, struct certmap_info);
|
||||
+ if (maps[c] == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ tmp_str = ldb_msg_find_attr_as_string(res->msgs[c], SYSDB_NAME, NULL);
|
||||
+ if (tmp_str == NULL) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE, "The object [%s] doesn't have a name.\n",
|
||||
+ ldb_dn_get_linearized(res->msgs[c]->dn));
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ maps[c]->name = talloc_strdup(maps, tmp_str);
|
||||
+ if (maps[c]->name == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ tmp_str = ldb_msg_find_attr_as_string(res->msgs[c],
|
||||
+ SYSDB_CERTMAP_MAPPING_RULE, NULL);
|
||||
+ if (tmp_str != NULL) {
|
||||
+ maps[c]->map_rule = talloc_strdup(maps, tmp_str);
|
||||
+ if (maps[c]->map_rule == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ tmp_str = ldb_msg_find_attr_as_string(res->msgs[c],
|
||||
+ SYSDB_CERTMAP_MATCHING_RULE, NULL);
|
||||
+ if (tmp_str != NULL) {
|
||||
+ maps[c]->match_rule = talloc_strdup(maps, tmp_str);
|
||||
+ if (maps[c]->match_rule == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ tmp_uint = ldb_msg_find_attr_as_uint64(res->msgs[c],
|
||||
+ SYSDB_CERTMAP_PRIORITY,
|
||||
+ (uint64_t) -1);
|
||||
+ if (tmp_uint != (uint64_t) -1) {
|
||||
+ if (tmp_uint >= UINT32_MAX) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "Priority value [%lu] too large.\n",
|
||||
+ (unsigned long) tmp_uint);
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ maps[c]->priority = (uint32_t) tmp_uint;
|
||||
+ }
|
||||
+
|
||||
+ tmp_el = ldb_msg_find_element(res->msgs[c], SYSDB_CERTMAP_DOMAINS);
|
||||
+ if (tmp_el != NULL) {
|
||||
+ num_values = tmp_el->num_values;
|
||||
+ } else {
|
||||
+ num_values = 0;
|
||||
+ }
|
||||
+
|
||||
+ maps[c]->domains = talloc_zero_array(maps[c], const char *,
|
||||
+ num_values + 1);
|
||||
+ if (maps[c]->domains == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_array failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ for (d = 0; d < num_values; d++) {
|
||||
+ maps[c]->domains[d] = talloc_strndup(maps[c]->domains,
|
||||
+ (char *) tmp_el->values[d].data,
|
||||
+ tmp_el->values[d].length);
|
||||
+ if (maps[c]->domains[d] == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *certmaps = talloc_steal(mem_ctx, maps);
|
||||
+ *user_name_hint = hint;
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/src/tests/cmocka/test_sysdb_certmap.c b/src/tests/cmocka/test_sysdb_certmap.c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fb07165561779226935f436c308c85abfc305635
|
||||
--- /dev/null
|
||||
+++ b/src/tests/cmocka/test_sysdb_certmap.c
|
||||
@@ -0,0 +1,260 @@
|
||||
+/*
|
||||
+ SSSD
|
||||
+
|
||||
+ sysdb_certmap - Tests for sysdb certmap realted calls
|
||||
+
|
||||
+ Authors:
|
||||
+ Jakub Hrozek <jhrozek@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 <stdarg.h>
|
||||
+#include <stddef.h>
|
||||
+#include <setjmp.h>
|
||||
+#include <cmocka.h>
|
||||
+#include <popt.h>
|
||||
+
|
||||
+#include "tests/cmocka/common_mock.h"
|
||||
+#include "tests/common.h"
|
||||
+
|
||||
+#define TESTS_PATH "certmap_" BASE_FILE_STEM
|
||||
+#define TEST_CONF_DB "test_sysdb_certmap.ldb"
|
||||
+#define TEST_ID_PROVIDER "ldap"
|
||||
+#define TEST_DOM_NAME "certmap_test"
|
||||
+
|
||||
+struct certmap_test_ctx {
|
||||
+ struct sss_test_ctx *tctx;
|
||||
+};
|
||||
+
|
||||
+static int test_sysdb_setup(void **state)
|
||||
+{
|
||||
+ struct certmap_test_ctx *test_ctx;
|
||||
+ struct sss_test_conf_param params[] = {
|
||||
+ { NULL, NULL }, /* Sentinel */
|
||||
+ };
|
||||
+
|
||||
+ assert_true(leak_check_setup());
|
||||
+
|
||||
+ test_ctx = talloc_zero(global_talloc_context,
|
||||
+ struct certmap_test_ctx);
|
||||
+ assert_non_null(test_ctx);
|
||||
+ check_leaks_push(test_ctx);
|
||||
+
|
||||
+ test_dom_suite_setup(TESTS_PATH);
|
||||
+
|
||||
+ test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH,
|
||||
+ TEST_CONF_DB, TEST_DOM_NAME,
|
||||
+ TEST_ID_PROVIDER, params);
|
||||
+ assert_non_null(test_ctx->tctx);
|
||||
+
|
||||
+ *state = test_ctx;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int test_sysdb_teardown(void **state)
|
||||
+{
|
||||
+ struct certmap_test_ctx *test_ctx =
|
||||
+ talloc_get_type(*state, struct certmap_test_ctx);
|
||||
+
|
||||
+ test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
|
||||
+ talloc_free(test_ctx->tctx);
|
||||
+ assert_true(check_leaks_pop(test_ctx));
|
||||
+ talloc_free(test_ctx);
|
||||
+ assert_true(leak_check_teardown());
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void test_sysdb_get_certmap_not_exists(void **state)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct certmap_info **certmap;
|
||||
+ bool user_name_hint;
|
||||
+ struct certmap_test_ctx *ctctx = talloc_get_type(*state,
|
||||
+ struct certmap_test_ctx);
|
||||
+
|
||||
+ ret = sysdb_get_certmap(ctctx, ctctx->tctx->sysdb, &certmap,
|
||||
+ &user_name_hint);
|
||||
+ assert_int_equal(ret, ENOENT);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static void check_certmap(struct certmap_info *m, struct certmap_info *r,
|
||||
+ size_t exp_domains)
|
||||
+{
|
||||
+ size_t d;
|
||||
+
|
||||
+ assert_non_null(r);
|
||||
+ assert_non_null(m);
|
||||
+ assert_string_equal(m->name, r->name);
|
||||
+
|
||||
+ if (r->map_rule == NULL) {
|
||||
+ assert_null(m->map_rule);
|
||||
+ } else {
|
||||
+ assert_string_equal(m->map_rule, r->map_rule);
|
||||
+ }
|
||||
+
|
||||
+ if (r->match_rule == NULL) {
|
||||
+ assert_null(m->match_rule);
|
||||
+ } else {
|
||||
+ assert_string_equal(m->match_rule, r->match_rule);
|
||||
+ }
|
||||
+
|
||||
+ assert_int_equal(m->priority, r->priority);
|
||||
+ assert_non_null(m->domains);
|
||||
+ if (r->domains == NULL) {
|
||||
+ assert_null(m->domains[0]);
|
||||
+ } else {
|
||||
+ for (d = 0; r->domains[d]; d++) {
|
||||
+ assert_non_null(m->domains[d]);
|
||||
+ assert_true(string_in_list(m->domains[d], discard_const(r->domains),
|
||||
+ true));
|
||||
+ }
|
||||
+
|
||||
+ assert_int_equal(d, exp_domains);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static void test_sysdb_update_certmap(void **state)
|
||||
+{
|
||||
+ int ret;
|
||||
+ const char *domains[] = { "dom1.test", "dom2.test", "dom3.test", NULL };
|
||||
+ struct certmap_info map_a = { discard_const("map_a"), 11, discard_const("abc"), discard_const("def"), NULL };
|
||||
+ struct certmap_info map_b = { discard_const("map_b"), 22, discard_const("abc"), NULL, domains };
|
||||
+ struct certmap_info *certmap_empty[] = { NULL };
|
||||
+ struct certmap_info *certmap_a[] = { &map_a, NULL };
|
||||
+ struct certmap_info *certmap_b[] = { &map_b, NULL };
|
||||
+ struct certmap_info *certmap_ab[] = { &map_a, &map_b, NULL };
|
||||
+ struct certmap_info **certmap;
|
||||
+ struct certmap_test_ctx *ctctx = talloc_get_type(*state,
|
||||
+ struct certmap_test_ctx);
|
||||
+ bool user_name_hint;
|
||||
+
|
||||
+ ret = sysdb_update_certmap(ctctx->tctx->sysdb, NULL, false);
|
||||
+ assert_int_equal(ret, EINVAL);
|
||||
+
|
||||
+ ret = sysdb_update_certmap(ctctx->tctx->sysdb, certmap_empty, false);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = sysdb_get_certmap(ctctx, ctctx->tctx->sysdb, &certmap,
|
||||
+ &user_name_hint);
|
||||
+ assert_int_equal(ret, ENOENT);
|
||||
+
|
||||
+ ret = sysdb_update_certmap(ctctx->tctx->sysdb, certmap_a, false);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = sysdb_get_certmap(ctctx, ctctx->tctx->sysdb, &certmap,
|
||||
+ &user_name_hint);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ assert_false(user_name_hint);
|
||||
+ assert_non_null(certmap);
|
||||
+ assert_non_null(certmap[0]);
|
||||
+ assert_string_equal(certmap[0]->name, map_a.name);
|
||||
+ assert_string_equal(certmap[0]->map_rule, map_a.map_rule);
|
||||
+ assert_string_equal(certmap[0]->match_rule, map_a.match_rule);
|
||||
+ assert_int_equal(certmap[0]->priority, map_a.priority);
|
||||
+ assert_non_null(certmap[0]->domains);
|
||||
+ assert_null(certmap[0]->domains[0]);
|
||||
+ assert_null(certmap[1]);
|
||||
+ check_certmap(certmap[0], &map_a, 0);
|
||||
+ talloc_free(certmap);
|
||||
+
|
||||
+ ret = sysdb_update_certmap(ctctx->tctx->sysdb, certmap_b, true);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = sysdb_get_certmap(ctctx, ctctx->tctx->sysdb, &certmap,
|
||||
+ &user_name_hint);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ assert_true(user_name_hint);
|
||||
+ assert_non_null(certmap);
|
||||
+ assert_non_null(certmap[0]);
|
||||
+
|
||||
+ check_certmap(certmap[0], &map_b, 3);
|
||||
+ assert_null(certmap[1]);
|
||||
+ talloc_free(certmap);
|
||||
+
|
||||
+ ret = sysdb_update_certmap(ctctx->tctx->sysdb, certmap_ab, false);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = sysdb_get_certmap(ctctx, ctctx->tctx->sysdb, &certmap,
|
||||
+ &user_name_hint);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ assert_false(user_name_hint);
|
||||
+ assert_non_null(certmap);
|
||||
+ assert_non_null(certmap[0]);
|
||||
+ assert_non_null(certmap[1]);
|
||||
+ assert_null(certmap[2]);
|
||||
+ if (strcmp(certmap[0]->name, "map_a") == 0) {
|
||||
+ check_certmap(certmap[0], &map_a, 0);
|
||||
+ check_certmap(certmap[1], &map_b, 3);
|
||||
+ } else {
|
||||
+ check_certmap(certmap[0], &map_b, 3);
|
||||
+ check_certmap(certmap[1], &map_a, 0);
|
||||
+ }
|
||||
+ talloc_free(certmap);
|
||||
+}
|
||||
+
|
||||
+int main(int argc, const char *argv[])
|
||||
+{
|
||||
+ int rv;
|
||||
+ int no_cleanup = 0;
|
||||
+ poptContext pc;
|
||||
+ int opt;
|
||||
+ struct poptOption long_options[] = {
|
||||
+ POPT_AUTOHELP
|
||||
+ SSSD_DEBUG_OPTS
|
||||
+ {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0,
|
||||
+ _("Do not delete the test database after a test run"), NULL },
|
||||
+ POPT_TABLEEND
|
||||
+ };
|
||||
+
|
||||
+ const struct CMUnitTest tests[] = {
|
||||
+ cmocka_unit_test_setup_teardown(test_sysdb_get_certmap_not_exists,
|
||||
+ test_sysdb_setup,
|
||||
+ test_sysdb_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_sysdb_update_certmap,
|
||||
+ test_sysdb_setup,
|
||||
+ test_sysdb_teardown),
|
||||
+ };
|
||||
+
|
||||
+ /* Set debug level to invalid value so we can deside if -d 0 was used. */
|
||||
+ debug_level = SSSDBG_INVALID;
|
||||
+
|
||||
+ pc = poptGetContext(argv[0], argc, argv, long_options, 0);
|
||||
+ while((opt = poptGetNextOpt(pc)) != -1) {
|
||||
+ switch(opt) {
|
||||
+ default:
|
||||
+ fprintf(stderr, "\nInvalid option %s: %s\n\n",
|
||||
+ poptBadOption(pc, 0), poptStrerror(opt));
|
||||
+ poptPrintUsage(pc, stderr, 0);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+ poptFreeContext(pc);
|
||||
+
|
||||
+ DEBUG_CLI_INIT(debug_level);
|
||||
+
|
||||
+ tests_set_cwd();
|
||||
+ test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, LOCAL_SYSDB_FILE);
|
||||
+ test_dom_suite_setup(TESTS_PATH);
|
||||
+ rv = cmocka_run_group_tests(tests, NULL, NULL);
|
||||
+
|
||||
+ if (rv == 0 && no_cleanup == 0) {
|
||||
+ test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, LOCAL_SYSDB_FILE);
|
||||
+ }
|
||||
+ return rv;
|
||||
+}
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,484 +0,0 @@
|
||||
From c44728a02d5e2c9eaced11e74820a6ae6a985f61 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Mon, 6 Feb 2017 10:28:46 +0100
|
||||
Subject: [PATCH 13/97] IPA: add certmap support
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Read certificate mapping data from the IPA server and configure the
|
||||
certificate mapping library accordingly.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/providers/ipa/ipa_config.h | 2 +
|
||||
src/providers/ipa/ipa_subdomains.c | 354 ++++++++++++++++++++++++++++++
|
||||
src/providers/ipa/ipa_subdomains_server.c | 4 +
|
||||
src/providers/ldap/ldap_id.c | 4 +-
|
||||
src/providers/ldap/sdap.h | 4 +
|
||||
5 files changed, 367 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/providers/ipa/ipa_config.h b/src/providers/ipa/ipa_config.h
|
||||
index 2f1e147d7edab0aca2a16269c6a73bc607b21bd5..60f2d5d7b71227a1d86889ceaf6f0f9ac868480d 100644
|
||||
--- a/src/providers/ipa/ipa_config.h
|
||||
+++ b/src/providers/ipa/ipa_config.h
|
||||
@@ -37,6 +37,8 @@
|
||||
#define IPA_CONFIG_SEARCH_BASE_TEMPLATE "cn=etc,%s"
|
||||
#define IPA_CONFIG_FILTER "(&(cn=ipaConfig)(objectClass=ipaGuiConfig))"
|
||||
|
||||
+#define IPA_OC_CONFIG "ipaConfig"
|
||||
+
|
||||
struct tevent_req * ipa_get_config_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct sdap_handle *sh,
|
||||
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
|
||||
index b2e96b204213a52014edcc6042ffa1ff8152b8bf..7537550606ef09c0b87a80932c75aa4f93c0efab 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains.c
|
||||
+++ b/src/providers/ipa/ipa_subdomains.c
|
||||
@@ -56,6 +56,24 @@
|
||||
|
||||
#define IPA_SUBDOMAIN_DISABLED_PERIOD 3600
|
||||
|
||||
+#define IPA_OC_CERTMAP_CONFIG_OBJECT "ipaCertMapConfigObject"
|
||||
+#define IPA_CERTMAP_PROMPT_USERNAME "ipaCertMapPromptUserName"
|
||||
+
|
||||
+#define IPA_OC_CERTMAP_RULE "ipaCertMapRule"
|
||||
+#define IPA_CERTMAP_MAPRULE "ipaCertMapMapRule"
|
||||
+#define IPA_CERTMAP_MATCHRULE "ipaCertMapMatchRule"
|
||||
+#define IPA_CERTMAP_PRIORITY "ipaCertMapPriority"
|
||||
+#define IPA_ENABLED_FLAG "ipaEnabledFlag"
|
||||
+#define IPA_TRUE_VALUE "TRUE"
|
||||
+#define IPA_ASSOCIATED_DOMAIN "associatedDomain"
|
||||
+
|
||||
+#define OBJECTCLASS "objectClass"
|
||||
+
|
||||
+#define CERTMAP_FILTER "(|(&("OBJECTCLASS"="IPA_OC_CERTMAP_RULE")" \
|
||||
+ "("IPA_ENABLED_FLAG"="IPA_TRUE_VALUE"))" \
|
||||
+ "("OBJECTCLASS"="IPA_OC_CERTMAP_CONFIG_OBJECT"))"
|
||||
+
|
||||
+
|
||||
struct ipa_subdomains_ctx {
|
||||
struct be_ctx *be_ctx;
|
||||
struct ipa_id_ctx *ipa_id_ctx;
|
||||
@@ -286,6 +304,193 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+struct priv_sss_debug {
|
||||
+ int level;
|
||||
+};
|
||||
+
|
||||
+void ext_debug(void *private, const char *file, long line, const char *function,
|
||||
+ const char *format, ...)
|
||||
+{
|
||||
+ va_list ap;
|
||||
+ struct priv_sss_debug *data = private;
|
||||
+ int level = SSSDBG_OP_FAILURE;
|
||||
+
|
||||
+ if (data != NULL) {
|
||||
+ level = data->level;
|
||||
+ }
|
||||
+
|
||||
+ if (DEBUG_IS_SET(level)) {
|
||||
+ va_start(ap, format);
|
||||
+ sss_vdebug_fn(file, line, function, level, APPEND_LINE_FEED,
|
||||
+ format, ap);
|
||||
+ va_end(ap);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static errno_t ipa_certmap_parse_results(TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_domain_info *domain,
|
||||
+ struct sdap_options *sdap_opts,
|
||||
+ size_t count,
|
||||
+ struct sysdb_attrs **reply,
|
||||
+ struct certmap_info ***_certmap_list)
|
||||
+{
|
||||
+ struct certmap_info **certmap_list = NULL;
|
||||
+ struct certmap_info *m;
|
||||
+ const char *value;
|
||||
+ const char **values;
|
||||
+ size_t c;
|
||||
+ size_t lc = 0;
|
||||
+ int ret;
|
||||
+ struct sss_certmap_ctx *certmap_ctx = NULL;
|
||||
+ const char **ocs = NULL;
|
||||
+ bool user_name_hint = false;
|
||||
+
|
||||
+ certmap_list = talloc_zero_array(mem_ctx, struct certmap_info *, count + 1);
|
||||
+ if (certmap_list == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ for (c = 0; c < count; c++) {
|
||||
+ ret = sysdb_attrs_get_string_array(reply[c], SYSDB_OBJECTCLASS, mem_ctx,
|
||||
+ &ocs);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Missing objectclasses for config objects.\n");
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (string_in_list(IPA_OC_CERTMAP_CONFIG_OBJECT, discard_const(ocs),
|
||||
+ false)) {
|
||||
+ ret = sysdb_attrs_get_bool(reply[c], IPA_CERTMAP_PROMPT_USERNAME,
|
||||
+ &user_name_hint);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Failed to read user name hint option, skipping.\n");
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ m = talloc_zero(certmap_list, struct certmap_info);
|
||||
+ if (m == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_attrs_get_string(reply[c], IPA_CN, &value);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ m->name = talloc_strdup(m, value);
|
||||
+ if (m->name == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_attrs_get_string(reply[c], IPA_CERTMAP_MATCHRULE, &value);
|
||||
+ if (ret == EOK) {
|
||||
+ m->match_rule = talloc_strdup(m, value);
|
||||
+ if (m->match_rule == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ } else if (ret != ENOENT) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_attrs_get_string(reply[c], IPA_CERTMAP_MAPRULE, &value);
|
||||
+ if (ret == EOK) {
|
||||
+ m->map_rule = talloc_strdup(m, value);
|
||||
+ if (m->map_rule == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ } else if (ret != ENOENT) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_attrs_get_string_array(reply[c], IPA_ASSOCIATED_DOMAIN, m,
|
||||
+ &values);
|
||||
+ if (ret == EOK) {
|
||||
+ m->domains = values;
|
||||
+ } else if (ret != ENOENT) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_attrs_get_uint32_t(reply[c], IPA_CERTMAP_PRIORITY,
|
||||
+ &m->priority);
|
||||
+ if (ret != EOK && ret != ENOENT) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
|
||||
+ goto done;
|
||||
+ } else if (ret == ENOENT) {
|
||||
+ m->priority = SSS_CERTMAP_MIN_PRIO;
|
||||
+ }
|
||||
+
|
||||
+ certmap_list[lc++] = m;
|
||||
+ }
|
||||
+
|
||||
+ certmap_list[lc] = NULL;
|
||||
+
|
||||
+ ret = sss_certmap_init(mem_ctx, ext_debug, NULL, &certmap_ctx);
|
||||
+ if (ret != 0) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_init failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ for (c = 0; certmap_list[c] != NULL; c++) {
|
||||
+ DEBUG(SSSDBG_TRACE_ALL, "Trying to add rule [%s][%d][%s][%s].\n",
|
||||
+ certmap_list[c]->name,
|
||||
+ certmap_list[c]->priority,
|
||||
+ certmap_list[c]->match_rule,
|
||||
+ certmap_list[c]->map_rule);
|
||||
+
|
||||
+ ret = sss_certmap_add_rule(certmap_ctx, certmap_list[c]->priority,
|
||||
+ certmap_list[c]->match_rule,
|
||||
+ certmap_list[c]->map_rule,
|
||||
+ certmap_list[c]->domains);
|
||||
+ if (ret != 0) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "sss_certmap_add_rule failed for rule [%s], skipping. "
|
||||
+ "Please check for typos and if rule syntax is supported.\n",
|
||||
+ certmap_list[c]->name);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_update_certmap(domain->sysdb, certmap_list, user_name_hint);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_certmap failed");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ sss_certmap_free_ctx(sdap_opts->certmap_ctx);
|
||||
+ sdap_opts->certmap_ctx = talloc_steal(sdap_opts, certmap_ctx);
|
||||
+
|
||||
+ if (_certmap_list != NULL) {
|
||||
+ *_certmap_list = certmap_list;
|
||||
+ }
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(ocs);
|
||||
+ if (ret != EOK) {
|
||||
+ sss_certmap_free_ctx(certmap_ctx);
|
||||
+ talloc_free(certmap_list);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static errno_t ipa_subdom_enumerates(struct sss_domain_info *parent,
|
||||
struct sysdb_attrs *attrs,
|
||||
bool *_enumerates)
|
||||
@@ -801,6 +1006,125 @@ static errno_t ipa_subdomains_ranges_recv(struct tevent_req *req)
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+#define IPA_CERTMAP_SEARCH_BASE_TEMPLATE "cn=certmap,%s"
|
||||
+
|
||||
+struct ipa_subdomains_certmap_state {
|
||||
+ struct sss_domain_info *domain;
|
||||
+ struct sdap_options *sdap_opts;
|
||||
+};
|
||||
+
|
||||
+static void ipa_subdomains_certmap_done(struct tevent_req *subreq);
|
||||
+
|
||||
+static struct tevent_req *
|
||||
+ipa_subdomains_certmap_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct ipa_subdomains_ctx *sd_ctx,
|
||||
+ struct sdap_handle *sh)
|
||||
+{
|
||||
+ struct ipa_subdomains_certmap_state *state;
|
||||
+ struct tevent_req *subreq;
|
||||
+ struct tevent_req *req;
|
||||
+ errno_t ret;
|
||||
+ char *ldap_basedn;
|
||||
+ char *search_base;
|
||||
+ const char *attrs[] = { OBJECTCLASS, IPA_CN,
|
||||
+ IPA_CERTMAP_MAPRULE, IPA_CERTMAP_MATCHRULE,
|
||||
+ IPA_CERTMAP_PRIORITY, IPA_ASSOCIATED_DOMAIN,
|
||||
+ IPA_CERTMAP_PROMPT_USERNAME,
|
||||
+ NULL };
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state,
|
||||
+ struct ipa_subdomains_certmap_state);
|
||||
+ if (req == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ state->domain = sd_ctx->be_ctx->domain;
|
||||
+ state->sdap_opts = sd_ctx->sdap_id_ctx->opts;
|
||||
+
|
||||
+ ret = domain_to_basedn(state, state->domain->name, &ldap_basedn);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
|
||||
+ goto immediately;
|
||||
+ }
|
||||
+
|
||||
+ search_base = talloc_asprintf(state, IPA_CERTMAP_SEARCH_BASE_TEMPLATE,
|
||||
+ ldap_basedn);
|
||||
+ if (search_base == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto immediately;
|
||||
+ }
|
||||
+
|
||||
+ subreq = sdap_get_generic_send(state, ev, sd_ctx->sdap_id_ctx->opts, sh,
|
||||
+ search_base, LDAP_SCOPE_SUBTREE,
|
||||
+ CERTMAP_FILTER,
|
||||
+ attrs, NULL, 0, 0, false);
|
||||
+ if (subreq == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto immediately;
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_set_callback(subreq, ipa_subdomains_certmap_done, req);
|
||||
+
|
||||
+ return req;
|
||||
+
|
||||
+immediately:
|
||||
+ if (ret == EOK) {
|
||||
+ tevent_req_done(req);
|
||||
+ } else {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ }
|
||||
+ tevent_req_post(req, ev);
|
||||
+
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static void ipa_subdomains_certmap_done(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct ipa_subdomains_certmap_state *state;
|
||||
+ struct tevent_req *req;
|
||||
+ struct sysdb_attrs **reply;
|
||||
+ size_t reply_count;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_callback_data(subreq, struct tevent_req);
|
||||
+ state = tevent_req_data(req, struct ipa_subdomains_certmap_state);
|
||||
+
|
||||
+ ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
|
||||
+ talloc_zfree(subreq);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get data from LDAP [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = ipa_certmap_parse_results(state, state->domain,
|
||||
+ state->sdap_opts,
|
||||
+ reply_count, reply, NULL);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to parse certmap results [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
+ if (ret != EOK) {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_done(req);
|
||||
+}
|
||||
+
|
||||
+static errno_t ipa_subdomains_certmap_recv(struct tevent_req *req)
|
||||
+{
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
struct ipa_subdomains_master_state {
|
||||
struct sss_domain_info *domain;
|
||||
struct ipa_options *ipa_options;
|
||||
@@ -1365,6 +1689,7 @@ struct ipa_subdomains_refresh_state {
|
||||
static errno_t ipa_subdomains_refresh_retry(struct tevent_req *req);
|
||||
static void ipa_subdomains_refresh_connect_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_ranges_done(struct tevent_req *subreq);
|
||||
+static void ipa_subdomains_refresh_certmap_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_master_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_slave_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_view_done(struct tevent_req *subreq);
|
||||
@@ -1487,6 +1812,35 @@ static void ipa_subdomains_refresh_ranges_done(struct tevent_req *subreq)
|
||||
return;
|
||||
}
|
||||
|
||||
+ subreq = ipa_subdomains_certmap_send(state, state->ev, state->sd_ctx,
|
||||
+ sdap_id_op_handle(state->sdap_op));
|
||||
+ if (subreq == NULL) {
|
||||
+ tevent_req_error(req, ENOMEM);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_set_callback(subreq, ipa_subdomains_refresh_certmap_done, req);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void ipa_subdomains_refresh_certmap_done(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct ipa_subdomains_refresh_state *state;
|
||||
+ struct tevent_req *req;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_callback_data(subreq, struct tevent_req);
|
||||
+ state = tevent_req_data(req, struct ipa_subdomains_refresh_state);
|
||||
+
|
||||
+ ret = ipa_subdomains_certmap_recv(subreq);
|
||||
+ talloc_zfree(subreq);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read certificate mapping rules "
|
||||
+ "[%d]: %s\n", ret, sss_strerror(ret));
|
||||
+ tevent_req_error(req, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
subreq = ipa_subdomains_master_send(state, state->ev, state->sd_ctx,
|
||||
sdap_id_op_handle(state->sdap_op));
|
||||
if (subreq == NULL) {
|
||||
diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
|
||||
index 1af8676c5a9c49121d0f0118a46796c6637f04f9..ae3baf036e4278fb67d86b42742fb7e80b46724e 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains_server.c
|
||||
+++ b/src/providers/ipa/ipa_subdomains_server.c
|
||||
@@ -362,6 +362,10 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
|
||||
ad_id_ctx->sdap_id_ctx->opts->idmap_ctx =
|
||||
id_ctx->sdap_id_ctx->opts->idmap_ctx;
|
||||
|
||||
+ /* Set up the certificate mapping context */
|
||||
+ ad_id_ctx->sdap_id_ctx->opts->certmap_ctx =
|
||||
+ id_ctx->sdap_id_ctx->opts->certmap_ctx;
|
||||
+
|
||||
*_ad_id_ctx = ad_id_ctx;
|
||||
return EOK;
|
||||
}
|
||||
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
|
||||
index 8e60769d09383ac8ebe33e5f64fd4fd9788e82cd..0bee0ca8d71abece6749fdb8393b9ceacb64417d 100644
|
||||
--- a/src/providers/ldap/ldap_id.c
|
||||
+++ b/src/providers/ldap/ldap_id.c
|
||||
@@ -247,7 +247,9 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
||||
}
|
||||
|
||||
ret = sss_cert_derb64_to_ldap_filter(state, filter_value, attr_name,
|
||||
- NULL, NULL, &user_filter);
|
||||
+ ctx->opts->certmap_ctx,
|
||||
+ state->domain,
|
||||
+ &user_filter);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
"sss_cert_derb64_to_ldap_filter failed.\n");
|
||||
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
|
||||
index 6079a8bf62d0bdf23c8d462dc0f19c705e391a6e..afdc01948eefe9dda943c8c7ad01a42dd76a1da8 100644
|
||||
--- a/src/providers/ldap/sdap.h
|
||||
+++ b/src/providers/ldap/sdap.h
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "providers/backend.h"
|
||||
#include <ldap.h>
|
||||
#include "util/sss_ldap.h"
|
||||
+#include "lib/certmap/sss_certmap.h"
|
||||
|
||||
struct sdap_msg {
|
||||
struct sdap_msg *next;
|
||||
@@ -478,6 +479,9 @@ struct sdap_options {
|
||||
|
||||
bool support_matching_rule;
|
||||
enum dc_functional_level dc_functional_level;
|
||||
+
|
||||
+ /* Certificate mapping support */
|
||||
+ struct sss_certmap_ctx *certmap_ctx;
|
||||
};
|
||||
|
||||
struct sdap_server_opts {
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,736 +0,0 @@
|
||||
From 440797cba931aa491bf418035f55935943e22b4b Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Wed, 15 Mar 2017 14:21:26 +0100
|
||||
Subject: [PATCH 14/97] nss-idmap: add sss_nss_getlistbycert()
|
||||
|
||||
This patch adds a getlistbycert() call to libsss_nss_idmap to make it on
|
||||
par with InfoPipe.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
src/python/pysss_nss_idmap.c | 103 ++++++++++++++++++-
|
||||
src/responder/nss/nss_cmd.c | 7 ++
|
||||
src/responder/nss/nss_protocol.h | 6 ++
|
||||
src/responder/nss/nss_protocol_sid.c | 63 ++++++++++++
|
||||
src/sss_client/idmap/sss_nss_idmap.c | 110 +++++++++++++++++++-
|
||||
src/sss_client/idmap/sss_nss_idmap.exports | 6 ++
|
||||
src/sss_client/idmap/sss_nss_idmap.h | 17 +++-
|
||||
src/sss_client/sss_cli.h | 5 +
|
||||
src/tests/cmocka/test_nss_srv.c | 158 +++++++++++++++++++++++++++++
|
||||
10 files changed, 471 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index bd0ca0d303e1742ad26c7648cd24e2c0135af34e..7516338bc6fd95045d20db8155a0c82fd7003358 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -1128,7 +1128,7 @@ libsss_nss_idmap_la_LIBADD = \
|
||||
$(CLIENT_LIBS)
|
||||
libsss_nss_idmap_la_LDFLAGS = \
|
||||
-Wl,--version-script,$(srcdir)/src/sss_client/idmap/sss_nss_idmap.exports \
|
||||
- -version-info 2:0:2
|
||||
+ -version-info 3:0:3
|
||||
|
||||
dist_noinst_DATA += src/sss_client/idmap/sss_nss_idmap.exports
|
||||
|
||||
diff --git a/src/python/pysss_nss_idmap.c b/src/python/pysss_nss_idmap.c
|
||||
index c57cc10a86a7a9a22a791c1eae027a1aafa8f780..2e5851c7a6e48629fd93e428aada499fcbe36ebb 100644
|
||||
--- a/src/python/pysss_nss_idmap.c
|
||||
+++ b/src/python/pysss_nss_idmap.c
|
||||
@@ -36,9 +36,37 @@ enum lookup_type {
|
||||
SIDBYID,
|
||||
NAMEBYSID,
|
||||
IDBYSID,
|
||||
- NAMEBYCERT
|
||||
+ NAMEBYCERT,
|
||||
+ LISTBYCERT
|
||||
};
|
||||
|
||||
+static int add_dict_to_list(PyObject *py_list, PyObject *res_type,
|
||||
+ PyObject *res, PyObject *id_type)
|
||||
+{
|
||||
+ int ret;
|
||||
+ PyObject *py_dict;
|
||||
+
|
||||
+ py_dict = PyDict_New();
|
||||
+ if (py_dict == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = PyDict_SetItem(py_dict, res_type, res);
|
||||
+ if (ret != 0) {
|
||||
+ Py_XDECREF(py_dict);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = PyDict_SetItem(py_dict, PyBytes_FromString(SSS_TYPE_KEY), id_type);
|
||||
+ if (ret != 0) {
|
||||
+ Py_XDECREF(py_dict);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = PyList_Append(py_list, py_dict);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
static int add_dict(PyObject *py_result, PyObject *key, PyObject *res_type,
|
||||
PyObject *res, PyObject *id_type)
|
||||
{
|
||||
@@ -191,6 +219,57 @@ static int do_getnamebycert(PyObject *py_result, PyObject *py_cert)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int do_getlistbycert(PyObject *py_result, PyObject *py_cert)
|
||||
+{
|
||||
+ int ret;
|
||||
+ const char *cert;
|
||||
+ char **names = NULL;
|
||||
+ enum sss_id_type *id_types = NULL;
|
||||
+ size_t c;
|
||||
+
|
||||
+ cert = py_string_or_unicode_as_string(py_cert);
|
||||
+ if (cert == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_nss_getlistbycert(cert, &names, &id_types);
|
||||
+ if (ret == 0) {
|
||||
+
|
||||
+ PyObject *py_list;
|
||||
+
|
||||
+ py_list = PyList_New(0);
|
||||
+ if (py_list == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ for (c = 0; names[c] != NULL; c++) {
|
||||
+ ret = add_dict_to_list(py_list,
|
||||
+ PyBytes_FromString(SSS_NAME_KEY),
|
||||
+ PyUnicode_FromString(names[c]),
|
||||
+ PYNUMBER_FROMLONG(id_types[c]));
|
||||
+ if (ret != 0) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+ ret = PyDict_SetItem(py_result, py_cert, py_list);
|
||||
+ if (ret != 0) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
+ free(id_types);
|
||||
+ if (names != NULL) {
|
||||
+ for (c = 0; names[c] != NULL; c++) {
|
||||
+ free(names[c]);
|
||||
+ }
|
||||
+ free(names);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static int do_getidbysid(PyObject *py_result, PyObject *py_sid)
|
||||
{
|
||||
const char *sid;
|
||||
@@ -231,6 +310,9 @@ static int do_lookup(enum lookup_type type, PyObject *py_result,
|
||||
case NAMEBYCERT:
|
||||
return do_getnamebycert(py_result, py_inp);
|
||||
break;
|
||||
+ case LISTBYCERT:
|
||||
+ return do_getlistbycert(py_result, py_inp);
|
||||
+ break;
|
||||
default:
|
||||
return ENOSYS;
|
||||
}
|
||||
@@ -368,7 +450,7 @@ static PyObject * py_getidbysid(PyObject *module, PyObject *args)
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(getnamebycert_doc,
|
||||
-"getnamebycert(sid or list/tuple of certificates) -> dict(sid => dict(results))\n\
|
||||
+"getnamebycert(certificate or list/tuple of certificates) -> dict(certificate => dict(results))\n\
|
||||
\n\
|
||||
Returns a dictionary with a dictonary of results for each given certificates.\n\
|
||||
The result dictonary contain the name and the type of the object which can be\n\
|
||||
@@ -382,6 +464,21 @@ static PyObject * py_getnamebycert(PyObject *module, PyObject *args)
|
||||
return check_args(NAMEBYCERT, args);
|
||||
}
|
||||
|
||||
+PyDoc_STRVAR(getlistbycert_doc,
|
||||
+"getnamebycert(certificate or list/tuple of certificates) -> dict(certificate => dict(results))\n\
|
||||
+\n\
|
||||
+Returns a dictionary with a dictonary of results for each given certificates.\n\
|
||||
+The result dictonary contain the name and the type of the object which can be\n\
|
||||
+accessed with the key constants NAME_KEY and TYPE_KEY, respectively.\n\
|
||||
+\n\
|
||||
+NOTE: getlistbycert currently works only with id_provider set as \"ad\" or \"ipa\""
|
||||
+);
|
||||
+
|
||||
+static PyObject * py_getlistbycert(PyObject *module, PyObject *args)
|
||||
+{
|
||||
+ return check_args(LISTBYCERT, args);
|
||||
+}
|
||||
+
|
||||
static PyMethodDef methods[] = {
|
||||
{ sss_py_const_p(char, "getsidbyname"), (PyCFunction) py_getsidbyname,
|
||||
METH_VARARGS, getsidbyname_doc },
|
||||
@@ -393,6 +490,8 @@ static PyMethodDef methods[] = {
|
||||
METH_VARARGS, getidbysid_doc },
|
||||
{ sss_py_const_p(char, "getnamebycert"), (PyCFunction) py_getnamebycert,
|
||||
METH_VARARGS, getnamebycert_doc },
|
||||
+ { sss_py_const_p(char, "getlistbycert"), (PyCFunction) py_getlistbycert,
|
||||
+ METH_VARARGS, getlistbycert_doc },
|
||||
{ NULL,NULL, 0, NULL }
|
||||
};
|
||||
|
||||
diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c
|
||||
index 08b3d32f2662efc1cc803f6e9e5f2d064f7d3033..1931bf62a686c7f30852dac547866609cf54a81b 100644
|
||||
--- a/src/responder/nss/nss_cmd.c
|
||||
+++ b/src/responder/nss/nss_cmd.c
|
||||
@@ -932,6 +932,12 @@ static errno_t nss_cmd_getnamebycert(struct cli_ctx *cli_ctx)
|
||||
nss_protocol_fill_single_name);
|
||||
}
|
||||
|
||||
+static errno_t nss_cmd_getlistbycert(struct cli_ctx *cli_ctx)
|
||||
+{
|
||||
+ return nss_getby_cert(cli_ctx, CACHE_REQ_USER_BY_CERT,
|
||||
+ nss_protocol_fill_name_list);
|
||||
+}
|
||||
+
|
||||
struct sss_cmd_table *get_nss_cmds(void)
|
||||
{
|
||||
static struct sss_cmd_table nss_cmds[] = {
|
||||
@@ -961,6 +967,7 @@ struct sss_cmd_table *get_nss_cmds(void)
|
||||
{ SSS_NSS_GETIDBYSID, nss_cmd_getidbysid },
|
||||
{ SSS_NSS_GETORIGBYNAME, nss_cmd_getorigbyname },
|
||||
{ SSS_NSS_GETNAMEBYCERT, nss_cmd_getnamebycert },
|
||||
+ { SSS_NSS_GETLISTBYCERT, nss_cmd_getlistbycert },
|
||||
{ SSS_CLI_NULL, NULL }
|
||||
};
|
||||
|
||||
diff --git a/src/responder/nss/nss_protocol.h b/src/responder/nss/nss_protocol.h
|
||||
index c94e7b911eb3c0f97b8c06b1766573311cde41ae..e4c0e52c0e642e885ef2c8423ea564beff7242cf 100644
|
||||
--- a/src/responder/nss/nss_protocol.h
|
||||
+++ b/src/responder/nss/nss_protocol.h
|
||||
@@ -175,6 +175,12 @@ nss_protocol_fill_single_name(struct nss_ctx *nss_ctx,
|
||||
struct cache_req_result *result);
|
||||
|
||||
errno_t
|
||||
+nss_protocol_fill_name_list(struct nss_ctx *nss_ctx,
|
||||
+ struct nss_cmd_ctx *cmd_ctx,
|
||||
+ struct sss_packet *packet,
|
||||
+ struct cache_req_result *result);
|
||||
+
|
||||
+errno_t
|
||||
nss_protocol_fill_id(struct nss_ctx *nss_ctx,
|
||||
struct nss_cmd_ctx *cmd_ctx,
|
||||
struct sss_packet *packet,
|
||||
diff --git a/src/responder/nss/nss_protocol_sid.c b/src/responder/nss/nss_protocol_sid.c
|
||||
index 0b97e65f75412d40832d861568d8e2f9de5e1732..a6a4e27d039c67ef98f6d5900d5e3fcadb3ee717 100644
|
||||
--- a/src/responder/nss/nss_protocol_sid.c
|
||||
+++ b/src/responder/nss/nss_protocol_sid.c
|
||||
@@ -498,3 +498,66 @@ nss_protocol_fill_id(struct nss_ctx *nss_ctx,
|
||||
|
||||
return EOK;
|
||||
}
|
||||
+
|
||||
+errno_t
|
||||
+nss_protocol_fill_name_list(struct nss_ctx *nss_ctx,
|
||||
+ struct nss_cmd_ctx *cmd_ctx,
|
||||
+ struct sss_packet *packet,
|
||||
+ struct cache_req_result *result)
|
||||
+{
|
||||
+ enum sss_id_type *id_types;
|
||||
+ size_t rp = 0;
|
||||
+ size_t body_len;
|
||||
+ uint8_t *body;
|
||||
+ errno_t ret;
|
||||
+ struct sized_string *sz_names;
|
||||
+ size_t len;
|
||||
+ size_t c;
|
||||
+ const char *tmp_str;
|
||||
+
|
||||
+ sz_names = talloc_array(cmd_ctx, struct sized_string, result->count);
|
||||
+ if (sz_names == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ id_types = talloc_array(cmd_ctx, enum sss_id_type, result->count);
|
||||
+ if (id_types == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ len = 0;
|
||||
+ for (c = 0; c < result->count; c++) {
|
||||
+ ret = nss_get_id_type(cmd_ctx, result, &(id_types[c]));
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ tmp_str = nss_get_name_from_msg(result->domain, result->msgs[c]);
|
||||
+ if (tmp_str == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+ to_sized_string(&(sz_names[c]), tmp_str);
|
||||
+
|
||||
+ len += sz_names[c].len;
|
||||
+ }
|
||||
+
|
||||
+ len += (2 + result->count) * sizeof(uint32_t);
|
||||
+
|
||||
+ ret = sss_packet_grow(packet, len);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sss_packet_grow failed.\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ sss_packet_get_body(packet, &body, &body_len);
|
||||
+
|
||||
+ SAFEALIGN_SET_UINT32(&body[rp], result->count, &rp); /* Num results. */
|
||||
+ SAFEALIGN_SET_UINT32(&body[rp], 0, &rp); /* Reserved. */
|
||||
+ for (c = 0; c < result->count; c++) {
|
||||
+ SAFEALIGN_SET_UINT32(&body[rp], id_types[c], &rp);
|
||||
+ SAFEALIGN_SET_STRING(&body[rp], sz_names[c].str, sz_names[c].len,
|
||||
+ &rp);
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
diff --git a/src/sss_client/idmap/sss_nss_idmap.c b/src/sss_client/idmap/sss_nss_idmap.c
|
||||
index fa5a499e3606f7e45a406de4d63002ba35365cb1..6f3af267a1e763e7dce77e3862be377ae2bfe984 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_idmap.c
|
||||
+++ b/src/sss_client/idmap/sss_nss_idmap.c
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "util/strtonum.h"
|
||||
|
||||
#define DATA_START (3 * sizeof(uint32_t))
|
||||
+#define LIST_START (2 * sizeof(uint32_t))
|
||||
union input {
|
||||
const char *str;
|
||||
uint32_t id;
|
||||
@@ -38,10 +39,12 @@ union input {
|
||||
|
||||
struct output {
|
||||
enum sss_id_type type;
|
||||
+ enum sss_id_type *types;
|
||||
union {
|
||||
char *str;
|
||||
uint32_t id;
|
||||
struct sss_nss_kv *kv_list;
|
||||
+ char **names;
|
||||
} d;
|
||||
};
|
||||
|
||||
@@ -72,6 +75,63 @@ void sss_nss_free_kv(struct sss_nss_kv *kv_list)
|
||||
}
|
||||
}
|
||||
|
||||
+void sss_nss_free_list(char **l)
|
||||
+{
|
||||
+ size_t c;
|
||||
+
|
||||
+ if (l != NULL) {
|
||||
+ for (c = 0; l[c] != NULL; c++) {
|
||||
+ free(l[c]);
|
||||
+ }
|
||||
+ free(l);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int buf_to_name_type_list(uint8_t *buf, size_t buf_len, uint32_t num,
|
||||
+ char ***names, enum sss_id_type **types)
|
||||
+{
|
||||
+ int ret;
|
||||
+ size_t c;
|
||||
+ char **n = NULL;
|
||||
+ enum sss_id_type *t = NULL;
|
||||
+ size_t rp = 0;
|
||||
+
|
||||
+ n = calloc(num + 1, sizeof(char *));
|
||||
+ if (n == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ t = calloc(num + 1, sizeof(enum sss_id_type));
|
||||
+ if (t == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ for (c = 0; c < num; c++) {
|
||||
+ SAFEALIGN_COPY_UINT32(&(t[c]), buf + rp, &rp);
|
||||
+ n[c] = strdup((char *) buf + rp);
|
||||
+ if (n[c] == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ rp += strlen(n[c]) + 1;
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ if (ret != EOK) {
|
||||
+ sss_nss_free_list(n);
|
||||
+ free(t);
|
||||
+ } else {
|
||||
+ *names = n;
|
||||
+ *types = t;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int buf_to_kv_list(uint8_t *buf, size_t buf_len,
|
||||
struct sss_nss_kv **kv_list)
|
||||
{
|
||||
@@ -153,13 +213,14 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd ,
|
||||
size_t data_len;
|
||||
uint32_t c;
|
||||
struct sss_nss_kv *kv_list;
|
||||
+ char **names;
|
||||
+ enum sss_id_type *types;
|
||||
|
||||
switch (cmd) {
|
||||
case SSS_NSS_GETSIDBYNAME:
|
||||
case SSS_NSS_GETNAMEBYSID:
|
||||
case SSS_NSS_GETIDBYSID:
|
||||
case SSS_NSS_GETORIGBYNAME:
|
||||
- case SSS_NSS_GETNAMEBYCERT:
|
||||
ret = sss_strnlen(inp.str, 2048, &inp_len);
|
||||
if (ret != EOK) {
|
||||
return EINVAL;
|
||||
@@ -169,6 +230,17 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd ,
|
||||
rd.data = inp.str;
|
||||
|
||||
break;
|
||||
+ case SSS_NSS_GETNAMEBYCERT:
|
||||
+ case SSS_NSS_GETLISTBYCERT:
|
||||
+ ret = sss_strnlen(inp.str, 10 * 1024 , &inp_len);
|
||||
+ if (ret != EOK) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ rd.len = inp_len + 1;
|
||||
+ rd.data = inp.str;
|
||||
+
|
||||
+ break;
|
||||
case SSS_NSS_GETSIDBYID:
|
||||
rd.len = sizeof(uint32_t);
|
||||
rd.data = &inp.id;
|
||||
@@ -195,7 +267,7 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd ,
|
||||
if (num_results == 0) {
|
||||
ret = ENOENT;
|
||||
goto done;
|
||||
- } else if (num_results > 1) {
|
||||
+ } else if (num_results > 1 && cmd != SSS_NSS_GETLISTBYCERT) {
|
||||
ret = EBADMSG;
|
||||
goto done;
|
||||
}
|
||||
@@ -237,6 +309,18 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd ,
|
||||
out->d.id = c;
|
||||
|
||||
break;
|
||||
+ case SSS_NSS_GETLISTBYCERT:
|
||||
+ ret = buf_to_name_type_list(repbuf + LIST_START, replen - LIST_START,
|
||||
+ num_results,
|
||||
+ &names, &types);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ out->types = types;
|
||||
+ out->d.names = names;
|
||||
+
|
||||
+ break;
|
||||
case SSS_NSS_GETORIGBYNAME:
|
||||
ret = buf_to_kv_list(repbuf + DATA_START, data_len, &kv_list);
|
||||
if (ret != EOK) {
|
||||
@@ -392,3 +476,25 @@ int sss_nss_getnamebycert(const char *cert, char **fq_name,
|
||||
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+int sss_nss_getlistbycert(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_GETLISTBYCERT, &out);
|
||||
+ if (ret == EOK) {
|
||||
+ *fq_name = out.d.names;
|
||||
+ *type = out.types;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/src/sss_client/idmap/sss_nss_idmap.exports b/src/sss_client/idmap/sss_nss_idmap.exports
|
||||
index bd5d80212017d38334c3cdeefa47d6029f42aebb..49dac6fc9351b0ca98cd46e83b85ec8ef0075a0d 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_idmap.exports
|
||||
+++ b/src/sss_client/idmap/sss_nss_idmap.exports
|
||||
@@ -25,3 +25,9 @@ SSS_NSS_IDMAP_0.2.0 {
|
||||
global:
|
||||
sss_nss_getnamebycert;
|
||||
} SSS_NSS_IDMAP_0.1.0;
|
||||
+
|
||||
+SSS_NSS_IDMAP_0.3.0 {
|
||||
+ # public functions
|
||||
+ global:
|
||||
+ sss_nss_getlistbycert;
|
||||
+} SSS_NSS_IDMAP_0.2.0;
|
||||
diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h
|
||||
index 8a6299194e7b91e084b26c0c96e2f93875a832e7..cbf19479ff9ec6e0d6e07e1f7e48a1571e147740 100644
|
||||
--- a/src/sss_client/idmap/sss_nss_idmap.h
|
||||
+++ b/src/sss_client/idmap/sss_nss_idmap.h
|
||||
@@ -130,7 +130,7 @@ int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list,
|
||||
* @param[in] cert base64 encoded certificate
|
||||
* @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
|
||||
+ * @param[out] type Type of the object related to the cert
|
||||
*
|
||||
* @return
|
||||
* - see #sss_nss_getsidbyname
|
||||
@@ -139,6 +139,21 @@ int sss_nss_getnamebycert(const char *cert, 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
|
||||
+ *
|
||||
+ * @param[in] cert base64 encoded certificate
|
||||
+ * @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
|
||||
+ */
|
||||
+int sss_nss_getlistbycert(const char *cert, char ***fq_name,
|
||||
+ enum sss_id_type **type);
|
||||
+
|
||||
+/**
|
||||
* @brief Free key-value list returned by sss_nss_getorigbyname()
|
||||
*
|
||||
* @param[in] kv_list Key-value list returned by sss_nss_getorigbyname().
|
||||
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
|
||||
index 8091e11515184dc9b7f32eed535055d9eee3143f..59fee7a4eceb2c185e156e812af7f2f4c6b2a0dd 100644
|
||||
--- a/src/sss_client/sss_cli.h
|
||||
+++ b/src/sss_client/sss_cli.h
|
||||
@@ -260,6 +260,11 @@ SSS_NSS_GETNAMEBYCERT = 0x0116, /**< Takes the zero terminated string
|
||||
of a X509 certificate and returns the zero
|
||||
terminated fully qualified name of the
|
||||
related object. */
|
||||
+SSS_NSS_GETLISTBYCERT = 0x0117, /**< Takes the zero terminated string
|
||||
+ of the base64 encoded DER representation
|
||||
+ of a X509 certificate and returns a list
|
||||
+ of zero terminated fully qualified names
|
||||
+ of the related objects. */
|
||||
};
|
||||
|
||||
/**
|
||||
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
|
||||
index 76b9c6fb05673130de0957e93291919c263a28f3..50714715cc80338640f2a77ecbe17bd5e0d6e911 100644
|
||||
--- a/src/tests/cmocka/test_nss_srv.c
|
||||
+++ b/src/tests/cmocka/test_nss_srv.c
|
||||
@@ -3454,6 +3454,16 @@ struct passwd testbycert = {
|
||||
.pw_passwd = discard_const("*"),
|
||||
};
|
||||
|
||||
+struct passwd testbycert2 = {
|
||||
+ .pw_name = discard_const("testcertuser2"),
|
||||
+ .pw_uid = 23457,
|
||||
+ .pw_gid = 6890,
|
||||
+ .pw_dir = discard_const("/home/testcertuser2"),
|
||||
+ .pw_gecos = discard_const("test cert user2"),
|
||||
+ .pw_shell = discard_const("/bin/sh"),
|
||||
+ .pw_passwd = discard_const("*"),
|
||||
+};
|
||||
+
|
||||
#define TEST_TOKEN_CERT \
|
||||
"MIIECTCCAvGgAwIBAgIBCDANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \
|
||||
"REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA2MjMx" \
|
||||
@@ -3495,6 +3505,57 @@ static int test_nss_getnamebycert_check(uint32_t status, uint8_t *body, size_t b
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+static int test_nss_getlistbycert_check(uint32_t status, uint8_t *body, size_t blen)
|
||||
+{
|
||||
+ size_t rp = 0;
|
||||
+ uint32_t id_type;
|
||||
+ uint32_t num;
|
||||
+ uint32_t reserved;
|
||||
+ const char *name;
|
||||
+ int found = 0;
|
||||
+ const char *fq_name1 = "testcertuser@"TEST_DOM_NAME ;
|
||||
+ const char *fq_name2 = "testcertuser2@"TEST_DOM_NAME;
|
||||
+
|
||||
+ assert_int_equal(status, EOK);
|
||||
+
|
||||
+ /* num_results and reserved */
|
||||
+ SAFEALIGN_COPY_UINT32(&num, body + rp, &rp);
|
||||
+ assert_in_range(num, 1, 2);
|
||||
+ SAFEALIGN_COPY_UINT32(&reserved, body + rp, &rp);
|
||||
+ assert_int_equal(reserved, 0);
|
||||
+
|
||||
+ SAFEALIGN_COPY_UINT32(&id_type, body + rp, &rp);
|
||||
+ assert_int_equal(id_type, SSS_ID_TYPE_UID);
|
||||
+
|
||||
+ name = (const char *)body + rp;
|
||||
+ if (num == 1) {
|
||||
+ assert_string_equal(name, fq_name1);
|
||||
+ return EOK;
|
||||
+ }
|
||||
+
|
||||
+ rp += strlen(name) + 1;
|
||||
+ if (strcmp(name, fq_name1) == 0) {
|
||||
+ found = 1;
|
||||
+ } else if (strcmp(name, fq_name2) == 0) {
|
||||
+ found = 2;
|
||||
+ }
|
||||
+ assert_in_range(found, 1, 2);
|
||||
+
|
||||
+ SAFEALIGN_COPY_UINT32(&id_type, body + rp, &rp);
|
||||
+ assert_int_equal(id_type, SSS_ID_TYPE_UID);
|
||||
+
|
||||
+ name = (const char *)body + rp;
|
||||
+ if (found == 1) {
|
||||
+ assert_string_equal(name, fq_name2);
|
||||
+ } else {
|
||||
+ assert_string_equal(name, fq_name1);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static void test_nss_getnamebycert(void **state)
|
||||
{
|
||||
errno_t ret;
|
||||
@@ -3572,6 +3633,99 @@ void test_nss_getnamebycert_neg(void **state)
|
||||
assert_int_equal(nss_test_ctx->ncache_hits, 1);
|
||||
}
|
||||
|
||||
+static void test_nss_getlistbycert(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ struct sysdb_attrs *attrs;
|
||||
+ unsigned char *der = NULL;
|
||||
+ size_t der_size;
|
||||
+
|
||||
+ attrs = sysdb_new_attrs(nss_test_ctx);
|
||||
+ assert_non_null(attrs);
|
||||
+
|
||||
+ der = sss_base64_decode(nss_test_ctx, TEST_TOKEN_CERT, &der_size);
|
||||
+ assert_non_null(der);
|
||||
+
|
||||
+ ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_CERT, der, der_size);
|
||||
+ talloc_free(der);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Prime the cache with a valid user */
|
||||
+ ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom,
|
||||
+ &testbycert, attrs, 0);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ talloc_free(attrs);
|
||||
+
|
||||
+ mock_input_cert(TEST_TOKEN_CERT);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETLISTBYCERT);
|
||||
+ mock_fill_bysid();
|
||||
+
|
||||
+ /* Query for that user, call a callback when command finishes */
|
||||
+ /* Should go straight to back end, without contacting DP. */
|
||||
+ /* If there is only a single user mapped the result will look like the */
|
||||
+ /* result of getnamebycert. */
|
||||
+ set_cmd_cb(test_nss_getlistbycert_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETLISTBYCERT,
|
||||
+ 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);
|
||||
+}
|
||||
+
|
||||
+static void test_nss_getlistbycert_multi(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ struct sysdb_attrs *attrs;
|
||||
+ unsigned char *der = NULL;
|
||||
+ size_t der_size;
|
||||
+
|
||||
+ der = sss_base64_decode(nss_test_ctx, TEST_TOKEN_CERT, &der_size);
|
||||
+ assert_non_null(der);
|
||||
+
|
||||
+ attrs = sysdb_new_attrs(nss_test_ctx);
|
||||
+ assert_non_null(attrs);
|
||||
+
|
||||
+ ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_CERT, der, der_size);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Prime the cache with two valid user */
|
||||
+ ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom,
|
||||
+ &testbycert, attrs, 0);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ talloc_free(attrs);
|
||||
+
|
||||
+ /* Looks like attrs is modified during store_user() makes sure we start
|
||||
+ * with fresh data. */
|
||||
+ attrs = sysdb_new_attrs(nss_test_ctx);
|
||||
+ assert_non_null(attrs);
|
||||
+
|
||||
+ ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_CERT, der, der_size);
|
||||
+ talloc_free(der);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom,
|
||||
+ &testbycert2, attrs, 0);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ talloc_free(attrs);
|
||||
+
|
||||
+ mock_input_cert(TEST_TOKEN_CERT);
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETLISTBYCERT);
|
||||
+ mock_fill_bysid();
|
||||
+
|
||||
+ /* Query for that user, call a callback when command finishes */
|
||||
+ /* Should go straight to back end, without contacting DP */
|
||||
+ set_cmd_cb(test_nss_getlistbycert_check);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETLISTBYCERT,
|
||||
+ 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);
|
||||
+}
|
||||
+
|
||||
struct passwd sid_user = {
|
||||
.pw_name = discard_const("testusersid"),
|
||||
.pw_uid = 1234,
|
||||
@@ -3818,6 +3972,10 @@ int main(int argc, const char *argv[])
|
||||
nss_test_setup, nss_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getnamebycert,
|
||||
nss_test_setup, nss_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_nss_getlistbycert,
|
||||
+ nss_test_setup, nss_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_nss_getlistbycert_multi,
|
||||
+ nss_test_setup, nss_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getsidbyname,
|
||||
nss_test_setup, nss_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getsidbyupn,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,70 +0,0 @@
|
||||
From a0b1bfa76073d3ce3208e67e6d72bb92088edac5 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Tue, 28 Feb 2017 14:19:53 +0100
|
||||
Subject: [PATCH 15/97] nss: allow larger buffer for certificate based requests
|
||||
|
||||
To make sure larger certificates can be processed as well the maximal
|
||||
buffer size is increased for requests by certificate.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/responder/common/responder_packet.c | 21 ++++++++++++++++++++-
|
||||
src/responder/common/responder_packet.h | 1 +
|
||||
2 files changed, 21 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/responder/common/responder_packet.c b/src/responder/common/responder_packet.c
|
||||
index 4f5e110837eb76609d31a77c62a00e00530ffc90..cc4d66995965cca4c86a80c31d2afd4c9ac3e0e4 100644
|
||||
--- a/src/responder/common/responder_packet.c
|
||||
+++ b/src/responder/common/responder_packet.c
|
||||
@@ -179,6 +179,8 @@ int sss_packet_recv(struct sss_packet *packet, int fd)
|
||||
size_t rb;
|
||||
size_t len;
|
||||
void *buf;
|
||||
+ size_t new_len;
|
||||
+ int ret;
|
||||
|
||||
buf = (uint8_t *)packet->buffer + packet->iop;
|
||||
if (packet->iop > 4) len = sss_packet_get_len(packet) - packet->iop;
|
||||
@@ -205,7 +207,24 @@ int sss_packet_recv(struct sss_packet *packet, int fd)
|
||||
}
|
||||
|
||||
if (sss_packet_get_len(packet) > packet->memsize) {
|
||||
- return EINVAL;
|
||||
+ /* Allow certificate based requests to use larger buffer but not
|
||||
+ * larger than SSS_CERT_PACKET_MAX_RECV_SIZE. Due to the way
|
||||
+ * sss_packet_grow() works the packet len must be set to '0' first and
|
||||
+ * then grow to the expected size. */
|
||||
+ if ((sss_packet_get_cmd(packet) == SSS_NSS_GETNAMEBYCERT
|
||||
+ || sss_packet_get_cmd(packet) == SSS_NSS_GETLISTBYCERT)
|
||||
+ && packet->memsize < SSS_CERT_PACKET_MAX_RECV_SIZE
|
||||
+ && (new_len = sss_packet_get_len(packet))
|
||||
+ < SSS_CERT_PACKET_MAX_RECV_SIZE) {
|
||||
+ new_len = sss_packet_get_len(packet);
|
||||
+ sss_packet_set_len(packet, 0);
|
||||
+ ret = sss_packet_grow(packet, new_len);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ } else {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
}
|
||||
|
||||
packet->iop += rb;
|
||||
diff --git a/src/responder/common/responder_packet.h b/src/responder/common/responder_packet.h
|
||||
index 3ad0eee28477e446c9e4996617beb55f32923d47..afceb4aaefa40fd86bdfde820c92c09b65cd8702 100644
|
||||
--- a/src/responder/common/responder_packet.h
|
||||
+++ b/src/responder/common/responder_packet.h
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "sss_client/sss_cli.h"
|
||||
|
||||
#define SSS_PACKET_MAX_RECV_SIZE 1024
|
||||
+#define SSS_CERT_PACKET_MAX_RECV_SIZE ( 10 * SSS_PACKET_MAX_RECV_SIZE )
|
||||
|
||||
struct sss_packet;
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,44 +0,0 @@
|
||||
From a04bef313508c423ed06cc54805a3b8106ab90cd Mon Sep 17 00:00:00 2001
|
||||
From: Justin Stephenson <jstephen@redhat.com>
|
||||
Date: Mon, 20 Mar 2017 11:51:05 -0400
|
||||
Subject: [PATCH 16/97] IPA: Add s2n request to string function
|
||||
|
||||
Add a function to convert request_types to string allowing the
|
||||
ability to print request type information for ipa_s2n functions during
|
||||
IPA client operations.
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
src/providers/ipa/ipa_s2n_exop.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
|
||||
index 07bbb2b4d252c8ca9ada4d890c36c903c9f75773..4fe20689fe4c0f2bb5217691dd05b37d2a1cc820 100644
|
||||
--- a/src/providers/ipa/ipa_s2n_exop.c
|
||||
+++ b/src/providers/ipa/ipa_s2n_exop.c
|
||||
@@ -979,6 +979,22 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static const char *ipa_s2n_reqtype2str(enum request_types request_type)
|
||||
+{
|
||||
+ switch (request_type) {
|
||||
+ case REQ_SIMPLE:
|
||||
+ return "REQ_SIMPLE";
|
||||
+ case REQ_FULL:
|
||||
+ return "REQ_FULL";
|
||||
+ case REQ_FULL_WITH_MEMBERS:
|
||||
+ return "REQ_FULL_WITH_MEMBERS";
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return "Unknown request type";
|
||||
+}
|
||||
+
|
||||
struct ipa_s2n_get_list_state {
|
||||
struct tevent_context *ev;
|
||||
struct ipa_id_ctx *ipa_ctx;
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,82 +0,0 @@
|
||||
From cd83aead3c9799ac05d8f8977dbb92bbd399c6d5 Mon Sep 17 00:00:00 2001
|
||||
From: Justin Stephenson <jstephen@redhat.com>
|
||||
Date: Thu, 16 Mar 2017 14:46:55 -0400
|
||||
Subject: [PATCH 17/97] IPA: Enhance debug logging for ipa s2n operations
|
||||
|
||||
Add log messages to provide useful debug logging surrounding
|
||||
IPA client extended operations to the IPA Server during AD trust
|
||||
requests to retrieve information. Print more details about the
|
||||
objects requested and received during the ipa_s2n operations.
|
||||
|
||||
This will improve log analysis and troubleshooting efforts during AD
|
||||
trust user and group resolution failures on IPA clients, such as missing
|
||||
groups.
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
src/providers/ipa/ipa_s2n_exop.c | 28 ++++++++++++++++++++++++++++
|
||||
1 file changed, 28 insertions(+)
|
||||
|
||||
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
|
||||
index 4fe20689fe4c0f2bb5217691dd05b37d2a1cc820..c99312274073858e5e03f3e82c069dafc839eb61 100644
|
||||
--- a/src/providers/ipa/ipa_s2n_exop.c
|
||||
+++ b/src/providers/ipa/ipa_s2n_exop.c
|
||||
@@ -1156,6 +1156,13 @@ static errno_t ipa_s2n_get_list_step(struct tevent_req *req)
|
||||
need_v1 = true;
|
||||
}
|
||||
|
||||
+ if (state->req_input.type == REQ_INP_NAME
|
||||
+ && state->req_input.inp.name != NULL) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "Sending request_type: [%s] for group [%s].\n",
|
||||
+ ipa_s2n_reqtype2str(state->request_type),
|
||||
+ state->list[state->list_idx]);
|
||||
+ }
|
||||
+
|
||||
subreq = ipa_s2n_exop_send(state, state->ev, state->sh, need_v1,
|
||||
state->exop_timeout, bv_req);
|
||||
if (subreq == NULL) {
|
||||
@@ -1194,6 +1201,9 @@ static void ipa_s2n_get_list_next(struct tevent_req *subreq)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "Received [%s] attributes from IPA server.\n",
|
||||
+ state->attrs->a.name);
|
||||
+
|
||||
if (is_default_view(state->ipa_ctx->view_name)) {
|
||||
ret = ipa_s2n_get_list_save_step(req);
|
||||
if (ret == EOK) {
|
||||
@@ -1375,6 +1385,11 @@ struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "Sending request_type: [%s] for trust user [%s] "
|
||||
+ "to IPA server\n",
|
||||
+ ipa_s2n_reqtype2str(state->request_type),
|
||||
+ req_input->inp.name);
|
||||
+
|
||||
subreq = ipa_s2n_exop_send(state, state->ev, state->sh, is_v1,
|
||||
state->exop_timeout, bv_req);
|
||||
if (subreq == NULL) {
|
||||
@@ -1661,6 +1676,19 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq)
|
||||
state->attrs = attrs;
|
||||
|
||||
if (attrs->response_type == RESP_USER_GROUPLIST) {
|
||||
+
|
||||
+ if (DEBUG_IS_SET(SSSDBG_TRACE_FUNC)) {
|
||||
+ size_t c;
|
||||
+
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "Received [%zu] groups in group list "
|
||||
+ "from IPA Server\n", attrs->ngroups);
|
||||
+
|
||||
+ for (c = 0; c < attrs->ngroups; c++) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "[%s].\n", attrs->groups[c]);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
ret = get_group_dn_list(state, state->dom,
|
||||
attrs->ngroups, attrs->groups,
|
||||
&group_dn_list, &missing_list);
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,45 +0,0 @@
|
||||
From 3a4a88259ba90d3dc45c1adbbfd39bd7c0204a12 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 15 Mar 2017 13:32:42 +0100
|
||||
Subject: [PATCH 18/97] UTIL: iobuf: Make input parameter for the readonly
|
||||
operation const
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/util/sss_iobuf.c | 2 +-
|
||||
src/util/sss_iobuf.h | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/util/sss_iobuf.c b/src/util/sss_iobuf.c
|
||||
index 7c72ea94d7a005dfd9671793b3ad470a6de7967a..900418b750a3455ebc2c3bb1893db726692260b8 100644
|
||||
--- a/src/util/sss_iobuf.c
|
||||
+++ b/src/util/sss_iobuf.c
|
||||
@@ -49,7 +49,7 @@ struct sss_iobuf *sss_iobuf_init_empty(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
struct sss_iobuf *sss_iobuf_init_readonly(TALLOC_CTX *mem_ctx,
|
||||
- uint8_t *data,
|
||||
+ const uint8_t *data,
|
||||
size_t size)
|
||||
{
|
||||
struct sss_iobuf *iobuf;
|
||||
diff --git a/src/util/sss_iobuf.h b/src/util/sss_iobuf.h
|
||||
index eae357a40f2948e63df189f2842edee68691a542..900faaa212230f72f52e344c085167e80ae2b465 100644
|
||||
--- a/src/util/sss_iobuf.h
|
||||
+++ b/src/util/sss_iobuf.h
|
||||
@@ -47,7 +47,7 @@ struct sss_iobuf *sss_iobuf_init_empty(TALLOC_CTX *mem_ctx,
|
||||
* @return The newly created buffer on success or NULL on an error.
|
||||
*/
|
||||
struct sss_iobuf *sss_iobuf_init_readonly(TALLOC_CTX *mem_ctx,
|
||||
- uint8_t *data,
|
||||
+ const uint8_t *data,
|
||||
size_t size);
|
||||
|
||||
/*
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 24889dc5e7eb7bc992ab0fa05edfdfa1d157131a Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 15 Mar 2017 13:42:03 +0100
|
||||
Subject: [PATCH 19/97] UTIL: Fix a typo in the tcurl test tool
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/tests/tcurl_test_tool.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/tests/tcurl_test_tool.c b/src/tests/tcurl_test_tool.c
|
||||
index 35ea979780df47c92ed92bc5bba713faa8909b90..38cea432885c97ca3827c8f158bf7e3ebfc67b31 100644
|
||||
--- a/src/tests/tcurl_test_tool.c
|
||||
+++ b/src/tests/tcurl_test_tool.c
|
||||
@@ -204,8 +204,8 @@ int main(int argc, const char *argv[])
|
||||
urls[i],
|
||||
headers,
|
||||
inbufs[i],
|
||||
- 10);
|
||||
- if (ctx == NULL) {
|
||||
+ 5);
|
||||
+ if (req == NULL) {
|
||||
DEBUG(SSSDBG_FATAL_FAILURE, "Could not create request\n");
|
||||
talloc_zfree(tool_ctx);
|
||||
return 1;
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,36 +0,0 @@
|
||||
From c194e8d7cad0184d710d9979e9f12d5cfe176f4a Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Thu, 23 Feb 2017 20:55:05 +0100
|
||||
Subject: [PATCH 20/97] UTIL: Add SAFEALIGN_COPY_UINT8_CHECK
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This macro will be used later in the KCM code
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/util/util_safealign.h | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/src/util/util_safealign.h b/src/util/util_safealign.h
|
||||
index 0d9a579cdbfafc30bf2d0a6ad2651c71428ebd93..57f04a17d4a38300b959c1593d756b351ebd89e8 100644
|
||||
--- a/src/util/util_safealign.h
|
||||
+++ b/src/util/util_safealign.h
|
||||
@@ -130,6 +130,12 @@ safealign_memcpy(void *dest, const void *src, size_t n, size_t *counter)
|
||||
safealign_memcpy(dest, src, srclen, pctr); \
|
||||
} while(0)
|
||||
|
||||
+#define SAFEALIGN_COPY_UINT8_CHECK(dest, src, len, pctr) do { \
|
||||
+ if ((*(pctr) + sizeof(uint8_t)) > (len) || \
|
||||
+ SIZE_T_OVERFLOW(*(pctr), sizeof(uint8_t))) { return EINVAL; } \
|
||||
+ safealign_memcpy(dest, src, sizeof(uint8_t), pctr); \
|
||||
+} while(0)
|
||||
+
|
||||
/* Aliases for backward compatibility. */
|
||||
#define SAFEALIGN_SET_VALUE SAFEALIGN_SETMEM_VALUE
|
||||
#define SAFEALIGN_SET_INT64 SAFEALIGN_SETMEM_INT64
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,34 +0,0 @@
|
||||
From 4f511a4c5f0084e22ce4c7613f1b279533c68cc5 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 20 Sep 2016 22:00:27 +0200
|
||||
Subject: [PATCH 21/97] UTIL: Add utility macro cli_creds_get_gid()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The KCM responder checks the owneship of the ccache based on both UID
|
||||
and GID of the peer. In order to reuse the already existing creds
|
||||
structure, let's just add a new macro that returns the GID from the
|
||||
creds structure.
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/util/util_creds.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/util/util_creds.h b/src/util/util_creds.h
|
||||
index 65468fa12b8c6921859574c40f5759c936a10e86..936b9965d1ccd2b437d93b38d789b6f8389f47a6 100644
|
||||
--- a/src/util/util_creds.h
|
||||
+++ b/src/util/util_creds.h
|
||||
@@ -71,6 +71,7 @@ struct cli_creds {
|
||||
};
|
||||
|
||||
#define cli_creds_get_uid(x) x->ucred.uid
|
||||
+#define cli_creds_get_gid(x) x->ucred.gid
|
||||
|
||||
#else /* not HAVE_UCRED */
|
||||
struct cli_creds {
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,194 +0,0 @@
|
||||
From 5f7f45a64bdb9353f15b945db4ad2564b4b28ab2 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Thu, 23 Feb 2017 21:57:13 +0100
|
||||
Subject: [PATCH 22/97] UTIL: Add type-specific getsetters to sss_iobuf
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The KCM responder receives its input as unstructured data. To make the
|
||||
parsing easier, this commit adds several type-specific getsetters to the
|
||||
iobuf module.
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/util/sss_iobuf.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
src/util/sss_iobuf.h | 33 ++++++++++++++++
|
||||
2 files changed, 141 insertions(+)
|
||||
|
||||
diff --git a/src/util/sss_iobuf.c b/src/util/sss_iobuf.c
|
||||
index 900418b750a3455ebc2c3bb1893db726692260b8..fc288d2df2bfaaba393dd490d4da8976de804cb5 100644
|
||||
--- a/src/util/sss_iobuf.c
|
||||
+++ b/src/util/sss_iobuf.c
|
||||
@@ -184,6 +184,25 @@ errno_t sss_iobuf_read(struct sss_iobuf *iobuf,
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+errno_t sss_iobuf_read_len(struct sss_iobuf *iobuf,
|
||||
+ size_t len,
|
||||
+ uint8_t *_buf)
|
||||
+{
|
||||
+ size_t read;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = sss_iobuf_read(iobuf, len, _buf, &read);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (read != len) {
|
||||
+ return ENOBUFS;
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
errno_t sss_iobuf_write_len(struct sss_iobuf *iobuf,
|
||||
uint8_t *buf,
|
||||
size_t len)
|
||||
@@ -203,3 +222,92 @@ errno_t sss_iobuf_write_len(struct sss_iobuf *iobuf,
|
||||
|
||||
return EOK;
|
||||
}
|
||||
+
|
||||
+errno_t sss_iobuf_read_uint32(struct sss_iobuf *iobuf,
|
||||
+ uint32_t *_val)
|
||||
+{
|
||||
+ SAFEALIGN_COPY_UINT32_CHECK(_val, iobuf_ptr(iobuf),
|
||||
+ iobuf->capacity, &iobuf->dp);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+errno_t sss_iobuf_read_int32(struct sss_iobuf *iobuf,
|
||||
+ int32_t *_val)
|
||||
+{
|
||||
+ SAFEALIGN_COPY_INT32_CHECK(_val, iobuf_ptr(iobuf),
|
||||
+ iobuf->capacity, &iobuf->dp);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+errno_t sss_iobuf_write_uint32(struct sss_iobuf *iobuf,
|
||||
+ uint32_t val)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = ensure_bytes(iobuf, sizeof(uint32_t));
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ SAFEALIGN_SETMEM_UINT32(iobuf_ptr(iobuf), val, &iobuf->dp);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+errno_t sss_iobuf_write_int32(struct sss_iobuf *iobuf,
|
||||
+ int32_t val)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = ensure_bytes(iobuf, sizeof(int32_t));
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ SAFEALIGN_SETMEM_INT32(iobuf_ptr(iobuf), val, &iobuf->dp);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+errno_t sss_iobuf_read_stringz(struct sss_iobuf *iobuf,
|
||||
+ const char **_out)
|
||||
+{
|
||||
+ uint8_t *end;
|
||||
+ size_t len;
|
||||
+
|
||||
+ if (iobuf == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (_out == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ *_out = NULL;
|
||||
+
|
||||
+ end = memchr(iobuf_ptr(iobuf), '\0', sss_iobuf_get_size(iobuf));
|
||||
+ if (end == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ len = end + 1 - iobuf_ptr(iobuf);
|
||||
+ if (sss_iobuf_get_size(iobuf) < len) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ *_out = (const char *) iobuf_ptr(iobuf);
|
||||
+ iobuf->dp += len;
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+errno_t sss_iobuf_write_stringz(struct sss_iobuf *iobuf,
|
||||
+ const char *str)
|
||||
+{
|
||||
+ if (iobuf == NULL || str == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ SAFEALIGN_MEMCPY_CHECK(iobuf_ptr(iobuf),
|
||||
+ str, strlen(str)+1,
|
||||
+ sss_iobuf_get_size(iobuf),
|
||||
+ &iobuf->dp);
|
||||
+ return EOK;
|
||||
+}
|
||||
diff --git a/src/util/sss_iobuf.h b/src/util/sss_iobuf.h
|
||||
index 900faaa212230f72f52e344c085167e80ae2b465..cc3dfd1e98eeb49b979ac321bd0253bffa8a6dff 100644
|
||||
--- a/src/util/sss_iobuf.h
|
||||
+++ b/src/util/sss_iobuf.h
|
||||
@@ -96,6 +96,22 @@ errno_t sss_iobuf_read(struct sss_iobuf *iobuf,
|
||||
size_t *_read);
|
||||
|
||||
/*
|
||||
+ * @brief Read an exact number of bytes from an IO buffer
|
||||
+ *
|
||||
+ * Read exactly len bytes from an IO buffer. If the buffer contains fewer
|
||||
+ * bytes than len, ENOBUFS is returned.
|
||||
+ *
|
||||
+ * @param[in] iobuf The IO buffer to read from
|
||||
+ * @param[in] len The maximum number of bytes to read
|
||||
+ * @param[out] _buf The buffer to read data into from iobuf
|
||||
+ *
|
||||
+ * @return EOK on success, errno otherwise
|
||||
+ */
|
||||
+errno_t sss_iobuf_read_len(struct sss_iobuf *iobuf,
|
||||
+ size_t len,
|
||||
+ uint8_t *_buf);
|
||||
+
|
||||
+/*
|
||||
* @brief Write into an IO buffer
|
||||
*
|
||||
* Attempts to write len bytes into the iobuf. If the capacity is exceeded,
|
||||
@@ -115,4 +131,21 @@ errno_t sss_iobuf_write_len(struct sss_iobuf *iobuf,
|
||||
uint8_t *buf,
|
||||
size_t len);
|
||||
|
||||
+errno_t sss_iobuf_read_uint32(struct sss_iobuf *iobuf,
|
||||
+ uint32_t *_val);
|
||||
+
|
||||
+errno_t sss_iobuf_write_uint32(struct sss_iobuf *iobuf,
|
||||
+ uint32_t val);
|
||||
+
|
||||
+errno_t sss_iobuf_read_int32(struct sss_iobuf *iobuf,
|
||||
+ int32_t *_val);
|
||||
+
|
||||
+errno_t sss_iobuf_write_int32(struct sss_iobuf *iobuf,
|
||||
+ int32_t val);
|
||||
+
|
||||
+errno_t sss_iobuf_read_stringz(struct sss_iobuf *iobuf,
|
||||
+ const char **_out);
|
||||
+
|
||||
+errno_t sss_iobuf_write_stringz(struct sss_iobuf *iobuf,
|
||||
+ const char *str);
|
||||
#endif /* __SSS_IOBUF_H_ */
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,262 +0,0 @@
|
||||
From 1dbf09404e20b6e30a24afe72b6d349734aee62f Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 20 Sep 2016 22:03:30 +0200
|
||||
Subject: [PATCH 23/97] UTIL: krb5 principal (un)marshalling
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The KCM responder needs to read the contents of the principal blob that
|
||||
the Kerberos library sends. Since libkrb5 doesn't export any API to do
|
||||
so, we need to implement marshalling and unmarshalling of the principal
|
||||
ourselves.
|
||||
|
||||
In future, when the KCM server also supports renewals, we will also need
|
||||
to unmarshall the credentials, but until that is not really needed, the
|
||||
credentials will be stored as a blob.
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/util/sss_krb5.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
src/util/sss_krb5.h | 9 +++
|
||||
2 files changed, 204 insertions(+)
|
||||
|
||||
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
|
||||
index 4808a7703d07bb4eba91f14a7a515aadaec1774b..d461cf881566af37f31524c16f6a5f1511a5dc89 100644
|
||||
--- a/src/util/sss_krb5.c
|
||||
+++ b/src/util/sss_krb5.c
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
+#include "util/sss_iobuf.h"
|
||||
#include "util/util.h"
|
||||
#include "util/sss_krb5.h"
|
||||
|
||||
@@ -1128,3 +1129,197 @@ done:
|
||||
|
||||
return res;
|
||||
}
|
||||
+
|
||||
+static errno_t iobuf_read_uint32be(struct sss_iobuf *iobuf,
|
||||
+ uint32_t *_val)
|
||||
+{
|
||||
+ uint32_t beval;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = sss_iobuf_read_uint32(iobuf, &beval);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ *_val = be32toh(beval);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static errno_t iobuf_write_uint32be(struct sss_iobuf *iobuf,
|
||||
+ uint32_t val)
|
||||
+{
|
||||
+ uint32_t beval;
|
||||
+
|
||||
+ beval = htobe32(val);
|
||||
+ return sss_iobuf_write_uint32(iobuf, beval);
|
||||
+}
|
||||
+
|
||||
+static errno_t iobuf_get_len_bytes(TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_iobuf *iobuf,
|
||||
+ uint32_t *_nbytes,
|
||||
+ uint8_t **_bytes)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ uint32_t nbytes;
|
||||
+ uint8_t *bytes = NULL;
|
||||
+
|
||||
+ ret = iobuf_read_uint32be(iobuf, &nbytes);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ bytes = talloc_zero_size(mem_ctx, nbytes);
|
||||
+ if (bytes == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_iobuf_read_len(iobuf, nbytes, bytes);
|
||||
+ if (ret != EOK) {
|
||||
+ talloc_free(bytes);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ *_bytes = bytes;
|
||||
+ *_nbytes = nbytes;
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static errno_t get_krb5_data(TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_iobuf *iobuf,
|
||||
+ krb5_data *k5data)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ uint32_t nbytes;
|
||||
+ uint8_t *bytes = NULL;
|
||||
+
|
||||
+ ret = iobuf_get_len_bytes(mem_ctx, iobuf, &nbytes, &bytes);
|
||||
+ if (ret != EOK) {
|
||||
+ talloc_free(bytes);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ k5data->data = (char *) bytes; /* FIXME - the cast is ugly */
|
||||
+ k5data->length = nbytes;
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static errno_t set_krb5_data(struct sss_iobuf *iobuf,
|
||||
+ krb5_data *k5data)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = iobuf_write_uint32be(iobuf, k5data->length);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ if (k5data->length > 0) {
|
||||
+ ret = sss_iobuf_write_len(iobuf,
|
||||
+ (uint8_t *) k5data->data,
|
||||
+ k5data->length);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+/* FIXME - it would be nice if Kerberos exported these APIs.. */
|
||||
+krb5_error_code sss_krb5_unmarshal_princ(TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_iobuf *iobuf,
|
||||
+ krb5_principal *_princ)
|
||||
+{
|
||||
+ krb5_principal princ = NULL;
|
||||
+ krb5_error_code ret;
|
||||
+ uint32_t ncomps;
|
||||
+
|
||||
+ if (iobuf == NULL || _princ == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ princ = talloc_zero(mem_ctx, struct krb5_principal_data);
|
||||
+ if (princ == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ princ->magic = KV5M_PRINCIPAL;
|
||||
+
|
||||
+ ret = iobuf_read_uint32be(iobuf, (uint32_t *) &princ->type);
|
||||
+ if (ret != EOK) {
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ ret = iobuf_read_uint32be(iobuf, &ncomps);
|
||||
+ if (ret != EOK) {
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (ncomps > sss_iobuf_get_capacity(iobuf)) {
|
||||
+ /* Sanity check to avoid large allocations */
|
||||
+ ret = EINVAL;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (ncomps != 0) {
|
||||
+ princ->data = talloc_zero_array(princ, krb5_data, ncomps);
|
||||
+ if (princ->data == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ princ->length = ncomps;
|
||||
+ }
|
||||
+
|
||||
+ ret = get_krb5_data(princ, iobuf, &princ->realm);
|
||||
+ if (ret != EOK) {
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ for (size_t i = 0; i < ncomps; i++) {
|
||||
+ ret = get_krb5_data(princ->data, iobuf, &princ->data[i]);
|
||||
+ if (ret != EOK) {
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *_princ = princ;
|
||||
+ return 0;
|
||||
+
|
||||
+fail:
|
||||
+ talloc_free(princ);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+krb5_error_code sss_krb5_marshal_princ(krb5_principal princ,
|
||||
+ struct sss_iobuf *iobuf)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+
|
||||
+ if (iobuf == NULL || princ == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ ret = iobuf_write_uint32be(iobuf, princ->type);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = iobuf_write_uint32be(iobuf, princ->length);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = set_krb5_data(iobuf, &princ->realm);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < princ->length; i++) {
|
||||
+ ret = set_krb5_data(iobuf, &princ->data[i]);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+ return EOK;
|
||||
+}
|
||||
diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h
|
||||
index ac0f6082c75a8878f72346733e592b7575d44089..0d9043be98749b1a21a1b74c68f07298fa27f230 100644
|
||||
--- a/src/util/sss_krb5.h
|
||||
+++ b/src/util/sss_krb5.h
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <krb5.h>
|
||||
#endif
|
||||
|
||||
+#include "util/sss_iobuf.h"
|
||||
#include "util/util.h"
|
||||
|
||||
#define KRB5_CHILD_LOG_FILE "krb5_child"
|
||||
@@ -186,4 +187,12 @@ krb5_error_code sss_krb5_kt_have_content(krb5_context context,
|
||||
krb5_keytab keytab);
|
||||
|
||||
bool sss_krb5_realm_has_proxy(const char *realm);
|
||||
+
|
||||
+krb5_error_code sss_krb5_marshal_princ(krb5_principal princ,
|
||||
+ struct sss_iobuf *iobuf);
|
||||
+
|
||||
+krb5_error_code sss_krb5_unmarshal_princ(TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_iobuf *iobuf,
|
||||
+ krb5_principal *_princ);
|
||||
+
|
||||
#endif /* __SSS_KRB5_H__ */
|
||||
--
|
||||
2.12.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,578 +0,0 @@
|
||||
From 9dcdbf596e138df3eec202487549a67cd3b0091b Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Fri, 23 Sep 2016 14:00:10 +0200
|
||||
Subject: [PATCH 25/97] KCM: request parsing and sending a reply
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Implements parsing the KCM client request into per-client buffers and
|
||||
sending a response for both the failure case and for success.
|
||||
|
||||
The protocol is documented at:
|
||||
http://k5wiki.kerberos.org/wiki/Projects/KCM_client
|
||||
|
||||
Several places don't use the sss_iobuf structure, because they don't
|
||||
parse variable-length data from the buffer and it's much more efficient
|
||||
to just allocate the needed request and reply structure on the stack.
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/responder/kcm/kcmsrv_cmd.c | 467 ++++++++++++++++++++++++++++++++++++++++-
|
||||
src/responder/kcm/kcmsrv_pvt.h | 21 +-
|
||||
2 files changed, 474 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/src/responder/kcm/kcmsrv_cmd.c b/src/responder/kcm/kcmsrv_cmd.c
|
||||
index e9a03cbd41169c93e00b0630dc1e05e205881ec9..cbf70353730d8a4e03d8f75c97395f4ef007e77f 100644
|
||||
--- a/src/responder/kcm/kcmsrv_cmd.c
|
||||
+++ b/src/responder/kcm/kcmsrv_cmd.c
|
||||
@@ -19,14 +19,430 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
+#include <krb5/krb5.h>
|
||||
+
|
||||
#include "config.h"
|
||||
#include "util/util.h"
|
||||
+#include "util/sss_iobuf.h"
|
||||
#include "responder/common/responder.h"
|
||||
+#include "responder/kcm/kcmsrv_pvt.h"
|
||||
+#include "responder/kcm/kcm.h"
|
||||
|
||||
-struct kcm_proto_ctx {
|
||||
- void *unused;
|
||||
+/* The first four bytes of a message is always the size */
|
||||
+#define KCM_MSG_LEN_SIZE 4
|
||||
+
|
||||
+/* The return code is 32bits */
|
||||
+#define KCM_RETCODE_SIZE 4
|
||||
+
|
||||
+/* The maximum length of a request or reply as defined by the RPC
|
||||
+ * protocol. This is the same constant size as MIT KRB5 uses
|
||||
+ */
|
||||
+#define KCM_PACKET_MAX_SIZE 2048
|
||||
+
|
||||
+/* KCM operation, its raw input and raw output and result */
|
||||
+struct kcm_op_io {
|
||||
+ struct kcm_op *op;
|
||||
+ struct kcm_data request;
|
||||
+ struct sss_iobuf *reply;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * KCM IO-vector operations
|
||||
+ */
|
||||
+struct kcm_iovec {
|
||||
+ /* We don't use iovec b/c void pointers don't allow for
|
||||
+ * pointer arithmetics and it's convenient to keep track
|
||||
+ * of processed bytes
|
||||
+ */
|
||||
+ uint8_t *kiov_base;
|
||||
+ size_t kiov_len;
|
||||
+ size_t nprocessed;
|
||||
+};
|
||||
+
|
||||
+static errno_t kcm_iovec_op(int fd, struct kcm_iovec *kiov, bool do_read)
|
||||
+{
|
||||
+ ssize_t len;
|
||||
+ struct iovec iov[1];
|
||||
+
|
||||
+ iov[0].iov_base = kiov->kiov_base + kiov->nprocessed;
|
||||
+ iov[0].iov_len = kiov->kiov_len - kiov->nprocessed;
|
||||
+ if (iov[0].iov_len == 0) {
|
||||
+ /* This iovec is full (read) or depleted (write), proceed to the next one */
|
||||
+ return EOK;
|
||||
+ }
|
||||
+
|
||||
+ if (do_read) {
|
||||
+ len = readv(fd, iov, 1);
|
||||
+ } else {
|
||||
+ len = writev(fd, iov, 1);
|
||||
+ }
|
||||
+
|
||||
+ if (len == -1) {
|
||||
+ if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
|
||||
+ return EAGAIN;
|
||||
+ } else {
|
||||
+ return errno;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (len == 0) {
|
||||
+ /* Read event on fd that doesn't yield data? error */
|
||||
+ return ENODATA;
|
||||
+ }
|
||||
+
|
||||
+ /* Decrease the amount of available free space in the iovec */
|
||||
+ kiov->nprocessed += len;
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static errno_t kcm_read_iovec(int fd, struct kcm_iovec *kiov)
|
||||
+{
|
||||
+ return kcm_iovec_op(fd, kiov, true);
|
||||
+}
|
||||
+
|
||||
+static errno_t kcm_write_iovec(int fd, struct kcm_iovec *kiov)
|
||||
+{
|
||||
+ return kcm_iovec_op(fd, kiov, false);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Parsing KCM input
|
||||
+ *
|
||||
+ * The request is received as two IO vectors:
|
||||
+ *
|
||||
+ * first iovec:
|
||||
+ * length 32-bit big-endian integer
|
||||
+ *
|
||||
+ * second iovec:
|
||||
+ * major protocol number 8-bit big-endian integer
|
||||
+ * minor protocol number 8-bit big-endian integer
|
||||
+ * opcode 16-bit big-endian integer
|
||||
+ * message payload buffer
|
||||
+ */
|
||||
+struct kcm_reqbuf {
|
||||
+ uint8_t lenbuf[KCM_MSG_LEN_SIZE];
|
||||
+ struct kcm_iovec v_len;
|
||||
+
|
||||
+ /* Includes the major, minor versions etc */
|
||||
+ uint8_t msgbuf[KCM_PACKET_MAX_SIZE];
|
||||
+ struct kcm_iovec v_msg;
|
||||
+};
|
||||
+
|
||||
+static errno_t kcm_input_parse(struct kcm_reqbuf *reqbuf,
|
||||
+ struct kcm_op_io *op_io)
|
||||
+{
|
||||
+ size_t lc = 0;
|
||||
+ size_t mc = 0;
|
||||
+ uint16_t opcode = 0;
|
||||
+ uint16_t opcode_be = 0;
|
||||
+ uint32_t len_be = 0;
|
||||
+ uint32_t msglen;
|
||||
+ uint8_t proto_maj = 0;
|
||||
+ uint8_t proto_min = 0;
|
||||
+
|
||||
+ /* The first 4 bytes before the payload is message length */
|
||||
+ SAFEALIGN_COPY_UINT32_CHECK(&len_be,
|
||||
+ reqbuf->v_len.kiov_base,
|
||||
+ reqbuf->v_len.kiov_len,
|
||||
+ &lc);
|
||||
+ msglen = be32toh(len_be);
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS,
|
||||
+ "Received message with length %"PRIu32"\n", msglen);
|
||||
+
|
||||
+ if (msglen == 0) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Illegal zero-length message\n");
|
||||
+ return EBADMSG;
|
||||
+ }
|
||||
+
|
||||
+ if (msglen != reqbuf->v_msg.nprocessed) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Sender claims the message is %"PRIu32" bytes, "
|
||||
+ "but received %zu\n",
|
||||
+ msglen, reqbuf->v_msg.nprocessed);
|
||||
+ return EBADMSG;
|
||||
+ }
|
||||
+
|
||||
+ /* First 16 bits are 8 bit major and 8bit major protocol version */
|
||||
+ SAFEALIGN_COPY_UINT8_CHECK(&proto_maj,
|
||||
+ reqbuf->v_msg.kiov_base + mc,
|
||||
+ reqbuf->v_msg.kiov_len,
|
||||
+ &mc);
|
||||
+ SAFEALIGN_COPY_UINT8_CHECK(&proto_min,
|
||||
+ reqbuf->v_msg.kiov_base + mc,
|
||||
+ reqbuf->v_msg.kiov_len,
|
||||
+ &mc);
|
||||
+
|
||||
+ if (proto_maj != KCM_PROTOCOL_VERSION_MAJOR) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Expected major version %d, got %"PRIu16"\n",
|
||||
+ KCM_PROTOCOL_VERSION_MAJOR, (uint16_t) proto_maj);
|
||||
+ return ERR_KCM_MALFORMED_IN_PKT;
|
||||
+ }
|
||||
+
|
||||
+ if (proto_min != KCM_PROTOCOL_VERSION_MINOR) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Expected minor version %d, got %"PRIu16"\n",
|
||||
+ KCM_PROTOCOL_VERSION_MINOR, (uint16_t) proto_maj);
|
||||
+ return ERR_KCM_MALFORMED_IN_PKT;
|
||||
+ }
|
||||
+
|
||||
+ SAFEALIGN_COPY_UINT16_CHECK(&opcode_be,
|
||||
+ reqbuf->v_msg.kiov_base + mc,
|
||||
+ reqbuf->v_msg.kiov_len,
|
||||
+ &mc);
|
||||
+
|
||||
+ opcode = be16toh(opcode_be);
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "Received operation code %"PRIu16"\n", opcode);
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Constructing a reply for failure and success
|
||||
+ *
|
||||
+ * The reply consists of three IO vectors:
|
||||
+ * 1) length iovec:
|
||||
+ * length: 32-bit big-endian
|
||||
+ *
|
||||
+ * 2) return code iovec:
|
||||
+ * retcode: 32-bit big-endian. Non-zero on failure in the KCM server,
|
||||
+ * zero if the KCM operation ran (even if the operation itself
|
||||
+ * failed)
|
||||
+ *
|
||||
+ * 3) reply iovec
|
||||
+ * message: buffer, first 32-bits of the buffer is the return code of
|
||||
+ * the KCM operation, the rest depends on the operation itself.
|
||||
+ * The buffer's length is specified by the first integer in the
|
||||
+ * reply (very intuitive, right?)
|
||||
+ *
|
||||
+ * The client always reads the length and return code iovectors. However, the
|
||||
+ * client reads the reply iovec only if retcode is 0 in the return code iovector
|
||||
+ * (see kcmio_unix_socket_read() in the MIT tree)
|
||||
+ */
|
||||
+struct kcm_repbuf {
|
||||
+ uint8_t lenbuf[KCM_MSG_LEN_SIZE];
|
||||
+ struct kcm_iovec v_len;
|
||||
+
|
||||
+ uint8_t rcbuf[KCM_RETCODE_SIZE];
|
||||
+ struct kcm_iovec v_rc;
|
||||
+
|
||||
+ uint8_t msgbuf[KCM_PACKET_MAX_SIZE];
|
||||
+ struct kcm_iovec v_msg;
|
||||
+};
|
||||
+
|
||||
+static errno_t kcm_failbuf_construct(errno_t ret,
|
||||
+ struct kcm_repbuf *repbuf)
|
||||
+{
|
||||
+ size_t c;
|
||||
+
|
||||
+ c = 0;
|
||||
+ SAFEALIGN_SETMEM_UINT32(repbuf->lenbuf, 0, &c);
|
||||
+ c = 0;
|
||||
+ SAFEALIGN_SETMEM_UINT32(repbuf->rcbuf, htobe32(ret), &c);
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Construct a reply buffer and send it to the KCM client
|
||||
+ */
|
||||
+static void kcm_reply_error(struct cli_ctx *cctx,
|
||||
+ errno_t retcode,
|
||||
+ struct kcm_repbuf *repbuf)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ krb5_error_code kerr;
|
||||
+
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "KCM operation returs failure [%d]: %s\n",
|
||||
+ retcode, sss_strerror(retcode));
|
||||
+ kerr = sss2krb5_error(retcode);
|
||||
+
|
||||
+ ret = kcm_failbuf_construct(kerr, repbuf);
|
||||
+ if (ret != EOK) {
|
||||
+ /* If we can't construct the reply buffer, just terminate the client */
|
||||
+ talloc_free(cctx);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ TEVENT_FD_WRITEABLE(cctx->cfde);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Request-reply dispatcher
|
||||
+ */
|
||||
+struct kcm_req_ctx {
|
||||
+ /* client context owns per-client buffers including this one */
|
||||
+ struct cli_ctx *cctx;
|
||||
+
|
||||
+ /* raw IO buffers */
|
||||
+ struct kcm_reqbuf reqbuf;
|
||||
+ struct kcm_repbuf repbuf;
|
||||
+
|
||||
+ /* long-lived responder structures */
|
||||
+ struct kcm_ctx *kctx;
|
||||
+
|
||||
+ struct kcm_op_io op_io;
|
||||
};
|
||||
|
||||
+static errno_t kcm_recv_data(int fd, struct kcm_reqbuf *reqbuf)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = kcm_read_iovec(fd, &reqbuf->v_len);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = kcm_read_iovec(fd, &reqbuf->v_msg);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static struct kcm_req_ctx *kcm_new_req(TALLOC_CTX *mem_ctx,
|
||||
+ struct cli_ctx *cctx,
|
||||
+ struct kcm_ctx *kctx)
|
||||
+{
|
||||
+ struct kcm_req_ctx *req;
|
||||
+
|
||||
+ req = talloc_zero(cctx, struct kcm_req_ctx);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ req->reqbuf.v_len.kiov_base = req->reqbuf.lenbuf;
|
||||
+ req->reqbuf.v_len.kiov_len = KCM_MSG_LEN_SIZE;
|
||||
+
|
||||
+ req->reqbuf.v_msg.kiov_base = req->reqbuf.msgbuf;
|
||||
+ req->reqbuf.v_msg.kiov_len = KCM_PACKET_MAX_SIZE;
|
||||
+
|
||||
+ req->repbuf.v_len.kiov_base = req->repbuf.lenbuf;
|
||||
+ req->repbuf.v_len.kiov_len = KCM_MSG_LEN_SIZE;
|
||||
+
|
||||
+ req->repbuf.v_rc.kiov_base = req->repbuf.rcbuf;
|
||||
+ req->repbuf.v_rc.kiov_len = KCM_RETCODE_SIZE;
|
||||
+
|
||||
+ req->repbuf.v_msg.kiov_base = req->repbuf.msgbuf;
|
||||
+ /* Length of the msg iobuf will be adjusted later, so far use the full
|
||||
+ * length so that constructing the reply can use that capacity
|
||||
+ */
|
||||
+ req->repbuf.v_msg.kiov_len = KCM_PACKET_MAX_SIZE;
|
||||
+
|
||||
+ req->cctx = cctx;
|
||||
+ req->kctx = kctx;
|
||||
+
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static void kcm_recv(struct cli_ctx *cctx)
|
||||
+{
|
||||
+ struct kcm_req_ctx *req;
|
||||
+ struct kcm_ctx *kctx;
|
||||
+ int ret;
|
||||
+
|
||||
+ kctx = talloc_get_type(cctx->rctx->pvt_ctx, struct kcm_ctx);
|
||||
+ req = talloc_get_type(cctx->state_ctx, struct kcm_req_ctx);
|
||||
+ if (req == NULL) {
|
||||
+ /* A new request comes in, setup data structures */
|
||||
+ req = kcm_new_req(cctx, cctx, kctx);
|
||||
+ if (req == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Cannot set up client connection\n");
|
||||
+ talloc_free(cctx);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ cctx->state_ctx = req;
|
||||
+ }
|
||||
+
|
||||
+ ret = kcm_recv_data(cctx->cfd, &req->reqbuf);
|
||||
+ switch (ret) {
|
||||
+ case ENODATA:
|
||||
+ DEBUG(SSSDBG_TRACE_ALL, "Client closed connection.\n");
|
||||
+ talloc_free(cctx);
|
||||
+ return;
|
||||
+ case EAGAIN:
|
||||
+ DEBUG(SSSDBG_TRACE_ALL, "Retry later\n");
|
||||
+ return;
|
||||
+ case EOK:
|
||||
+ /* all fine */
|
||||
+ break;
|
||||
+ default:
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
+ "Failed to receive data (%d, %s), aborting client\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ talloc_free(cctx);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ret = kcm_input_parse(&req->reqbuf, &req->op_io);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
+ "Failed to parse data (%d, %s), aborting client\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ /* do not read anymore, client is done sending */
|
||||
+ TEVENT_FD_NOT_READABLE(cctx->cfde);
|
||||
+
|
||||
+ kcm_reply_error(cctx, ret, &req->repbuf);
|
||||
+ return;
|
||||
+
|
||||
+fail:
|
||||
+ /* Fail with reply */
|
||||
+ kcm_reply_error(cctx, ret, &req->repbuf);
|
||||
+}
|
||||
+
|
||||
+static int kcm_send_data(struct cli_ctx *cctx)
|
||||
+{
|
||||
+ struct kcm_req_ctx *req;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = talloc_get_type(cctx->state_ctx, struct kcm_req_ctx);
|
||||
+
|
||||
+ ret = kcm_write_iovec(cctx->cfd, &req->repbuf.v_len);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = kcm_write_iovec(cctx->cfd, &req->repbuf.v_rc);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = kcm_write_iovec(cctx->cfd, &req->repbuf.v_msg);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static void kcm_send(struct cli_ctx *cctx)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = kcm_send_data(cctx);
|
||||
+ if (ret == EAGAIN) {
|
||||
+ /* not all data was sent, loop again */
|
||||
+ return;
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "Failed to send data, aborting client!\n");
|
||||
+ talloc_free(cctx);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* ok all sent */
|
||||
+ TEVENT_FD_NOT_WRITEABLE(cctx->cfde);
|
||||
+ TEVENT_FD_READABLE(cctx->cfde);
|
||||
+ talloc_zfree(cctx->state_ctx);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
static void kcm_fd_handler(struct tevent_context *ev,
|
||||
struct tevent_fd *fde,
|
||||
uint16_t flags, void *ptr)
|
||||
@@ -39,25 +455,54 @@ static void kcm_fd_handler(struct tevent_context *ev,
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
"Could not create idle timer for client. "
|
||||
- "This connection may not auto-terminate\n");
|
||||
+ "This connection may not auto-terminate\n");
|
||||
/* Non-fatal, continue */
|
||||
}
|
||||
+
|
||||
+ if (flags & TEVENT_FD_READ) {
|
||||
+ kcm_recv(cctx);
|
||||
+ return;
|
||||
+ }
|
||||
+ if (flags & TEVENT_FD_WRITE) {
|
||||
+ kcm_send(cctx);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
|
||||
int kcm_connection_setup(struct cli_ctx *cctx)
|
||||
{
|
||||
- struct kcm_proto_ctx *protocol_ctx;
|
||||
-
|
||||
- protocol_ctx = talloc_zero(cctx, struct kcm_proto_ctx);
|
||||
- if (protocol_ctx == NULL) {
|
||||
- return ENOMEM;
|
||||
- }
|
||||
-
|
||||
- cctx->protocol_ctx = protocol_ctx;
|
||||
cctx->cfd_handler = kcm_fd_handler;
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+krb5_error_code sss2krb5_error(errno_t err)
|
||||
+{
|
||||
+ switch (err) {
|
||||
+ case EOK:
|
||||
+ return 0;
|
||||
+ case ENOMEM:
|
||||
+ return KRB5_CC_NOMEM;
|
||||
+ case EACCES:
|
||||
+ return KRB5_FCC_PERM;
|
||||
+ case ERR_KCM_OP_NOT_IMPLEMENTED:
|
||||
+ return KRB5_CC_NOSUPP;
|
||||
+ case ERR_WRONG_NAME_FORMAT:
|
||||
+ return KRB5_CC_BADNAME;
|
||||
+ case ERR_NO_MATCHING_CREDS:
|
||||
+ return KRB5_FCC_NOFILE;
|
||||
+ case ERR_NO_CREDS:
|
||||
+ return KRB5_CC_NOTFOUND;
|
||||
+ case ERR_KCM_CC_END:
|
||||
+ return KRB5_CC_END;
|
||||
+ case ERR_KCM_MALFORMED_IN_PKT:
|
||||
+ case EINVAL:
|
||||
+ case EIO:
|
||||
+ return KRB5_CC_IO;
|
||||
+ }
|
||||
+
|
||||
+ return KRB5_FCC_INTERNAL;
|
||||
+}
|
||||
+
|
||||
/* Dummy, not used here but required to link to other responder files */
|
||||
struct cli_protocol_version *register_cli_protocol_version(void)
|
||||
{
|
||||
diff --git a/src/responder/kcm/kcmsrv_pvt.h b/src/responder/kcm/kcmsrv_pvt.h
|
||||
index a7c9d062c17f09986d894064176c3a461d396ac0..fd1fd9fa32d59a323d465def68999f24f84e3923 100644
|
||||
--- a/src/responder/kcm/kcmsrv_pvt.h
|
||||
+++ b/src/responder/kcm/kcmsrv_pvt.h
|
||||
@@ -27,13 +27,20 @@
|
||||
#include <sys/types.h>
|
||||
#include "responder/common/responder.h"
|
||||
|
||||
-/* KCM IO structure */
|
||||
+/*
|
||||
+ * KCM IO structure
|
||||
+ *
|
||||
+ * In theory we cold use sss_iobuf there, but since iobuf was
|
||||
+ * made opaque, this allows it to allocate the structures on
|
||||
+ * the stack in one go.
|
||||
+ * */
|
||||
struct kcm_data {
|
||||
uint8_t *data;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
-/* To avoid leaking the sssd-specific responder data to other
|
||||
+/*
|
||||
+ * To avoid leaking the sssd-specific responder data to other
|
||||
* modules, the ccache databases and other KCM specific data
|
||||
* are kept separately
|
||||
*/
|
||||
@@ -41,7 +48,8 @@ struct kcm_resp_ctx {
|
||||
krb5_context k5c;
|
||||
};
|
||||
|
||||
-/* responder context that contains both the responder data,
|
||||
+/*
|
||||
+ * responder context that contains both the responder data,
|
||||
* like the ccaches and the sssd-specific stuff like the
|
||||
* generic responder ctx
|
||||
*/
|
||||
@@ -55,4 +63,11 @@ struct kcm_ctx {
|
||||
|
||||
int kcm_connection_setup(struct cli_ctx *cctx);
|
||||
|
||||
+/*
|
||||
+ * Internally in SSSD-KCM we use SSSD-internal error codes so that we
|
||||
+ * can always the same sss_strerror() functions to format the errors
|
||||
+ * nicely, but the client expects libkrb5 error codes.
|
||||
+ */
|
||||
+krb5_error_code sss2krb5_error(errno_t err);
|
||||
+
|
||||
#endif /* __KCMSRV_PVT_H__ */
|
||||
--
|
||||
2.12.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,907 +0,0 @@
|
||||
From 70fe6e2bb398b8669ad1aebeaf0abcbffc307475 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 7 Mar 2017 13:49:43 +0100
|
||||
Subject: [PATCH 27/97] KCM: Add a in-memory credential storage
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Implements a simple back end for the ccache module that lets the KCM
|
||||
server store credentials directly in memory.
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
Makefile.am | 1 +
|
||||
src/responder/kcm/kcm.c | 13 +-
|
||||
src/responder/kcm/kcmsrv_ccache.c | 2 +-
|
||||
src/responder/kcm/kcmsrv_ccache_mem.c | 805 ++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 817 insertions(+), 4 deletions(-)
|
||||
create mode 100644 src/responder/kcm/kcmsrv_ccache_mem.c
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index a2b9dc49e95fa2d025f5174d2902866fab180a78..5605c1a53c44fd9e83394e80b7f71828df1d39b6 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -1492,6 +1492,7 @@ sssd_kcm_SOURCES = \
|
||||
src/responder/kcm/kcm.c \
|
||||
src/responder/kcm/kcmsrv_cmd.c \
|
||||
src/responder/kcm/kcmsrv_ccache.c \
|
||||
+ src/responder/kcm/kcmsrv_ccache_mem.c \
|
||||
src/util/sss_sockets.c \
|
||||
src/util/sss_krb5.c \
|
||||
src/util/sss_iobuf.c \
|
||||
diff --git a/src/responder/kcm/kcm.c b/src/responder/kcm/kcm.c
|
||||
index 90a6999c5e39d48a1a2ea8168d171612a65077d5..2c12ef215ce3967df183e51c20590c5f439d278f 100644
|
||||
--- a/src/responder/kcm/kcm.c
|
||||
+++ b/src/responder/kcm/kcm.c
|
||||
@@ -22,9 +22,9 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <popt.h>
|
||||
-#include <krb5/krb5.h>
|
||||
|
||||
#include "responder/kcm/kcm.h"
|
||||
+#include "responder/kcm/kcmsrv_ccache.h"
|
||||
#include "responder/kcm/kcmsrv_pvt.h"
|
||||
#include "responder/common/responder.h"
|
||||
#include "util/util.h"
|
||||
@@ -110,7 +110,8 @@ static int kcm_data_destructor(void *ptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct kcm_resp_ctx *kcm_data_setup(TALLOC_CTX *mem_ctx)
|
||||
+static struct kcm_resp_ctx *kcm_data_setup(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev)
|
||||
{
|
||||
struct kcm_resp_ctx *kcm_data;
|
||||
krb5_error_code kret;
|
||||
@@ -121,6 +122,12 @@ static struct kcm_resp_ctx *kcm_data_setup(TALLOC_CTX *mem_ctx)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ kcm_data->db = kcm_ccdb_init(kcm_data, ev, CCDB_BE_MEMORY);
|
||||
+ if (kcm_data->db == NULL) {
|
||||
+ talloc_free(kcm_data);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
kret = krb5_init_context(&kcm_data->k5c);
|
||||
if (kret != EOK) {
|
||||
talloc_free(kcm_data);
|
||||
@@ -169,7 +176,7 @@ static int kcm_process_init(TALLOC_CTX *mem_ctx,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- kctx->kcm_data = kcm_data_setup(kctx);
|
||||
+ kctx->kcm_data = kcm_data_setup(kctx, ev);
|
||||
if (kctx->kcm_data == NULL) {
|
||||
DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
"fatal error initializing responder data\n");
|
||||
diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
|
||||
index 2c565b8378e3ec297faf655d3c48d7ab902713d3..2ae120269b0c62275ba2acdff6d6daa8b7077708 100644
|
||||
--- a/src/responder/kcm/kcmsrv_ccache.c
|
||||
+++ b/src/responder/kcm/kcmsrv_ccache.c
|
||||
@@ -240,7 +240,7 @@ struct kcm_ccdb *kcm_ccdb_init(TALLOC_CTX *mem_ctx,
|
||||
switch (cc_be) {
|
||||
case CCDB_BE_MEMORY:
|
||||
DEBUG(SSSDBG_FUNC_DATA, "KCM back end: memory\n");
|
||||
- /* Not implemented yet */
|
||||
+ ccdb->ops = &ccdb_mem_ops;
|
||||
break;
|
||||
case CCDB_BE_SECRETS:
|
||||
DEBUG(SSSDBG_FUNC_DATA, "KCM back end: sssd-secrets\n");
|
||||
diff --git a/src/responder/kcm/kcmsrv_ccache_mem.c b/src/responder/kcm/kcmsrv_ccache_mem.c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1c4f3df8d3b35b0428a143d4b545562d9cc0e574
|
||||
--- /dev/null
|
||||
+++ b/src/responder/kcm/kcmsrv_ccache_mem.c
|
||||
@@ -0,0 +1,805 @@
|
||||
+/*
|
||||
+ SSSD
|
||||
+
|
||||
+ KCM Server - ccache in-memory storage
|
||||
+
|
||||
+ Copyright (C) Red Hat, 2016
|
||||
+
|
||||
+ 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 "config.h"
|
||||
+
|
||||
+#include <talloc.h>
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#include "util/util.h"
|
||||
+#include "responder/kcm/kcmsrv_ccache_pvt.h"
|
||||
+#include "responder/kcm/kcmsrv_ccache_be.h"
|
||||
+
|
||||
+struct ccdb_mem;
|
||||
+
|
||||
+/*
|
||||
+ * The KCM memory database is just a double-linked list of kcm_ccache structures
|
||||
+ */
|
||||
+struct ccache_mem_wrap {
|
||||
+ struct kcm_ccache *cc;
|
||||
+ bool is_default;
|
||||
+
|
||||
+ struct ccache_mem_wrap *next;
|
||||
+ struct ccache_mem_wrap *prev;
|
||||
+
|
||||
+ struct ccdb_mem *mem_be;
|
||||
+};
|
||||
+
|
||||
+struct ccdb_mem {
|
||||
+ /* Both ccaches and the next-id are kept in memory */
|
||||
+ struct ccache_mem_wrap *head;
|
||||
+ unsigned int nextid;
|
||||
+};
|
||||
+
|
||||
+/* In order to provide a consistent interface, we need to let the caller
|
||||
+ * of getbyXXX own the ccache, therefore the memory back end returns a shallow
|
||||
+ * copy of the ccache
|
||||
+ */
|
||||
+static struct kcm_ccache *kcm_ccache_dup(TALLOC_CTX *mem_ctx,
|
||||
+ struct kcm_ccache *in)
|
||||
+{
|
||||
+ struct kcm_ccache *out;
|
||||
+
|
||||
+ out = talloc_zero(mem_ctx, struct kcm_ccache);
|
||||
+ if (out == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ memcpy(out, in, sizeof(struct kcm_ccache));
|
||||
+
|
||||
+ return out;
|
||||
+}
|
||||
+
|
||||
+static struct ccache_mem_wrap *memdb_get_by_uuid(struct ccdb_mem *memdb,
|
||||
+ struct cli_creds *client,
|
||||
+ uuid_t uuid)
|
||||
+{
|
||||
+ uid_t uid;
|
||||
+ struct ccache_mem_wrap *ccwrap = NULL;
|
||||
+ struct ccache_mem_wrap *out = NULL;
|
||||
+
|
||||
+ uid = cli_creds_get_uid(client);
|
||||
+
|
||||
+ DLIST_FOR_EACH(ccwrap, memdb->head) {
|
||||
+ if (ccwrap->cc == NULL) {
|
||||
+ /* since KCM stores ccaches, better not crash.. */
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "BUG: ccwrap contains NULL cc\n");
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (ccwrap->cc->owner.uid == uid) {
|
||||
+ if (uuid_compare(uuid, ccwrap->cc->uuid) == 0) {
|
||||
+ out = ccwrap;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return out;
|
||||
+}
|
||||
+
|
||||
+static struct ccache_mem_wrap *memdb_get_by_name(struct ccdb_mem *memdb,
|
||||
+ struct cli_creds *client,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ uid_t uid;
|
||||
+ struct ccache_mem_wrap *ccwrap = NULL;
|
||||
+ struct ccache_mem_wrap *out = NULL;
|
||||
+
|
||||
+ uid = cli_creds_get_uid(client);
|
||||
+
|
||||
+ DLIST_FOR_EACH(ccwrap, memdb->head) {
|
||||
+ if (ccwrap->cc == NULL) {
|
||||
+ /* since KCM stores ccaches, better not crash.. */
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "BUG: ccwrap contains NULL cc\n");
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (ccwrap->cc->owner.uid == uid) {
|
||||
+ if (strcmp(ccwrap->cc->name, name) == 0) {
|
||||
+ out = ccwrap;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return out;
|
||||
+}
|
||||
+
|
||||
+/* Since with the in-memory database, the database operations are just
|
||||
+ * fake-async wrappers around otherwise sync operations, we don't often
|
||||
+ * need any state, so we use this empty structure instead
|
||||
+ */
|
||||
+struct ccdb_mem_dummy_state {
|
||||
+};
|
||||
+
|
||||
+static int ccwrap_destructor(void *ptr)
|
||||
+{
|
||||
+ struct ccache_mem_wrap *ccwrap = talloc_get_type(ptr, struct ccache_mem_wrap);
|
||||
+
|
||||
+ if (ccwrap == NULL) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (ccwrap->cc != NULL) {
|
||||
+ if (ccwrap->cc->creds) {
|
||||
+ safezero(sss_iobuf_get_data(ccwrap->cc->creds->cred_blob),
|
||||
+ sss_iobuf_get_size(ccwrap->cc->creds->cred_blob));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ DLIST_REMOVE(ccwrap->mem_be->head, ccwrap);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static errno_t ccdb_mem_init(struct kcm_ccdb *db)
|
||||
+{
|
||||
+ struct ccdb_mem *memdb = NULL;
|
||||
+
|
||||
+ memdb = talloc_zero(db, struct ccdb_mem);
|
||||
+ if (memdb == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+ db->db_handle = memdb;
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+struct ccdb_mem_nextid_state {
|
||||
+ unsigned int nextid;
|
||||
+};
|
||||
+
|
||||
+static struct tevent_req *ccdb_mem_nextid_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ccdb *db,
|
||||
+ struct cli_creds *client)
|
||||
+{
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct ccdb_mem_nextid_state *state = NULL;
|
||||
+ struct ccdb_mem *memdb = NULL;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct ccdb_mem_nextid_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ memdb = talloc_get_type(db->db_handle, struct ccdb_mem);
|
||||
+ if (memdb == NULL) {
|
||||
+ ret = EIO;
|
||||
+ goto immediate;
|
||||
+ }
|
||||
+
|
||||
+ state->nextid = memdb->nextid++;
|
||||
+
|
||||
+ ret = EOK;
|
||||
+immediate:
|
||||
+ if (ret == EOK) {
|
||||
+ tevent_req_done(req);
|
||||
+ } else {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ }
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static errno_t ccdb_mem_nextid_recv(struct tevent_req *req,
|
||||
+ unsigned int *_nextid)
|
||||
+{
|
||||
+ struct ccdb_mem_nextid_state *state = tevent_req_data(req,
|
||||
+ struct ccdb_mem_nextid_state);
|
||||
+
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ *_nextid = state->nextid;
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+struct ccdb_mem_list_state {
|
||||
+ uuid_t *uuid_list;
|
||||
+};
|
||||
+
|
||||
+static struct tevent_req *ccdb_mem_list_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ccdb *db,
|
||||
+ struct cli_creds *client)
|
||||
+{
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct ccache_mem_wrap *ccwrap = NULL;
|
||||
+ struct ccdb_mem_list_state *state = NULL;
|
||||
+ struct ccdb_mem *memdb = talloc_get_type(db->db_handle, struct ccdb_mem);
|
||||
+ size_t num_ccaches = 0;
|
||||
+ size_t cc_index = 0;
|
||||
+ errno_t ret;
|
||||
+ uid_t uid;
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct ccdb_mem_list_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ uid = cli_creds_get_uid(client);
|
||||
+
|
||||
+ DLIST_FOR_EACH(ccwrap, memdb->head) {
|
||||
+ if (ccwrap->cc->owner.uid == uid) {
|
||||
+ num_ccaches++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ state->uuid_list = talloc_zero_array(state, uuid_t, num_ccaches+1);
|
||||
+ if (state->uuid_list == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto immediate;
|
||||
+ }
|
||||
+
|
||||
+ cc_index = 0;
|
||||
+ DLIST_FOR_EACH(ccwrap, memdb->head) {
|
||||
+ if (ccwrap->cc->owner.uid == uid) {
|
||||
+ uuid_copy(state->uuid_list[cc_index], ccwrap->cc->uuid);
|
||||
+ cc_index++;
|
||||
+ }
|
||||
+ }
|
||||
+ uuid_clear(state->uuid_list[num_ccaches]);
|
||||
+
|
||||
+ ret = EOK;
|
||||
+immediate:
|
||||
+ if (ret == EOK) {
|
||||
+ tevent_req_done(req);
|
||||
+ } else {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ }
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static errno_t ccdb_mem_list_recv(struct tevent_req *req,
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ uuid_t **_uuid_list)
|
||||
+{
|
||||
+ struct ccdb_mem_list_state *state = tevent_req_data(req,
|
||||
+ struct ccdb_mem_list_state);
|
||||
+
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ *_uuid_list = talloc_steal(mem_ctx, state->uuid_list);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static struct tevent_req *ccdb_mem_set_default_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ccdb *db,
|
||||
+ struct cli_creds *client,
|
||||
+ uuid_t uuid)
|
||||
+{
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct ccdb_mem_dummy_state *state = NULL;
|
||||
+ struct ccdb_mem *memdb = talloc_get_type(db->db_handle, struct ccdb_mem);
|
||||
+ struct ccache_mem_wrap *ccwrap = NULL;
|
||||
+ uid_t uid = cli_creds_get_uid(client);
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct ccdb_mem_dummy_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* Reset all ccache defaults first */
|
||||
+ DLIST_FOR_EACH(ccwrap, memdb->head) {
|
||||
+ if (ccwrap->cc == NULL) {
|
||||
+ /* since KCM stores ccaches, better not crash.. */
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "BUG: ccwrap contains NULL cc\n");
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (ccwrap->cc->owner.uid == uid) {
|
||||
+ ccwrap->is_default = false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Then set the default for the right ccache. This also allows to
|
||||
+ * pass a null uuid to just reset the old ccache (for example after
|
||||
+ * deleting the default
|
||||
+ */
|
||||
+ ccwrap = memdb_get_by_uuid(memdb, client, uuid);
|
||||
+ if (ccwrap != NULL) {
|
||||
+ ccwrap->is_default = true;
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_done(req);
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static errno_t ccdb_mem_set_default_recv(struct tevent_req *req)
|
||||
+{
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+struct ccdb_mem_get_default_state {
|
||||
+ uuid_t dfl_uuid;
|
||||
+};
|
||||
+
|
||||
+static struct tevent_req *ccdb_mem_get_default_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ccdb *db,
|
||||
+ struct cli_creds *client)
|
||||
+{
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct ccdb_mem_get_default_state *state = NULL;
|
||||
+ struct ccache_mem_wrap *ccwrap = NULL;
|
||||
+ struct ccdb_mem *memdb = talloc_get_type(db->db_handle, struct ccdb_mem);
|
||||
+ uid_t uid = cli_creds_get_uid(client);
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct ccdb_mem_get_default_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ /* Reset all ccache defaults first */
|
||||
+ DLIST_FOR_EACH(ccwrap, memdb->head) {
|
||||
+ if (ccwrap->cc == NULL) {
|
||||
+ /* since KCM stores ccaches, better not crash.. */
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "BUG: ccwrap contains NULL cc\n");
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (ccwrap->cc->owner.uid == uid && ccwrap->is_default == true) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (ccwrap == NULL) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ "No ccache marked as default, returning null ccache\n");
|
||||
+ uuid_clear(state->dfl_uuid);
|
||||
+ } else {
|
||||
+ uuid_copy(state->dfl_uuid, ccwrap->cc->uuid);
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_done(req);
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static errno_t ccdb_mem_get_default_recv(struct tevent_req *req,
|
||||
+ uuid_t dfl)
|
||||
+{
|
||||
+ struct ccdb_mem_get_default_state *state = tevent_req_data(req,
|
||||
+ struct ccdb_mem_get_default_state);
|
||||
+
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+
|
||||
+ uuid_copy(dfl, state->dfl_uuid);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+struct ccdb_mem_getbyuuid_state {
|
||||
+ struct kcm_ccache *cc;
|
||||
+};
|
||||
+
|
||||
+static struct tevent_req *ccdb_mem_getbyuuid_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ccdb *db,
|
||||
+ struct cli_creds *client,
|
||||
+ uuid_t uuid)
|
||||
+{
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct ccdb_mem_getbyuuid_state *state = NULL;
|
||||
+ struct ccdb_mem *memdb = talloc_get_type(db->db_handle, struct ccdb_mem);
|
||||
+ struct ccache_mem_wrap *ccwrap = NULL;
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct ccdb_mem_getbyuuid_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ccwrap = memdb_get_by_uuid(memdb, client, uuid);
|
||||
+ if (ccwrap != NULL) {
|
||||
+ state->cc = kcm_ccache_dup(state, ccwrap->cc);
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_done(req);
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static errno_t ccdb_mem_getbyuuid_recv(struct tevent_req *req,
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ struct kcm_ccache **_cc)
|
||||
+{
|
||||
+ struct ccdb_mem_getbyuuid_state *state = tevent_req_data(req,
|
||||
+ struct ccdb_mem_getbyuuid_state);
|
||||
+
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ *_cc = talloc_steal(mem_ctx, state->cc);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+struct ccdb_mem_getbyname_state {
|
||||
+ struct kcm_ccache *cc;
|
||||
+};
|
||||
+
|
||||
+static struct tevent_req *ccdb_mem_getbyname_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ccdb *db,
|
||||
+ struct cli_creds *client,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct ccdb_mem_getbyname_state *state = NULL;
|
||||
+ struct ccache_mem_wrap *ccwrap = NULL;
|
||||
+ struct ccdb_mem *memdb = talloc_get_type(db->db_handle, struct ccdb_mem);
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct ccdb_mem_getbyname_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ccwrap = memdb_get_by_name(memdb, client, name);
|
||||
+ if (ccwrap != NULL) {
|
||||
+ state->cc = kcm_ccache_dup(state, ccwrap->cc);
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_done(req);
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static errno_t ccdb_mem_getbyname_recv(struct tevent_req *req,
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ struct kcm_ccache **_cc)
|
||||
+{
|
||||
+ struct ccdb_mem_getbyname_state *state = tevent_req_data(req,
|
||||
+ struct ccdb_mem_getbyname_state);
|
||||
+
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ *_cc = talloc_steal(mem_ctx, state->cc);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+struct ccdb_mem_name_by_uuid_state {
|
||||
+ const char *name;
|
||||
+};
|
||||
+
|
||||
+struct tevent_req *ccdb_mem_name_by_uuid_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ccdb *db,
|
||||
+ struct cli_creds *client,
|
||||
+ uuid_t uuid)
|
||||
+{
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct ccdb_mem_name_by_uuid_state *state = NULL;
|
||||
+ struct ccdb_mem *memdb = talloc_get_type(db->db_handle, struct ccdb_mem);
|
||||
+ struct ccache_mem_wrap *ccwrap = NULL;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct ccdb_mem_name_by_uuid_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ccwrap = memdb_get_by_uuid(memdb, client, uuid);
|
||||
+ if (ccwrap == NULL) {
|
||||
+ ret = ERR_KCM_CC_END;
|
||||
+ goto immediate;
|
||||
+ }
|
||||
+
|
||||
+ state->name = talloc_strdup(state, ccwrap->cc->name);
|
||||
+ if (state->name == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto immediate;
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+immediate:
|
||||
+ if (ret == EOK) {
|
||||
+ tevent_req_done(req);
|
||||
+ } else {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ }
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+errno_t ccdb_mem_name_by_uuid_recv(struct tevent_req *req,
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ const char **_name)
|
||||
+{
|
||||
+ struct ccdb_mem_name_by_uuid_state *state = tevent_req_data(req,
|
||||
+ struct ccdb_mem_name_by_uuid_state);
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ *_name = talloc_steal(mem_ctx, state->name);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+struct ccdb_mem_uuid_by_name_state {
|
||||
+ uuid_t uuid;
|
||||
+};
|
||||
+
|
||||
+struct tevent_req *ccdb_mem_uuid_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ccdb *db,
|
||||
+ struct cli_creds *client,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct ccdb_mem_uuid_by_name_state *state = NULL;
|
||||
+ struct ccdb_mem *memdb = talloc_get_type(db->db_handle, struct ccdb_mem);
|
||||
+ struct ccache_mem_wrap *ccwrap = NULL;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct ccdb_mem_uuid_by_name_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ccwrap = memdb_get_by_name(memdb, client, name);
|
||||
+ if (ccwrap == NULL) {
|
||||
+ ret = ERR_KCM_CC_END;
|
||||
+ goto immediate;
|
||||
+ }
|
||||
+
|
||||
+ uuid_copy(state->uuid, ccwrap->cc->uuid);
|
||||
+
|
||||
+ ret = EOK;
|
||||
+immediate:
|
||||
+ if (ret == EOK) {
|
||||
+ tevent_req_done(req);
|
||||
+ } else {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ }
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+errno_t ccdb_mem_uuid_by_name_recv(struct tevent_req *req,
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ uuid_t _uuid)
|
||||
+{
|
||||
+ struct ccdb_mem_uuid_by_name_state *state = tevent_req_data(req,
|
||||
+ struct ccdb_mem_uuid_by_name_state);
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ uuid_copy(_uuid, state->uuid);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static struct tevent_req *ccdb_mem_create_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ccdb *db,
|
||||
+ struct cli_creds *client,
|
||||
+ struct kcm_ccache *cc)
|
||||
+{
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct ccdb_mem_dummy_state *state = NULL;
|
||||
+ struct ccache_mem_wrap *ccwrap;
|
||||
+ struct ccdb_mem *memdb = talloc_get_type(db->db_handle, struct ccdb_mem);
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct ccdb_mem_dummy_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ccwrap = talloc_zero(memdb, struct ccache_mem_wrap);
|
||||
+ if (ccwrap == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto immediate;
|
||||
+ }
|
||||
+ ccwrap->cc = cc;
|
||||
+ ccwrap->mem_be = memdb;
|
||||
+ talloc_steal(ccwrap, cc);
|
||||
+
|
||||
+ DLIST_ADD(memdb->head, ccwrap);
|
||||
+ talloc_set_destructor((TALLOC_CTX *) ccwrap, ccwrap_destructor);
|
||||
+
|
||||
+ ret = EOK;
|
||||
+immediate:
|
||||
+ if (ret == EOK) {
|
||||
+ tevent_req_done(req);
|
||||
+ } else {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ }
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static errno_t ccdb_mem_create_recv(struct tevent_req *req)
|
||||
+{
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static struct tevent_req *ccdb_mem_mod_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ccdb *db,
|
||||
+ struct cli_creds *client,
|
||||
+ uuid_t uuid,
|
||||
+ struct kcm_mod_ctx *mod_cc)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct ccdb_mem_dummy_state *state = NULL;
|
||||
+ struct ccache_mem_wrap *ccwrap = NULL;
|
||||
+ struct ccdb_mem *memdb = talloc_get_type(db->db_handle, struct ccdb_mem);
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct ccdb_mem_dummy_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* UUID is immutable, so search by that */
|
||||
+ ccwrap = memdb_get_by_uuid(memdb, client, uuid);
|
||||
+ if (ccwrap == NULL) {
|
||||
+ ret = ERR_KCM_CC_END;
|
||||
+ goto immediate;
|
||||
+ }
|
||||
+
|
||||
+ kcm_mod_cc(ccwrap->cc, mod_cc);
|
||||
+
|
||||
+ ret = EOK;
|
||||
+immediate:
|
||||
+ if (ret == EOK) {
|
||||
+ tevent_req_done(req);
|
||||
+ } else {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ }
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static errno_t ccdb_mem_mod_recv(struct tevent_req *req)
|
||||
+{
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static struct tevent_req *ccdb_mem_store_cred_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ccdb *db,
|
||||
+ struct cli_creds *client,
|
||||
+ uuid_t uuid,
|
||||
+ struct sss_iobuf *cred_blob)
|
||||
+{
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct ccdb_mem_dummy_state *state = NULL;
|
||||
+ struct ccdb_mem *memdb = talloc_get_type(db->db_handle, struct ccdb_mem);
|
||||
+ struct ccache_mem_wrap *ccwrap = NULL;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct ccdb_mem_dummy_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ccwrap = memdb_get_by_uuid(memdb, client, uuid);
|
||||
+ if (ccwrap == NULL) {
|
||||
+ ret = ERR_KCM_CC_END;
|
||||
+ goto immediate;
|
||||
+ }
|
||||
+
|
||||
+ ret = kcm_cc_store_cred_blob(ccwrap->cc, cred_blob);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Cannot store credentials to ccache [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto immediate;
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+immediate:
|
||||
+ if (ret == EOK) {
|
||||
+ tevent_req_done(req);
|
||||
+ } else {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ }
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static errno_t ccdb_mem_store_cred_recv(struct tevent_req *req)
|
||||
+{
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static struct tevent_req *ccdb_mem_delete_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ccdb *db,
|
||||
+ struct cli_creds *client,
|
||||
+ uuid_t uuid)
|
||||
+{
|
||||
+ struct tevent_req *req = NULL;
|
||||
+ struct ccdb_mem_dummy_state *state = NULL;
|
||||
+ struct ccache_mem_wrap *ccwrap;
|
||||
+ struct ccdb_mem *memdb = talloc_get_type(db->db_handle, struct ccdb_mem);
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct ccdb_mem_dummy_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ccwrap = memdb_get_by_uuid(memdb, client, uuid);
|
||||
+ if (ccwrap == NULL) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "BUG: Attempting to free unknown ccache\n");
|
||||
+ ret = ERR_KCM_CC_END;
|
||||
+ goto immediate;
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+ /* Destructor takes care of everything */
|
||||
+ talloc_free(ccwrap);
|
||||
+immediate:
|
||||
+ if (ret == EOK) {
|
||||
+ tevent_req_done(req);
|
||||
+ } else {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ }
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static errno_t ccdb_mem_delete_recv(struct tevent_req *req)
|
||||
+{
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+const struct kcm_ccdb_ops ccdb_mem_ops = {
|
||||
+ .init = ccdb_mem_init,
|
||||
+
|
||||
+ .nextid_send = ccdb_mem_nextid_send,
|
||||
+ .nextid_recv = ccdb_mem_nextid_recv,
|
||||
+
|
||||
+ .set_default_send = ccdb_mem_set_default_send,
|
||||
+ .set_default_recv = ccdb_mem_set_default_recv,
|
||||
+
|
||||
+ .get_default_send = ccdb_mem_get_default_send,
|
||||
+ .get_default_recv = ccdb_mem_get_default_recv,
|
||||
+
|
||||
+ .list_send = ccdb_mem_list_send,
|
||||
+ .list_recv = ccdb_mem_list_recv,
|
||||
+
|
||||
+ .getbyname_send = ccdb_mem_getbyname_send,
|
||||
+ .getbyname_recv = ccdb_mem_getbyname_recv,
|
||||
+
|
||||
+ .getbyuuid_send = ccdb_mem_getbyuuid_send,
|
||||
+ .getbyuuid_recv = ccdb_mem_getbyuuid_recv,
|
||||
+
|
||||
+ .name_by_uuid_send = ccdb_mem_name_by_uuid_send,
|
||||
+ .name_by_uuid_recv = ccdb_mem_name_by_uuid_recv,
|
||||
+
|
||||
+ .uuid_by_name_send = ccdb_mem_uuid_by_name_send,
|
||||
+ .uuid_by_name_recv = ccdb_mem_uuid_by_name_recv,
|
||||
+
|
||||
+ .create_send = ccdb_mem_create_send,
|
||||
+ .create_recv = ccdb_mem_create_recv,
|
||||
+
|
||||
+ .mod_send = ccdb_mem_mod_send,
|
||||
+ .mod_recv = ccdb_mem_mod_recv,
|
||||
+
|
||||
+ .store_cred_send = ccdb_mem_store_cred_send,
|
||||
+ .store_cred_recv = ccdb_mem_store_cred_recv,
|
||||
+
|
||||
+ .delete_send = ccdb_mem_delete_send,
|
||||
+ .delete_recv = ccdb_mem_delete_recv,
|
||||
+};
|
||||
--
|
||||
2.12.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,278 +0,0 @@
|
||||
From ba89271f594e5ed381b4dcb876a2d2787cf51902 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 8 Mar 2017 17:46:09 +0100
|
||||
Subject: [PATCH 29/97] MAN: Add a manual page for sssd-kcm
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
contrib/sssd.spec.in | 1 +
|
||||
src/man/Makefile.am | 9 ++-
|
||||
src/man/po/po4a.cfg | 1 +
|
||||
src/man/sssd-kcm.8.xml | 193 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 203 insertions(+), 1 deletion(-)
|
||||
create mode 100644 src/man/sssd-kcm.8.xml
|
||||
|
||||
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
|
||||
index 52d33b4de281dc1d91a9027ac1c8c878e66fb396..1d4d020415ee28292bb4d88c78de205465d812f1 100644
|
||||
--- a/contrib/sssd.spec.in
|
||||
+++ b/contrib/sssd.spec.in
|
||||
@@ -1206,6 +1206,7 @@ done
|
||||
%config(noreplace) %{_sysconfdir}/krb5.conf.d/kcm_default_ccache
|
||||
%{_unitdir}/sssd-kcm.socket
|
||||
%{_unitdir}/sssd-kcm.service
|
||||
+%{_mandir}/man8/sssd-kcm.8*
|
||||
%endif
|
||||
|
||||
%pre common
|
||||
diff --git a/src/man/Makefile.am b/src/man/Makefile.am
|
||||
index 142d6e2743f814294e3d92c8342070b8230bb3e5..3a063614f085691652db32d76315375466e0d3de 100644
|
||||
--- a/src/man/Makefile.am
|
||||
+++ b/src/man/Makefile.am
|
||||
@@ -27,6 +27,9 @@ endif
|
||||
if BUILD_SECRETS
|
||||
SEC_CONDS = ;with_secrets
|
||||
endif
|
||||
+if BUILD_SECRETS
|
||||
+KCM_CONDS = ;with_kcm
|
||||
+endif
|
||||
if GPO_DEFAULT_ENFORCING
|
||||
GPO_CONDS = ;gpo_default_enforcing
|
||||
else
|
||||
@@ -40,7 +43,7 @@ FILES_CONDS = ;enable_files_domain
|
||||
else
|
||||
FILES_CONDS = ;no_enable_files_domain
|
||||
endif
|
||||
-CONDS = with_false$(SUDO_CONDS)$(AUTOFS_CONDS)$(SSH_CONDS)$(PAC_RESPONDER_CONDS)$(IFP_CONDS)$(GPO_CONDS)$(SEC_CONDS)$(SYSTEMD_CONDS)$(FILES_CONDS)
|
||||
+CONDS = with_false$(SUDO_CONDS)$(AUTOFS_CONDS)$(SSH_CONDS)$(PAC_RESPONDER_CONDS)$(IFP_CONDS)$(GPO_CONDS)$(SEC_CONDS)$(SYSTEMD_CONDS)$(FILES_CONDS)$(KCM_CONDS)
|
||||
|
||||
|
||||
#Special Rules:
|
||||
@@ -85,6 +88,10 @@ if BUILD_SECRETS
|
||||
man_MANS += sssd-secrets.5
|
||||
endif
|
||||
|
||||
+if BUILD_KCM
|
||||
+man_MANS += sssd-kcm.8
|
||||
+endif
|
||||
+
|
||||
if BUILD_NFS_IDMAP
|
||||
man_MANS += sss_rpcidmapd.5
|
||||
endif
|
||||
diff --git a/src/man/po/po4a.cfg b/src/man/po/po4a.cfg
|
||||
index d1f6ac39f841c61ae3d2393fb3402dc21b9cbd69..a02f97e777fa76615e4d5cbcfc788956706d8cd0 100644
|
||||
--- a/src/man/po/po4a.cfg
|
||||
+++ b/src/man/po/po4a.cfg
|
||||
@@ -31,6 +31,7 @@
|
||||
[type:docbook] sssctl.8.xml $lang:$(builddir)/$lang/sssctl.8.xml
|
||||
[type:docbook] sssd-files.5.xml $lang:$(builddir)/$lang/sssd-files.5.xml
|
||||
[type:docbook] sssd-secrets.5.xml $lang:$(builddir)/$lang/sssd-secrets.5.xml
|
||||
+[type:docbook] sssd-kcm.8.xml $lang:$(builddir)/$lang/sssd-kcm.8.xml
|
||||
[type:docbook] include/service_discovery.xml $lang:$(builddir)/$lang/include/service_discovery.xml opt:"-k 0"
|
||||
[type:docbook] include/upstream.xml $lang:$(builddir)/$lang/include/upstream.xml opt:"-k 0"
|
||||
[type:docbook] include/failover.xml $lang:$(builddir)/$lang/include/failover.xml opt:"-k 0"
|
||||
diff --git a/src/man/sssd-kcm.8.xml b/src/man/sssd-kcm.8.xml
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5dc93838e48723bdb470c0a9c8575bd17c7593e8
|
||||
--- /dev/null
|
||||
+++ b/src/man/sssd-kcm.8.xml
|
||||
@@ -0,0 +1,193 @@
|
||||
+<?xml version="1.0" encoding="UTF-8"?>
|
||||
+<!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook V4.4//EN"
|
||||
+"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
||||
+<reference>
|
||||
+<title>SSSD Manual pages</title>
|
||||
+<refentry>
|
||||
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/upstream.xml" />
|
||||
+
|
||||
+ <refmeta>
|
||||
+ <refentrytitle>sssd-kcm</refentrytitle>
|
||||
+ <manvolnum>8</manvolnum>
|
||||
+ <refmiscinfo class="manual">File Formats and Conventions</refmiscinfo>
|
||||
+ </refmeta>
|
||||
+
|
||||
+ <refnamediv id='name'>
|
||||
+ <refname>sssd-kcm</refname>
|
||||
+ <refpurpose>SSSD Kerberos Cache Manager</refpurpose>
|
||||
+ </refnamediv>
|
||||
+
|
||||
+ <refsect1 id='description'>
|
||||
+ <title>DESCRIPTION</title>
|
||||
+ <para>
|
||||
+ This manual page describes the configuration of the SSSD Kerberos
|
||||
+ Cache Manager (KCM). KCM is a process that stores, tracks and
|
||||
+ manages Kerberos credential caches. It originates in the Heimdal
|
||||
+ Kerberos project, although the MIT Kerberos library also provides
|
||||
+ client side (more details on that below) support for the KCM
|
||||
+ credential cache.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ In a setup where Kerberos caches are managed by KCM, the
|
||||
+ Kerberos library (typically used through an application, like
|
||||
+ e.g.,
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>kinit</refentrytitle><manvolnum>1</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ is a <quote>"KCM client"</quote> and the KCM daemon
|
||||
+ is being referred to as a <quote>"KCM server"</quote>. The client
|
||||
+ and server communicate over a UNIX socket.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ The KCM server keeps track of each credential caches's owner and
|
||||
+ performs access check control based on the UID and GID of the
|
||||
+ KCM client. The root user has access to all credential caches.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ The KCM credential cache has several interesting properties:
|
||||
+ <itemizedlist>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ since the process runs in userspace, it is subject to UID namespacing, ulike the kernel keyring
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ unlike the kernel keyring-based cache, which is shared between all containers, the KCM server is a separate process whose entry point is a UNIX socket
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ the SSSD implementation stores the ccaches in the SSSD
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>sssd-secrets</refentrytitle><manvolnum>5</manvolnum>
|
||||
+ </citerefentry>
|
||||
+ secrets store, allowing the ccaches to survive KCM server restarts or machine reboots.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </itemizedlist>
|
||||
+ This allows the system to use a collection-aware credential
|
||||
+ cache, yet share the credential cache between some or no
|
||||
+ containers by bind-mounting the socket.
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='usage'>
|
||||
+ <title>USING THE KCM CREDENTIAL CACHE</title>
|
||||
+ <para>
|
||||
+ In order to use KCM credential cache, it must be selected as the default
|
||||
+ credential type in
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>krb5.conf</refentrytitle><manvolnum>5</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ The credentials cache name must be only <quote>KCM:</quote>
|
||||
+ without any template expansions. For example:
|
||||
+ <programlisting>
|
||||
+[libdefaults]
|
||||
+ default_ccache_name = KCM:
|
||||
+ </programlisting>
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Next, make sure the Kerberos client libraries and the KCM server must agree
|
||||
+ on the UNIX socket path. By default, both use the same path
|
||||
+ <replaceable>/var/run/.heim_org.h5l.kcm-socket</replaceable>. To configure
|
||||
+ the Kerberos library, change its <quote>kcm_socket</quote> option which
|
||||
+ is described in the
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>krb5.conf</refentrytitle><manvolnum>5</manvolnum>
|
||||
+ </citerefentry>
|
||||
+ manual page.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Finally, make sure the SSSD KCM server can be contacted.
|
||||
+ The KCM service is typically socket-activated by
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>systemd</refentrytitle>
|
||||
+ <manvolnum>1</manvolnum>
|
||||
+ </citerefentry>.
|
||||
+ Unlike
|
||||
+ other SSSD services, it cannot be started by adding the
|
||||
+ <quote>kcm</quote> string to the <quote>service</quote>
|
||||
+ directive.
|
||||
+ <programlisting>
|
||||
+systemctl start sssd-kcm.socket
|
||||
+systemctl enable sssd-kcm.socket
|
||||
+systemctl enable sssd-kcm.service
|
||||
+ </programlisting>
|
||||
+ Please note your distribution may already configure the units
|
||||
+ for you.
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='storage'>
|
||||
+ <title>THE CREDENTIAL CACHE STORAGE</title>
|
||||
+ <para>
|
||||
+ The credential caches are stored in the SSSD secrets service (see
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>sssd-secrets</refentrytitle><manvolnum>5</manvolnum>
|
||||
+ </citerefentry>
|
||||
+ for more details). Therefore it is important that also the sssd-secrets
|
||||
+ service is enabled and its socket is started:
|
||||
+ <programlisting>
|
||||
+systemctl start sssd-secrets.socket
|
||||
+systemctl enable sssd-secrets.socket
|
||||
+systemctl enable sssd-secrets.service
|
||||
+ </programlisting>
|
||||
+ Your distribution should already set the dependencies between the services.
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='options'>
|
||||
+ <title>CONFIGURATION OPTIONS</title>
|
||||
+ <para>
|
||||
+ The KCM service is configured in the <quote>kcm</quote>
|
||||
+ section of the sssd.conf file. Please note that currently,
|
||||
+ is it not sufficient to restart the sssd-kcm service, because
|
||||
+ the sssd configuration is only parsed and read to an internal
|
||||
+ configuration database by the sssd service. Therefore you
|
||||
+ must restart the sssd service if you change anything in the
|
||||
+ <quote>kcm</quote> section of sssd.conf.
|
||||
+ For a detailed syntax reference, refer to the <quote>FILE FORMAT</quote> section of the
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>sssd.conf</refentrytitle>
|
||||
+ <manvolnum>5</manvolnum>
|
||||
+ </citerefentry> manual page.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ The generic SSSD service options such as
|
||||
+ <quote>debug_level</quote> or <quote>fd_limit</quote> are
|
||||
+ accepted by the kcm service. Please refer to the
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>sssd.conf</refentrytitle>
|
||||
+ <manvolnum>5</manvolnum>
|
||||
+ </citerefentry> manual page for a complete list. In addition,
|
||||
+ there are some KCM-specific options as well.
|
||||
+ </para>
|
||||
+ <variablelist>
|
||||
+ <varlistentry>
|
||||
+ <term>socket_path (string)</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ The socket the KCM service will listen on.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Default: <replaceable>/var/run/.heim_org.h5l.kcm-socket</replaceable>
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ </variablelist>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='see_also'>
|
||||
+ <title>SEE ALSO</title>
|
||||
+ <para>
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>sssd</refentrytitle><manvolnum>8</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>sssd.conf</refentrytitle><manvolnum>5</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+</refentry>
|
||||
+</reference>
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,799 +0,0 @@
|
||||
From 0700118d8388c38b8cb28279510b206b76a3a411 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 13 Dec 2016 17:17:16 +0100
|
||||
Subject: [PATCH 30/97] TESTS: Add integration tests for the KCM responder
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
contrib/ci/configure.sh | 7 +
|
||||
contrib/ci/deps.sh | 6 +
|
||||
src/tests/intg/Makefile.am | 4 +
|
||||
src/tests/intg/kdc.py | 175 +++++++++++++++++++++
|
||||
src/tests/intg/krb5utils.py | 156 +++++++++++++++++++
|
||||
src/tests/intg/test_kcm.py | 361 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
6 files changed, 709 insertions(+)
|
||||
create mode 100644 src/tests/intg/kdc.py
|
||||
create mode 100644 src/tests/intg/krb5utils.py
|
||||
create mode 100644 src/tests/intg/test_kcm.py
|
||||
|
||||
diff --git a/contrib/ci/configure.sh b/contrib/ci/configure.sh
|
||||
index 8e779cfe634a7555e0e8e3b52f42c07e62980fbc..7590743c2aa5fe31bcdf1a3e92a3f482dbec699b 100644
|
||||
--- a/contrib/ci/configure.sh
|
||||
+++ b/contrib/ci/configure.sh
|
||||
@@ -38,6 +38,13 @@ if [[ "$DISTRO_BRANCH" == -redhat-redhatenterprise*-6.*- ||
|
||||
"--disable-cifs-idmap-plugin"
|
||||
"--with-syslog=syslog"
|
||||
"--without-python3-bindings"
|
||||
+ "--without-kcm"
|
||||
+ )
|
||||
+fi
|
||||
+
|
||||
+if [[ "$DISTRO_BRANCH" == -redhat-fedora-2[0-2]* ]]; then
|
||||
+ CONFIGURE_ARG_LIST+=(
|
||||
+ "--without-kcm"
|
||||
)
|
||||
fi
|
||||
|
||||
diff --git a/contrib/ci/deps.sh b/contrib/ci/deps.sh
|
||||
index c525e62e8c1d5b9fa042dee4ad03790dbceba242..4467e117c3a896a7f01ef7cb9e94fe28c2ea2838 100644
|
||||
--- a/contrib/ci/deps.sh
|
||||
+++ b/contrib/ci/deps.sh
|
||||
@@ -47,6 +47,8 @@ if [[ "$DISTRO_BRANCH" == -redhat-* ]]; then
|
||||
uid_wrapper
|
||||
python-requests
|
||||
curl-devel
|
||||
+ krb5-server
|
||||
+ krb5-workstation
|
||||
)
|
||||
_DEPS_LIST_SPEC=`
|
||||
sed -e 's/@PACKAGE_VERSION@/0/g' \
|
||||
@@ -122,6 +124,10 @@ if [[ "$DISTRO_BRANCH" == -debian-* ]]; then
|
||||
libhttp-parser-dev
|
||||
libjansson-dev
|
||||
libcurl4-openssl-dev
|
||||
+ krb5-kdc
|
||||
+ krb5-admin-server
|
||||
+ krb5-user
|
||||
+ uuid-dev
|
||||
)
|
||||
DEPS_INTGCHECK_SATISFIED=true
|
||||
fi
|
||||
diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am
|
||||
index 1d36fa0d2d50307fbc871f5b2a6f0cb1cc95db81..8526beace09b15c99aa27ac98d5038d1980f6a71 100644
|
||||
--- a/src/tests/intg/Makefile.am
|
||||
+++ b/src/tests/intg/Makefile.am
|
||||
@@ -26,6 +26,9 @@ dist_noinst_DATA = \
|
||||
files_ops.py \
|
||||
test_files_ops.py \
|
||||
test_files_provider.py \
|
||||
+ kdc.py \
|
||||
+ krb5utils.py \
|
||||
+ test_kcm.py \
|
||||
$(NULL)
|
||||
|
||||
config.py: config.py.m4
|
||||
@@ -80,5 +83,6 @@ intgcheck-installed: config.py passwd group
|
||||
NSS_WRAPPER_MODULE_FN_PREFIX="sss" \
|
||||
UID_WRAPPER=1 \
|
||||
UID_WRAPPER_ROOT=1 \
|
||||
+ NON_WRAPPED_UID=$$(echo $$UID) \
|
||||
fakeroot $(PYTHON2) $(PYTEST) -v --tb=native $(INTGCHECK_PYTEST_ARGS) .
|
||||
rm -f $(DESTDIR)$(logpath)/*
|
||||
diff --git a/src/tests/intg/kdc.py b/src/tests/intg/kdc.py
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..dec33a979916c0979561afb22dc39d6eb8894ff3
|
||||
--- /dev/null
|
||||
+++ b/src/tests/intg/kdc.py
|
||||
@@ -0,0 +1,175 @@
|
||||
+#
|
||||
+# MIT Kerberos server class
|
||||
+#
|
||||
+# Copyright (c) 2016 Red Hat, Inc.
|
||||
+#
|
||||
+# This 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; version 2 only
|
||||
+#
|
||||
+# 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/>.
|
||||
+#
|
||||
+import os
|
||||
+import signal
|
||||
+import shutil
|
||||
+import subprocess
|
||||
+
|
||||
+from util import *
|
||||
+
|
||||
+
|
||||
+class KDC(object):
|
||||
+ """
|
||||
+ MIT Kerberos KDC instance
|
||||
+ """
|
||||
+
|
||||
+ def __init__(self, basedir, realm,
|
||||
+ includedir=None,
|
||||
+ kdc_port=10088,
|
||||
+ kadmin_port=10749,
|
||||
+ master_key='master'):
|
||||
+ self.basedir = basedir
|
||||
+ self.realm = realm
|
||||
+ self.kdc_port = kdc_port
|
||||
+ self.kadmin_port = kadmin_port
|
||||
+ self.master_key = master_key
|
||||
+
|
||||
+ self.kdc_basedir = self.basedir + "/var/krb5kdc"
|
||||
+ self.includedir = includedir or (self.kdc_basedir + "/include")
|
||||
+ self.kdc_logdir = self.kdc_basedir + "/log"
|
||||
+ self.kdc_conf_path = self.kdc_basedir + "/kdc.conf"
|
||||
+ self.krb5_conf_path = self.kdc_basedir + "/krb5.conf"
|
||||
+
|
||||
+ self.kdc_pid_file = self.kdc_basedir + "/kdc.pid"
|
||||
+
|
||||
+ self.acl_file = self.kdc_basedir + "/kadm5.acl"
|
||||
+
|
||||
+ self.admin_princ = "admin/admin@" + self.realm
|
||||
+
|
||||
+ def start_kdc(self, extra_args=[]):
|
||||
+ args = ["krb5kdc", '-P', self.kdc_pid_file] + extra_args
|
||||
+ return self._run_in_env(args, self.get_krb5_env())
|
||||
+
|
||||
+ def stop_kdc(self):
|
||||
+ try:
|
||||
+ with open(self.kdc_pid_file, "r") as pid_file:
|
||||
+ os.kill(int(pid_file.read()), signal.SIGTERM)
|
||||
+ except IOError as ioex:
|
||||
+ if ioex.errno == 2:
|
||||
+ pass
|
||||
+ else:
|
||||
+ raise ioex
|
||||
+
|
||||
+ def teardown(self):
|
||||
+ self.stop_kdc()
|
||||
+ shutil.rmtree(self.kdc_basedir)
|
||||
+
|
||||
+ def set_up(self):
|
||||
+ self._create_config()
|
||||
+ self._create_acl()
|
||||
+ self._create_kdb()
|
||||
+
|
||||
+ def get_krb5_env(self):
|
||||
+ my_env = os.environ
|
||||
+ my_env['KRB5_CONFIG'] = self.krb5_conf_path
|
||||
+ my_env['KRB5_KDC_PROFILE'] = self.kdc_conf_path
|
||||
+ return my_env
|
||||
+
|
||||
+ def add_config(self, include_files):
|
||||
+ for name, contents in include_files.items():
|
||||
+ include_fpath = os.path.join(self.includedir, name)
|
||||
+ with open(include_fpath, 'w') as include_file:
|
||||
+ include_file.write(contents)
|
||||
+
|
||||
+ def add_principal(self, princ, password=None):
|
||||
+ args = ["kadmin.local", "-q"]
|
||||
+ if password is None:
|
||||
+ args += ["addprinc -randkey %s" % (princ)]
|
||||
+ else:
|
||||
+ args += ["addprinc -pw %s %s" % (password, princ)]
|
||||
+ return self._run_in_env(args, self.get_krb5_env())
|
||||
+
|
||||
+ def _run_in_env(self, args, env):
|
||||
+ cmd = subprocess.Popen(args, env=env)
|
||||
+ out, err = cmd.communicate()
|
||||
+ return cmd.returncode, out, err
|
||||
+
|
||||
+ def _create_config(self):
|
||||
+ try:
|
||||
+ os.makedirs(self.kdc_basedir)
|
||||
+ os.makedirs(self.kdc_logdir)
|
||||
+ os.makedirs(self.includedir)
|
||||
+ except OSError as osex:
|
||||
+ if osex.errno == 17:
|
||||
+ pass
|
||||
+
|
||||
+ kdc_conf = self._format_kdc_conf()
|
||||
+ with open(self.kdc_conf_path, 'w') as kdc_conf_file:
|
||||
+ kdc_conf_file.write(kdc_conf)
|
||||
+
|
||||
+ krb5_conf = self._format_krb5_conf()
|
||||
+ with open(self.krb5_conf_path, 'w') as krb5_conf_file:
|
||||
+ krb5_conf_file.write(krb5_conf)
|
||||
+
|
||||
+ def _create_acl(self):
|
||||
+ with open(self.acl_file, 'w') as acl_fobject:
|
||||
+ acl_fobject.write(self.admin_princ)
|
||||
+
|
||||
+ def _create_kdb(self):
|
||||
+ self._run_in_env(
|
||||
+ ['kdb5_util', 'create', '-W', '-s', '-P', self.master_key],
|
||||
+ self.get_krb5_env()
|
||||
+ )
|
||||
+
|
||||
+ def _format_kdc_conf(self):
|
||||
+ database_path = self.kdc_basedir + "/principal"
|
||||
+ key_stash = self.kdc_basedir + "/stash." + self.realm
|
||||
+
|
||||
+ kdc_logfile = "FILE:" + self.kdc_logdir + "/krb5kdc.log"
|
||||
+ kadmin_logfile = "FILE:" + self.kdc_logdir + "/kadmin.log"
|
||||
+ libkrb5_logfile = "FILE:" + self.kdc_logdir + "/libkrb5.log"
|
||||
+
|
||||
+ kdc_conf = unindent("""
|
||||
+ [kdcdefaults]
|
||||
+ kdc_ports = {self.kdc_port}
|
||||
+ kdc_tcp_ports = {self.kdc_port}
|
||||
+
|
||||
+ [realms]
|
||||
+ {self.realm} = {{
|
||||
+ kadmind_port = {self.kadmin_port}
|
||||
+ database_name = {database_path}
|
||||
+ key_stash_file = {key_stash}
|
||||
+ acl_file = {self.acl_file}
|
||||
+ }}
|
||||
+
|
||||
+ [logging]
|
||||
+ kdc = {kdc_logfile}
|
||||
+ admin_server = {kadmin_logfile}
|
||||
+ default = {libkrb5_logfile}
|
||||
+ """).format(**locals())
|
||||
+ return kdc_conf
|
||||
+
|
||||
+ def _format_krb5_conf(self):
|
||||
+ kdc_uri = "localhost:%d" % self.kdc_port
|
||||
+ kadmin_uri = "localhost:%d" % self.kadmin_port
|
||||
+
|
||||
+ krb5_conf = unindent("""
|
||||
+ includedir {self.includedir}
|
||||
+
|
||||
+ [libdefaults]
|
||||
+ default_realm = {self.realm}
|
||||
+ dns_lookup_kdc = false
|
||||
+ dns_lookup_realm = false
|
||||
+
|
||||
+ [realms]
|
||||
+ {self.realm} = {{
|
||||
+ kdc = {kdc_uri}
|
||||
+ admin_server = {kadmin_uri}
|
||||
+ }}
|
||||
+ """).format(**locals())
|
||||
+ return krb5_conf
|
||||
diff --git a/src/tests/intg/krb5utils.py b/src/tests/intg/krb5utils.py
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..775cffd0bbfa011f2d8ffc1169dccfef96d78fab
|
||||
--- /dev/null
|
||||
+++ b/src/tests/intg/krb5utils.py
|
||||
@@ -0,0 +1,156 @@
|
||||
+#
|
||||
+# MIT Kerberos server class
|
||||
+#
|
||||
+# Copyright (c) 2016 Red Hat, Inc.
|
||||
+#
|
||||
+# This 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; version 2 only
|
||||
+#
|
||||
+# 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/>.
|
||||
+#
|
||||
+import os
|
||||
+import subprocess
|
||||
+
|
||||
+
|
||||
+class NoPrincipals(Exception):
|
||||
+ def __init__(self):
|
||||
+ Exception.__init__(self, 'No principals in the collection')
|
||||
+
|
||||
+
|
||||
+class PrincNotFound(Exception):
|
||||
+ def __init__(self, principal):
|
||||
+ Exception.__init__(self, 'Principal %s not found' % principal)
|
||||
+
|
||||
+
|
||||
+class Krb5Utils(object):
|
||||
+ """
|
||||
+ Helper class to test Kerberos command line utilities
|
||||
+ """
|
||||
+ def __init__(self, krb5_conf_path):
|
||||
+ self.krb5_conf_path = krb5_conf_path
|
||||
+
|
||||
+ def _run_in_env(self, args, stdin=None, extra_env=None):
|
||||
+ my_env = os.environ
|
||||
+ my_env['KRB5_CONFIG'] = self.krb5_conf_path
|
||||
+
|
||||
+ if 'KRB5CCNAME' in my_env:
|
||||
+ del my_env['KRB5CCNAME']
|
||||
+ if extra_env is not None:
|
||||
+ my_env.update(extra_env)
|
||||
+
|
||||
+ cmd = subprocess.Popen(args,
|
||||
+ env=my_env,
|
||||
+ stdin=subprocess.PIPE,
|
||||
+ stdout=subprocess.PIPE,
|
||||
+ stderr=subprocess.PIPE)
|
||||
+ out, err = cmd.communicate(stdin)
|
||||
+ return cmd.returncode, out.decode('utf-8'), err.decode('utf-8')
|
||||
+
|
||||
+ def kinit(self, principal, password, env=None):
|
||||
+ args = ["kinit", principal]
|
||||
+ return self._run_in_env(args, password.encode('utf-8'), env)
|
||||
+
|
||||
+ def kvno(self, principal, env=None):
|
||||
+ args = ["kvno", principal]
|
||||
+ return self._run_in_env(args, env)
|
||||
+
|
||||
+ def kdestroy(self, all_ccaches=False, env=None):
|
||||
+ args = ["kdestroy"]
|
||||
+ if all_ccaches is True:
|
||||
+ args += ["-A"]
|
||||
+ retval, _, _ = self._run_in_env(args, env)
|
||||
+ return retval
|
||||
+
|
||||
+ def kswitch(self, principal, env=None):
|
||||
+ args = ["kswitch", '-p', principal]
|
||||
+ retval, _, _ = self._run_in_env(args, env)
|
||||
+ return retval
|
||||
+
|
||||
+ def _check_klist_l(self, line, exp_principal, exp_cache):
|
||||
+ try:
|
||||
+ princ, cache = line.split()
|
||||
+ except ValueError:
|
||||
+ return False
|
||||
+
|
||||
+ if exp_cache is not None and cache != exp_cache:
|
||||
+ return False
|
||||
+
|
||||
+ if exp_principal != princ:
|
||||
+ return False
|
||||
+
|
||||
+ return True
|
||||
+
|
||||
+ def num_princs(self, env=None):
|
||||
+ args = ["klist", "-l"]
|
||||
+ retval, out, err = self._run_in_env(args, extra_env=env)
|
||||
+ if retval != 0:
|
||||
+ return 0
|
||||
+
|
||||
+ outlines = [l for l in out.split('\n') if len(l) > 1]
|
||||
+ return len(outlines) - 2
|
||||
+
|
||||
+ def list_princs(self, env=None):
|
||||
+ args = ["klist", "-l"]
|
||||
+ retval, out, err = self._run_in_env(args, extra_env=env)
|
||||
+ if retval == 1:
|
||||
+ raise NoPrincipals
|
||||
+ elif retval != 0:
|
||||
+ raise Exception("klist failed: %d: %s\n", retval, err)
|
||||
+
|
||||
+ outlines = out.split('\n')
|
||||
+ if len(outlines) < 2:
|
||||
+ raise Exception("Not enough output from klist -l")
|
||||
+
|
||||
+ return [l for l in outlines[2:] if len(l) > 0]
|
||||
+
|
||||
+ def has_principal(self, exp_principal, exp_cache=None, env=None):
|
||||
+ try:
|
||||
+ princlist = self.list_princs(env)
|
||||
+ except NoPrincipals:
|
||||
+ return False
|
||||
+
|
||||
+ for line in princlist:
|
||||
+ matches = self._check_klist_l(line, exp_principal, exp_cache)
|
||||
+ if matches is True:
|
||||
+ return True
|
||||
+
|
||||
+ return False
|
||||
+
|
||||
+ def default_principal(self, env=None):
|
||||
+ principals = self.list_princs(env)
|
||||
+ return principals[0].split()[0]
|
||||
+
|
||||
+ def _parse_klist_a(self, out):
|
||||
+ dflprinc = None
|
||||
+ thisrealm = None
|
||||
+ ccache_dict = dict()
|
||||
+
|
||||
+ for line in [l for l in out.split('\n') if len(l) > 0]:
|
||||
+ if line.startswith("Default principal"):
|
||||
+ dflprinc = line.split()[2]
|
||||
+ thisrealm = '@' + dflprinc.split('@')[1]
|
||||
+ elif thisrealm is not None and line.endswith(thisrealm):
|
||||
+ svc = line.split()[-1]
|
||||
+ if dflprinc in ccache_dict:
|
||||
+ ccache_dict[dflprinc].append(svc)
|
||||
+ else:
|
||||
+ ccache_dict[dflprinc] = [svc]
|
||||
+
|
||||
+ return ccache_dict
|
||||
+
|
||||
+ def list_all_princs(self, env=None):
|
||||
+ args = ["klist", "-A"]
|
||||
+ retval, out, err = self._run_in_env(args, extra_env=env)
|
||||
+ if retval == 1:
|
||||
+ raise NoPrincipals
|
||||
+ elif retval != 0:
|
||||
+ raise Exception("klist -A failed: %d: %s\n", retval, err)
|
||||
+
|
||||
+ return self._parse_klist_a(out)
|
||||
diff --git a/src/tests/intg/test_kcm.py b/src/tests/intg/test_kcm.py
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ad1e4923bfe339cb040464757431d2ef3bf57ce1
|
||||
--- /dev/null
|
||||
+++ b/src/tests/intg/test_kcm.py
|
||||
@@ -0,0 +1,361 @@
|
||||
+#
|
||||
+# KCM responder integration tests
|
||||
+#
|
||||
+# Copyright (c) 2016 Red Hat, Inc.
|
||||
+#
|
||||
+# This 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; version 2 only
|
||||
+#
|
||||
+# 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/>.
|
||||
+#
|
||||
+import os
|
||||
+import os.path
|
||||
+import stat
|
||||
+import subprocess
|
||||
+import pytest
|
||||
+import socket
|
||||
+import time
|
||||
+import signal
|
||||
+
|
||||
+import kdc
|
||||
+import krb5utils
|
||||
+import config
|
||||
+from util import unindent, run_shell
|
||||
+
|
||||
+class KcmTestEnv(object):
|
||||
+ def __init__(self, k5kdc, k5util):
|
||||
+ self.k5kdc = k5kdc
|
||||
+ self.k5util = k5util
|
||||
+ self.counter = 0
|
||||
+
|
||||
+ def my_uid(self):
|
||||
+ s_myuid = os.environ['NON_WRAPPED_UID']
|
||||
+ return int(s_myuid)
|
||||
+
|
||||
+ def ccname(self, my_uid=None):
|
||||
+ if my_uid is None:
|
||||
+ my_uid = self.my_uid()
|
||||
+
|
||||
+ return "KCM:%d" % my_uid
|
||||
+
|
||||
+
|
||||
+@pytest.fixture(scope="module")
|
||||
+def kdc_instance(request):
|
||||
+ """Kerberos server instance fixture"""
|
||||
+ kdc_instance = kdc.KDC(config.PREFIX, "KCMTEST")
|
||||
+ try:
|
||||
+ kdc_instance.set_up()
|
||||
+ kdc_instance.start_kdc()
|
||||
+ except:
|
||||
+ kdc_instance.teardown()
|
||||
+ raise
|
||||
+ request.addfinalizer(kdc_instance.teardown)
|
||||
+ return kdc_instance
|
||||
+
|
||||
+
|
||||
+def create_conf_fixture(request, contents):
|
||||
+ """Generate sssd.conf and add teardown for removing it"""
|
||||
+ with open(config.CONF_PATH, "w") as conf:
|
||||
+ conf.write(contents)
|
||||
+ os.chmod(config.CONF_PATH, stat.S_IRUSR | stat.S_IWUSR)
|
||||
+ request.addfinalizer(lambda: os.unlink(config.CONF_PATH))
|
||||
+
|
||||
+
|
||||
+def create_sssd_kcm_fixture(sock_path, request):
|
||||
+ if subprocess.call(['sssd', "--genconf"]) != 0:
|
||||
+ raise Exception("failed to regenerate confdb")
|
||||
+
|
||||
+ resp_path = os.path.join(config.LIBEXEC_PATH, "sssd", "sssd_kcm")
|
||||
+ if not os.access(resp_path, os.X_OK):
|
||||
+ # It would be cleaner to use pytest.mark.skipif on the package level
|
||||
+ # but upstream insists on supporting RHEL-6..
|
||||
+ pytest.skip("No KCM responder, skipping")
|
||||
+
|
||||
+ kcm_pid = os.fork()
|
||||
+ assert kcm_pid >= 0
|
||||
+
|
||||
+ if kcm_pid == 0:
|
||||
+ if subprocess.call([resp_path, "--uid=0", "--gid=0"]) != 0:
|
||||
+ print("sssd_kcm failed to start")
|
||||
+ sys.exit(99)
|
||||
+ else:
|
||||
+ abs_sock_path = os.path.join(config.RUNSTATEDIR, sock_path)
|
||||
+ sck = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
+ for _ in range(1, 10):
|
||||
+ try:
|
||||
+ sck.connect(abs_sock_path)
|
||||
+ except:
|
||||
+ time.sleep(0.1)
|
||||
+ else:
|
||||
+ break
|
||||
+ sck.close()
|
||||
+ assert os.path.exists(abs_sock_path)
|
||||
+
|
||||
+ def kcm_teardown():
|
||||
+ if kcm_pid == 0:
|
||||
+ return
|
||||
+ os.kill(kcm_pid, signal.SIGTERM)
|
||||
+
|
||||
+ request.addfinalizer(kcm_teardown)
|
||||
+ return kcm_pid
|
||||
+
|
||||
+
|
||||
+@pytest.fixture
|
||||
+def setup_for_kcm(request, kdc_instance):
|
||||
+ """
|
||||
+ Just set up the local provider for tests and enable the KCM
|
||||
+ responder
|
||||
+ """
|
||||
+ kcm_path = os.path.join(config.RUNSTATEDIR, "kcm.socket")
|
||||
+
|
||||
+ sssd_conf = unindent("""\
|
||||
+ [sssd]
|
||||
+ domains = local
|
||||
+ services = nss
|
||||
+
|
||||
+ [domain/local]
|
||||
+ id_provider = local
|
||||
+
|
||||
+ [kcm]
|
||||
+ socket_path = {kcm_path}
|
||||
+ """).format(**locals())
|
||||
+
|
||||
+ kcm_socket_include = unindent("""
|
||||
+ [libdefaults]
|
||||
+ default_ccache_name = KCM:
|
||||
+ kcm_socket = {kcm_path}
|
||||
+ """).format(**locals())
|
||||
+ kdc_instance.add_config({'kcm_socket': kcm_socket_include})
|
||||
+
|
||||
+ create_conf_fixture(request, sssd_conf)
|
||||
+ create_sssd_kcm_fixture(kcm_path, request)
|
||||
+
|
||||
+ k5util = krb5utils.Krb5Utils(kdc_instance.krb5_conf_path)
|
||||
+
|
||||
+ return KcmTestEnv(kdc_instance, k5util)
|
||||
+
|
||||
+
|
||||
+def test_kcm_init_list_destroy(setup_for_kcm):
|
||||
+ """
|
||||
+ Test that kinit, kdestroy and klist work with KCM
|
||||
+ """
|
||||
+ testenv = setup_for_kcm
|
||||
+ testenv.k5kdc.add_principal("kcmtest", "Secret123")
|
||||
+
|
||||
+ ok = testenv.k5util.has_principal("kcmtest@KCMTEST")
|
||||
+ assert ok is False
|
||||
+ nprincs = testenv.k5util.num_princs()
|
||||
+ assert nprincs == 0
|
||||
+
|
||||
+ out, _, _ = testenv.k5util.kinit("kcmtest", "Secret123")
|
||||
+ assert out == 0
|
||||
+ nprincs = testenv.k5util.num_princs()
|
||||
+ assert nprincs == 1
|
||||
+
|
||||
+ exp_ccname = testenv.ccname()
|
||||
+ ok = testenv.k5util.has_principal("kcmtest@KCMTEST", exp_ccname)
|
||||
+ assert ok is True
|
||||
+
|
||||
+ out = testenv.k5util.kdestroy()
|
||||
+ assert out == 0
|
||||
+
|
||||
+ ok = testenv.k5util.has_principal("kcmtest@KCMTEST")
|
||||
+ assert ok is False
|
||||
+ nprincs = testenv.k5util.num_princs()
|
||||
+ assert nprincs == 0
|
||||
+
|
||||
+
|
||||
+def test_kcm_overwrite(setup_for_kcm):
|
||||
+ """
|
||||
+ That that reusing a ccache reinitializes the cache and doesn't
|
||||
+ add the same principal twice
|
||||
+ """
|
||||
+ testenv = setup_for_kcm
|
||||
+ testenv.k5kdc.add_principal("kcmtest", "Secret123")
|
||||
+ exp_ccache = {'kcmtest@KCMTEST': ['krbtgt/KCMTEST@KCMTEST']}
|
||||
+
|
||||
+ assert testenv.k5util.num_princs() == 0
|
||||
+
|
||||
+ out, _, _ = testenv.k5util.kinit("kcmtest", "Secret123")
|
||||
+ assert out == 0
|
||||
+ assert exp_ccache == testenv.k5util.list_all_princs()
|
||||
+
|
||||
+ out, _, _ = testenv.k5util.kinit("kcmtest", "Secret123")
|
||||
+ assert out == 0
|
||||
+ assert exp_ccache == testenv.k5util.list_all_princs()
|
||||
+
|
||||
+
|
||||
+def test_collection_init_list_destroy(setup_for_kcm):
|
||||
+ """
|
||||
+ Test that multiple principals and service tickets can be stored
|
||||
+ in a collection.
|
||||
+ """
|
||||
+ testenv = setup_for_kcm
|
||||
+ testenv.k5kdc.add_principal("alice", "alicepw")
|
||||
+ testenv.k5kdc.add_principal("bob", "bobpw")
|
||||
+ testenv.k5kdc.add_principal("carol", "carolpw")
|
||||
+ testenv.k5kdc.add_principal("host/somehostname")
|
||||
+
|
||||
+ assert testenv.k5util.num_princs() == 0
|
||||
+
|
||||
+ out, _, _ = testenv.k5util.kinit("alice", "alicepw")
|
||||
+ assert out == 0
|
||||
+ assert testenv.k5util.default_principal() == 'alice@KCMTEST'
|
||||
+ cc_coll = testenv.k5util.list_all_princs()
|
||||
+ assert len(cc_coll) == 1
|
||||
+ assert cc_coll['alice@KCMTEST'] == ['krbtgt/KCMTEST@KCMTEST']
|
||||
+ assert 'bob@KCMTEST' not in cc_coll
|
||||
+ assert 'carol@KCMTEST' not in cc_coll
|
||||
+
|
||||
+ out, _, _ = testenv.k5util.kinit("bob", "bobpw")
|
||||
+ assert out == 0
|
||||
+ assert testenv.k5util.default_principal() == 'bob@KCMTEST'
|
||||
+ cc_coll = testenv.k5util.list_all_princs()
|
||||
+ assert len(cc_coll) == 2
|
||||
+ assert cc_coll['alice@KCMTEST'] == ['krbtgt/KCMTEST@KCMTEST']
|
||||
+ assert cc_coll['bob@KCMTEST'] == ['krbtgt/KCMTEST@KCMTEST']
|
||||
+ assert 'carol@KCMTEST' not in cc_coll
|
||||
+
|
||||
+ out, _, _ = testenv.k5util.kinit("carol", "carolpw")
|
||||
+ assert out == 0
|
||||
+ assert testenv.k5util.default_principal() == 'carol@KCMTEST'
|
||||
+ cc_coll = testenv.k5util.list_all_princs()
|
||||
+ assert len(cc_coll) == 3
|
||||
+ assert cc_coll['alice@KCMTEST'] == ['krbtgt/KCMTEST@KCMTEST']
|
||||
+ assert cc_coll['bob@KCMTEST'] == ['krbtgt/KCMTEST@KCMTEST']
|
||||
+ assert cc_coll['carol@KCMTEST'] == ['krbtgt/KCMTEST@KCMTEST']
|
||||
+
|
||||
+ out, _, _ = testenv.k5util.kvno('host/somehostname')
|
||||
+ assert out == 0
|
||||
+ cc_coll = testenv.k5util.list_all_princs()
|
||||
+ assert len(cc_coll) == 3
|
||||
+ assert set(cc_coll['carol@KCMTEST']) == set(['krbtgt/KCMTEST@KCMTEST',
|
||||
+ 'host/somehostname@KCMTEST'])
|
||||
+
|
||||
+ out = testenv.k5util.kdestroy()
|
||||
+ assert out == 0
|
||||
+ assert testenv.k5util.default_principal() == 'bob@KCMTEST'
|
||||
+ cc_coll = testenv.k5util.list_all_princs()
|
||||
+ assert len(cc_coll) == 2
|
||||
+ assert cc_coll['alice@KCMTEST'] == ['krbtgt/KCMTEST@KCMTEST']
|
||||
+ assert cc_coll['bob@KCMTEST'] == ['krbtgt/KCMTEST@KCMTEST']
|
||||
+ assert 'carol@KCMTEST' not in cc_coll
|
||||
+
|
||||
+ # FIXME - a bug in libkrb5?
|
||||
+ #out = testenv.k5util.kdestroy(all_ccaches=True)
|
||||
+ #assert out == 0
|
||||
+ #cc_coll = testenv.k5util.list_all_princs()
|
||||
+ #assert len(cc_coll) == 0
|
||||
+
|
||||
+
|
||||
+def test_kswitch(setup_for_kcm):
|
||||
+ """
|
||||
+ Test switching between principals
|
||||
+ """
|
||||
+ testenv = setup_for_kcm
|
||||
+ testenv.k5kdc.add_principal("alice", "alicepw")
|
||||
+ testenv.k5kdc.add_principal("bob", "bobpw")
|
||||
+ testenv.k5kdc.add_principal("host/somehostname")
|
||||
+ testenv.k5kdc.add_principal("host/differenthostname")
|
||||
+
|
||||
+ out, _, _ = testenv.k5util.kinit("alice", "alicepw")
|
||||
+ assert out == 0
|
||||
+ assert testenv.k5util.default_principal() == 'alice@KCMTEST'
|
||||
+
|
||||
+ out, _, _ = testenv.k5util.kinit("bob", "bobpw")
|
||||
+ assert out == 0
|
||||
+ assert testenv.k5util.default_principal() == 'bob@KCMTEST'
|
||||
+
|
||||
+ cc_coll = testenv.k5util.list_all_princs()
|
||||
+ assert len(cc_coll) == 2
|
||||
+ assert cc_coll['alice@KCMTEST'] == ['krbtgt/KCMTEST@KCMTEST']
|
||||
+ assert cc_coll['bob@KCMTEST'] == ['krbtgt/KCMTEST@KCMTEST']
|
||||
+
|
||||
+ out = testenv.k5util.kswitch("alice@KCMTEST")
|
||||
+ assert testenv.k5util.default_principal() == 'alice@KCMTEST'
|
||||
+ out, _, _ = testenv.k5util.kvno('host/somehostname')
|
||||
+ assert out == 0
|
||||
+ cc_coll = testenv.k5util.list_all_princs()
|
||||
+ assert len(cc_coll) == 2
|
||||
+ assert set(cc_coll['alice@KCMTEST']) == set(['krbtgt/KCMTEST@KCMTEST',
|
||||
+ 'host/somehostname@KCMTEST'])
|
||||
+ assert cc_coll['bob@KCMTEST'] == ['krbtgt/KCMTEST@KCMTEST']
|
||||
+
|
||||
+ out = testenv.k5util.kswitch("bob@KCMTEST")
|
||||
+ assert testenv.k5util.default_principal() == 'bob@KCMTEST'
|
||||
+ out, _, _ = testenv.k5util.kvno('host/differenthostname')
|
||||
+ assert out == 0
|
||||
+ cc_coll = testenv.k5util.list_all_princs()
|
||||
+ assert len(cc_coll) == 2
|
||||
+ assert set(cc_coll['alice@KCMTEST']) == set(['krbtgt/KCMTEST@KCMTEST',
|
||||
+ 'host/somehostname@KCMTEST'])
|
||||
+ assert set(cc_coll['bob@KCMTEST']) == set([
|
||||
+ 'krbtgt/KCMTEST@KCMTEST',
|
||||
+ 'host/differenthostname@KCMTEST'])
|
||||
+
|
||||
+
|
||||
+def test_subsidiaries(setup_for_kcm):
|
||||
+ """
|
||||
+ Test that subsidiary caches are usable and KCM: without specifying UID
|
||||
+ can be used to identify the collection
|
||||
+ """
|
||||
+ testenv = setup_for_kcm
|
||||
+ testenv.k5kdc.add_principal("alice", "alicepw")
|
||||
+ testenv.k5kdc.add_principal("bob", "bobpw")
|
||||
+ testenv.k5kdc.add_principal("host/somehostname")
|
||||
+ testenv.k5kdc.add_principal("host/differenthostname")
|
||||
+
|
||||
+ out, _, _ = testenv.k5util.kinit("alice", "alicepw")
|
||||
+ assert out == 0
|
||||
+ out, _, _ = testenv.k5util.kvno('host/somehostname')
|
||||
+
|
||||
+ out, _, _ = testenv.k5util.kinit("bob", "bobpw")
|
||||
+ assert out == 0
|
||||
+ out, _, _ = testenv.k5util.kvno('host/differenthostname')
|
||||
+
|
||||
+ exp_cc_coll = dict()
|
||||
+ exp_cc_coll['alice@KCMTEST'] = 'host/somehostname@KCMTEST'
|
||||
+ exp_cc_coll['bob@KCMTEST'] = 'host/differenthostname@KCMTEST'
|
||||
+
|
||||
+ klist_l = testenv.k5util.list_princs()
|
||||
+ princ_ccache = dict()
|
||||
+ for line in klist_l:
|
||||
+ princ, subsidiary = line.split()
|
||||
+ princ_ccache[princ] = subsidiary
|
||||
+
|
||||
+ for princ, subsidiary in princ_ccache.items():
|
||||
+ env = {'KRB5CCNAME': subsidiary}
|
||||
+ cc_coll = testenv.k5util.list_all_princs(env=env)
|
||||
+ assert len(cc_coll) == 1
|
||||
+ assert princ in cc_coll
|
||||
+ assert exp_cc_coll[princ] in cc_coll[princ]
|
||||
+
|
||||
+ cc_coll = testenv.k5util.list_all_princs(env={'KRB5CCNAME': 'KCM:'})
|
||||
+ assert len(cc_coll) == 2
|
||||
+ assert set(cc_coll['alice@KCMTEST']) == set(['krbtgt/KCMTEST@KCMTEST',
|
||||
+ 'host/somehostname@KCMTEST'])
|
||||
+ assert set(cc_coll['bob@KCMTEST']) == set([
|
||||
+ 'krbtgt/KCMTEST@KCMTEST',
|
||||
+ 'host/differenthostname@KCMTEST'])
|
||||
+
|
||||
+
|
||||
+def test_kdestroy_nocache(setup_for_kcm):
|
||||
+ """
|
||||
+ Destroying a non-existing ccache should not throw an error
|
||||
+ """
|
||||
+ testenv = setup_for_kcm
|
||||
+ testenv.k5kdc.add_principal("alice", "alicepw")
|
||||
+ out, _, _ = testenv.k5util.kinit("alice", "alicepw")
|
||||
+ assert out == 0
|
||||
+
|
||||
+ testenv.k5util.kdestroy()
|
||||
+ assert out == 0
|
||||
+ out = testenv.k5util.kdestroy()
|
||||
+ assert out == 0
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,405 +0,0 @@
|
||||
From 8bb2fcbce7c3fcfd986f1bc835fbcc43ac7cd9d1 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 3 Jan 2017 16:00:38 +0100
|
||||
Subject: [PATCH 31/97] SECRETS: Create DB path before the operation itself
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This is a refactoring where instead of creating the ldb path in the
|
||||
operation itself, we create the ldb path when creating the local db request
|
||||
and pass the path to the operation.
|
||||
|
||||
This would allow us to store different kind of objects in the secrets
|
||||
storage later.
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/responder/secrets/local.c | 170 +++++++++++++++++++++---------------------
|
||||
1 file changed, 84 insertions(+), 86 deletions(-)
|
||||
|
||||
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c
|
||||
index ed70193bcb27d84eaf449f6f7571c94f466c9896..9dcdd9925e542499d3a962b4998103b07c26a5ab 100644
|
||||
--- a/src/responder/secrets/local.c
|
||||
+++ b/src/responder/secrets/local.c
|
||||
@@ -199,39 +199,36 @@ static char *local_dn_to_path(TALLOC_CTX *mem_ctx,
|
||||
return path;
|
||||
}
|
||||
|
||||
+struct local_db_req {
|
||||
+ char *path;
|
||||
+ struct ldb_dn *basedn;
|
||||
+};
|
||||
+
|
||||
#define LOCAL_SIMPLE_FILTER "(type=simple)"
|
||||
#define LOCAL_CONTAINER_FILTER "(type=container)"
|
||||
|
||||
static int local_db_get_simple(TALLOC_CTX *mem_ctx,
|
||||
struct local_context *lctx,
|
||||
- const char *req_path,
|
||||
+ struct local_db_req *lc_req,
|
||||
char **secret)
|
||||
{
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
static const char *attrs[] = { "secret", "enctype", NULL };
|
||||
struct ldb_result *res;
|
||||
- struct ldb_dn *dn;
|
||||
const char *attr_secret;
|
||||
const char *attr_enctype;
|
||||
int ret;
|
||||
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, "Retrieving a secret from [%s]\n", req_path);
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "Retrieving a secret from [%s]\n", lc_req->path);
|
||||
|
||||
tmp_ctx = talloc_new(mem_ctx);
|
||||
if (!tmp_ctx) return ENOMEM;
|
||||
|
||||
- ret = local_db_dn(tmp_ctx, lctx->ldb, req_path, &dn);
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
DEBUG(SSSDBG_TRACE_INTERNAL,
|
||||
"Searching for [%s] at [%s] with scope=base\n",
|
||||
- LOCAL_SIMPLE_FILTER, ldb_dn_get_linearized(dn));
|
||||
+ LOCAL_SIMPLE_FILTER, ldb_dn_get_linearized(lc_req->basedn));
|
||||
|
||||
- ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
|
||||
+ ret = ldb_search(lctx->ldb, tmp_ctx, &res, lc_req->basedn, LDB_SCOPE_BASE,
|
||||
attrs, "%s", LOCAL_SIMPLE_FILTER);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_TRACE_LIBS,
|
||||
@@ -278,34 +275,26 @@ done:
|
||||
|
||||
static int local_db_list_keys(TALLOC_CTX *mem_ctx,
|
||||
struct local_context *lctx,
|
||||
- const char *req_path,
|
||||
+ struct local_db_req *lc_req,
|
||||
char ***_keys,
|
||||
int *num_keys)
|
||||
{
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
static const char *attrs[] = { "secret", NULL };
|
||||
struct ldb_result *res;
|
||||
- struct ldb_dn *dn;
|
||||
char **keys;
|
||||
int ret;
|
||||
|
||||
tmp_ctx = talloc_new(mem_ctx);
|
||||
if (!tmp_ctx) return ENOMEM;
|
||||
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, "Listing keys at [%s]\n", req_path);
|
||||
-
|
||||
- ret = local_db_dn(tmp_ctx, lctx->ldb, req_path, &dn);
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||
- goto done;
|
||||
- }
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "Listing keys at [%s]\n", lc_req->path);
|
||||
|
||||
DEBUG(SSSDBG_TRACE_INTERNAL,
|
||||
"Searching for [%s] at [%s] with scope=subtree\n",
|
||||
- LOCAL_SIMPLE_FILTER, ldb_dn_get_linearized(dn));
|
||||
+ LOCAL_SIMPLE_FILTER, ldb_dn_get_linearized(lc_req->basedn));
|
||||
|
||||
- ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_SUBTREE,
|
||||
+ ret = ldb_search(lctx->ldb, tmp_ctx, &res, lc_req->basedn, LDB_SCOPE_SUBTREE,
|
||||
attrs, "%s", LOCAL_SIMPLE_FILTER);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_TRACE_LIBS,
|
||||
@@ -327,7 +316,7 @@ static int local_db_list_keys(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < res->count; i++) {
|
||||
- keys[i] = local_dn_to_path(keys, dn, res->msgs[i]->dn);
|
||||
+ keys[i] = local_dn_to_path(keys, lc_req->basedn, res->msgs[i]->dn);
|
||||
if (!keys[i]) {
|
||||
ret = ENOMEM;
|
||||
goto done;
|
||||
@@ -474,7 +463,7 @@ static int local_check_max_payload_size(struct local_context *lctx,
|
||||
|
||||
static int local_db_put_simple(TALLOC_CTX *mem_ctx,
|
||||
struct local_context *lctx,
|
||||
- const char *req_path,
|
||||
+ struct local_db_req *lc_req,
|
||||
const char *secret)
|
||||
{
|
||||
struct ldb_message *msg;
|
||||
@@ -482,20 +471,14 @@ static int local_db_put_simple(TALLOC_CTX *mem_ctx,
|
||||
char *enc_secret;
|
||||
int ret;
|
||||
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "Adding a secret to [%s]\n", lc_req->path);
|
||||
+
|
||||
msg = ldb_msg_new(mem_ctx);
|
||||
if (!msg) {
|
||||
ret = ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
-
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, "Adding a secret to [%s]\n", req_path);
|
||||
-
|
||||
- ret = local_db_dn(msg, lctx->ldb, req_path, &msg->dn);
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||
- goto done;
|
||||
- }
|
||||
+ msg->dn = lc_req->basedn;
|
||||
|
||||
/* make sure containers exist */
|
||||
ret = local_db_check_containers(msg, lctx, msg->dn);
|
||||
@@ -585,32 +568,24 @@ done:
|
||||
|
||||
static int local_db_delete(TALLOC_CTX *mem_ctx,
|
||||
struct local_context *lctx,
|
||||
- const char *req_path)
|
||||
+ struct local_db_req *lc_req)
|
||||
{
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
- struct ldb_dn *dn;
|
||||
static const char *attrs[] = { NULL };
|
||||
struct ldb_result *res;
|
||||
int ret;
|
||||
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, "Removing a secret from [%s]\n", req_path);
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "Removing a secret from [%s]\n", lc_req->path);
|
||||
|
||||
tmp_ctx = talloc_new(mem_ctx);
|
||||
if (!tmp_ctx) return ENOMEM;
|
||||
|
||||
- ret = local_db_dn(mem_ctx, lctx->ldb, req_path, &dn);
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
DEBUG(SSSDBG_TRACE_INTERNAL,
|
||||
"Searching for [%s] at [%s] with scope=base\n",
|
||||
- LOCAL_CONTAINER_FILTER, ldb_dn_get_linearized(dn));
|
||||
+ LOCAL_CONTAINER_FILTER, ldb_dn_get_linearized(lc_req->basedn));
|
||||
|
||||
- ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
|
||||
- attrs, LOCAL_CONTAINER_FILTER);
|
||||
+ ret = ldb_search(lctx->ldb, tmp_ctx, &res, lc_req->basedn, LDB_SCOPE_BASE,
|
||||
+ attrs, LOCAL_CONTAINER_FILTER);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_TRACE_LIBS,
|
||||
"ldb_search returned %d: %s\n", ret, ldb_strerror(ret));
|
||||
@@ -619,8 +594,8 @@ static int local_db_delete(TALLOC_CTX *mem_ctx,
|
||||
|
||||
if (res->count == 1) {
|
||||
DEBUG(SSSDBG_TRACE_INTERNAL,
|
||||
- "Searching for children of [%s]\n", ldb_dn_get_linearized(dn));
|
||||
- ret = ldb_search(lctx->ldb, tmp_ctx, &res, dn, LDB_SCOPE_ONELEVEL,
|
||||
+ "Searching for children of [%s]\n", ldb_dn_get_linearized(lc_req->basedn));
|
||||
+ ret = ldb_search(lctx->ldb, tmp_ctx, &res, lc_req->basedn, LDB_SCOPE_ONELEVEL,
|
||||
attrs, NULL);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_TRACE_LIBS,
|
||||
@@ -632,13 +607,13 @@ static int local_db_delete(TALLOC_CTX *mem_ctx,
|
||||
ret = EEXIST;
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
"Failed to remove '%s': Container is not empty\n",
|
||||
- ldb_dn_get_linearized(dn));
|
||||
+ ldb_dn_get_linearized(lc_req->basedn));
|
||||
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
- ret = ldb_delete(lctx->ldb, dn);
|
||||
+ ret = ldb_delete(lctx->ldb, lc_req->basedn);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_TRACE_LIBS,
|
||||
"ldb_delete returned %d: %s\n", ret, ldb_strerror(ret));
|
||||
@@ -653,25 +628,19 @@ done:
|
||||
|
||||
static int local_db_create(TALLOC_CTX *mem_ctx,
|
||||
struct local_context *lctx,
|
||||
- const char *req_path)
|
||||
+ struct local_db_req *lc_req)
|
||||
{
|
||||
struct ldb_message *msg;
|
||||
int ret;
|
||||
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "Creating a container at [%s]\n", lc_req->path);
|
||||
+
|
||||
msg = ldb_msg_new(mem_ctx);
|
||||
if (!msg) {
|
||||
ret = ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
-
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, "Creating a container at [%s]\n", req_path);
|
||||
-
|
||||
- ret = local_db_dn(msg, lctx->ldb, req_path, &msg->dn);
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- "local_db_dn failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||
- goto done;
|
||||
- }
|
||||
+ msg->dn = lc_req->basedn;
|
||||
|
||||
/* make sure containers exist */
|
||||
ret = local_db_check_containers(msg, lctx, msg->dn);
|
||||
@@ -724,10 +693,13 @@ done:
|
||||
}
|
||||
|
||||
static int local_secrets_map_path(TALLOC_CTX *mem_ctx,
|
||||
+ struct ldb_context *ldb,
|
||||
struct sec_req_ctx *secreq,
|
||||
- char **local_db_path)
|
||||
+ struct local_db_req **_lc_req)
|
||||
{
|
||||
int ret;
|
||||
+ struct local_db_req *lc_req;
|
||||
+ const char *basedn;
|
||||
|
||||
/* be strict for now */
|
||||
if (secreq->parsed_url.fragment != NULL) {
|
||||
@@ -755,20 +727,46 @@ static int local_secrets_map_path(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
- /* drop SEC_BASEPATH prefix */
|
||||
- *local_db_path =
|
||||
- talloc_strdup(mem_ctx, &secreq->mapped_path[sizeof(SEC_BASEPATH) - 1]);
|
||||
- if (!*local_db_path) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- "Failed to map request to local db path\n");
|
||||
+ lc_req = talloc(mem_ctx, struct local_db_req);
|
||||
+ if (lc_req == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
- DEBUG(SSSDBG_TRACE_LIBS, "Local DB path is %s\n", *local_db_path);
|
||||
- return EOK;
|
||||
+ /* drop the prefix and select a basedn instead */
|
||||
+ if (strncmp(secreq->mapped_path,
|
||||
+ SEC_BASEPATH, sizeof(SEC_BASEPATH) - 1) == 0) {
|
||||
+ lc_req->path = talloc_strdup(lc_req,
|
||||
+ secreq->mapped_path + (sizeof(SEC_BASEPATH) - 1));
|
||||
+ basedn = SECRETS_BASEDN;
|
||||
+ } else {
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (lc_req->path == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Failed to map request to local db path\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = local_db_dn(mem_ctx, ldb, basedn, lc_req->path, &lc_req->basedn);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Failed to map request to local db DN\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "Local DB path is %s\n", lc_req->path);
|
||||
+ ret = EOK;
|
||||
+ *_lc_req = lc_req;
|
||||
+done:
|
||||
+ if (ret != EOK) {
|
||||
+ talloc_free(lc_req);
|
||||
+ }
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
-
|
||||
struct local_secret_state {
|
||||
struct tevent_context *ev;
|
||||
struct sec_req_ctx *secreq;
|
||||
@@ -785,7 +783,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
|
||||
struct sec_data body = { 0 };
|
||||
const char *content_type;
|
||||
bool body_is_json;
|
||||
- char *req_path;
|
||||
+ struct local_db_req *lc_req;
|
||||
char *secret;
|
||||
char **keys;
|
||||
int nkeys;
|
||||
@@ -821,14 +819,14 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
DEBUG(SSSDBG_TRACE_LIBS, "Content-Type: %s\n", content_type);
|
||||
|
||||
- ret = local_secrets_map_path(state, secreq, &req_path);
|
||||
+ ret = local_secrets_map_path(state, lctx->ldb, secreq, &lc_req);
|
||||
if (ret) goto done;
|
||||
|
||||
switch (secreq->method) {
|
||||
case HTTP_GET:
|
||||
- DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP GET at [%s]\n", req_path);
|
||||
- if (req_path[strlen(req_path) - 1] == '/') {
|
||||
- ret = local_db_list_keys(state, lctx, req_path, &keys, &nkeys);
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP GET at [%s]\n", lc_req->path);
|
||||
+ if (lc_req->path[strlen(lc_req->path) - 1] == '/') {
|
||||
+ ret = local_db_list_keys(state, lctx, lc_req, &keys, &nkeys);
|
||||
if (ret) goto done;
|
||||
|
||||
ret = sec_array_to_json(state, keys, nkeys, &body.data);
|
||||
@@ -838,7 +836,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
|
||||
break;
|
||||
}
|
||||
|
||||
- ret = local_db_get_simple(state, lctx, req_path, &secret);
|
||||
+ ret = local_db_get_simple(state, lctx, lc_req, &secret);
|
||||
if (ret) goto done;
|
||||
|
||||
if (body_is_json) {
|
||||
@@ -855,7 +853,7 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
|
||||
break;
|
||||
|
||||
case HTTP_PUT:
|
||||
- DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP PUT at [%s]\n", req_path);
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP PUT at [%s]\n", lc_req->path);
|
||||
if (body_is_json) {
|
||||
ret = sec_json_to_simple_secret(state, secreq->body.data,
|
||||
&secret);
|
||||
@@ -866,27 +864,27 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
if (ret) goto done;
|
||||
|
||||
- ret = local_db_put_simple(state, lctx, req_path, secret);
|
||||
+ ret = local_db_put_simple(state, lctx, lc_req, secret);
|
||||
if (ret) goto done;
|
||||
break;
|
||||
|
||||
case HTTP_DELETE:
|
||||
- ret = local_db_delete(state, lctx, req_path);
|
||||
+ ret = local_db_delete(state, lctx, lc_req);
|
||||
if (ret) goto done;
|
||||
break;
|
||||
|
||||
case HTTP_POST:
|
||||
- DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP POST at [%s]\n", req_path);
|
||||
- plen = strlen(req_path);
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP POST at [%s]\n", lc_req->path);
|
||||
+ plen = strlen(lc_req->path);
|
||||
|
||||
- if (req_path[plen - 1] != '/') {
|
||||
+ if (lc_req->path[plen - 1] != '/') {
|
||||
ret = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
- req_path[plen - 1] = '\0';
|
||||
+ lc_req->path[plen - 1] = '\0';
|
||||
|
||||
- ret = local_db_create(state, lctx, req_path);
|
||||
+ ret = local_db_create(state, lctx, lc_req);
|
||||
if (ret) goto done;
|
||||
break;
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,40 +0,0 @@
|
||||
From 73ce539aa70f43ccd5302b3ef8a02ff028558b12 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Fri, 3 Feb 2017 14:33:47 +0100
|
||||
Subject: [PATCH 32/97] SECRETS: Return a nicer error message on request with
|
||||
no PUT data
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
I managed to create this pathological situation with the tcurl tool
|
||||
which didn't send any PUT data. The error in sssd-secrets was quite
|
||||
strange (ENOMEM). This patch just adds a safeguard sooner so that we
|
||||
return a graceful error.
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/responder/secrets/local.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c
|
||||
index 9dcdd9925e542499d3a962b4998103b07c26a5ab..26c97a2849febbf0ac482d526cf927bfc103b4f2 100644
|
||||
--- a/src/responder/secrets/local.c
|
||||
+++ b/src/responder/secrets/local.c
|
||||
@@ -853,6 +853,12 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
|
||||
break;
|
||||
|
||||
case HTTP_PUT:
|
||||
+ if (secreq->body.length == 0) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "PUT with no data\n");
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
DEBUG(SSSDBG_TRACE_LIBS, "Processing HTTP PUT at [%s]\n", lc_req->path);
|
||||
if (body_is_json) {
|
||||
ret = sec_json_to_simple_secret(state, secreq->body.data,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,206 +0,0 @@
|
||||
From 60612b5fbdaaa62ebe6c7f4c27200316f08506d6 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 21 Mar 2017 14:14:42 +0100
|
||||
Subject: [PATCH 33/97] SECRETS: Store ccaches in secrets for the KCM responder
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Adds a new "hive" to the secrets responder whose base path is /kcm. Only
|
||||
root can contact the /kcm hive, because the KCM responder only runs as
|
||||
root and it must impersonate other users and store ccaches on their behalf.
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/responder/secrets/local.c | 16 +++++++-
|
||||
src/responder/secrets/providers.c | 71 ++++++++++++++++++++++++++++++----
|
||||
src/responder/secrets/secsrv_private.h | 10 ++++-
|
||||
3 files changed, 86 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/responder/secrets/local.c b/src/responder/secrets/local.c
|
||||
index 26c97a2849febbf0ac482d526cf927bfc103b4f2..02007ada8b673071ecba033df0eb3f81af93fcbd 100644
|
||||
--- a/src/responder/secrets/local.c
|
||||
+++ b/src/responder/secrets/local.c
|
||||
@@ -26,6 +26,9 @@
|
||||
|
||||
#define MKEY_SIZE (256 / 8)
|
||||
|
||||
+#define SECRETS_BASEDN "cn=secrets"
|
||||
+#define KCM_BASEDN "cn=kcm"
|
||||
+
|
||||
struct local_context {
|
||||
struct ldb_context *ldb;
|
||||
struct sec_data master_key;
|
||||
@@ -119,6 +122,7 @@ static int local_encrypt(struct local_context *lctx, TALLOC_CTX *mem_ctx,
|
||||
|
||||
static int local_db_dn(TALLOC_CTX *mem_ctx,
|
||||
struct ldb_context *ldb,
|
||||
+ const char *basedn,
|
||||
const char *req_path,
|
||||
struct ldb_dn **req_dn)
|
||||
{
|
||||
@@ -126,7 +130,7 @@ static int local_db_dn(TALLOC_CTX *mem_ctx,
|
||||
const char *s, *e;
|
||||
int ret;
|
||||
|
||||
- dn = ldb_dn_new(mem_ctx, ldb, "cn=secrets");
|
||||
+ dn = ldb_dn_new(mem_ctx, ldb, basedn);
|
||||
if (!dn) {
|
||||
ret = ENOMEM;
|
||||
goto done;
|
||||
@@ -738,6 +742,11 @@ static int local_secrets_map_path(TALLOC_CTX *mem_ctx,
|
||||
lc_req->path = talloc_strdup(lc_req,
|
||||
secreq->mapped_path + (sizeof(SEC_BASEPATH) - 1));
|
||||
basedn = SECRETS_BASEDN;
|
||||
+ } else if (strncmp(secreq->mapped_path,
|
||||
+ SEC_KCM_BASEPATH, sizeof(SEC_KCM_BASEPATH) - 1) == 0) {
|
||||
+ lc_req->path = talloc_strdup(lc_req,
|
||||
+ secreq->mapped_path + (sizeof(SEC_KCM_BASEPATH) - 1));
|
||||
+ basedn = KCM_BASEDN;
|
||||
} else {
|
||||
ret = EINVAL;
|
||||
goto done;
|
||||
@@ -820,7 +829,10 @@ static struct tevent_req *local_secret_req(TALLOC_CTX *mem_ctx,
|
||||
DEBUG(SSSDBG_TRACE_LIBS, "Content-Type: %s\n", content_type);
|
||||
|
||||
ret = local_secrets_map_path(state, lctx->ldb, secreq, &lc_req);
|
||||
- if (ret) goto done;
|
||||
+ if (ret) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot map request path to local path\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
switch (secreq->method) {
|
||||
case HTTP_GET:
|
||||
diff --git a/src/responder/secrets/providers.c b/src/responder/secrets/providers.c
|
||||
index eba555d2e422d08db211979422a2957e48b51589..94831c73036d269addca45c0117811a2c68873fd 100644
|
||||
--- a/src/responder/secrets/providers.c
|
||||
+++ b/src/responder/secrets/providers.c
|
||||
@@ -24,6 +24,14 @@
|
||||
#include "responder/secrets/secsrv_proxy.h"
|
||||
#include <jansson.h>
|
||||
|
||||
+typedef int (*url_mapper_fn)(struct sec_req_ctx *secreq,
|
||||
+ char **mapped_path);
|
||||
+
|
||||
+struct url_pfx_router {
|
||||
+ const char *prefix;
|
||||
+ url_mapper_fn mapper_fn;
|
||||
+};
|
||||
+
|
||||
static int sec_map_url_to_user_path(struct sec_req_ctx *secreq,
|
||||
char **mapped_path)
|
||||
{
|
||||
@@ -42,10 +50,43 @@ static int sec_map_url_to_user_path(struct sec_req_ctx *secreq,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
- DEBUG(SSSDBG_TRACE_LIBS, "User-specific path is [%s]\n", *mapped_path);
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS,
|
||||
+ "User-specific secrets path is [%s]\n", *mapped_path);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+static int kcm_map_url_to_path(struct sec_req_ctx *secreq,
|
||||
+ char **mapped_path)
|
||||
+{
|
||||
+ uid_t c_euid;
|
||||
+
|
||||
+ c_euid = client_euid(secreq->cctx->creds);
|
||||
+ if (c_euid != KCM_PEER_UID) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "UID %"SPRIuid" is not allowed to access "
|
||||
+ "the "SEC_KCM_BASEPATH" hive\n",
|
||||
+ c_euid);
|
||||
+ return EPERM;
|
||||
+ }
|
||||
+
|
||||
+ *mapped_path = talloc_strdup(secreq, secreq->parsed_url.path );
|
||||
+ if (!*mapped_path) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Failed to map request to user specific url\n");
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS,
|
||||
+ "User-specific KCM path is [%s]\n", *mapped_path);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static struct url_pfx_router secrets_url_mapping[] = {
|
||||
+ { SEC_BASEPATH, sec_map_url_to_user_path },
|
||||
+ { SEC_KCM_BASEPATH, kcm_map_url_to_path },
|
||||
+ { NULL, NULL },
|
||||
+};
|
||||
+
|
||||
int sec_req_routing(TALLOC_CTX *mem_ctx, struct sec_req_ctx *secreq,
|
||||
struct provider_handle **handle)
|
||||
{
|
||||
@@ -55,21 +96,35 @@ int sec_req_routing(TALLOC_CTX *mem_ctx, struct sec_req_ctx *secreq,
|
||||
char *provider;
|
||||
int num_sections;
|
||||
int ret;
|
||||
+ url_mapper_fn mapper_fn = NULL;
|
||||
|
||||
sctx = talloc_get_type(secreq->cctx->rctx->pvt_ctx, struct sec_ctx);
|
||||
|
||||
- /* patch must start with /secrets/ for now */
|
||||
- ret = strncasecmp(secreq->parsed_url.path,
|
||||
- SEC_BASEPATH, sizeof(SEC_BASEPATH) - 1);
|
||||
- if (ret != 0) {
|
||||
+ for (int i = 0; secrets_url_mapping[i].prefix != NULL; i++) {
|
||||
+ if (strncasecmp(secreq->parsed_url.path,
|
||||
+ secrets_url_mapping[i].prefix,
|
||||
+ strlen(secrets_url_mapping[i].prefix)) == 0) {
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS,
|
||||
+ "Mapping prefix %s\n", secrets_url_mapping[i].prefix);
|
||||
+ mapper_fn = secrets_url_mapping[i].mapper_fn;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (mapper_fn == NULL) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- "Path [%s] does not start with "SEC_BASEPATH"\n",
|
||||
+ "Path [%s] does not start with any allowed prefix\n",
|
||||
secreq->parsed_url.path);
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
- ret = sec_map_url_to_user_path(secreq, &secreq->mapped_path);
|
||||
- if (ret) return ret;
|
||||
+ ret = mapper_fn(secreq, &secreq->mapped_path);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Failed to map the user path [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
|
||||
/* source default provider */
|
||||
ret = confdb_get_string(secreq->cctx->rctx->cdb, mem_ctx,
|
||||
diff --git a/src/responder/secrets/secsrv_private.h b/src/responder/secrets/secsrv_private.h
|
||||
index 1c3fbd8eadb237551233f048503ddc01b4ba00ae..a8544f656517a17fe4576247779bff4850beaf97 100644
|
||||
--- a/src/responder/secrets/secsrv_private.h
|
||||
+++ b/src/responder/secrets/secsrv_private.h
|
||||
@@ -101,7 +101,15 @@ int sec_get_provider(struct sec_ctx *sctx, const char *name,
|
||||
struct provider_handle **out_handle);
|
||||
int sec_add_provider(struct sec_ctx *sctx, struct provider_handle *handle);
|
||||
|
||||
-#define SEC_BASEPATH "/secrets/"
|
||||
+#define SEC_BASEPATH "/secrets/"
|
||||
+#define SEC_KCM_BASEPATH "/kcm/"
|
||||
+
|
||||
+/* The KCM responder must "impersonate" the owner of the credentials.
|
||||
+ * Only a trusted UID can do that -- root by default, but unit
|
||||
+ * tests might choose otherwise */
|
||||
+#ifndef KCM_PEER_UID
|
||||
+#define KCM_PEER_UID 0
|
||||
+#endif /* KCM_PEER_UID */
|
||||
|
||||
/* providers.c */
|
||||
int sec_req_routing(TALLOC_CTX *mem_ctx, struct sec_req_ctx *secreq,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,129 +0,0 @@
|
||||
From c9db8b8b19827c3d492b8d2769aa77a37dbc12d3 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 14 Mar 2017 15:34:57 +0100
|
||||
Subject: [PATCH 34/97] TCURL: Support HTTP POST for creating containers
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The curl integration must allow us to create containers, therefore we
|
||||
also add support of the POST HTTP request type.
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/tests/intg/test_secrets.py | 28 ++++++++++++++++++++++++++++
|
||||
src/tests/tcurl_test_tool.c | 5 +++++
|
||||
src/util/tev_curl.c | 7 +++++++
|
||||
src/util/tev_curl.h | 1 +
|
||||
4 files changed, 41 insertions(+)
|
||||
|
||||
diff --git a/src/tests/intg/test_secrets.py b/src/tests/intg/test_secrets.py
|
||||
index cbc1a1f06d2abb826bc0a880cb5a842f577657ea..d71c1904558cc6f8a6eee36c4049582705bc30ac 100644
|
||||
--- a/src/tests/intg/test_secrets.py
|
||||
+++ b/src/tests/intg/test_secrets.py
|
||||
@@ -271,6 +271,34 @@ def test_curlwrap_crd_ops(setup_for_secrets,
|
||||
'http://localhost/secrets/foo'],
|
||||
404)
|
||||
|
||||
+ # Create a container
|
||||
+ run_curlwrap_tool([curlwrap_tool, '-o',
|
||||
+ '-v', '-s', sock_path,
|
||||
+ 'http://localhost/secrets/cont/'],
|
||||
+ 200)
|
||||
+
|
||||
+ # set a secret foo:bar
|
||||
+ run_curlwrap_tool([curlwrap_tool, '-p',
|
||||
+ '-v', '-s', sock_path,
|
||||
+ 'http://localhost/secrets/cont/cfoo',
|
||||
+ 'foo_under_cont'],
|
||||
+ 200)
|
||||
+
|
||||
+ # list secrets
|
||||
+ output = run_curlwrap_tool([curlwrap_tool,
|
||||
+ '-v', '-s', sock_path,
|
||||
+ 'http://localhost/secrets/cont/'],
|
||||
+ 200)
|
||||
+ assert "cfoo" in output
|
||||
+
|
||||
+ # get the foo secret
|
||||
+ output = run_curlwrap_tool([curlwrap_tool,
|
||||
+ '-v', '-s', sock_path,
|
||||
+ 'http://localhost/secrets/cont/cfoo'],
|
||||
+ 200)
|
||||
+ assert "foo_under_cont" in output
|
||||
+
|
||||
+
|
||||
|
||||
def test_curlwrap_parallel(setup_for_secrets,
|
||||
curlwrap_tool):
|
||||
diff --git a/src/tests/tcurl_test_tool.c b/src/tests/tcurl_test_tool.c
|
||||
index 38cea432885c97ca3827c8f158bf7e3ebfc67b31..2af950ebb76a22bdf4a6dfd58442b10486e64293 100644
|
||||
--- a/src/tests/tcurl_test_tool.c
|
||||
+++ b/src/tests/tcurl_test_tool.c
|
||||
@@ -88,6 +88,7 @@ int main(int argc, const char *argv[])
|
||||
{ "get", 'g', POPT_ARG_NONE, NULL, 'g', "Perform a HTTP GET (default)", NULL },
|
||||
{ "put", 'p', POPT_ARG_NONE, NULL, 'p', "Perform a HTTP PUT", NULL },
|
||||
{ "del", 'd', POPT_ARG_NONE, NULL, 'd', "Perform a HTTP DELETE", NULL },
|
||||
+ { "post", 'o', POPT_ARG_NONE, NULL, 'o', "Perform a HTTP POST", NULL },
|
||||
{ "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "Print response code and body", NULL },
|
||||
POPT_TABLEEND
|
||||
};
|
||||
@@ -118,6 +119,9 @@ int main(int argc, const char *argv[])
|
||||
case 'd':
|
||||
req_type = TCURL_HTTP_DELETE;
|
||||
break;
|
||||
+ case 'o':
|
||||
+ req_type = TCURL_HTTP_POST;
|
||||
+ break;
|
||||
case 'v':
|
||||
pc_verbose = 1;
|
||||
break;
|
||||
@@ -145,6 +149,7 @@ int main(int argc, const char *argv[])
|
||||
switch (req_type) {
|
||||
case TCURL_HTTP_GET:
|
||||
case TCURL_HTTP_DELETE:
|
||||
+ case TCURL_HTTP_POST:
|
||||
urls[n_reqs++] = extra_arg_ptr;
|
||||
break;
|
||||
case TCURL_HTTP_PUT:
|
||||
diff --git a/src/util/tev_curl.c b/src/util/tev_curl.c
|
||||
index fd436653b5aeb611a9648a8b81a330fd3fcfe875..645d1182d10f825f209f48e0ba7e6804dde1971c 100644
|
||||
--- a/src/util/tev_curl.c
|
||||
+++ b/src/util/tev_curl.c
|
||||
@@ -154,6 +154,8 @@ static const char *http_req2str(enum tcurl_http_request req)
|
||||
return "PUT";
|
||||
case TCURL_HTTP_DELETE:
|
||||
return "DELETE";
|
||||
+ case TCURL_HTTP_POST:
|
||||
+ return "POST";
|
||||
}
|
||||
|
||||
return "Uknown request type";
|
||||
@@ -815,6 +817,11 @@ static errno_t tcurl_set_options(struct tcurl_http_state *state,
|
||||
}
|
||||
|
||||
switch (req_type) {
|
||||
+ case TCURL_HTTP_POST:
|
||||
+ crv = curl_easy_setopt(state->http_handle,
|
||||
+ CURLOPT_CUSTOMREQUEST,
|
||||
+ "POST");
|
||||
+ break;
|
||||
case TCURL_HTTP_PUT:
|
||||
/* CURLOPT_UPLOAD enables HTTP_PUT */
|
||||
crv = curl_easy_setopt(state->http_handle,
|
||||
diff --git a/src/util/tev_curl.h b/src/util/tev_curl.h
|
||||
index de0601df4327d97001a8a825cd4709936f6c8466..444eb286e09d189b4588e2b2152b5202df3914d8 100644
|
||||
--- a/src/util/tev_curl.h
|
||||
+++ b/src/util/tev_curl.h
|
||||
@@ -34,6 +34,7 @@ enum tcurl_http_request {
|
||||
TCURL_HTTP_GET,
|
||||
TCURL_HTTP_PUT,
|
||||
TCURL_HTTP_DELETE,
|
||||
+ TCURL_HTTP_POST,
|
||||
};
|
||||
|
||||
/**
|
||||
--
|
||||
2.12.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,219 +0,0 @@
|
||||
From 35c9dfe9ba78d3a635cd1af0fb6349ba44344623 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 14 Mar 2017 11:17:05 +0100
|
||||
Subject: [PATCH 36/97] KCM: Make the secrets ccache back end configurable,
|
||||
make secrets the default
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Adds a new option 'ccache_storage' that allows to select either the
|
||||
memory back end or the secrets back end. The secrets back end is the
|
||||
default one and this option is even undocumented.
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/confdb/confdb.h | 1 +
|
||||
src/config/cfg_rules.ini | 1 +
|
||||
src/responder/kcm/kcm.c | 49 ++++++++++++++++++++++++++++++++----
|
||||
src/responder/kcm/kcmsrv_ccache.c | 2 +-
|
||||
src/responder/kcm/kcmsrv_ccache.h | 6 +----
|
||||
src/responder/kcm/kcmsrv_ccache_be.h | 1 +
|
||||
src/responder/kcm/kcmsrv_pvt.h | 7 ++++++
|
||||
7 files changed, 56 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
|
||||
index c443e869a7a6782265b42c4ad122867c4e3dd8e0..fb60675ca8beb2c2a157bf021ed9cad362742988 100644
|
||||
--- a/src/confdb/confdb.h
|
||||
+++ b/src/confdb/confdb.h
|
||||
@@ -234,6 +234,7 @@
|
||||
/* KCM Service */
|
||||
#define CONFDB_KCM_CONF_ENTRY "config/kcm"
|
||||
#define CONFDB_KCM_SOCKET "socket_path"
|
||||
+#define CONFDB_KCM_DB "ccache_storage" /* Undocumented on purpose */
|
||||
|
||||
struct confdb_ctx;
|
||||
struct config_file_ctx;
|
||||
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
|
||||
index 5e789c51658c51c0af1338d23d6c0f30f40bf119..67a5d1f5ad447a942b437ffd04a7f5d7cfe77d7f 100644
|
||||
--- a/src/config/cfg_rules.ini
|
||||
+++ b/src/config/cfg_rules.ini
|
||||
@@ -280,6 +280,7 @@ option = fd_limit
|
||||
option = client_idle_timeout
|
||||
option = description
|
||||
option = socket_path
|
||||
+option = ccache_storage
|
||||
|
||||
[rule/allowed_domain_options]
|
||||
validator = ini_allowed_options
|
||||
diff --git a/src/responder/kcm/kcm.c b/src/responder/kcm/kcm.c
|
||||
index 2c12ef215ce3967df183e51c20590c5f439d278f..063c27b915b4b92f6259496feee891aa94a498b6 100644
|
||||
--- a/src/responder/kcm/kcm.c
|
||||
+++ b/src/responder/kcm/kcm.c
|
||||
@@ -47,6 +47,37 @@ static int kcm_responder_ctx_destructor(void *ptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static errno_t kcm_get_ccdb_be(struct kcm_ctx *kctx)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ char *str_db;
|
||||
+
|
||||
+ ret = confdb_get_string(kctx->rctx->cdb,
|
||||
+ kctx->rctx,
|
||||
+ kctx->rctx->confdb_service_path,
|
||||
+ CONFDB_KCM_DB,
|
||||
+ "secrets",
|
||||
+ &str_db);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Cannot get the KCM database type [%d]: %s\n",
|
||||
+ ret, strerror(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(SSSDBG_CONF_SETTINGS, "KCM database type: %s\n", str_db);
|
||||
+ if (strcasecmp(str_db, "memory") == 0) {
|
||||
+ kctx->cc_be = CCDB_BE_MEMORY;
|
||||
+ return EOK;
|
||||
+ } else if (strcasecmp(str_db, "secrets") == 0) {
|
||||
+ kctx->cc_be = CCDB_BE_SECRETS;
|
||||
+ return EOK;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "Unexpected KCM database type %s\n", str_db);
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
static int kcm_get_config(struct kcm_ctx *kctx)
|
||||
{
|
||||
int ret;
|
||||
@@ -88,14 +119,21 @@ static int kcm_get_config(struct kcm_ctx *kctx)
|
||||
&sock_name);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
- "Cannot get the client idle timeout [%d]: %s\n",
|
||||
+ "Cannot get KCM socket path [%d]: %s\n",
|
||||
ret, strerror(ret));
|
||||
goto done;
|
||||
}
|
||||
kctx->rctx->sock_name = sock_name;
|
||||
|
||||
+ ret = kcm_get_ccdb_be(kctx);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Cannot get KCM ccache DB [%d]: %s\n",
|
||||
+ ret, strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
ret = EOK;
|
||||
-
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
@@ -111,7 +149,8 @@ static int kcm_data_destructor(void *ptr)
|
||||
}
|
||||
|
||||
static struct kcm_resp_ctx *kcm_data_setup(TALLOC_CTX *mem_ctx,
|
||||
- struct tevent_context *ev)
|
||||
+ struct tevent_context *ev,
|
||||
+ enum kcm_ccdb_be cc_be)
|
||||
{
|
||||
struct kcm_resp_ctx *kcm_data;
|
||||
krb5_error_code kret;
|
||||
@@ -122,7 +161,7 @@ static struct kcm_resp_ctx *kcm_data_setup(TALLOC_CTX *mem_ctx,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- kcm_data->db = kcm_ccdb_init(kcm_data, ev, CCDB_BE_MEMORY);
|
||||
+ kcm_data->db = kcm_ccdb_init(kcm_data, ev, cc_be);
|
||||
if (kcm_data->db == NULL) {
|
||||
talloc_free(kcm_data);
|
||||
return NULL;
|
||||
@@ -176,7 +215,7 @@ static int kcm_process_init(TALLOC_CTX *mem_ctx,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- kctx->kcm_data = kcm_data_setup(kctx, ev);
|
||||
+ kctx->kcm_data = kcm_data_setup(kctx, ev, kctx->cc_be);
|
||||
if (kctx->kcm_data == NULL) {
|
||||
DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
"fatal error initializing responder data\n");
|
||||
diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
|
||||
index 2ae120269b0c62275ba2acdff6d6daa8b7077708..a22184e0f2b1300f3678bb343b6a110bf144a36b 100644
|
||||
--- a/src/responder/kcm/kcmsrv_ccache.c
|
||||
+++ b/src/responder/kcm/kcmsrv_ccache.c
|
||||
@@ -244,7 +244,7 @@ struct kcm_ccdb *kcm_ccdb_init(TALLOC_CTX *mem_ctx,
|
||||
break;
|
||||
case CCDB_BE_SECRETS:
|
||||
DEBUG(SSSDBG_FUNC_DATA, "KCM back end: sssd-secrets\n");
|
||||
- /* Not implemented yet */
|
||||
+ ccdb->ops = &ccdb_sec_ops;
|
||||
break;
|
||||
default:
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Unknown ccache database\n");
|
||||
diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h
|
||||
index 18c8c47ad4ecb24521a85a1833b239c7a2a8bb45..36c481c5335d557318f0ed0204d93e533b4b6c41 100644
|
||||
--- a/src/responder/kcm/kcmsrv_ccache.h
|
||||
+++ b/src/responder/kcm/kcmsrv_ccache.h
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "util/util.h"
|
||||
#include "util/sss_iobuf.h"
|
||||
#include "util/util_creds.h"
|
||||
+#include "responder/kcm/kcmsrv_pvt.h"
|
||||
|
||||
#define UUID_BYTES 16
|
||||
#define UUID_STR_SIZE 37
|
||||
@@ -113,11 +114,6 @@ errno_t kcm_cc_store_cred_blob(struct kcm_ccache *cc,
|
||||
struct kcm_cred *kcm_cc_get_cred(struct kcm_ccache *cc);
|
||||
struct kcm_cred *kcm_cc_next_cred(struct kcm_cred *crd);
|
||||
|
||||
-enum kcm_ccdb_be {
|
||||
- CCDB_BE_MEMORY,
|
||||
- CCDB_BE_SECRETS,
|
||||
-};
|
||||
-
|
||||
/* An opaque database that contains all the ccaches */
|
||||
struct kcm_ccdb;
|
||||
|
||||
diff --git a/src/responder/kcm/kcmsrv_ccache_be.h b/src/responder/kcm/kcmsrv_ccache_be.h
|
||||
index 1bd2b6981e227675866e82e0a5389445cac4df66..a0796c298bae15a01adf612a6195a494ba6b4d23 100644
|
||||
--- a/src/responder/kcm/kcmsrv_ccache_be.h
|
||||
+++ b/src/responder/kcm/kcmsrv_ccache_be.h
|
||||
@@ -200,5 +200,6 @@ struct kcm_ccdb_ops {
|
||||
};
|
||||
|
||||
extern const struct kcm_ccdb_ops ccdb_mem_ops;
|
||||
+extern const struct kcm_ccdb_ops ccdb_sec_ops;
|
||||
|
||||
#endif /* _KCMSRV_CCACHE_BE_ */
|
||||
diff --git a/src/responder/kcm/kcmsrv_pvt.h b/src/responder/kcm/kcmsrv_pvt.h
|
||||
index a29680246c1e616da75e1bbff951ce2fad66fb65..74f30c00014105ed533744779b02c5d42523722d 100644
|
||||
--- a/src/responder/kcm/kcmsrv_pvt.h
|
||||
+++ b/src/responder/kcm/kcmsrv_pvt.h
|
||||
@@ -49,6 +49,12 @@ struct kcm_resp_ctx {
|
||||
struct kcm_ccdb *db;
|
||||
};
|
||||
|
||||
+/* Supported ccache back ends */
|
||||
+enum kcm_ccdb_be {
|
||||
+ CCDB_BE_MEMORY,
|
||||
+ CCDB_BE_SECRETS,
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* responder context that contains both the responder data,
|
||||
* like the ccaches and the sssd-specific stuff like the
|
||||
@@ -58,6 +64,7 @@ struct kcm_ctx {
|
||||
struct resp_ctx *rctx;
|
||||
int fd_limit;
|
||||
char *socket_path;
|
||||
+ enum kcm_ccdb_be cc_be;
|
||||
|
||||
struct kcm_resp_ctx *kcm_data;
|
||||
};
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,909 +0,0 @@
|
||||
From 2b5518eeaacc6245cfa77ee4a7086f16208060fc Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 21 Mar 2017 13:25:11 +0100
|
||||
Subject: [PATCH 37/97] KCM: Queue requests by the same UID
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In order to avoid race conditions, we queue requests towards the KCM
|
||||
responder coming from the same client UID.
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
Makefile.am | 21 ++-
|
||||
src/responder/kcm/kcm.c | 7 +
|
||||
src/responder/kcm/kcmsrv_cmd.c | 10 +-
|
||||
src/responder/kcm/kcmsrv_op_queue.c | 264 ++++++++++++++++++++++++++
|
||||
src/responder/kcm/kcmsrv_ops.c | 44 ++++-
|
||||
src/responder/kcm/kcmsrv_ops.h | 1 +
|
||||
src/responder/kcm/kcmsrv_pvt.h | 20 ++
|
||||
src/tests/cmocka/test_kcm_queue.c | 365 ++++++++++++++++++++++++++++++++++++
|
||||
8 files changed, 721 insertions(+), 11 deletions(-)
|
||||
create mode 100644 src/responder/kcm/kcmsrv_op_queue.c
|
||||
create mode 100644 src/tests/cmocka/test_kcm_queue.c
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index e9eaa312c91e3aee40bcf13c90a0ad8c683045d5..91afdd669aa11a3cc316588d3b51d7e8e9c91cb8 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -304,7 +304,10 @@ non_interactive_cmocka_based_tests += test_inotify
|
||||
endif # HAVE_INOTIFY
|
||||
|
||||
if BUILD_KCM
|
||||
-non_interactive_cmocka_based_tests += test_kcm_json
|
||||
+non_interactive_cmocka_based_tests += \
|
||||
+ test_kcm_json \
|
||||
+ test_kcm_queue \
|
||||
+ $(NULL)
|
||||
endif # BUILD_KCM
|
||||
|
||||
if BUILD_SAMBA
|
||||
@@ -1501,6 +1504,7 @@ sssd_kcm_SOURCES = \
|
||||
src/responder/kcm/kcmsrv_ccache_json.c \
|
||||
src/responder/kcm/kcmsrv_ccache_secrets.c \
|
||||
src/responder/kcm/kcmsrv_ops.c \
|
||||
+ src/responder/kcm/kcmsrv_op_queue.c \
|
||||
src/util/sss_sockets.c \
|
||||
src/util/sss_krb5.c \
|
||||
src/util/sss_iobuf.c \
|
||||
@@ -3402,6 +3406,21 @@ test_kcm_json_LDADD = \
|
||||
$(SSSD_INTERNAL_LTLIBS) \
|
||||
libsss_test_common.la \
|
||||
$(NULL)
|
||||
+
|
||||
+test_kcm_queue_SOURCES = \
|
||||
+ src/tests/cmocka/test_kcm_queue.c \
|
||||
+ src/responder/kcm/kcmsrv_op_queue.c \
|
||||
+ $(NULL)
|
||||
+test_kcm_queue_CFLAGS = \
|
||||
+ $(AM_CFLAGS) \
|
||||
+ $(NULL)
|
||||
+test_kcm_queue_LDADD = \
|
||||
+ $(CMOCKA_LIBS) \
|
||||
+ $(SSSD_LIBS) \
|
||||
+ $(SSSD_INTERNAL_LTLIBS) \
|
||||
+ libsss_test_common.la \
|
||||
+ $(NULL)
|
||||
+
|
||||
endif # BUILD_KCM
|
||||
|
||||
endif # HAVE_CMOCKA
|
||||
diff --git a/src/responder/kcm/kcm.c b/src/responder/kcm/kcm.c
|
||||
index 063c27b915b4b92f6259496feee891aa94a498b6..3ee978066c589a5cc38b0ae358f741d389d00e7a 100644
|
||||
--- a/src/responder/kcm/kcm.c
|
||||
+++ b/src/responder/kcm/kcm.c
|
||||
@@ -133,6 +133,13 @@ static int kcm_get_config(struct kcm_ctx *kctx)
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ kctx->qctx = kcm_ops_queue_create(kctx);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Cannot create KCM request queue [%d]: %s\n",
|
||||
+ ret, strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
ret = EOK;
|
||||
done:
|
||||
return ret;
|
||||
diff --git a/src/responder/kcm/kcmsrv_cmd.c b/src/responder/kcm/kcmsrv_cmd.c
|
||||
index 537e88953fd1a190a9a73bcdd430d8e0db8f9291..81015de4a91617de3dca444cde95b636c8d5c0d1 100644
|
||||
--- a/src/responder/kcm/kcmsrv_cmd.c
|
||||
+++ b/src/responder/kcm/kcmsrv_cmd.c
|
||||
@@ -353,14 +353,18 @@ struct kcm_req_ctx {
|
||||
|
||||
static void kcm_cmd_request_done(struct tevent_req *req);
|
||||
|
||||
-static errno_t kcm_cmd_dispatch(struct kcm_req_ctx *req_ctx)
|
||||
+static errno_t kcm_cmd_dispatch(struct kcm_ctx *kctx,
|
||||
+ struct kcm_req_ctx *req_ctx)
|
||||
{
|
||||
struct tevent_req *req;
|
||||
struct cli_ctx *cctx;
|
||||
|
||||
cctx = req_ctx->cctx;
|
||||
|
||||
- req = kcm_cmd_send(req_ctx, cctx->ev, req_ctx->kctx->kcm_data,
|
||||
+ req = kcm_cmd_send(req_ctx,
|
||||
+ cctx->ev,
|
||||
+ kctx->qctx,
|
||||
+ req_ctx->kctx->kcm_data,
|
||||
req_ctx->cctx->creds,
|
||||
&req_ctx->op_io.request,
|
||||
req_ctx->op_io.op);
|
||||
@@ -505,7 +509,7 @@ static void kcm_recv(struct cli_ctx *cctx)
|
||||
/* do not read anymore, client is done sending */
|
||||
TEVENT_FD_NOT_READABLE(cctx->cfde);
|
||||
|
||||
- ret = kcm_cmd_dispatch(req);
|
||||
+ ret = kcm_cmd_dispatch(kctx, req);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
"Failed to dispatch KCM operation [%d]: %s\n",
|
||||
diff --git a/src/responder/kcm/kcmsrv_op_queue.c b/src/responder/kcm/kcmsrv_op_queue.c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f6c425dd5b64877c8b7401e488dd6565157fc9b5
|
||||
--- /dev/null
|
||||
+++ b/src/responder/kcm/kcmsrv_op_queue.c
|
||||
@@ -0,0 +1,264 @@
|
||||
+/*
|
||||
+ SSSD
|
||||
+
|
||||
+ KCM Server - the KCM operations wait queue
|
||||
+
|
||||
+ Copyright (C) Red Hat, 2017
|
||||
+
|
||||
+ 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 "util/util.h"
|
||||
+#include "util/util_creds.h"
|
||||
+#include "responder/kcm/kcmsrv_pvt.h"
|
||||
+
|
||||
+#define QUEUE_HASH_SIZE 32
|
||||
+
|
||||
+struct kcm_ops_queue_entry {
|
||||
+ struct tevent_req *req;
|
||||
+ uid_t uid;
|
||||
+
|
||||
+ hash_table_t *wait_queue_hash;
|
||||
+
|
||||
+ struct kcm_ops_queue_entry *head;
|
||||
+ struct kcm_ops_queue_entry *next;
|
||||
+ struct kcm_ops_queue_entry *prev;
|
||||
+};
|
||||
+
|
||||
+struct kcm_ops_queue_ctx {
|
||||
+ /* UID: dlist of kcm_ops_queue_entry */
|
||||
+ hash_table_t *wait_queue_hash;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Per-UID wait queue
|
||||
+ *
|
||||
+ * They key in the hash table is the UID of the peer. The value of each
|
||||
+ * hash table entry is a linked list of kcm_ops_queue_entry structures
|
||||
+ * which primarily hold the tevent request being queued.
|
||||
+ */
|
||||
+struct kcm_ops_queue_ctx *kcm_ops_queue_create(TALLOC_CTX *mem_ctx)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ struct kcm_ops_queue_ctx *queue_ctx;
|
||||
+
|
||||
+ queue_ctx = talloc_zero(mem_ctx, struct kcm_ops_queue_ctx);
|
||||
+ if (queue_ctx == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_hash_create_ex(mem_ctx, QUEUE_HASH_SIZE,
|
||||
+ &queue_ctx->wait_queue_hash, 0, 0, 0, 0,
|
||||
+ NULL, NULL);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "sss_hash_create failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||
+ talloc_free(queue_ctx);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return queue_ctx;
|
||||
+}
|
||||
+
|
||||
+static int kcm_op_queue_entry_destructor(struct kcm_ops_queue_entry *entry)
|
||||
+{
|
||||
+ int ret;
|
||||
+ struct kcm_ops_queue_entry *next_entry;
|
||||
+ hash_key_t key;
|
||||
+
|
||||
+ if (entry == NULL) {
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ /* Take the next entry from the queue */
|
||||
+ next_entry = entry->next;
|
||||
+
|
||||
+ /* Remove the current entry from the queue */
|
||||
+ DLIST_REMOVE(entry->head, entry);
|
||||
+
|
||||
+ if (next_entry == NULL) {
|
||||
+ key.type = HASH_KEY_ULONG;
|
||||
+ key.ul = entry->uid;
|
||||
+
|
||||
+ /* If this was the last entry, remove the key (the UID) from the
|
||||
+ * hash table to signal the queue is empty
|
||||
+ */
|
||||
+ ret = hash_delete(entry->wait_queue_hash, &key);
|
||||
+ if (ret != HASH_SUCCESS) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Failed to remove wait queue for user %"SPRIuid"\n",
|
||||
+ entry->uid);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Otherwise, mark the current head as done to run the next request */
|
||||
+ tevent_req_done(next_entry->req);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static errno_t kcm_op_queue_add(hash_table_t *wait_queue_hash,
|
||||
+ struct kcm_ops_queue_entry *entry,
|
||||
+ uid_t uid)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ hash_key_t key;
|
||||
+ hash_value_t value;
|
||||
+ struct kcm_ops_queue_entry *head = NULL;
|
||||
+
|
||||
+ key.type = HASH_KEY_ULONG;
|
||||
+ key.ul = uid;
|
||||
+
|
||||
+ ret = hash_lookup(wait_queue_hash, &key, &value);
|
||||
+ switch (ret) {
|
||||
+ case HASH_SUCCESS:
|
||||
+ /* The key with this UID already exists. Its value is request queue
|
||||
+ * for the UID, so let's just add the current request to the end
|
||||
+ * of the queue and wait for the previous requests to finish
|
||||
+ */
|
||||
+ if (value.type != HASH_VALUE_PTR) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected hash value type.\n");
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ head = talloc_get_type(value.ptr, struct kcm_ops_queue_entry);
|
||||
+ if (head == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid queue pointer\n");
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ entry->head = head;
|
||||
+ DLIST_ADD_END(head, entry, struct kcm_ops_queue_entry *);
|
||||
+
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "Waiting in queue\n");
|
||||
+ ret = EAGAIN;
|
||||
+ break;
|
||||
+
|
||||
+ case HASH_ERROR_KEY_NOT_FOUND:
|
||||
+ /* No request for this UID yet. Enqueue this request in case
|
||||
+ * another one comes in and return EOK to run the current request
|
||||
+ * immediatelly
|
||||
+ */
|
||||
+ entry->head = entry;
|
||||
+
|
||||
+ value.type = HASH_VALUE_PTR;
|
||||
+ value.ptr = entry;
|
||||
+
|
||||
+ ret = hash_enter(wait_queue_hash, &key, &value);
|
||||
+ if (ret != HASH_SUCCESS) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "hash_enter failed.\n");
|
||||
+ return EIO;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS,
|
||||
+ "Added a first request to the queue, running immediately\n");
|
||||
+ ret = EOK;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "hash_lookup failed.\n");
|
||||
+ return EIO;
|
||||
+ }
|
||||
+
|
||||
+ talloc_steal(wait_queue_hash, entry);
|
||||
+ talloc_set_destructor(entry, kcm_op_queue_entry_destructor);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+struct kcm_op_queue_state {
|
||||
+ struct kcm_ops_queue_entry *entry;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * Enqueue a request.
|
||||
+ *
|
||||
+ * If the request queue /for the given ID/ is empty, that is, if this
|
||||
+ * request is the first one in the queue, run the request immediatelly.
|
||||
+ *
|
||||
+ * Otherwise just add it to the queue and wait until the previous request
|
||||
+ * finishes and only at that point mark the current request as done, which
|
||||
+ * will trigger calling the recv function and allow the request to continue.
|
||||
+ */
|
||||
+struct tevent_req *kcm_op_queue_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ops_queue_ctx *qctx,
|
||||
+ struct cli_creds *client)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ struct tevent_req *req;
|
||||
+ struct kcm_op_queue_state *state;
|
||||
+ uid_t uid;
|
||||
+
|
||||
+ uid = cli_creds_get_uid(client);
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct kcm_op_queue_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ state->entry = talloc_zero(state, struct kcm_ops_queue_entry);
|
||||
+ if (state->entry == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto immediate;
|
||||
+ }
|
||||
+ state->entry->req = req;
|
||||
+ state->entry->uid = uid;
|
||||
+ state->entry->wait_queue_hash = qctx->wait_queue_hash;
|
||||
+
|
||||
+ DEBUG(SSSDBG_FUNC_DATA,
|
||||
+ "Adding request by %"SPRIuid" to the wait queue\n", uid);
|
||||
+
|
||||
+ ret = kcm_op_queue_add(qctx->wait_queue_hash, state->entry, uid);
|
||||
+ if (ret == EOK) {
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS,
|
||||
+ "Wait queue was empty, running immediately\n");
|
||||
+ goto immediate;
|
||||
+ } else if (ret != EAGAIN) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Cannot enqueue request [%d]: %s\n", ret, sss_strerror(ret));
|
||||
+ goto immediate;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "Waiting our turn in the queue\n");
|
||||
+ return req;
|
||||
+
|
||||
+immediate:
|
||||
+ if (ret == EOK) {
|
||||
+ tevent_req_done(req);
|
||||
+ } else {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ }
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * The queue recv function is called when this request is 'activated'. The queue
|
||||
+ * entry should be allocated on the same memory context as the enqueued request
|
||||
+ * to trigger freeing the kcm_ops_queue_entry structure destructor when the
|
||||
+ * parent request is done and its tevent_req freed. This would in turn unblock
|
||||
+ * the next request in the queue
|
||||
+ */
|
||||
+errno_t kcm_op_queue_recv(struct tevent_req *req,
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ struct kcm_ops_queue_entry **_entry)
|
||||
+{
|
||||
+ struct kcm_op_queue_state *state = tevent_req_data(req,
|
||||
+ struct kcm_op_queue_state);
|
||||
+
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ *_entry = talloc_steal(mem_ctx, state->entry);
|
||||
+ return EOK;
|
||||
+}
|
||||
diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c
|
||||
index 50e8cc635424e15d53e3c8d122c5525044f59c8a..2feaf51f227ce9d90f706229ce7ac201b282dc6f 100644
|
||||
--- a/src/responder/kcm/kcmsrv_ops.c
|
||||
+++ b/src/responder/kcm/kcmsrv_ops.c
|
||||
@@ -67,17 +67,21 @@ struct kcm_op {
|
||||
|
||||
struct kcm_cmd_state {
|
||||
struct kcm_op *op;
|
||||
+ struct tevent_context *ev;
|
||||
|
||||
+ struct kcm_ops_queue_entry *queue_entry;
|
||||
struct kcm_op_ctx *op_ctx;
|
||||
struct sss_iobuf *reply;
|
||||
|
||||
uint32_t op_ret;
|
||||
};
|
||||
|
||||
+static void kcm_cmd_queue_done(struct tevent_req *subreq);
|
||||
static void kcm_cmd_done(struct tevent_req *subreq);
|
||||
|
||||
struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
+ struct kcm_ops_queue_ctx *qctx,
|
||||
struct kcm_resp_ctx *kcm_data,
|
||||
struct cli_creds *client,
|
||||
struct kcm_data *input,
|
||||
@@ -93,6 +97,7 @@ struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
|
||||
return NULL;
|
||||
}
|
||||
state->op = op;
|
||||
+ state->ev = ev;
|
||||
|
||||
if (op == NULL) {
|
||||
ret = EINVAL;
|
||||
@@ -154,18 +159,43 @@ struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
|
||||
goto immediate;
|
||||
}
|
||||
|
||||
- subreq = op->fn_send(state, ev, state->op_ctx);
|
||||
+ subreq = kcm_op_queue_send(state, ev, qctx, client);
|
||||
if (subreq == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto immediate;
|
||||
}
|
||||
+ tevent_req_set_callback(subreq, kcm_cmd_queue_done, req);
|
||||
+ return req;
|
||||
+
|
||||
+immediate:
|
||||
+ tevent_req_error(req, ret);
|
||||
+ tevent_req_post(req, ev);
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static void kcm_cmd_queue_done(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
|
||||
+ struct kcm_cmd_state *state = tevent_req_data(req, struct kcm_cmd_state);
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ /* When this request finishes, it frees the queue_entry which unblocks
|
||||
+ * other requests by the same UID
|
||||
+ */
|
||||
+ ret = kcm_op_queue_recv(subreq, state, &state->queue_entry);
|
||||
+ talloc_zfree(subreq);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot acquire queue slot\n");
|
||||
+ tevent_req_error(req, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ subreq = state->op->fn_send(state, state->ev, state->op_ctx);
|
||||
+ if (subreq == NULL) {
|
||||
+ tevent_req_error(req, ENOMEM);
|
||||
+ return;
|
||||
+ }
|
||||
tevent_req_set_callback(subreq, kcm_cmd_done, req);
|
||||
- return req;
|
||||
-
|
||||
-immediate:
|
||||
- tevent_req_error(req, ret);
|
||||
- tevent_req_post(req, ev);
|
||||
- return req;
|
||||
}
|
||||
|
||||
static void kcm_cmd_done(struct tevent_req *subreq)
|
||||
diff --git a/src/responder/kcm/kcmsrv_ops.h b/src/responder/kcm/kcmsrv_ops.h
|
||||
index 8e6feaf56a10b73c8b6375aea9ef26c392b5b492..67d9f86026bf949548471f2280c130ebefd2f865 100644
|
||||
--- a/src/responder/kcm/kcmsrv_ops.h
|
||||
+++ b/src/responder/kcm/kcmsrv_ops.h
|
||||
@@ -34,6 +34,7 @@ const char *kcm_opt_name(struct kcm_op *op);
|
||||
|
||||
struct tevent_req *kcm_cmd_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
+ struct kcm_ops_queue_ctx *qctx,
|
||||
struct kcm_resp_ctx *kcm_data,
|
||||
struct cli_creds *client,
|
||||
struct kcm_data *input,
|
||||
diff --git a/src/responder/kcm/kcmsrv_pvt.h b/src/responder/kcm/kcmsrv_pvt.h
|
||||
index 74f30c00014105ed533744779b02c5d42523722d..f081a6bf0c6e40d2f8a83b07f9bbc2abacff359d 100644
|
||||
--- a/src/responder/kcm/kcmsrv_pvt.h
|
||||
+++ b/src/responder/kcm/kcmsrv_pvt.h
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
+#include <krb5/krb5.h>
|
||||
#include "responder/common/responder.h"
|
||||
|
||||
/*
|
||||
@@ -65,6 +66,7 @@ struct kcm_ctx {
|
||||
int fd_limit;
|
||||
char *socket_path;
|
||||
enum kcm_ccdb_be cc_be;
|
||||
+ struct kcm_ops_queue_ctx *qctx;
|
||||
|
||||
struct kcm_resp_ctx *kcm_data;
|
||||
};
|
||||
@@ -78,4 +80,22 @@ int kcm_connection_setup(struct cli_ctx *cctx);
|
||||
*/
|
||||
krb5_error_code sss2krb5_error(errno_t err);
|
||||
|
||||
+/* We enqueue all requests by the same UID to avoid concurrency issues
|
||||
+ * especially when performing multiple round-trips to sssd-secrets. In
|
||||
+ * future, we should relax the queue to allow multiple read-only operations
|
||||
+ * if no write operations are in progress.
|
||||
+ */
|
||||
+struct kcm_ops_queue_entry;
|
||||
+
|
||||
+struct kcm_ops_queue_ctx *kcm_ops_queue_create(TALLOC_CTX *mem_ctx);
|
||||
+
|
||||
+struct tevent_req *kcm_op_queue_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ops_queue_ctx *qctx,
|
||||
+ struct cli_creds *client);
|
||||
+
|
||||
+errno_t kcm_op_queue_recv(struct tevent_req *req,
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ struct kcm_ops_queue_entry **_entry);
|
||||
+
|
||||
#endif /* __KCMSRV_PVT_H__ */
|
||||
diff --git a/src/tests/cmocka/test_kcm_queue.c b/src/tests/cmocka/test_kcm_queue.c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ba0d2405629960df5c623848f3207b7c80fa948d
|
||||
--- /dev/null
|
||||
+++ b/src/tests/cmocka/test_kcm_queue.c
|
||||
@@ -0,0 +1,365 @@
|
||||
+/*
|
||||
+ Copyright (C) 2017 Red Hat
|
||||
+
|
||||
+ SSSD tests: Test KCM wait queue
|
||||
+
|
||||
+ 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 "config.h"
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <popt.h>
|
||||
+
|
||||
+#include "util/util.h"
|
||||
+#include "util/util_creds.h"
|
||||
+#include "tests/cmocka/common_mock.h"
|
||||
+#include "responder/kcm/kcmsrv_pvt.h"
|
||||
+
|
||||
+#define INVALID_ID -1
|
||||
+#define FAST_REQ_ID 0
|
||||
+#define SLOW_REQ_ID 1
|
||||
+
|
||||
+#define FAST_REQ_DELAY 1
|
||||
+#define SLOW_REQ_DELAY 2
|
||||
+
|
||||
+struct timed_request_state {
|
||||
+ struct tevent_context *ev;
|
||||
+ struct kcm_ops_queue_ctx *qctx;
|
||||
+ struct cli_creds *client;
|
||||
+ int delay;
|
||||
+ int req_id;
|
||||
+
|
||||
+ struct kcm_ops_queue_entry *queue_entry;
|
||||
+};
|
||||
+
|
||||
+static void timed_request_start(struct tevent_req *subreq);
|
||||
+static void timed_request_done(struct tevent_context *ev,
|
||||
+ struct tevent_timer *te,
|
||||
+ struct timeval current_time,
|
||||
+ void *pvt);
|
||||
+
|
||||
+static struct tevent_req *timed_request_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct kcm_ops_queue_ctx *qctx,
|
||||
+ struct cli_creds *client,
|
||||
+ int delay,
|
||||
+ int req_id)
|
||||
+{
|
||||
+ struct tevent_req *req;
|
||||
+ struct tevent_req *subreq;
|
||||
+ struct timed_request_state *state;
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state, struct timed_request_state);
|
||||
+ if (req == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ state->ev = ev;
|
||||
+ state->qctx = qctx;
|
||||
+ state->client = client;
|
||||
+ state->delay = delay;
|
||||
+ state->req_id = req_id;
|
||||
+
|
||||
+ DEBUG(SSSDBG_TRACE_ALL, "Request %p with delay %d\n", req, delay);
|
||||
+
|
||||
+ subreq = kcm_op_queue_send(state, ev, qctx, client);
|
||||
+ if (subreq == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ tevent_req_set_callback(subreq, timed_request_start, req);
|
||||
+
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static void timed_request_start(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct timeval tv;
|
||||
+ struct tevent_timer *timeout = NULL;
|
||||
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
||||
+ struct tevent_req);
|
||||
+ struct timed_request_state *state = tevent_req_data(req,
|
||||
+ struct timed_request_state);
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = kcm_op_queue_recv(subreq, state, &state->queue_entry);
|
||||
+ talloc_zfree(subreq);
|
||||
+ if (ret != EOK) {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ tv = tevent_timeval_current_ofs(state->delay, 0);
|
||||
+ timeout = tevent_add_timer(state->ev, state, tv, timed_request_done, req);
|
||||
+ if (timeout == NULL) {
|
||||
+ tevent_req_error(req, ENOMEM);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void timed_request_done(struct tevent_context *ev,
|
||||
+ struct tevent_timer *te,
|
||||
+ struct timeval current_time,
|
||||
+ void *pvt)
|
||||
+{
|
||||
+ struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
|
||||
+ DEBUG(SSSDBG_TRACE_ALL, "Request %p done\n", req);
|
||||
+ tevent_req_done(req);
|
||||
+}
|
||||
+
|
||||
+static errno_t timed_request_recv(struct tevent_req *req,
|
||||
+ int *req_id)
|
||||
+{
|
||||
+ struct timed_request_state *state = tevent_req_data(req,
|
||||
+ struct timed_request_state);
|
||||
+
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+ *req_id = state->req_id;
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+struct test_ctx {
|
||||
+ struct kcm_ops_queue_ctx *qctx;
|
||||
+ struct tevent_context *ev;
|
||||
+
|
||||
+ int *req_ids;
|
||||
+
|
||||
+ int num_requests;
|
||||
+ int finished_requests;
|
||||
+ bool done;
|
||||
+ errno_t error;
|
||||
+};
|
||||
+
|
||||
+static int setup_kcm_queue(void **state)
|
||||
+{
|
||||
+ struct test_ctx *tctx;
|
||||
+
|
||||
+ tctx = talloc_zero(NULL, struct test_ctx);
|
||||
+ assert_non_null(tctx);
|
||||
+
|
||||
+ tctx->ev = tevent_context_init(tctx);
|
||||
+ assert_non_null(tctx->ev);
|
||||
+
|
||||
+ tctx->qctx = kcm_ops_queue_create(tctx);
|
||||
+ assert_non_null(tctx->qctx);
|
||||
+
|
||||
+ *state = tctx;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int teardown_kcm_queue(void **state)
|
||||
+{
|
||||
+ struct test_ctx *tctx = talloc_get_type(*state, struct test_ctx);
|
||||
+ talloc_free(tctx);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void test_kcm_queue_done(struct tevent_req *req)
|
||||
+{
|
||||
+ struct test_ctx *test_ctx = tevent_req_callback_data(req,
|
||||
+ struct test_ctx);
|
||||
+ int req_id = INVALID_ID;
|
||||
+
|
||||
+ test_ctx->error = timed_request_recv(req, &req_id);
|
||||
+ talloc_zfree(req);
|
||||
+ if (test_ctx->error != EOK) {
|
||||
+ test_ctx->done = true;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (test_ctx->req_ids[test_ctx->finished_requests] != req_id) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Request %d finished, expected %d\n",
|
||||
+ req_id, test_ctx->req_ids[test_ctx->finished_requests]);
|
||||
+ test_ctx->error = EIO;
|
||||
+ test_ctx->done = true;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ test_ctx->finished_requests++;
|
||||
+ if (test_ctx->finished_requests == test_ctx->num_requests) {
|
||||
+ test_ctx->done = true;
|
||||
+ return;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Just make sure that a single pass through the queue works
|
||||
+ */
|
||||
+static void test_kcm_queue_single(void **state)
|
||||
+{
|
||||
+ struct test_ctx *test_ctx = talloc_get_type(*state, struct test_ctx);
|
||||
+ struct tevent_req *req;
|
||||
+ struct cli_creds client;
|
||||
+ static int req_ids[] = { 0 };
|
||||
+
|
||||
+ client.ucred.uid = getuid();
|
||||
+ client.ucred.gid = getgid();
|
||||
+
|
||||
+ req = timed_request_send(test_ctx,
|
||||
+ test_ctx->ev,
|
||||
+ test_ctx->qctx,
|
||||
+ &client, 1, 0);
|
||||
+ assert_non_null(req);
|
||||
+ tevent_req_set_callback(req, test_kcm_queue_done, test_ctx);
|
||||
+
|
||||
+ test_ctx->num_requests = 1;
|
||||
+ test_ctx->req_ids = req_ids;
|
||||
+
|
||||
+ while (test_ctx->done == false) {
|
||||
+ tevent_loop_once(test_ctx->ev);
|
||||
+ }
|
||||
+ assert_int_equal(test_ctx->error, EOK);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Test that multiple requests from the same ID wait for one another
|
||||
+ */
|
||||
+static void test_kcm_queue_multi_same_id(void **state)
|
||||
+{
|
||||
+ struct test_ctx *test_ctx = talloc_get_type(*state, struct test_ctx);
|
||||
+ struct tevent_req *req;
|
||||
+ struct cli_creds client;
|
||||
+ /* The slow request will finish first because request from
|
||||
+ * the same ID are serialized
|
||||
+ */
|
||||
+ static int req_ids[] = { SLOW_REQ_ID, FAST_REQ_ID };
|
||||
+
|
||||
+ client.ucred.uid = getuid();
|
||||
+ client.ucred.gid = getgid();
|
||||
+
|
||||
+ req = timed_request_send(test_ctx,
|
||||
+ test_ctx->ev,
|
||||
+ test_ctx->qctx,
|
||||
+ &client,
|
||||
+ SLOW_REQ_DELAY,
|
||||
+ SLOW_REQ_ID);
|
||||
+ assert_non_null(req);
|
||||
+ tevent_req_set_callback(req, test_kcm_queue_done, test_ctx);
|
||||
+
|
||||
+ req = timed_request_send(test_ctx,
|
||||
+ test_ctx->ev,
|
||||
+ test_ctx->qctx,
|
||||
+ &client,
|
||||
+ FAST_REQ_DELAY,
|
||||
+ FAST_REQ_ID);
|
||||
+ assert_non_null(req);
|
||||
+ tevent_req_set_callback(req, test_kcm_queue_done, test_ctx);
|
||||
+
|
||||
+ test_ctx->num_requests = 2;
|
||||
+ test_ctx->req_ids = req_ids;
|
||||
+
|
||||
+ while (test_ctx->done == false) {
|
||||
+ tevent_loop_once(test_ctx->ev);
|
||||
+ }
|
||||
+ assert_int_equal(test_ctx->error, EOK);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Test that multiple requests from different IDs don't wait for one
|
||||
+ * another and can run concurrently
|
||||
+ */
|
||||
+static void test_kcm_queue_multi_different_id(void **state)
|
||||
+{
|
||||
+ struct test_ctx *test_ctx = talloc_get_type(*state, struct test_ctx);
|
||||
+ struct tevent_req *req;
|
||||
+ struct cli_creds client;
|
||||
+ /* In this test, the fast request will finish sooner because
|
||||
+ * both requests are from different IDs, allowing them to run
|
||||
+ * concurrently
|
||||
+ */
|
||||
+ static int req_ids[] = { FAST_REQ_ID, SLOW_REQ_ID };
|
||||
+
|
||||
+ client.ucred.uid = getuid();
|
||||
+ client.ucred.gid = getgid();
|
||||
+
|
||||
+ req = timed_request_send(test_ctx,
|
||||
+ test_ctx->ev,
|
||||
+ test_ctx->qctx,
|
||||
+ &client,
|
||||
+ SLOW_REQ_DELAY,
|
||||
+ SLOW_REQ_ID);
|
||||
+ assert_non_null(req);
|
||||
+ tevent_req_set_callback(req, test_kcm_queue_done, test_ctx);
|
||||
+
|
||||
+ client.ucred.uid = getuid() + 1;
|
||||
+ client.ucred.gid = getgid() + 1;
|
||||
+
|
||||
+ req = timed_request_send(test_ctx,
|
||||
+ test_ctx->ev,
|
||||
+ test_ctx->qctx,
|
||||
+ &client,
|
||||
+ FAST_REQ_DELAY,
|
||||
+ FAST_REQ_ID);
|
||||
+ assert_non_null(req);
|
||||
+ tevent_req_set_callback(req, test_kcm_queue_done, test_ctx);
|
||||
+
|
||||
+ test_ctx->num_requests = 2;
|
||||
+ test_ctx->req_ids = req_ids;
|
||||
+
|
||||
+ while (test_ctx->done == false) {
|
||||
+ tevent_loop_once(test_ctx->ev);
|
||||
+ }
|
||||
+ assert_int_equal(test_ctx->error, EOK);
|
||||
+}
|
||||
+
|
||||
+int main(int argc, const char *argv[])
|
||||
+{
|
||||
+ poptContext pc;
|
||||
+ int opt;
|
||||
+ int rv;
|
||||
+ struct poptOption long_options[] = {
|
||||
+ POPT_AUTOHELP
|
||||
+ SSSD_DEBUG_OPTS
|
||||
+ POPT_TABLEEND
|
||||
+ };
|
||||
+
|
||||
+ const struct CMUnitTest tests[] = {
|
||||
+ cmocka_unit_test_setup_teardown(test_kcm_queue_single,
|
||||
+ setup_kcm_queue,
|
||||
+ teardown_kcm_queue),
|
||||
+ cmocka_unit_test_setup_teardown(test_kcm_queue_multi_same_id,
|
||||
+ setup_kcm_queue,
|
||||
+ teardown_kcm_queue),
|
||||
+ cmocka_unit_test_setup_teardown(test_kcm_queue_multi_different_id,
|
||||
+ setup_kcm_queue,
|
||||
+ teardown_kcm_queue),
|
||||
+ };
|
||||
+
|
||||
+ /* Set debug level to invalid value so we can deside if -d 0 was used. */
|
||||
+ debug_level = SSSDBG_INVALID;
|
||||
+
|
||||
+ pc = poptGetContext(argv[0], argc, argv, long_options, 0);
|
||||
+ while((opt = poptGetNextOpt(pc)) != -1) {
|
||||
+ switch(opt) {
|
||||
+ default:
|
||||
+ fprintf(stderr, "\nInvalid option %s: %s\n\n",
|
||||
+ poptBadOption(pc, 0), poptStrerror(opt));
|
||||
+ poptPrintUsage(pc, stderr, 0);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+ poptFreeContext(pc);
|
||||
+
|
||||
+ DEBUG_CLI_INIT(debug_level);
|
||||
+
|
||||
+ /* Even though normally the tests should clean up after themselves
|
||||
+ * they might not after a failed run. Remove the old db to be sure */
|
||||
+ tests_set_cwd();
|
||||
+
|
||||
+ rv = cmocka_run_group_tests(tests, NULL, NULL);
|
||||
+
|
||||
+ return rv;
|
||||
+}
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,55 +0,0 @@
|
||||
From e89ba95737202d551db2c9524127e6c4cf308796 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 21 Mar 2017 14:26:54 +0100
|
||||
Subject: [PATCH 38/97] KCM: Idle-terminate the responder if the secrets back
|
||||
end is used
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Existing with memory database would be fatal as we keep the ccaches in
|
||||
memory then, but if the ccaches are stored in sssd-secrets, we can just
|
||||
exit on idle.
|
||||
|
||||
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
---
|
||||
src/config/cfg_rules.ini | 1 +
|
||||
src/responder/kcm/kcm.c | 9 +++++++++
|
||||
2 files changed, 10 insertions(+)
|
||||
|
||||
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
|
||||
index 67a5d1f5ad447a942b437ffd04a7f5d7cfe77d7f..933ebccd828189d923d2186753dfbc0b5c0814ce 100644
|
||||
--- a/src/config/cfg_rules.ini
|
||||
+++ b/src/config/cfg_rules.ini
|
||||
@@ -281,6 +281,7 @@ option = client_idle_timeout
|
||||
option = description
|
||||
option = socket_path
|
||||
option = ccache_storage
|
||||
+option = responder_idle_timeout
|
||||
|
||||
[rule/allowed_domain_options]
|
||||
validator = ini_allowed_options
|
||||
diff --git a/src/responder/kcm/kcm.c b/src/responder/kcm/kcm.c
|
||||
index 3ee978066c589a5cc38b0ae358f741d389d00e7a..2202f96381a2622a2c5433e281172287b325f960 100644
|
||||
--- a/src/responder/kcm/kcm.c
|
||||
+++ b/src/responder/kcm/kcm.c
|
||||
@@ -133,6 +133,15 @@ static int kcm_get_config(struct kcm_ctx *kctx)
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ if (kctx->cc_be == CCDB_BE_SECRETS) {
|
||||
+ ret = responder_setup_idle_timeout_config(kctx->rctx);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "Cannot set up idle responder timeout\n");
|
||||
+ /* Not fatal */
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
kctx->qctx = kcm_ops_queue_create(kctx);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,34 +0,0 @@
|
||||
From 00172861b6908a72c41046e1b2b48d2b009127dd Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Ville=20Skytt=C3=A4?= <ville.skytta@iki.fi>
|
||||
Date: Wed, 22 Mar 2017 20:32:21 +0000
|
||||
Subject: [PATCH 39/97] SSSDConfig: Python 3.6 invalid escape sequence
|
||||
deprecation fix
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
https://docs.python.org/3/whatsnew/3.6.html#deprecated-python-behavior
|
||||
|
||||
Merges: https://pagure.io/SSSD/sssd/pull-request/3346
|
||||
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/config/SSSDConfig/__init__.py.in | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
|
||||
index 03a1a43336604bb815626e64cb54052bdf87acf2..29e9b4fae6835db4ccb9937fd93457d462e4a15d 100644
|
||||
--- a/src/config/SSSDConfig/__init__.py.in
|
||||
+++ b/src/config/SSSDConfig/__init__.py.in
|
||||
@@ -483,7 +483,7 @@ class SSSDConfigSchema(SSSDChangeConf):
|
||||
self.readfp(fd)
|
||||
fd.close()
|
||||
# Read in the provider files
|
||||
- for file in filter(lambda f: re.search('^sssd-.*\.conf$', f),
|
||||
+ for file in filter(lambda f: re.search(r'^sssd-.*\.conf$', f),
|
||||
os.listdir(schemaplugindir)):
|
||||
fd = open(schemaplugindir+ "/" + file)
|
||||
self.readfp(fd)
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 7c67679ba86682d8c2afea404ec0229641a7f473 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Slebodnik <lslebodn@redhat.com>
|
||||
Date: Mon, 27 Mar 2017 11:59:01 +0200
|
||||
Subject: [PATCH 40/97] CONFIGURE: Fix fallback if pkg-config for uuid is
|
||||
missing
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
---
|
||||
src/external/libuuid.m4 | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/external/libuuid.m4 b/src/external/libuuid.m4
|
||||
index 55411a2118bd787c9d50ba61f9cb791e1c76088d..323521c9224e443f40a15b417038d2dcea9b66f3 100644
|
||||
--- a/src/external/libuuid.m4
|
||||
+++ b/src/external/libuuid.m4
|
||||
@@ -4,7 +4,7 @@ AC_SUBST(UUID_CFLAGS)
|
||||
PKG_CHECK_MODULES([UUID], [uuid], [found_uuid=yes], [found_uuid=no])
|
||||
|
||||
SSS_AC_EXPAND_LIB_DIR()
|
||||
-AS_IF([test x"$found_uuid" = xyes],
|
||||
+AS_IF([test x"$found_uuid" != xyes],
|
||||
[AC_CHECK_HEADERS([uuid/uuid.h],
|
||||
[AC_CHECK_LIB([uuid],
|
||||
[uuid_generate],
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,52 +0,0 @@
|
||||
From 8e785c7478e1a79179842106a62f3f85118b6690 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Slebodnik <lslebodn@redhat.com>
|
||||
Date: Tue, 28 Mar 2017 12:18:13 +0200
|
||||
Subject: [PATCH 41/97] intg: fix configure failure with strict cflags
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The warning -Wstrict-prototypes is a part of AM_CFLAGS which was appended
|
||||
for CFLAGS in make target intgcheck-prepare. And combination with
|
||||
strict CFLAGS in environment variable (e.g. -Werror) caused failures.
|
||||
|
||||
sh$ CFLAGS="-Werror" make intgcheck-prepare
|
||||
|
||||
checking for gcc... gcc
|
||||
checking whether the C compiler works... no
|
||||
configure: error: in `/home/build/sssd/ci-build-debug/intg/bld':
|
||||
configure: error: C compiler cannot create executables
|
||||
|
||||
configure:3719: checking whether the C compiler works
|
||||
configure:3741: gcc -g3 -O2 -Werror -D_FILE_OFFSET_BITS=64
|
||||
-D_LARGEFILE_SOURCE -Wall -Wshadow -Wstrict-prototypes
|
||||
-Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings
|
||||
-Wundef -Werror-implicit-function-declaration
|
||||
-Winit-self -Wmissing-include-dirs -fno-strict-aliasing
|
||||
-std=gnu99 -DKCM_PEER_UID=1000 conftest.c >&5
|
||||
conftest.c:11:1: error: function declaration isn't a prototype [-Werror=strict-prototypes]
|
||||
main ()
|
||||
^~~~
|
||||
cc1: all warnings being treated as errors
|
||||
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 91afdd669aa11a3cc316588d3b51d7e8e9c91cb8..359feddef298b0013c726409b7ba8b86504abf09 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -3486,7 +3486,7 @@ intgcheck-prepare:
|
||||
--without-semanage \
|
||||
--enable-files-domain \
|
||||
$(INTGCHECK_CONFIGURE_FLAGS) \
|
||||
- CFLAGS="$$CFLAGS $(AM_CFLAGS) -DKCM_PEER_UID=$$(id -u)"; \
|
||||
+ CFLAGS="$$CFLAGS -DKCM_PEER_UID=$$(id -u)"; \
|
||||
$(MAKE) $(AM_MAKEFLAGS) ; \
|
||||
: Force single-thread install to workaround concurrency issues; \
|
||||
$(MAKE) $(AM_MAKEFLAGS) -j1 install; \
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,54 +0,0 @@
|
||||
From f75ba99fc8dd64e45af2f642d9fb7660860fd28f Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Slebodnik <lslebodn@redhat.com>
|
||||
Date: Mon, 27 Mar 2017 14:44:29 +0200
|
||||
Subject: [PATCH 42/97] intg: Remove bashism from intgcheck-prepare
|
||||
|
||||
env variable UID is not defined in all shells (eg. dash)
|
||||
We also need to move invocation of "id -u" before nss_wraper
|
||||
is enabled otherwise we would get root instead of real user.
|
||||
|
||||
=================================== FAILURES ===================================
|
||||
________________________ test_kcm_mem_init_list_destroy ________________________
|
||||
Traceback (most recent call last):
|
||||
File "/home/build/sssd/src/tests/intg/test_kcm.py", line 198, in test_kcm_mem_init_list_destroy
|
||||
kcm_init_list_destroy(testenv)
|
||||
File "/home/build/sssd/src/tests/intg/test_kcm.py", line 183, in kcm_init_list_destroy
|
||||
exp_ccname = testenv.ccname()
|
||||
File "/home/build/sssd/src/tests/intg/test_kcm.py", line 45, in ccname
|
||||
my_uid = self.my_uid()
|
||||
File "/home/build/sssd/src/tests/intg/test_kcm.py", line 41, in my_uid
|
||||
return int(s_myuid)
|
||||
ValueError: invalid literal for int() with base 10: ''
|
||||
|
||||
And we already use different approach in top level Makefile.am
|
||||
3488) $(INTGCHECK_CONFIGURE_FLAGS) \
|
||||
3489) CFLAGS="$$CFLAGS $(AM_CFLAGS) -DKCM_PEER_UID=$$(id -u)"; \
|
||||
3490) $(MAKE) $(AM_MAKEFLAGS) ; \
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/tests/intg/Makefile.am | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am
|
||||
index 8526beace09b15c99aa27ac98d5038d1980f6a71..8566106e9017a8d3c9e7a3898a3a886e2966e346 100644
|
||||
--- a/src/tests/intg/Makefile.am
|
||||
+++ b/src/tests/intg/Makefile.am
|
||||
@@ -76,6 +76,7 @@ intgcheck-installed: config.py passwd group
|
||||
PATH="$(abs_builddir):$(abs_srcdir):$$PATH" \
|
||||
PYTHONPATH="$(abs_builddir):$(abs_srcdir)" \
|
||||
LDB_MODULES_PATH="$(DESTDIR)$(ldblibdir)" \
|
||||
+ NON_WRAPPED_UID=$$(id -u) \
|
||||
LD_PRELOAD="$$nss_wrapper $$uid_wrapper" \
|
||||
NSS_WRAPPER_PASSWD="$(abs_builddir)/passwd" \
|
||||
NSS_WRAPPER_GROUP="$(abs_builddir)/group" \
|
||||
@@ -83,6 +84,5 @@ intgcheck-installed: config.py passwd group
|
||||
NSS_WRAPPER_MODULE_FN_PREFIX="sss" \
|
||||
UID_WRAPPER=1 \
|
||||
UID_WRAPPER_ROOT=1 \
|
||||
- NON_WRAPPED_UID=$$(echo $$UID) \
|
||||
fakeroot $(PYTHON2) $(PYTEST) -v --tb=native $(INTGCHECK_PYTEST_ARGS) .
|
||||
rm -f $(DESTDIR)$(logpath)/*
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,127 +0,0 @@
|
||||
From e0e038218580166648ac24f23180f0f4c2769d99 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
|
||||
Date: Tue, 28 Mar 2017 18:33:46 +0200
|
||||
Subject: [PATCH 43/97] UTIL: Introduce subdomain_create_conf_path()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This is a utility function that replaces the create_subdom_conf_path().
|
||||
Differently than the latter, it only takes one parameter and is going to
|
||||
be used in a few different places (thus adding it to util.h).
|
||||
|
||||
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Reviewed-by: Lukas Slebodnik <lslebodn@redhat.com>
|
||||
---
|
||||
src/providers/ad/ad_common.c | 7 -------
|
||||
src/providers/ad/ad_common.h | 4 ----
|
||||
src/providers/ad/ad_subdomains.c | 4 +---
|
||||
src/providers/ipa/ipa_subdomains_server.c | 4 +---
|
||||
src/util/domain_info_utils.c | 15 +++++++++++++++
|
||||
src/util/util.h | 3 +++
|
||||
6 files changed, 20 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
|
||||
index ec952d3bb4587516ea26fd27c212d5620e2f3dda..f893b748a2ddcff1eab6e8d919d2aa950b825446 100644
|
||||
--- a/src/providers/ad/ad_common.c
|
||||
+++ b/src/providers/ad/ad_common.c
|
||||
@@ -33,13 +33,6 @@ errno_t ad_set_search_bases(struct sdap_options *id_opts);
|
||||
static errno_t ad_set_sdap_options(struct ad_options *ad_opts,
|
||||
struct sdap_options *id_opts);
|
||||
|
||||
-char *create_subdom_conf_path(TALLOC_CTX *mem_ctx,
|
||||
- const char *conf_path,
|
||||
- const char *subdom_name)
|
||||
-{
|
||||
- return talloc_asprintf(mem_ctx, "%s/%s", conf_path, subdom_name);
|
||||
-}
|
||||
-
|
||||
static struct sdap_options *
|
||||
ad_create_default_sdap_options(TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
|
||||
index e02b932cd2da737254de8417d5c82fcdcf14e8d7..2981550f6c390929501ec8942e861b16ea0a5cb0 100644
|
||||
--- a/src/providers/ad/ad_common.h
|
||||
+++ b/src/providers/ad/ad_common.h
|
||||
@@ -99,10 +99,6 @@ struct ad_options {
|
||||
struct be_nsupdate_ctx *dyndns_ctx;
|
||||
};
|
||||
|
||||
-char *create_subdom_conf_path(TALLOC_CTX *mem_ctx,
|
||||
- const char *conf_path,
|
||||
- const char *subdom_name);
|
||||
-
|
||||
errno_t
|
||||
ad_get_common_options(TALLOC_CTX *mem_ctx,
|
||||
struct confdb_ctx *cdb,
|
||||
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
|
||||
index 156ecab4272029d69c8b596eff041498a7524ce4..eecae9c9ca82ad67874c13a3c7b7c617d6232d5c 100644
|
||||
--- a/src/providers/ad/ad_subdomains.c
|
||||
+++ b/src/providers/ad/ad_subdomains.c
|
||||
@@ -171,9 +171,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
- subdom_conf_path = create_subdom_conf_path(id_ctx,
|
||||
- be_ctx->conf_path,
|
||||
- subdom->name);
|
||||
+ subdom_conf_path = subdomain_create_conf_path(id_ctx, subdom);
|
||||
if (subdom_conf_path == NULL) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "subdom_conf_path failed\n");
|
||||
return ENOMEM;
|
||||
diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
|
||||
index ae3baf036e4278fb67d86b42742fb7e80b46724e..e8ee30392d84f84e30bcdaa3d2110ba130b1ad73 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains_server.c
|
||||
+++ b/src/providers/ipa/ipa_subdomains_server.c
|
||||
@@ -176,9 +176,7 @@ static struct ad_options *ipa_ad_options_new(struct be_ctx *be_ctx,
|
||||
forest_realm = subdom->forest_root->realm;
|
||||
forest = subdom->forest_root->forest;
|
||||
|
||||
- subdom_conf_path = create_subdom_conf_path(id_ctx,
|
||||
- be_ctx->conf_path,
|
||||
- subdom->name);
|
||||
+ subdom_conf_path = subdomain_create_conf_path(id_ctx, subdom);
|
||||
if (subdom_conf_path == NULL) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "subdom_conf_path failed\n");
|
||||
return NULL;
|
||||
diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
|
||||
index 6ef6bcfb8c078a360673b6bdd2364fc2918cb324..a7f118842aa8ba870143b2f2b425a3e3c0ea5a78 100644
|
||||
--- a/src/util/domain_info_utils.c
|
||||
+++ b/src/util/domain_info_utils.c
|
||||
@@ -870,3 +870,18 @@ bool is_email_from_domain(const char *email, struct sss_domain_info *dom)
|
||||
|
||||
return false;
|
||||
}
|
||||
+
|
||||
+char *subdomain_create_conf_path(TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_domain_info *subdomain)
|
||||
+{
|
||||
+ if (!IS_SUBDOMAIN(subdomain)) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "The domain \"%s\" is not a subdomain.\n",
|
||||
+ subdomain->name);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return talloc_asprintf(mem_ctx, CONFDB_DOMAIN_PATH_TMPL "/%s",
|
||||
+ subdomain->parent->name,
|
||||
+ subdomain->name);
|
||||
+}
|
||||
diff --git a/src/util/util.h b/src/util/util.h
|
||||
index a2dc89b8ddb999437eda551ac17af28672d8759c..82760940269ad8883e725e3a5cf463486c9cfd36 100644
|
||||
--- a/src/util/util.h
|
||||
+++ b/src/util/util.h
|
||||
@@ -551,6 +551,9 @@ find_domain_by_object_name(struct sss_domain_info *domain,
|
||||
bool subdomain_enumerates(struct sss_domain_info *parent,
|
||||
const char *sd_name);
|
||||
|
||||
+char *subdomain_create_conf_path(TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_domain_info *subdomain);
|
||||
+
|
||||
errno_t sssd_domain_init(TALLOC_CTX *mem_ctx,
|
||||
struct confdb_ctx *cdb,
|
||||
const char *domain_name,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,531 +0,0 @@
|
||||
From a63d74f65db2db7389cd373cb37adcdaaa2d56ea Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
|
||||
Date: Thu, 23 Mar 2017 13:14:56 +0100
|
||||
Subject: [PATCH 44/97] SUBDOMAINS: Allow use_fully_qualified_names for
|
||||
subdomains
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Allow option use_fully_qualified_names in subdomain section.
|
||||
This option was recently added to subdomain_inherit.
|
||||
|
||||
Resolves:
|
||||
https://pagure.io/SSSD/sssd/issue/3337
|
||||
|
||||
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
---
|
||||
src/db/sysdb.h | 3 +-
|
||||
src/db/sysdb_private.h | 3 +-
|
||||
src/db/sysdb_subdomains.c | 63 +++++++++++++++++++++++++--
|
||||
src/man/sssd.conf.5.xml | 3 +-
|
||||
src/providers/ad/ad_subdomains.c | 3 +-
|
||||
src/providers/ipa/ipa_subdomains.c | 10 +++--
|
||||
src/responder/common/responder_get_domains.c | 9 ++--
|
||||
src/tests/cmocka/test_fqnames.c | 2 +-
|
||||
src/tests/cmocka/test_ipa_subdomains_server.c | 2 +-
|
||||
src/tests/cmocka/test_nss_srv.c | 6 ++-
|
||||
src/tests/cmocka/test_sysdb_subdomains.c | 25 ++++++-----
|
||||
src/tests/sysdb-tests.c | 14 +++---
|
||||
src/tools/common/sss_tools.c | 2 +-
|
||||
src/tools/sss_cache.c | 2 +-
|
||||
14 files changed, 107 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
|
||||
index 0cbb2c5c02355e9e9a4e73b075f92d16e4855045..6762b51bee02911fb97d5d393fad2495504ee5ad 100644
|
||||
--- a/src/db/sysdb.h
|
||||
+++ b/src/db/sysdb.h
|
||||
@@ -494,7 +494,8 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb,
|
||||
uint32_t trust_direction,
|
||||
struct ldb_message_element *upn_suffixes);
|
||||
|
||||
-errno_t sysdb_update_subdomains(struct sss_domain_info *domain);
|
||||
+errno_t sysdb_update_subdomains(struct sss_domain_info *domain,
|
||||
+ struct confdb_ctx *confdb);
|
||||
|
||||
errno_t sysdb_master_domain_update(struct sss_domain_info *domain);
|
||||
|
||||
diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h
|
||||
index bfd24799950ab3b31d57df11b8f91c0b2572f13a..dfddd2dda9e593bd02d52dee7d06f520a11bbdf6 100644
|
||||
--- a/src/db/sysdb_private.h
|
||||
+++ b/src/db/sysdb_private.h
|
||||
@@ -191,7 +191,8 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
|
||||
bool enumerate,
|
||||
const char *forest,
|
||||
const char **upn_suffixes,
|
||||
- uint32_t trust_direction);
|
||||
+ uint32_t trust_direction,
|
||||
+ struct confdb_ctx *confdb);
|
||||
|
||||
/* Helper functions to deal with the timestamp cache should not be used
|
||||
* outside the sysdb itself. The timestamp cache should be completely
|
||||
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
|
||||
index 01f49763b712769f4f74df47961526e5b1514cd4..916dbba153d8c08837425f6fd29a20f5a6aa9fc9 100644
|
||||
--- a/src/db/sysdb_subdomains.c
|
||||
+++ b/src/db/sysdb_subdomains.c
|
||||
@@ -23,6 +23,10 @@
|
||||
#include "util/util.h"
|
||||
#include "db/sysdb_private.h"
|
||||
|
||||
+static errno_t
|
||||
+check_subdom_config_file(struct confdb_ctx *confdb,
|
||||
+ struct sss_domain_info *subdomain);
|
||||
+
|
||||
struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
|
||||
struct sss_domain_info *parent,
|
||||
const char *name,
|
||||
@@ -33,10 +37,12 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
|
||||
bool enumerate,
|
||||
const char *forest,
|
||||
const char **upn_suffixes,
|
||||
- uint32_t trust_direction)
|
||||
+ uint32_t trust_direction,
|
||||
+ struct confdb_ctx *confdb)
|
||||
{
|
||||
struct sss_domain_info *dom;
|
||||
bool inherit_option;
|
||||
+ errno_t ret;
|
||||
|
||||
DEBUG(SSSDBG_TRACE_FUNC,
|
||||
"Creating [%s] as subdomain of [%s]!\n", name, parent->name);
|
||||
@@ -160,6 +166,17 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
dom->sysdb = parent->sysdb;
|
||||
|
||||
+ if (confdb != NULL) {
|
||||
+ /* If confdb was provided, also check for sssd.conf */
|
||||
+ ret = check_subdom_config_file(confdb, dom);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Failed to read subdomain configuration [%d]: %s",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
return dom;
|
||||
|
||||
fail:
|
||||
@@ -167,6 +184,45 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static errno_t
|
||||
+check_subdom_config_file(struct confdb_ctx *confdb,
|
||||
+ struct sss_domain_info *subdomain)
|
||||
+{
|
||||
+ char *sd_conf_path;
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ sd_conf_path = subdomain_create_conf_path(tmp_ctx, subdomain);
|
||||
+ if (sd_conf_path == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* use_fully_qualified_names */
|
||||
+ ret = confdb_get_bool(confdb, sd_conf_path, CONFDB_DOMAIN_FQ,
|
||||
+ true, &subdomain->fqnames);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Failed to get %s option for the subdomain: %s\n",
|
||||
+ CONFDB_DOMAIN_FQ, subdomain->name);
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(SSSDBG_CONF_SETTINGS, "%s/%s has value %s\n",
|
||||
+ sd_conf_path, CONFDB_DOMAIN_FQ,
|
||||
+ subdomain->fqnames ? "TRUE" : "FALSE");
|
||||
+
|
||||
+ ret = EOK;
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static bool is_forest_root(struct sss_domain_info *d)
|
||||
{
|
||||
if (d->forest == NULL) {
|
||||
@@ -232,7 +288,8 @@ static void link_forest_roots(struct sss_domain_info *domain)
|
||||
}
|
||||
}
|
||||
|
||||
-errno_t sysdb_update_subdomains(struct sss_domain_info *domain)
|
||||
+errno_t sysdb_update_subdomains(struct sss_domain_info *domain,
|
||||
+ struct confdb_ctx *confdb)
|
||||
{
|
||||
int i;
|
||||
errno_t ret;
|
||||
@@ -451,7 +508,7 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain)
|
||||
if (dom == NULL) {
|
||||
dom = new_subdomain(domain, domain, name, realm,
|
||||
flat, id, mpg, enumerate, forest,
|
||||
- upn_suffixes, trust_direction);
|
||||
+ upn_suffixes, trust_direction, confdb);
|
||||
if (dom == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto done;
|
||||
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
|
||||
index 284402bc00d37c6c33bf195d2bd719300f265851..1c27742cf0c1b6ffad23ab5b044bf4a168ed8f69 100644
|
||||
--- a/src/man/sssd.conf.5.xml
|
||||
+++ b/src/man/sssd.conf.5.xml
|
||||
@@ -2780,7 +2780,8 @@ subdomain_inherit = ldap_purge_cache_timeout
|
||||
<para>ldap_service_search_base,</para>
|
||||
<para>ad_server,</para>
|
||||
<para>ad_backup_server,</para>
|
||||
- <para>ad_site.</para>
|
||||
+ <para>ad_site,</para>
|
||||
+ <para>use_fully_qualified_names</para>
|
||||
<para>
|
||||
For more details about these options see their individual description
|
||||
in the manual page.
|
||||
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
|
||||
index eecae9c9ca82ad67874c13a3c7b7c617d6232d5c..bc659b2cb0a02723437d24d0021ec3592381e84c 100644
|
||||
--- a/src/providers/ad/ad_subdomains.c
|
||||
+++ b/src/providers/ad/ad_subdomains.c
|
||||
@@ -656,7 +656,8 @@ static errno_t ad_subdom_reinit(struct ad_subdomains_ctx *subdoms_ctx)
|
||||
/* Just continue */
|
||||
}
|
||||
|
||||
- ret = sysdb_update_subdomains(subdoms_ctx->be_ctx->domain);
|
||||
+ ret = sysdb_update_subdomains(subdoms_ctx->be_ctx->domain,
|
||||
+ subdoms_ctx->be_ctx->cdb);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_subdomains failed.\n");
|
||||
return ret;
|
||||
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
|
||||
index 7537550606ef09c0b87a80932c75aa4f93c0efab..a07b88fe2f499353293ba90345552413c9792f4b 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains.c
|
||||
+++ b/src/providers/ipa/ipa_subdomains.c
|
||||
@@ -126,7 +126,7 @@ ipa_subdom_reinit(struct ipa_subdomains_ctx *ctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ret = sysdb_update_subdomains(ctx->be_ctx->domain);
|
||||
+ ret = sysdb_update_subdomains(ctx->be_ctx->domain, ctx->be_ctx->cdb);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_subdomains failed.\n");
|
||||
return ret;
|
||||
@@ -780,7 +780,8 @@ done:
|
||||
static errno_t ipa_apply_view(struct sss_domain_info *domain,
|
||||
struct ipa_id_ctx *ipa_id_ctx,
|
||||
const char *view_name,
|
||||
- bool read_at_init)
|
||||
+ bool read_at_init,
|
||||
+ struct confdb_ctx *confdb)
|
||||
{
|
||||
const char *current = ipa_id_ctx->view_name;
|
||||
struct sysdb_ctx *sysdb = domain->sysdb;
|
||||
@@ -876,7 +877,7 @@ static errno_t ipa_apply_view(struct sss_domain_info *domain,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- ret = sysdb_update_subdomains(domain);
|
||||
+ ret = sysdb_update_subdomains(domain, confdb);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_subdomains failed "
|
||||
"[%d]: %s\n", ret, sss_strerror(ret));
|
||||
@@ -1654,7 +1655,8 @@ static void ipa_subdomains_view_name_done(struct tevent_req *subreq)
|
||||
|
||||
ret = ipa_apply_view(state->sd_ctx->be_ctx->domain,
|
||||
state->sd_ctx->ipa_id_ctx, view_name,
|
||||
- state->sd_ctx->view_read_at_init);
|
||||
+ state->sd_ctx->view_read_at_init,
|
||||
+ state->sd_ctx->be_ctx->cdb);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set view [%d]: %s\n",
|
||||
ret, sss_strerror(ret));
|
||||
diff --git a/src/responder/common/responder_get_domains.c b/src/responder/common/responder_get_domains.c
|
||||
index 0f39d107dad6c458785b1b8d708e60d7c34e3901..0f9c01214631200f9687635f6302fa5c07e8a1fe 100644
|
||||
--- a/src/responder/common/responder_get_domains.c
|
||||
+++ b/src/responder/common/responder_get_domains.c
|
||||
@@ -126,7 +126,8 @@ get_next_domain_recv(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
/* ====== Iterate over all domains, searching for their subdomains ======= */
|
||||
-static errno_t process_subdomains(struct sss_domain_info *dom);
|
||||
+static errno_t process_subdomains(struct sss_domain_info *dom,
|
||||
+ struct confdb_ctx *confdb);
|
||||
static void set_time_of_last_request(struct resp_ctx *rctx);
|
||||
static errno_t check_last_request(struct resp_ctx *rctx, const char *hint);
|
||||
|
||||
@@ -234,7 +235,7 @@ sss_dp_get_domains_process(struct tevent_req *subreq)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- ret = process_subdomains(state->dom);
|
||||
+ ret = process_subdomains(state->dom, state->rctx->cdb);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "process_subdomains failed, "
|
||||
"trying next domain.\n");
|
||||
@@ -270,7 +271,7 @@ fail:
|
||||
}
|
||||
|
||||
static errno_t
|
||||
-process_subdomains(struct sss_domain_info *domain)
|
||||
+process_subdomains(struct sss_domain_info *domain, struct confdb_ctx *confdb)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -288,7 +289,7 @@ process_subdomains(struct sss_domain_info *domain)
|
||||
/* Retrieve all subdomains of this domain from sysdb
|
||||
* and create their struct sss_domain_info representations
|
||||
*/
|
||||
- ret = sysdb_update_subdomains(domain);
|
||||
+ ret = sysdb_update_subdomains(domain, confdb);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_FUNC_DATA, "sysdb_update_subdomains failed.\n");
|
||||
goto done;
|
||||
diff --git a/src/tests/cmocka/test_fqnames.c b/src/tests/cmocka/test_fqnames.c
|
||||
index 19788248a39774bb4509363145ac4ce0815b7d28..0ed42a597b7787635c4971b4f1c3d9976949ccd2 100644
|
||||
--- a/src/tests/cmocka/test_fqnames.c
|
||||
+++ b/src/tests/cmocka/test_fqnames.c
|
||||
@@ -309,7 +309,7 @@ static int parse_name_test_setup(void **state)
|
||||
* discovered
|
||||
*/
|
||||
test_ctx->subdom = new_subdomain(dom, dom, SUBDOMNAME, NULL, SUBFLATNAME,
|
||||
- NULL, false, false, NULL, NULL, 0);
|
||||
+ NULL, false, false, NULL, NULL, 0, NULL);
|
||||
assert_non_null(test_ctx->subdom);
|
||||
|
||||
check_leaks_push(test_ctx);
|
||||
diff --git a/src/tests/cmocka/test_ipa_subdomains_server.c b/src/tests/cmocka/test_ipa_subdomains_server.c
|
||||
index 123cf11c01ef4687eecad31a9d73120a87c643e1..ca48425aca69e58358f5fd37e4b8238bfa9efe15 100644
|
||||
--- a/src/tests/cmocka/test_ipa_subdomains_server.c
|
||||
+++ b/src/tests/cmocka/test_ipa_subdomains_server.c
|
||||
@@ -263,7 +263,7 @@ static void add_test_subdomains(struct trust_test_ctx *test_ctx,
|
||||
direction, NULL);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- ret = sysdb_update_subdomains(test_ctx->tctx->dom);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
}
|
||||
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
|
||||
index 50714715cc80338640f2a77ecbe17bd5e0d6e911..3d7e0382197401cb2264671712152fe0709296b6 100644
|
||||
--- a/src/tests/cmocka/test_nss_srv.c
|
||||
+++ b/src/tests/cmocka/test_nss_srv.c
|
||||
@@ -3206,7 +3206,8 @@ static int nss_subdom_test_setup(void **state)
|
||||
|
||||
subdomain = new_subdomain(nss_test_ctx, nss_test_ctx->tctx->dom,
|
||||
testdom[0], testdom[1], testdom[2], testdom[3],
|
||||
- false, false, NULL, NULL, 0);
|
||||
+ false, false, NULL, NULL, 0,
|
||||
+ nss_test_ctx->tctx->confdb);
|
||||
assert_non_null(subdomain);
|
||||
|
||||
ret = sysdb_subdomain_store(nss_test_ctx->tctx->sysdb,
|
||||
@@ -3214,7 +3215,8 @@ static int nss_subdom_test_setup(void **state)
|
||||
false, false, NULL, 0, NULL);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- ret = sysdb_update_subdomains(nss_test_ctx->tctx->dom);
|
||||
+ ret = sysdb_update_subdomains(nss_test_ctx->tctx->dom,
|
||||
+ nss_test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
nss_test_ctx->subdom = subdomain;
|
||||
diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c
|
||||
index 49f44998a06740d1df70ac354ee741824acd8f50..84bcdc17b39dbc8822097c2006f157a09ea5e466 100644
|
||||
--- a/src/tests/cmocka/test_sysdb_subdomains.c
|
||||
+++ b/src/tests/cmocka/test_sysdb_subdomains.c
|
||||
@@ -103,7 +103,7 @@ static void test_sysdb_subdomain_create(void **state)
|
||||
false, false, NULL, 0, NULL);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- ret = sysdb_update_subdomains(test_ctx->tctx->dom);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
assert_non_null(test_ctx->tctx->dom->subdomains);
|
||||
@@ -115,7 +115,7 @@ static void test_sysdb_subdomain_create(void **state)
|
||||
false, false, NULL, 1, NULL);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- ret = sysdb_update_subdomains(test_ctx->tctx->dom);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
assert_non_null(test_ctx->tctx->dom->subdomains->next);
|
||||
@@ -133,7 +133,7 @@ static void test_sysdb_subdomain_create(void **state)
|
||||
false, false, NULL, 0, NULL);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- ret = sysdb_update_subdomains(test_ctx->tctx->dom);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
assert_int_equal(test_ctx->tctx->dom->subdomains->trust_direction, 1);
|
||||
@@ -145,7 +145,7 @@ static void test_sysdb_subdomain_create(void **state)
|
||||
ret = sysdb_subdomain_delete(test_ctx->tctx->sysdb, dom1[0]);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- ret = sysdb_update_subdomains(test_ctx->tctx->dom);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
assert_int_equal(sss_domain_get_state(test_ctx->tctx->dom->subdomains),
|
||||
@@ -235,11 +235,11 @@ static void test_sysdb_link_forest_root_ipa(void **state)
|
||||
0, NULL);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- ret = sysdb_update_subdomains(test_ctx->tctx->dom);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
/* Also update dom2 */
|
||||
- ret = sysdb_update_subdomains(test_ctx->tctx->dom->next);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->tctx->dom->next, test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
sub = find_domain_by_name(test_ctx->tctx->dom, dom1[0], true);
|
||||
@@ -315,11 +315,11 @@ static void test_sysdb_link_forest_root_ad(void **state)
|
||||
0, NULL);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- ret = sysdb_update_subdomains(test_ctx->tctx->dom);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
/* Also update dom2 */
|
||||
- ret = sysdb_update_subdomains(test_ctx->tctx->dom->next);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->tctx->dom->next, test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
assert_non_null(test_ctx->tctx->dom->forest_root);
|
||||
@@ -395,14 +395,15 @@ static void test_sysdb_link_forest_member_ad(void **state)
|
||||
ret = sysdb_master_domain_update(test_ctx->tctx->dom);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- ret = sysdb_update_subdomains(test_ctx->tctx->dom);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
/* Also update dom2 */
|
||||
ret = sysdb_master_domain_update(test_ctx->tctx->dom->next);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- ret = sysdb_update_subdomains(test_ctx->tctx->dom->next);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->tctx->dom->next,
|
||||
+ test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
/* Checks */
|
||||
@@ -472,7 +473,7 @@ static void test_sysdb_link_ad_multidom(void **state)
|
||||
ret = sysdb_master_domain_update(main_dom1);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- ret = sysdb_update_subdomains(main_dom1);
|
||||
+ ret = sysdb_update_subdomains(main_dom1, NULL);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
ret = sysdb_master_domain_add_info(main_dom2,
|
||||
@@ -492,7 +493,7 @@ static void test_sysdb_link_ad_multidom(void **state)
|
||||
ret = sysdb_master_domain_update(main_dom2);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- ret = sysdb_update_subdomains(main_dom2);
|
||||
+ ret = sysdb_update_subdomains(main_dom2, NULL);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
main_dom1 = find_domain_by_name(test_ctx->tctx->dom, TEST_DOM1_NAME, true);
|
||||
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
|
||||
index 5bdd631fbfa1b4463fb169e5f07b65fb2c784096..1767dc3c734c6b2e5f74564debd603e2442f491b 100644
|
||||
--- a/src/tests/sysdb-tests.c
|
||||
+++ b/src/tests/sysdb-tests.c
|
||||
@@ -1395,7 +1395,7 @@ START_TEST (test_sysdb_get_user_attr_subdomain)
|
||||
/* Create subdomain */
|
||||
subdomain = new_subdomain(test_ctx, test_ctx->domain,
|
||||
"test.sub", "TEST.SUB", "test", "S-3",
|
||||
- false, false, NULL, NULL, 0);
|
||||
+ false, false, NULL, NULL, 0, NULL);
|
||||
fail_if(subdomain == NULL, "Failed to create new subdomain.");
|
||||
|
||||
ret = sss_names_init_from_args(test_ctx,
|
||||
@@ -5821,14 +5821,14 @@ START_TEST(test_sysdb_subdomain_store_user)
|
||||
|
||||
subdomain = new_subdomain(test_ctx, test_ctx->domain,
|
||||
testdom[0], testdom[1], testdom[2], testdom[3],
|
||||
- false, false, NULL, NULL, 0);
|
||||
+ false, false, NULL, NULL, 0, NULL);
|
||||
fail_unless(subdomain != NULL, "Failed to create new subdomin.");
|
||||
ret = sysdb_subdomain_store(test_ctx->sysdb,
|
||||
testdom[0], testdom[1], testdom[2], testdom[3],
|
||||
false, false, NULL, 0, NULL);
|
||||
fail_if(ret != EOK, "Could not set up the test (test subdom)");
|
||||
|
||||
- ret = sysdb_update_subdomains(test_ctx->domain);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->domain, NULL);
|
||||
fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]",
|
||||
ret, strerror(ret));
|
||||
|
||||
@@ -5900,14 +5900,14 @@ START_TEST(test_sysdb_subdomain_user_ops)
|
||||
|
||||
subdomain = new_subdomain(test_ctx, test_ctx->domain,
|
||||
testdom[0], testdom[1], testdom[2], testdom[3],
|
||||
- false, false, NULL, NULL, 0);
|
||||
+ false, false, NULL, NULL, 0, NULL);
|
||||
fail_unless(subdomain != NULL, "Failed to create new subdomin.");
|
||||
ret = sysdb_subdomain_store(test_ctx->sysdb,
|
||||
testdom[0], testdom[1], testdom[2], testdom[3],
|
||||
false, false, NULL, 0, NULL);
|
||||
fail_if(ret != EOK, "Could not set up the test (test subdom)");
|
||||
|
||||
- ret = sysdb_update_subdomains(test_ctx->domain);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->domain, NULL);
|
||||
fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]",
|
||||
ret, strerror(ret));
|
||||
|
||||
@@ -5973,14 +5973,14 @@ START_TEST(test_sysdb_subdomain_group_ops)
|
||||
|
||||
subdomain = new_subdomain(test_ctx, test_ctx->domain,
|
||||
testdom[0], testdom[1], testdom[2], testdom[3],
|
||||
- false, false, NULL, NULL, 0);
|
||||
+ false, false, NULL, NULL, 0, NULL);
|
||||
fail_unless(subdomain != NULL, "Failed to create new subdomin.");
|
||||
ret = sysdb_subdomain_store(test_ctx->sysdb,
|
||||
testdom[0], testdom[1], testdom[2], testdom[3],
|
||||
false, false, NULL, 0, NULL);
|
||||
fail_if(ret != EOK, "Could not set up the test (test subdom)");
|
||||
|
||||
- ret = sysdb_update_subdomains(test_ctx->domain);
|
||||
+ ret = sysdb_update_subdomains(test_ctx->domain, NULL);
|
||||
fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]",
|
||||
ret, strerror(ret));
|
||||
|
||||
diff --git a/src/tools/common/sss_tools.c b/src/tools/common/sss_tools.c
|
||||
index 0f4f46894130daf722641f25a4cdfaae220252cc..97a3caab3bec88c5727eea2f08b200f1d3b23f0c 100644
|
||||
--- a/src/tools/common/sss_tools.c
|
||||
+++ b/src/tools/common/sss_tools.c
|
||||
@@ -154,7 +154,7 @@ static errno_t sss_tool_domains_init(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
/* Update list of subdomains for this domain */
|
||||
- ret = sysdb_update_subdomains(dom);
|
||||
+ ret = sysdb_update_subdomains(dom, confdb);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
"Failed to update subdomains for domain %s.\n",
|
||||
diff --git a/src/tools/sss_cache.c b/src/tools/sss_cache.c
|
||||
index 59e49a8aa92e3a08ec80e0597304f1a4af0a02be..8a40b38c07f7e76cde5b98e5916816581fea7973 100644
|
||||
--- a/src/tools/sss_cache.c
|
||||
+++ b/src/tools/sss_cache.c
|
||||
@@ -158,7 +158,7 @@ int main(int argc, const char *argv[])
|
||||
dinfo = get_next_domain(dinfo, SSS_GND_DESCEND)) {
|
||||
if (!IS_SUBDOMAIN(dinfo)) {
|
||||
/* Update list of subdomains for this domain */
|
||||
- ret = sysdb_update_subdomains(dinfo);
|
||||
+ ret = sysdb_update_subdomains(dinfo, tctx->confdb);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
"Failed to update subdomains for domain %s.\n", dinfo->name);
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,172 +0,0 @@
|
||||
From dcc52d9c6411528bab815351d1e6145d211a4765 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
||||
Date: Wed, 1 Mar 2017 08:34:57 +0000
|
||||
Subject: [PATCH 45/97] CACHE_REQ: Descend into subdomains on lookups
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Let's make all plugins, but the "host_by_name", to descend into the
|
||||
subdomains on lookups.
|
||||
|
||||
This patch basically prepares the field for the coming up patches that
|
||||
will allow group/user resolution in all domains (or a subset of the
|
||||
domains) to be possible by only using the short names without the domain
|
||||
component.
|
||||
|
||||
The "host_by_name" plugin was not changed as it's a specific IPA plugin
|
||||
and won't find anything on its subdomains.
|
||||
|
||||
Related:
|
||||
https://pagure.io/SSSD/sssd/issue/3001
|
||||
|
||||
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
src/responder/common/cache_req/plugins/cache_req_enum_svc.c | 2 +-
|
||||
src/responder/common/cache_req/plugins/cache_req_group_by_filter.c | 2 +-
|
||||
src/responder/common/cache_req/plugins/cache_req_group_by_name.c | 2 +-
|
||||
src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c | 2 +-
|
||||
src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c | 2 +-
|
||||
src/responder/common/cache_req/plugins/cache_req_object_by_name.c | 2 +-
|
||||
src/responder/common/cache_req/plugins/cache_req_svc_by_name.c | 2 +-
|
||||
src/responder/common/cache_req/plugins/cache_req_svc_by_port.c | 2 +-
|
||||
src/responder/common/cache_req/plugins/cache_req_user_by_filter.c | 2 +-
|
||||
src/responder/common/cache_req/plugins/cache_req_user_by_name.c | 2 +-
|
||||
10 files changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_enum_svc.c b/src/responder/common/cache_req/plugins/cache_req_enum_svc.c
|
||||
index 2c4917cde750c9063d898c16d3a58ca8c179bc70..28dea33c601f500b9c7af0de3eb9e1c342f03522 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_enum_svc.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_enum_svc.c
|
||||
@@ -68,7 +68,7 @@ const struct cache_req_plugin cache_req_enum_svc = {
|
||||
.allow_missing_fqn = true,
|
||||
.allow_switch_to_upn = false,
|
||||
.upn_equivalent = CACHE_REQ_SENTINEL,
|
||||
- .get_next_domain_flags = 0,
|
||||
+ .get_next_domain_flags = SSS_GND_DESCEND,
|
||||
|
||||
.is_well_known_fn = NULL,
|
||||
.prepare_domain_data_fn = NULL,
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c b/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c
|
||||
index 88e1137a3976308aaf404b684c6d88cc43708bca..6ce6ae0d63967ac50b813a47ac938251619948da 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c
|
||||
@@ -123,7 +123,7 @@ const struct cache_req_plugin cache_req_group_by_filter = {
|
||||
.allow_missing_fqn = false,
|
||||
.allow_switch_to_upn = false,
|
||||
.upn_equivalent = CACHE_REQ_SENTINEL,
|
||||
- .get_next_domain_flags = 0,
|
||||
+ .get_next_domain_flags = SSS_GND_DESCEND,
|
||||
|
||||
.is_well_known_fn = NULL,
|
||||
.prepare_domain_data_fn = cache_req_group_by_filter_prepare_domain_data,
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_name.c b/src/responder/common/cache_req/plugins/cache_req_group_by_name.c
|
||||
index be1eb9bd8552156d777e934b0be397b0e66df7cc..af6f23ccfd68f952027462ba3e74ed7219d04651 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_group_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_name.c
|
||||
@@ -186,7 +186,7 @@ const struct cache_req_plugin cache_req_group_by_name = {
|
||||
.allow_missing_fqn = false,
|
||||
.allow_switch_to_upn = false,
|
||||
.upn_equivalent = CACHE_REQ_SENTINEL,
|
||||
- .get_next_domain_flags = 0,
|
||||
+ .get_next_domain_flags = SSS_GND_DESCEND,
|
||||
|
||||
.is_well_known_fn = NULL,
|
||||
.prepare_domain_data_fn = cache_req_group_by_name_prepare_domain_data,
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c b/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c
|
||||
index 10fb67cbf6e78cfae33bc7208585cb80ea6a9bc4..307b65a24282838b99c472b50a71f06865aed3f0 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c
|
||||
@@ -201,7 +201,7 @@ const struct cache_req_plugin cache_req_initgroups_by_name = {
|
||||
.allow_missing_fqn = false,
|
||||
.allow_switch_to_upn = true,
|
||||
.upn_equivalent = CACHE_REQ_INITGROUPS_BY_UPN,
|
||||
- .get_next_domain_flags = 0,
|
||||
+ .get_next_domain_flags = SSS_GND_DESCEND,
|
||||
|
||||
.is_well_known_fn = NULL,
|
||||
.prepare_domain_data_fn = cache_req_initgroups_by_name_prepare_domain_data,
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c b/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c
|
||||
index bc6fc9a8f476f97cc4bc5004bc19ba35258a2b6d..e49d6d84a41ce8dabf18c87373826f8e7b684bda 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c
|
||||
@@ -120,7 +120,7 @@ const struct cache_req_plugin cache_req_netgroup_by_name = {
|
||||
.allow_missing_fqn = true,
|
||||
.allow_switch_to_upn = false,
|
||||
.upn_equivalent = CACHE_REQ_SENTINEL,
|
||||
- .get_next_domain_flags = 0,
|
||||
+ .get_next_domain_flags = SSS_GND_DESCEND,
|
||||
|
||||
.is_well_known_fn = NULL,
|
||||
.prepare_domain_data_fn = cache_req_netgroup_by_name_prepare_domain_data,
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_name.c b/src/responder/common/cache_req/plugins/cache_req_object_by_name.c
|
||||
index 2b2caeea172b23b1b1b226def5d926e26c5c0090..74d2b3dea287e890b38e4d5bb176ad2dc6337b7e 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_object_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_object_by_name.c
|
||||
@@ -196,7 +196,7 @@ const struct cache_req_plugin cache_req_object_by_name = {
|
||||
.allow_missing_fqn = false,
|
||||
.allow_switch_to_upn = true,
|
||||
.upn_equivalent = CACHE_REQ_USER_BY_UPN,
|
||||
- .get_next_domain_flags = 0,
|
||||
+ .get_next_domain_flags = SSS_GND_DESCEND,
|
||||
|
||||
.is_well_known_fn = cache_req_object_by_name_well_known,
|
||||
.prepare_domain_data_fn = cache_req_object_by_name_prepare_domain_data,
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c b/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c
|
||||
index cbb186df04c7ca7c02dceb98bd5700c984285a4d..ef13f097a8ae78ec9db5b7f6e14924b511578b34 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c
|
||||
@@ -144,7 +144,7 @@ const struct cache_req_plugin cache_req_svc_by_name = {
|
||||
.allow_missing_fqn = false,
|
||||
.allow_switch_to_upn = false,
|
||||
.upn_equivalent = CACHE_REQ_SENTINEL,
|
||||
- .get_next_domain_flags = 0,
|
||||
+ .get_next_domain_flags = SSS_GND_DESCEND,
|
||||
|
||||
.is_well_known_fn = NULL,
|
||||
.prepare_domain_data_fn = cache_req_svc_by_name_prepare_domain_data,
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c b/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c
|
||||
index 1da23d4505a1dad3b2425a996134f8298c03518a..afa2eeeda12794de26e798aee4b88900bc87ed93 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c
|
||||
@@ -117,7 +117,7 @@ const struct cache_req_plugin cache_req_svc_by_port = {
|
||||
.allow_missing_fqn = false,
|
||||
.allow_switch_to_upn = false,
|
||||
.upn_equivalent = CACHE_REQ_SENTINEL,
|
||||
- .get_next_domain_flags = 0,
|
||||
+ .get_next_domain_flags = SSS_GND_DESCEND,
|
||||
|
||||
.is_well_known_fn = NULL,
|
||||
.prepare_domain_data_fn = cache_req_svc_by_port_prepare_domain_data,
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c b/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c
|
||||
index ee7e69399e318b9835f1623bddc635bf09aa7a1c..eb71b42dad3a805298df0c8425409d571befb31b 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c
|
||||
@@ -123,7 +123,7 @@ const struct cache_req_plugin cache_req_user_by_filter = {
|
||||
.allow_missing_fqn = false,
|
||||
.allow_switch_to_upn = false,
|
||||
.upn_equivalent = CACHE_REQ_SENTINEL,
|
||||
- .get_next_domain_flags = 0,
|
||||
+ .get_next_domain_flags = SSS_GND_DESCEND,
|
||||
|
||||
.is_well_known_fn = NULL,
|
||||
.prepare_domain_data_fn = cache_req_user_by_filter_prepare_domain_data,
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_name.c b/src/responder/common/cache_req/plugins/cache_req_user_by_name.c
|
||||
index 4289f5fd4c79f0e512f0249abe4422589fa800a0..0670febdce2d51e0373045570dd07f56255db7bc 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_user_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_name.c
|
||||
@@ -191,7 +191,7 @@ const struct cache_req_plugin cache_req_user_by_name = {
|
||||
.allow_missing_fqn = false,
|
||||
.allow_switch_to_upn = true,
|
||||
.upn_equivalent = CACHE_REQ_USER_BY_UPN,
|
||||
- .get_next_domain_flags = 0,
|
||||
+ .get_next_domain_flags = SSS_GND_DESCEND,
|
||||
|
||||
.is_well_known_fn = NULL,
|
||||
.prepare_domain_data_fn = cache_req_user_by_name_prepare_domain_data,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,35 +0,0 @@
|
||||
From 46c99a59c8d6501aa3ad701c567fba577924b48b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Wed, 1 Mar 2017 13:21:19 +0000
|
||||
Subject: [PATCH 46/97] NSS/TESTS: Fix subdomains attribution
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Related:
|
||||
https://pagure.io/SSSD/sssd/issue/3001
|
||||
|
||||
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/tests/cmocka/test_nss_srv.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
|
||||
index 3d7e0382197401cb2264671712152fe0709296b6..cbe0dccdc1d883eae1a9621f12997ef43d05178e 100644
|
||||
--- a/src/tests/cmocka/test_nss_srv.c
|
||||
+++ b/src/tests/cmocka/test_nss_srv.c
|
||||
@@ -3219,7 +3219,7 @@ static int nss_subdom_test_setup(void **state)
|
||||
nss_test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
- nss_test_ctx->subdom = subdomain;
|
||||
+ nss_test_ctx->subdom = nss_test_ctx->tctx->dom->subdomains;
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,274 +0,0 @@
|
||||
From a3442e4a268ad2172c89d58e6daa759eb4b39e7c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
||||
Date: Wed, 1 Mar 2017 20:46:10 +0000
|
||||
Subject: [PATCH 47/97] NSS/TESTS: Improve setup/teardown for subdomains tests
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This patch basically makes the getgrnam_members_subdom(),
|
||||
getgrnam_mix_dom(), getgrnam_mix_dom_fqdn() and getgrnam_mix_subdom()
|
||||
more independent of each other.
|
||||
|
||||
Related:
|
||||
https://pagure.io/SSSD/sssd/issue/3001
|
||||
|
||||
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/tests/cmocka/test_nss_srv.c | 182 +++++++++++++++++++++++++++++++++-------
|
||||
1 file changed, 150 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
|
||||
index cbe0dccdc1d883eae1a9621f12997ef43d05178e..b468204fb1729618830513322f0d901c4c801e94 100644
|
||||
--- a/src/tests/cmocka/test_nss_srv.c
|
||||
+++ b/src/tests/cmocka/test_nss_srv.c
|
||||
@@ -418,6 +418,26 @@ static errno_t store_user(struct nss_test_ctx *ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static errno_t delete_user(struct nss_test_ctx *ctx,
|
||||
+ struct sss_domain_info *dom,
|
||||
+ struct passwd *user)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ char *fqname;
|
||||
+
|
||||
+ fqname = sss_create_internal_fqname(ctx,
|
||||
+ user->pw_name,
|
||||
+ dom->name);
|
||||
+ if (fqname == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_delete_user(dom, fqname, user->pw_uid);
|
||||
+
|
||||
+ talloc_free(fqname);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static errno_t set_user_attr(struct nss_test_ctx *ctx,
|
||||
struct sss_domain_info *dom,
|
||||
struct passwd *user,
|
||||
@@ -491,6 +511,27 @@ static errno_t store_group(struct nss_test_ctx *ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static errno_t delete_group(struct nss_test_ctx *ctx,
|
||||
+ struct sss_domain_info *dom,
|
||||
+ struct group *group)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ char *fqname;
|
||||
+
|
||||
+ fqname = sss_create_internal_fqname(ctx,
|
||||
+ group->gr_name,
|
||||
+ dom->name);
|
||||
+
|
||||
+ if (fqname == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_delete_group(dom, fqname, group->gr_gid);
|
||||
+
|
||||
+ talloc_free(fqname);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static void assert_groups_equal(struct group *expected,
|
||||
struct group *gr, const int nmem)
|
||||
{
|
||||
@@ -540,6 +581,42 @@ static errno_t store_group_member(struct nss_test_ctx *ctx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static errno_t remove_group_member(struct nss_test_ctx *ctx,
|
||||
+ const char *shortname_group,
|
||||
+ struct sss_domain_info *group_dom,
|
||||
+ const char *shortname_member,
|
||||
+ struct sss_domain_info *member_dom,
|
||||
+ enum sysdb_member_type type)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ char *group_fqname = NULL;
|
||||
+ char *member_fqname = NULL;
|
||||
+
|
||||
+ group_fqname = sss_create_internal_fqname(ctx,
|
||||
+ shortname_group,
|
||||
+ group_dom->name);
|
||||
+ if (group_fqname == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ member_fqname = sss_create_internal_fqname(ctx,
|
||||
+ shortname_member,
|
||||
+ member_dom->name);
|
||||
+ if (member_fqname == NULL) {
|
||||
+ talloc_free(group_fqname);
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_remove_group_member(group_dom,
|
||||
+ group_fqname,
|
||||
+ member_fqname,
|
||||
+ type,
|
||||
+ false);
|
||||
+
|
||||
+ talloc_free(group_fqname);
|
||||
+ talloc_free(member_fqname);
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
/* ====================== The tests =============================== */
|
||||
struct passwd getpwnam_usr = {
|
||||
@@ -1599,34 +1676,6 @@ void test_nss_getgrnam_members_subdom(void **state)
|
||||
{
|
||||
errno_t ret;
|
||||
|
||||
- ret = store_group(nss_test_ctx, nss_test_ctx->subdom,
|
||||
- &testsubdomgroup, 0);
|
||||
- assert_int_equal(ret, EOK);
|
||||
-
|
||||
- ret = store_user(nss_test_ctx, nss_test_ctx->subdom,
|
||||
- &submember1, NULL, 0);
|
||||
- assert_int_equal(ret, EOK);
|
||||
-
|
||||
- ret = store_user(nss_test_ctx, nss_test_ctx->subdom,
|
||||
- &submember2, NULL, 0);
|
||||
- assert_int_equal(ret, EOK);
|
||||
-
|
||||
- ret = store_group_member(nss_test_ctx,
|
||||
- testsubdomgroup.gr_name,
|
||||
- nss_test_ctx->subdom,
|
||||
- submember1.pw_name,
|
||||
- nss_test_ctx->subdom,
|
||||
- SYSDB_MEMBER_USER);
|
||||
- assert_int_equal(ret, EOK);
|
||||
-
|
||||
- ret = store_group_member(nss_test_ctx,
|
||||
- testsubdomgroup.gr_name,
|
||||
- nss_test_ctx->subdom,
|
||||
- submember2.pw_name,
|
||||
- nss_test_ctx->subdom,
|
||||
- SYSDB_MEMBER_USER);
|
||||
- assert_int_equal(ret, EOK);
|
||||
-
|
||||
mock_input_user_or_group("testsubdomgroup@"TEST_SUBDOM_NAME);
|
||||
will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
|
||||
will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
@@ -1757,6 +1806,14 @@ void test_nss_getgrnam_mix_dom_fqdn(void **state)
|
||||
{
|
||||
errno_t ret;
|
||||
|
||||
+ ret = store_group_member(nss_test_ctx,
|
||||
+ testgroup_members.gr_name,
|
||||
+ nss_test_ctx->tctx->dom,
|
||||
+ submember1.pw_name,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ SYSDB_MEMBER_USER);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
nss_test_ctx->tctx->dom->fqnames = true;
|
||||
|
||||
mock_input_user_or_group("testgroup_members@"TEST_DOM_NAME);
|
||||
@@ -3220,6 +3277,35 @@ static int nss_subdom_test_setup(void **state)
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
nss_test_ctx->subdom = nss_test_ctx->tctx->dom->subdomains;
|
||||
+
|
||||
+ ret = store_group(nss_test_ctx, nss_test_ctx->subdom,
|
||||
+ &testsubdomgroup, 0);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = store_user(nss_test_ctx, nss_test_ctx->subdom,
|
||||
+ &submember1, NULL, 0);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = store_user(nss_test_ctx, nss_test_ctx->subdom,
|
||||
+ &submember2, NULL, 0);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = store_group_member(nss_test_ctx,
|
||||
+ testsubdomgroup.gr_name,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ submember1.pw_name,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ SYSDB_MEMBER_USER);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = store_group_member(nss_test_ctx,
|
||||
+ testsubdomgroup.gr_name,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ submember2.pw_name,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ SYSDB_MEMBER_USER);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3241,6 +3327,38 @@ static int nss_test_teardown(void **state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int nss_subdom_test_teardown(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = remove_group_member(nss_test_ctx,
|
||||
+ testsubdomgroup.gr_name,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ submember2.pw_name,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ SYSDB_MEMBER_USER);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = remove_group_member(nss_test_ctx,
|
||||
+ testsubdomgroup.gr_name,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ submember1.pw_name,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ SYSDB_MEMBER_USER);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = delete_user(nss_test_ctx, nss_test_ctx->subdom, &submember2);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = delete_user(nss_test_ctx, nss_test_ctx->subdom, &submember1);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = delete_group(nss_test_ctx, nss_test_ctx->subdom, &testsubdomgroup);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ return nss_test_teardown(state);
|
||||
+}
|
||||
+
|
||||
struct passwd testbysid = {
|
||||
.pw_name = discard_const("testsiduser"),
|
||||
.pw_uid = 12345,
|
||||
@@ -3904,16 +4022,16 @@ int main(int argc, const char *argv[])
|
||||
nss_fqdn_test_setup, nss_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getgrnam_members_subdom,
|
||||
nss_subdom_test_setup,
|
||||
- nss_test_teardown),
|
||||
+ nss_subdom_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom,
|
||||
nss_subdom_test_setup,
|
||||
- nss_test_teardown),
|
||||
+ nss_subdom_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom_fqdn,
|
||||
nss_subdom_test_setup,
|
||||
- nss_test_teardown),
|
||||
+ nss_subdom_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_subdom,
|
||||
nss_subdom_test_setup,
|
||||
- nss_test_teardown),
|
||||
+ nss_subdom_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getgrnam_space,
|
||||
nss_test_setup, nss_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getgrnam_space_sub,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,355 +0,0 @@
|
||||
From 5856a621ac5909ca96520ac5a809eb83fd46d8bc Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
||||
Date: Wed, 1 Mar 2017 08:33:06 +0000
|
||||
Subject: [PATCH 48/97] NSS/TESTS: Include searches for non-fqnames members of
|
||||
a subdomain
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Let's extend the NSS tests in order to also test looking up users, from
|
||||
a subdomain, by their short names (non fully qualified names).
|
||||
|
||||
Related:
|
||||
https://pagure.io/SSSD/sssd/issue/3001
|
||||
|
||||
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/tests/cmocka/test_nss_srv.c | 246 ++++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 211 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
|
||||
index b468204fb1729618830513322f0d901c4c801e94..ede72b341b60842ad470df2794aa90ea9797e999 100644
|
||||
--- a/src/tests/cmocka/test_nss_srv.c
|
||||
+++ b/src/tests/cmocka/test_nss_srv.c
|
||||
@@ -1648,16 +1648,29 @@ static int test_nss_getgrnam_members_check_subdom(uint32_t status,
|
||||
tmp_ctx = talloc_new(nss_test_ctx);
|
||||
assert_non_null(tmp_ctx);
|
||||
|
||||
- exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
|
||||
- nss_test_ctx->subdom, submember1.pw_name);
|
||||
- assert_non_null(exp_members[0]);
|
||||
- exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
|
||||
- nss_test_ctx->subdom, submember2.pw_name);
|
||||
- assert_non_null(exp_members[1]);
|
||||
+ if (nss_test_ctx->subdom->fqnames) {
|
||||
+ exp_members[0] = sss_tc_fqname(tmp_ctx,
|
||||
+ nss_test_ctx->subdom->names,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ submember1.pw_name);
|
||||
+ assert_non_null(exp_members[0]);
|
||||
|
||||
- expected.gr_name = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
|
||||
- nss_test_ctx->subdom, testsubdomgroup.gr_name);
|
||||
- assert_non_null(expected.gr_name);
|
||||
+ exp_members[1] = sss_tc_fqname(tmp_ctx,
|
||||
+ nss_test_ctx->subdom->names,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ submember2.pw_name);
|
||||
+ assert_non_null(exp_members[1]);
|
||||
+
|
||||
+ expected.gr_name = sss_tc_fqname(tmp_ctx,
|
||||
+ nss_test_ctx->subdom->names,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ testsubdomgroup.gr_name);
|
||||
+ assert_non_null(expected.gr_name);
|
||||
+ } else {
|
||||
+ exp_members[0] = submember1.pw_name;
|
||||
+ exp_members[1] = submember2.pw_name;
|
||||
+ expected.gr_name = testsubdomgroup.gr_name;
|
||||
+ }
|
||||
|
||||
assert_int_equal(status, EOK);
|
||||
|
||||
@@ -1692,6 +1705,29 @@ void test_nss_getgrnam_members_subdom(void **state)
|
||||
assert_int_equal(ret, EOK);
|
||||
}
|
||||
|
||||
+void test_nss_getgrnam_members_subdom_nonfqnames(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ nss_test_ctx->subdom->fqnames = false;
|
||||
+
|
||||
+ mock_input_user_or_group("testsubdomgroup");
|
||||
+ mock_account_recv_simple();
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
|
||||
+ will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+
|
||||
+ /* Query for that group, call a callback when command finishes */
|
||||
+ set_cmd_cb(test_nss_getgrnam_members_check_subdom);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
|
||||
+ 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);
|
||||
+}
|
||||
+
|
||||
static int test_nss_getgrnam_check_mix_dom(uint32_t status,
|
||||
uint8_t *body, size_t blen)
|
||||
{
|
||||
@@ -1710,9 +1746,15 @@ static int test_nss_getgrnam_check_mix_dom(uint32_t status,
|
||||
tmp_ctx = talloc_new(nss_test_ctx);
|
||||
assert_non_null(tmp_ctx);
|
||||
|
||||
- exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
|
||||
- nss_test_ctx->subdom, submember1.pw_name);
|
||||
- assert_non_null(exp_members[0]);
|
||||
+ if (nss_test_ctx->subdom->fqnames) {
|
||||
+ exp_members[0] = sss_tc_fqname(tmp_ctx,
|
||||
+ nss_test_ctx->subdom->names,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ submember1.pw_name);
|
||||
+ assert_non_null(exp_members[0]);
|
||||
+ } else {
|
||||
+ exp_members[0] = submember1.pw_name;
|
||||
+ }
|
||||
exp_members[1] = testmember1.pw_name;
|
||||
exp_members[2] = testmember2.pw_name;
|
||||
|
||||
@@ -1756,6 +1798,35 @@ void test_nss_getgrnam_mix_dom(void **state)
|
||||
assert_int_equal(ret, EOK);
|
||||
}
|
||||
|
||||
+void test_nss_getgrnam_mix_dom_nonfqnames(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ nss_test_ctx->subdom->fqnames = false;
|
||||
+
|
||||
+ ret = store_group_member(nss_test_ctx,
|
||||
+ testgroup_members.gr_name,
|
||||
+ nss_test_ctx->tctx->dom,
|
||||
+ submember1.pw_name,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ SYSDB_MEMBER_USER);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ mock_input_user_or_group("testgroup_members");
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
|
||||
+ will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+
|
||||
+ /* Query for that group, call a callback when command finishes */
|
||||
+ set_cmd_cb(test_nss_getgrnam_check_mix_dom);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
|
||||
+ 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);
|
||||
+}
|
||||
+
|
||||
static int test_nss_getgrnam_check_mix_dom_fqdn(uint32_t status,
|
||||
uint8_t *body, size_t blen)
|
||||
{
|
||||
@@ -1773,21 +1844,33 @@ static int test_nss_getgrnam_check_mix_dom_fqdn(uint32_t status,
|
||||
tmp_ctx = talloc_new(nss_test_ctx);
|
||||
assert_non_null(tmp_ctx);
|
||||
|
||||
- exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
|
||||
- nss_test_ctx->subdom, submember1.pw_name);
|
||||
- assert_non_null(exp_members[0]);
|
||||
- exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names,
|
||||
- nss_test_ctx->tctx->dom, testmember1.pw_name);
|
||||
- assert_non_null(exp_members[1]);
|
||||
- exp_members[2] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names,
|
||||
- nss_test_ctx->tctx->dom, testmember2.pw_name);
|
||||
- assert_non_null(exp_members[2]);
|
||||
+ if (nss_test_ctx->subdom->fqnames) {
|
||||
+ exp_members[0] = sss_tc_fqname(tmp_ctx,
|
||||
+ nss_test_ctx->subdom->names,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ submember1.pw_name);
|
||||
+ assert_non_null(exp_members[0]);
|
||||
+ } else {
|
||||
+ exp_members[0] = submember1.pw_name;
|
||||
+ }
|
||||
+ if (nss_test_ctx->tctx->dom->fqnames) {
|
||||
+ exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names,
|
||||
+ nss_test_ctx->tctx->dom, testmember1.pw_name);
|
||||
+ assert_non_null(exp_members[1]);
|
||||
+ exp_members[2] = sss_tc_fqname(tmp_ctx, nss_test_ctx->tctx->dom->names,
|
||||
+ nss_test_ctx->tctx->dom, testmember2.pw_name);
|
||||
+ assert_non_null(exp_members[2]);
|
||||
|
||||
- expected.gr_name = sss_tc_fqname(tmp_ctx,
|
||||
- nss_test_ctx->tctx->dom->names,
|
||||
- nss_test_ctx->tctx->dom,
|
||||
- testgroup_members.gr_name);
|
||||
- assert_non_null(expected.gr_name);
|
||||
+ expected.gr_name = sss_tc_fqname(tmp_ctx,
|
||||
+ nss_test_ctx->tctx->dom->names,
|
||||
+ nss_test_ctx->tctx->dom,
|
||||
+ testgroup_members.gr_name);
|
||||
+ assert_non_null(expected.gr_name);
|
||||
+ } else {
|
||||
+ exp_members[1] = testmember1.pw_name;
|
||||
+ exp_members[2] = testmember2.pw_name;
|
||||
+ expected.gr_name = testgroup_members.gr_name;
|
||||
+ }
|
||||
|
||||
assert_int_equal(status, EOK);
|
||||
|
||||
@@ -1834,6 +1917,40 @@ void test_nss_getgrnam_mix_dom_fqdn(void **state)
|
||||
assert_int_equal(ret, EOK);
|
||||
}
|
||||
|
||||
+void test_nss_getgrnam_mix_dom_fqdn_nonfqnames(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = store_group_member(nss_test_ctx,
|
||||
+ testgroup_members.gr_name,
|
||||
+ nss_test_ctx->tctx->dom,
|
||||
+ submember1.pw_name,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ SYSDB_MEMBER_USER);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ nss_test_ctx->tctx->dom->fqnames = false;
|
||||
+ nss_test_ctx->subdom->fqnames = false;
|
||||
+
|
||||
+
|
||||
+ mock_input_user_or_group("testgroup_members");
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
|
||||
+ will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+
|
||||
+ /* Query for that group, call a callback when command finishes */
|
||||
+ set_cmd_cb(test_nss_getgrnam_check_mix_dom_fqdn);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
|
||||
+ 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);
|
||||
+
|
||||
+ /* Restore FQDN settings */
|
||||
+ nss_test_ctx->tctx->dom->fqnames = false;
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+}
|
||||
+
|
||||
static int test_nss_getgrnam_check_mix_subdom(uint32_t status,
|
||||
uint8_t *body, size_t blen)
|
||||
{
|
||||
@@ -1851,20 +1968,37 @@ static int test_nss_getgrnam_check_mix_subdom(uint32_t status,
|
||||
tmp_ctx = talloc_new(nss_test_ctx);
|
||||
assert_non_null(tmp_ctx);
|
||||
|
||||
- exp_members[0] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
|
||||
- nss_test_ctx->subdom, submember1.pw_name);
|
||||
- assert_non_null(exp_members[0]);
|
||||
- exp_members[1] = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
|
||||
- nss_test_ctx->subdom, submember2.pw_name);
|
||||
- assert_non_null(exp_members[1]);
|
||||
+ if (nss_test_ctx->subdom->fqnames) {
|
||||
+ exp_members[0] = sss_tc_fqname(tmp_ctx,
|
||||
+ nss_test_ctx->subdom->names,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ submember1.pw_name);
|
||||
+ assert_non_null(exp_members[0]);
|
||||
+
|
||||
+ exp_members[1] = sss_tc_fqname(tmp_ctx,
|
||||
+ nss_test_ctx->subdom->names,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ submember2.pw_name);
|
||||
+ assert_non_null(exp_members[1]);
|
||||
+ } else {
|
||||
+ exp_members[0] = submember1.pw_name;
|
||||
+ exp_members[1] = submember2.pw_name;
|
||||
+ }
|
||||
+
|
||||
/* Important: this member is from a non-qualified domain, so his name will
|
||||
* not be qualified either
|
||||
*/
|
||||
exp_members[2] = testmember1.pw_name;
|
||||
|
||||
- expected.gr_name = sss_tc_fqname(tmp_ctx, nss_test_ctx->subdom->names,
|
||||
- nss_test_ctx->subdom, testsubdomgroup.gr_name);
|
||||
- assert_non_null(expected.gr_name);
|
||||
+ if (nss_test_ctx->subdom->fqnames) {
|
||||
+ expected.gr_name = sss_tc_fqname(tmp_ctx,
|
||||
+ nss_test_ctx->subdom->names,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ testsubdomgroup.gr_name);
|
||||
+ assert_non_null(expected.gr_name);
|
||||
+ } else {
|
||||
+ expected.gr_name = testsubdomgroup.gr_name;
|
||||
+ }
|
||||
|
||||
assert_int_equal(status, EOK);
|
||||
|
||||
@@ -1906,6 +2040,36 @@ void test_nss_getgrnam_mix_subdom(void **state)
|
||||
assert_int_equal(ret, EOK);
|
||||
}
|
||||
|
||||
+void test_nss_getgrnam_mix_subdom_nonfqnames(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ nss_test_ctx->subdom->fqnames = false;
|
||||
+
|
||||
+ ret = store_group_member(nss_test_ctx,
|
||||
+ testsubdomgroup.gr_name,
|
||||
+ nss_test_ctx->subdom,
|
||||
+ testmember1.pw_name,
|
||||
+ nss_test_ctx->tctx->dom,
|
||||
+ SYSDB_MEMBER_USER);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ mock_input_user_or_group("testsubdomgroup");
|
||||
+ mock_account_recv_simple();
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM);
|
||||
+ will_return_always(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+
|
||||
+ /* Query for that group, call a callback when command finishes */
|
||||
+ set_cmd_cb(test_nss_getgrnam_check_mix_subdom);
|
||||
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM,
|
||||
+ 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);
|
||||
+}
|
||||
+
|
||||
struct group space_group = {
|
||||
.gr_gid = 2123,
|
||||
.gr_name = discard_const("space group"),
|
||||
@@ -4023,15 +4187,27 @@ int main(int argc, const char *argv[])
|
||||
cmocka_unit_test_setup_teardown(test_nss_getgrnam_members_subdom,
|
||||
nss_subdom_test_setup,
|
||||
nss_subdom_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_nss_getgrnam_members_subdom_nonfqnames,
|
||||
+ nss_subdom_test_setup,
|
||||
+ nss_subdom_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom,
|
||||
nss_subdom_test_setup,
|
||||
nss_subdom_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom_nonfqnames,
|
||||
+ nss_subdom_test_setup,
|
||||
+ nss_subdom_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom_fqdn,
|
||||
nss_subdom_test_setup,
|
||||
nss_subdom_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom_fqdn_nonfqnames,
|
||||
+ nss_subdom_test_setup,
|
||||
+ nss_subdom_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_subdom,
|
||||
nss_subdom_test_setup,
|
||||
nss_subdom_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_subdom_nonfqnames,
|
||||
+ nss_subdom_test_setup,
|
||||
+ nss_subdom_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getgrnam_space,
|
||||
nss_test_setup, nss_test_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_nss_getgrnam_space_sub,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,289 +0,0 @@
|
||||
From 2e85b015d8dd231094a09eab69b86e8b6fcc8b2b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
||||
Date: Fri, 24 Mar 2017 15:29:23 +0100
|
||||
Subject: [PATCH 49/97] SYSDB: Add methods to deal with the domain's resolution
|
||||
order
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In the following-up patches those newly introduced methods will be used
|
||||
to deal with the domainResolutionOrder attribute.
|
||||
|
||||
The sysdb_update_domain_resolution_order() method is purposely not
|
||||
checking whether a value has changed or not before writing to sysdb and
|
||||
while may not be optimal, the readability of the code has increased a
|
||||
lot by keeping it as simple as possible.
|
||||
|
||||
Tests for these new methods are part of the next commit.
|
||||
|
||||
Related:
|
||||
https://pagure.io/SSSD/sssd/issue/3001
|
||||
|
||||
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
Makefile.am | 2 +
|
||||
src/db/sysdb.h | 2 +
|
||||
src/db/sysdb_domain_resolution_order.c | 169 +++++++++++++++++++++++++++++++++
|
||||
src/db/sysdb_domain_resolution_order.h | 37 ++++++++
|
||||
4 files changed, 210 insertions(+)
|
||||
create mode 100644 src/db/sysdb_domain_resolution_order.c
|
||||
create mode 100644 src/db/sysdb_domain_resolution_order.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 359feddef298b0013c726409b7ba8b86504abf09..8052150be32d89813764e9bc436dfcb211a738d6 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -736,6 +736,7 @@ dist_noinst_HEADERS = \
|
||||
src/db/sysdb_private.h \
|
||||
src/db/sysdb_services.h \
|
||||
src/db/sysdb_ssh.h \
|
||||
+ src/db/sysdb_domain_resolution_order.h \
|
||||
src/confdb/confdb.h \
|
||||
src/confdb/confdb_private.h \
|
||||
src/confdb/confdb_setup.h \
|
||||
@@ -995,6 +996,7 @@ libsss_util_la_SOURCES = \
|
||||
src/db/sysdb_idmap.c \
|
||||
src/db/sysdb_gpo.c \
|
||||
src/db/sysdb_certmap.c \
|
||||
+ src/db/sysdb_domain_resolution_order.c \
|
||||
src/monitor/monitor_sbus.c \
|
||||
src/providers/dp_auth_util.c \
|
||||
src/providers/dp_pam_data_util.c \
|
||||
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
|
||||
index 6762b51bee02911fb97d5d393fad2495504ee5ad..42d2857ed7765c17e7d84b0da93ed07758fbe012 100644
|
||||
--- a/src/db/sysdb.h
|
||||
+++ b/src/db/sysdb.h
|
||||
@@ -184,6 +184,8 @@
|
||||
#define SYSDB_OVERRIDE_GROUP_CLASS "groupOverride"
|
||||
#define SYSDB_OVERRIDE_DN "overrideDN"
|
||||
#define SYSDB_OVERRIDE_OBJECT_DN "overrideObjectDN"
|
||||
+#define SYSDB_USE_DOMAIN_RESOLUTION_ORDER "useDomainResolutionOrder"
|
||||
+#define SYSDB_DOMAIN_RESOLUTION_ORDER "domainResolutionOrder"
|
||||
|
||||
#define SYSDB_NEXTID_FILTER "("SYSDB_NEXTID"=*)"
|
||||
|
||||
diff --git a/src/db/sysdb_domain_resolution_order.c b/src/db/sysdb_domain_resolution_order.c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..63774461a1e9f3dc863220d418e29e06d6e6e6df
|
||||
--- /dev/null
|
||||
+++ b/src/db/sysdb_domain_resolution_order.c
|
||||
@@ -0,0 +1,169 @@
|
||||
+/*
|
||||
+ Authors:
|
||||
+ Fabiano Fidêncio <fidencio@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 <ldb.h>
|
||||
+
|
||||
+#include "db/sysdb.h"
|
||||
+#include "db/sysdb_private.h"
|
||||
+
|
||||
+static errno_t
|
||||
+sysdb_get_domain_resolution_order_string_attr(TALLOC_CTX *mem_ctx,
|
||||
+ struct sysdb_ctx *sysdb,
|
||||
+ struct ldb_dn *dn,
|
||||
+ const char *const *attrs,
|
||||
+ const char **_attr)
|
||||
+{
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ struct ldb_result *res;
|
||||
+ const char *attr;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = ldb_search(sysdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs,
|
||||
+ NULL);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ ret = EIO;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (res->count > 1) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Base search returned [%d] results, expected 1.\n", res->count);
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ } else if (res->count == 0) {
|
||||
+ ret = ENOENT;
|
||||
+ goto done;
|
||||
+ } else {
|
||||
+ /* res->count == 1 */
|
||||
+ attr = ldb_msg_find_attr_as_string(res->msgs[0], attrs[0], NULL);
|
||||
+ if (attr == NULL) {
|
||||
+ ret = ENOENT;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *_attr = talloc_steal(mem_ctx, attr);
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+errno_t
|
||||
+sysdb_get_domain_resolution_order(TALLOC_CTX *mem_ctx,
|
||||
+ struct sysdb_ctx *sysdb,
|
||||
+ struct ldb_dn *dn,
|
||||
+ const char **_domain_resolution_order)
|
||||
+{
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ const char *domain_resolution_order = NULL;
|
||||
+ const char *attrs[] = { SYSDB_DOMAIN_RESOLUTION_ORDER, NULL };
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_get_domain_resolution_order_string_attr(
|
||||
+ tmp_ctx, sysdb, dn, attrs, &domain_resolution_order);
|
||||
+ if (ret != EOK && ret != ENOENT) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "sysdb_get_domain_resolution_order_string_attr() failed "
|
||||
+ "[%d]: [%s]",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ } else if (ret == ENOENT) {
|
||||
+ *_domain_resolution_order = NULL;
|
||||
+ goto done;
|
||||
+ } else {
|
||||
+ /* ret == EOK */
|
||||
+ *_domain_resolution_order = talloc_steal(mem_ctx,
|
||||
+ domain_resolution_order);
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+errno_t
|
||||
+sysdb_update_domain_resolution_order(struct sysdb_ctx *sysdb,
|
||||
+ struct ldb_dn *dn,
|
||||
+ const char *domain_resolution_order)
|
||||
+{
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ struct ldb_message *msg;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ msg = ldb_msg_new(tmp_ctx);
|
||||
+ if (msg == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ msg->dn = dn;
|
||||
+
|
||||
+ ret = ldb_msg_add_empty(msg, SYSDB_DOMAIN_RESOLUTION_ORDER,
|
||||
+ LDB_FLAG_MOD_REPLACE, NULL);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ ret = sysdb_error_to_errno(ret);
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (domain_resolution_order != NULL) {
|
||||
+ ret = ldb_msg_add_string(msg, SYSDB_DOMAIN_RESOLUTION_ORDER,
|
||||
+ domain_resolution_order);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ ret = sysdb_error_to_errno(ret);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = ldb_modify(sysdb->ldb, msg);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "ldb_modify()_failed: [%s][%d][%s]\n",
|
||||
+ ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb));
|
||||
+ ret = sysdb_error_to_errno(ret);
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/src/db/sysdb_domain_resolution_order.h b/src/db/sysdb_domain_resolution_order.h
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..45d2ea63f6bc14cd3184994530846ee6f762d4d0
|
||||
--- /dev/null
|
||||
+++ b/src/db/sysdb_domain_resolution_order.h
|
||||
@@ -0,0 +1,37 @@
|
||||
+/*
|
||||
+ Authors:
|
||||
+ Fabiano Fidêncio <fidencio@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 _SYSDB_DOMAIN_RESOLUTION_ORDER_H_
|
||||
+#define _SYSDB_DOMAIN_RESOLUTION_ORDER_H_
|
||||
+
|
||||
+#include "db/sysdb.h"
|
||||
+
|
||||
+errno_t
|
||||
+sysdb_get_domain_resolution_order(TALLOC_CTX *mem_ctx,
|
||||
+ struct sysdb_ctx *sysdb,
|
||||
+ struct ldb_dn *dn,
|
||||
+ const char **_domain_resolution_order);
|
||||
+
|
||||
+errno_t
|
||||
+sysdb_update_domain_resolution_order(struct sysdb_ctx *sysdb,
|
||||
+ struct ldb_dn *dn,
|
||||
+ const char *domain_resolution_order);
|
||||
+
|
||||
+#endif /* _SYSDB_DOMAIN_RESOLUTION_ORDER_H_ */
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,259 +0,0 @@
|
||||
From 723d514f641e2b5a5cbfe1c6c7bdd2a6f3c5070e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
||||
Date: Fri, 24 Mar 2017 23:15:04 +0100
|
||||
Subject: [PATCH 50/97] SYSDB/TESTS: Add tests for the domain's resolution
|
||||
order methods
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Introduce a new and small set of tests for these new helper methods that
|
||||
are going to be used in different parts of the code in the follow-up
|
||||
patches.
|
||||
|
||||
Related:
|
||||
https://pagure.io/SSSD/sssd/issue/3001
|
||||
|
||||
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
Makefile.am | 16 ++
|
||||
.../cmocka/test_sysdb_domain_resolution_order.c | 190 +++++++++++++++++++++
|
||||
2 files changed, 206 insertions(+)
|
||||
create mode 100644 src/tests/cmocka/test_sysdb_domain_resolution_order.c
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 8052150be32d89813764e9bc436dfcb211a738d6..450785bf4c482cce1e1440f1336879150537888e 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -263,6 +263,7 @@ if HAVE_CMOCKA
|
||||
test_sysdb_certmap \
|
||||
test_sysdb_sudo \
|
||||
test_sysdb_utils \
|
||||
+ test_sysdb_domain_resolution_order \
|
||||
test_wbc_calls \
|
||||
test_be_ptask \
|
||||
test_copy_ccache \
|
||||
@@ -2875,6 +2876,21 @@ test_sysdb_utils_LDADD = \
|
||||
libsss_test_common.la \
|
||||
$(NULL)
|
||||
|
||||
+test_sysdb_domain_resolution_order_SOURCES = \
|
||||
+ src/tests/cmocka/test_sysdb_domain_resolution_order.c \
|
||||
+ $(NULL)
|
||||
+test_sysdb_domain_resolution_order_CFLAGS = \
|
||||
+ $(AM_CFLAGS) \
|
||||
+ $(NULL)
|
||||
+test_sysdb_domain_resolution_order_LDADD = \
|
||||
+ $(CMOCKA_LIBS) \
|
||||
+ $(LDB_LIBS) \
|
||||
+ $(POPT_LIBS) \
|
||||
+ $(TALLOC_LIBS) \
|
||||
+ $(SSSD_INTERNAL_LTLIBS) \
|
||||
+ libsss_test_common.la \
|
||||
+ $(NULL)
|
||||
+
|
||||
test_wbc_calls_SOURCES = \
|
||||
src/tests/cmocka/test_wbc_calls.c \
|
||||
src/sss_client/idmap/sss_nss_idmap.c \
|
||||
diff --git a/src/tests/cmocka/test_sysdb_domain_resolution_order.c b/src/tests/cmocka/test_sysdb_domain_resolution_order.c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..59a85ce431be9ac27c1e8e6b5e4e5f8300af549e
|
||||
--- /dev/null
|
||||
+++ b/src/tests/cmocka/test_sysdb_domain_resolution_order.c
|
||||
@@ -0,0 +1,190 @@
|
||||
+/*
|
||||
+ SSSD
|
||||
+
|
||||
+ sysdb_domain_resolution_order - Tests for domain resolution order calls
|
||||
+
|
||||
+ Authors:
|
||||
+ Fabiano Fidêncio <fidencio@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 <stdarg.h>
|
||||
+#include <stddef.h>
|
||||
+#include <setjmp.h>
|
||||
+#include <cmocka.h>
|
||||
+#include <popt.h>
|
||||
+
|
||||
+#include "tests/cmocka/common_mock.h"
|
||||
+#include "tests/common.h"
|
||||
+#include "db/sysdb_domain_resolution_order.h"
|
||||
+#include "db/sysdb_private.h" /* for sysdb->ldb member */
|
||||
+
|
||||
+#define TESTS_PATH "tp_" BASE_FILE_STEM
|
||||
+#define TEST_CONF_DB "test_sysdb_domain_resolution_order.ldb"
|
||||
+
|
||||
+#define TEST_DOM_NAME "test_sysdb_domain_resolution_order"
|
||||
+
|
||||
+#define TEST_ID_PROVIDER "ldap"
|
||||
+
|
||||
+struct domain_resolution_order_test_ctx {
|
||||
+ struct sss_test_ctx *tctx;
|
||||
+};
|
||||
+
|
||||
+static int test_sysdb_domain_resolution_order_setup(void **state)
|
||||
+{
|
||||
+ struct domain_resolution_order_test_ctx *test_ctx;
|
||||
+
|
||||
+ assert_true(leak_check_setup());
|
||||
+
|
||||
+ test_ctx = talloc_zero(global_talloc_context,
|
||||
+ struct domain_resolution_order_test_ctx);
|
||||
+ assert_non_null(test_ctx);
|
||||
+
|
||||
+ test_dom_suite_setup(TESTS_PATH);
|
||||
+
|
||||
+ test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH,
|
||||
+ TEST_CONF_DB, TEST_DOM_NAME,
|
||||
+ TEST_ID_PROVIDER, NULL);
|
||||
+ assert_non_null(test_ctx->tctx);
|
||||
+
|
||||
+ *state = test_ctx;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int test_sysdb_domain_resolution_order_teardown(void **state)
|
||||
+{
|
||||
+ struct domain_resolution_order_test_ctx *test_ctx =
|
||||
+ talloc_get_type(*state, struct domain_resolution_order_test_ctx);
|
||||
+
|
||||
+ test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
|
||||
+ talloc_free(test_ctx);
|
||||
+ assert_true(leak_check_teardown());
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void test_sysdb_domain_resolution_order_ops(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ struct domain_resolution_order_test_ctx *test_ctx =
|
||||
+ talloc_get_type(*state, struct domain_resolution_order_test_ctx);
|
||||
+ const char *domains_in = NULL;
|
||||
+ const char *domains_out = NULL;
|
||||
+ struct ldb_dn *dn;
|
||||
+
|
||||
+ dn = ldb_dn_new_fmt(test_ctx, test_ctx->tctx->dom->sysdb->ldb,
|
||||
+ SYSDB_DOM_BASE, test_ctx->tctx->dom->name);
|
||||
+
|
||||
+ /* Adding domainResolutionOrder for the first time */
|
||||
+ domains_in = "foo:bar:foobar";
|
||||
+ ret = sysdb_update_domain_resolution_order(test_ctx->tctx->dom->sysdb,
|
||||
+ dn, domains_in);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = sysdb_get_domain_resolution_order(test_ctx,
|
||||
+ test_ctx->tctx->dom->sysdb, dn,
|
||||
+ &domains_out);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ assert_true(strcmp(domains_in, domains_out) == 0);
|
||||
+
|
||||
+ /* Setting the domainResolutionOrder to ":" ...
|
||||
+ *
|
||||
+ * It means, the domainResolutionOrder is set, but if there's another
|
||||
+ * domainResolutionOrder with lower precedence those must be ignored.
|
||||
+ */
|
||||
+ domains_in = ":";
|
||||
+ ret = sysdb_update_domain_resolution_order(test_ctx->tctx->dom->sysdb,
|
||||
+ dn, domains_in);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = sysdb_get_domain_resolution_order(test_ctx,
|
||||
+ test_ctx->tctx->dom->sysdb, dn,
|
||||
+ &domains_out);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ assert_true(strcmp(domains_in, domains_out) == 0);
|
||||
+
|
||||
+ /* Changing the domainResolutionOrder */
|
||||
+ domains_in = "bar:foobar:foo";
|
||||
+ ret = sysdb_update_domain_resolution_order(test_ctx->tctx->dom->sysdb,
|
||||
+ dn, domains_in);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = sysdb_get_domain_resolution_order(test_ctx,
|
||||
+ test_ctx->tctx->dom->sysdb, dn,
|
||||
+ &domains_out);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ assert_true(strcmp(domains_out, domains_out) == 0);
|
||||
+
|
||||
+ /* Removing the domainResolutionOrder attribute */
|
||||
+ domains_in = NULL;
|
||||
+ ret = sysdb_update_domain_resolution_order(test_ctx->tctx->dom->sysdb,
|
||||
+ dn, domains_in);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = sysdb_get_domain_resolution_order(test_ctx,
|
||||
+ test_ctx->tctx->dom->sysdb, dn,
|
||||
+ &domains_out);
|
||||
+ assert_int_equal(ret, ENOENT);
|
||||
+ assert_true(domains_out == NULL);
|
||||
+}
|
||||
+
|
||||
+int main(int argc, const char *argv[])
|
||||
+{
|
||||
+ int rv;
|
||||
+ int no_cleanup = 0;
|
||||
+ poptContext pc;
|
||||
+ int opt;
|
||||
+ struct poptOption long_options[] = {
|
||||
+ POPT_AUTOHELP
|
||||
+ SSSD_DEBUG_OPTS
|
||||
+ {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0,
|
||||
+ _("Do not delete the test database after a test run"), NULL },
|
||||
+ POPT_TABLEEND
|
||||
+ };
|
||||
+
|
||||
+ const struct CMUnitTest tests[] = {
|
||||
+ cmocka_unit_test_setup_teardown(test_sysdb_domain_resolution_order_ops,
|
||||
+ test_sysdb_domain_resolution_order_setup,
|
||||
+ test_sysdb_domain_resolution_order_teardown),
|
||||
+ };
|
||||
+
|
||||
+ /* Set debug level to invalid value so we can deside if -d 0 was used. */
|
||||
+ debug_level = SSSDBG_INVALID;
|
||||
+
|
||||
+ pc = poptGetContext(argv[0], argc, argv, long_options, 0);
|
||||
+ while((opt = poptGetNextOpt(pc)) != -1) {
|
||||
+ switch(opt) {
|
||||
+ default:
|
||||
+ fprintf(stderr, "\nInvalid option %s: %s\n\n",
|
||||
+ poptBadOption(pc, 0), poptStrerror(opt));
|
||||
+ poptPrintUsage(pc, stderr, 0);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+ poptFreeContext(pc);
|
||||
+
|
||||
+ DEBUG_CLI_INIT(debug_level);
|
||||
+
|
||||
+ tests_set_cwd();
|
||||
+ test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, LOCAL_SYSDB_FILE);
|
||||
+ test_dom_suite_setup(TESTS_PATH);
|
||||
+ rv = cmocka_run_group_tests(tests, NULL, NULL);
|
||||
+
|
||||
+ if (rv == 0 && no_cleanup == 0) {
|
||||
+ test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, LOCAL_SYSDB_FILE);
|
||||
+ }
|
||||
+ return rv;
|
||||
+}
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,369 +0,0 @@
|
||||
From 3cbf0e7b63e8e6888917e9215bbdc5674c2fa852 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
||||
Date: Wed, 22 Mar 2017 13:40:20 +0100
|
||||
Subject: [PATCH 51/97] IPA: Get ipaDomainsResolutionOrder from ipaConfig
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
ipaDomainsResolutionOrder provides a list of domains that have to be
|
||||
looked up firstly during cache_req searches.
|
||||
|
||||
This commit only fetches this list from the server and stores its value
|
||||
at sysdb so we can make use of it later on this patch series.
|
||||
|
||||
There are no tests for newly introduced sysdb methods are those are
|
||||
basically only calling sysdb_update_domain_resolution_order(),
|
||||
sysdb_get_domain_resolution_order() and
|
||||
sysdb_get_use_domain_resolution_order() which are have tests written
|
||||
for.
|
||||
|
||||
Related:
|
||||
https://pagure.io/SSSD/sssd/issue/3001
|
||||
|
||||
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/db/sysdb.h | 11 +++
|
||||
src/db/sysdb_subdomains.c | 67 +++++++++++++++
|
||||
src/providers/ipa/ipa_subdomains.c | 168 ++++++++++++++++++++++++++++++++++---
|
||||
3 files changed, 234 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
|
||||
index 42d2857ed7765c17e7d84b0da93ed07758fbe012..75a07d4d2effb028ec654342113f8478e1eba10e 100644
|
||||
--- a/src/db/sysdb.h
|
||||
+++ b/src/db/sysdb.h
|
||||
@@ -489,6 +489,17 @@ int sysdb_transaction_cancel(struct sysdb_ctx *sysdb);
|
||||
/* functions related to subdomains */
|
||||
errno_t sysdb_domain_create(struct sysdb_ctx *sysdb, const char *domain_name);
|
||||
|
||||
+errno_t sysdb_domain_get_domain_resolution_order(
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ struct sysdb_ctx *sysdb,
|
||||
+ const char *domain_name,
|
||||
+ const char **_domain_resolution_order);
|
||||
+
|
||||
+errno_t sysdb_domain_update_domain_resolution_order(
|
||||
+ struct sysdb_ctx *sysdb,
|
||||
+ const char *domain_name,
|
||||
+ const char *domain_resolution_order);
|
||||
+
|
||||
errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb,
|
||||
const char *name, const char *realm,
|
||||
const char *flat_name, const char *domain_id,
|
||||
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
|
||||
index 916dbba153d8c08837425f6fd29a20f5a6aa9fc9..e2a4f7bb1fcdf20b6b7e04efc7f396d1c3d08f0f 100644
|
||||
--- a/src/db/sysdb_subdomains.c
|
||||
+++ b/src/db/sysdb_subdomains.c
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "util/util.h"
|
||||
#include "db/sysdb_private.h"
|
||||
+#include "db/sysdb_domain_resolution_order.h"
|
||||
|
||||
static errno_t
|
||||
check_subdom_config_file(struct confdb_ctx *confdb,
|
||||
@@ -1210,3 +1211,69 @@ done:
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+errno_t
|
||||
+sysdb_domain_get_domain_resolution_order(TALLOC_CTX *mem_ctx,
|
||||
+ struct sysdb_ctx *sysdb,
|
||||
+ const char *domain_name,
|
||||
+ const char **_domain_resolution_order)
|
||||
+{
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ struct ldb_dn *dn;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, domain_name);
|
||||
+ if (dn == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_get_domain_resolution_order(mem_ctx, sysdb, dn,
|
||||
+ _domain_resolution_order);
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+errno_t
|
||||
+sysdb_domain_update_domain_resolution_order(struct sysdb_ctx *sysdb,
|
||||
+ const char *domain_name,
|
||||
+ const char *domain_resolution_order)
|
||||
+{
|
||||
+
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ struct ldb_dn *dn;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, domain_name);
|
||||
+ if (dn == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_update_domain_resolution_order(sysdb, dn,
|
||||
+ domain_resolution_order);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "sysdb_update_domain_resolution_order() failed [%d]: [%s].\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
|
||||
index a07b88fe2f499353293ba90345552413c9792f4b..01a0ce812d861b24565d2f71f27d6b8ceb2965bc 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains.c
|
||||
+++ b/src/providers/ipa/ipa_subdomains.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "providers/ipa/ipa_common.h"
|
||||
#include "providers/ipa/ipa_id.h"
|
||||
#include "providers/ipa/ipa_opts.h"
|
||||
+#include "providers/ipa/ipa_config.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -51,6 +52,8 @@
|
||||
|
||||
#define IPA_ASSIGNED_ID_VIEW "ipaAssignedIDView"
|
||||
|
||||
+#define IPA_DOMAIN_RESOLUTION_ORDER "ipaDomainResolutionOrder"
|
||||
+
|
||||
/* do not refresh more often than every 5 seconds for now */
|
||||
#define IPA_SUBDOMAIN_REFRESH_LIMIT 5
|
||||
|
||||
@@ -1681,6 +1684,117 @@ static errno_t ipa_subdomains_view_name_recv(struct tevent_req *req)
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+struct ipa_domain_resolution_order_state {
|
||||
+ struct sss_domain_info *domain;
|
||||
+};
|
||||
+
|
||||
+static void ipa_domain_resolution_order_done(struct tevent_req *subreq);
|
||||
+
|
||||
+static struct tevent_req *
|
||||
+ipa_domain_resolution_order_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct ipa_subdomains_ctx *sd_ctx,
|
||||
+ struct sdap_handle *sh)
|
||||
+{
|
||||
+ struct ipa_domain_resolution_order_state *state;
|
||||
+ struct tevent_req *subreq;
|
||||
+ struct tevent_req *req;
|
||||
+ const char *attrs[] = {IPA_DOMAIN_RESOLUTION_ORDER, NULL};
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state,
|
||||
+ struct ipa_domain_resolution_order_state);
|
||||
+ if (req == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ state->domain = sd_ctx->be_ctx->domain;
|
||||
+
|
||||
+ subreq = ipa_get_config_send(state, ev, sh, sd_ctx->sdap_id_ctx->opts,
|
||||
+ state->domain->name, attrs);
|
||||
+ if (subreq == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto immediately;
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_set_callback(subreq, ipa_domain_resolution_order_done, req);
|
||||
+
|
||||
+ return req;
|
||||
+
|
||||
+immediately:
|
||||
+ if (ret == EOK) {
|
||||
+ tevent_req_done(req);
|
||||
+ } else {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ }
|
||||
+ tevent_req_post(req, ev);
|
||||
+
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static void ipa_domain_resolution_order_done(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct ipa_domain_resolution_order_state *state;
|
||||
+ struct tevent_req *req;
|
||||
+ struct sysdb_attrs *config = NULL;
|
||||
+ const char *domain_resolution_order = NULL;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_callback_data(subreq, struct tevent_req);
|
||||
+ state = tevent_req_data(req, struct ipa_domain_resolution_order_state);
|
||||
+
|
||||
+ ret = ipa_get_config_recv(subreq, state, &config);
|
||||
+ talloc_zfree(subreq);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Failed to get the domains' resolution order configuration "
|
||||
+ "from the server [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (config != NULL) {
|
||||
+ ret = sysdb_attrs_get_string(config, IPA_DOMAIN_RESOLUTION_ORDER,
|
||||
+ &domain_resolution_order);
|
||||
+ if (ret != EOK && ret != ENOENT) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Failed to get the domains' resolution order configuration "
|
||||
+ "value [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ } else if (ret == ENOENT) {
|
||||
+ domain_resolution_order = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_domain_update_domain_resolution_order(
|
||||
+ state->domain->sysdb, state->domain->name,
|
||||
+ domain_resolution_order);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "sysdb_domain_update_resolution_order() [%d]: [%s].\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ if (ret != EOK) {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_done(req);
|
||||
+}
|
||||
+
|
||||
+static errno_t ipa_domain_resolution_order_recv(struct tevent_req *req)
|
||||
+{
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
|
||||
struct ipa_subdomains_refresh_state {
|
||||
struct tevent_context *ev;
|
||||
@@ -1695,6 +1809,7 @@ static void ipa_subdomains_refresh_certmap_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_master_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_slave_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_view_done(struct tevent_req *subreq);
|
||||
+static void ipa_domain_refresh_resolution_order_done(struct tevent_req *subreq);
|
||||
|
||||
static struct tevent_req *
|
||||
ipa_subdomains_refresh_send(TALLOC_CTX *mem_ctx,
|
||||
@@ -1916,7 +2031,6 @@ static void ipa_subdomains_refresh_view_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct ipa_subdomains_refresh_state *state;
|
||||
struct tevent_req *req;
|
||||
- int dp_error;
|
||||
errno_t ret;
|
||||
|
||||
req = tevent_req_callback_data(subreq, struct tevent_req);
|
||||
@@ -1924,24 +2038,55 @@ static void ipa_subdomains_refresh_view_done(struct tevent_req *subreq)
|
||||
|
||||
ret = ipa_subdomains_view_name_recv(subreq);
|
||||
talloc_zfree(subreq);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Unable to get view name [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ tevent_req_error(req, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ subreq = ipa_domain_resolution_order_send(state, state->ev, state->sd_ctx,
|
||||
+ sdap_id_op_handle(state->sdap_op));
|
||||
+ if (subreq == NULL) {
|
||||
+ tevent_req_error(req, ENOMEM);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_set_callback(subreq,
|
||||
+ ipa_domain_refresh_resolution_order_done,
|
||||
+ req);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ipa_domain_refresh_resolution_order_done(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct ipa_subdomains_refresh_state *state;
|
||||
+ struct tevent_req *req;
|
||||
+ int dp_error;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_callback_data(subreq, struct tevent_req);
|
||||
+ state = tevent_req_data(req, struct ipa_subdomains_refresh_state);
|
||||
+
|
||||
+ ret = ipa_domain_resolution_order_recv(subreq);
|
||||
+ talloc_zfree(subreq);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "Unable to get the domains order resolution [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ tevent_req_error(req, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
|
||||
if (dp_error == DP_ERR_OK && ret != EOK) {
|
||||
/* retry */
|
||||
ret = ipa_subdomains_refresh_retry(req);
|
||||
- if (ret != EOK) {
|
||||
- goto done;
|
||||
- }
|
||||
- return;
|
||||
} else if (dp_error == DP_ERR_OFFLINE) {
|
||||
ret = ERR_OFFLINE;
|
||||
- goto done;
|
||||
- } else if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get view name "
|
||||
- "[%d]: %s\n", ret, sss_strerror(ret));
|
||||
- goto done;
|
||||
}
|
||||
|
||||
-done:
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_TRACE_FUNC, "Unable to refresh subdomains [%d]: %s\n",
|
||||
ret, sss_strerror(ret));
|
||||
@@ -1949,7 +2094,6 @@ done:
|
||||
return;
|
||||
}
|
||||
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, "Subdomains refreshed.\n");
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,54 +0,0 @@
|
||||
From 17ab121a6c69d74acf1d40f2bbcbe90d77bb6b8a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
||||
Date: Fri, 24 Mar 2017 08:08:58 +0100
|
||||
Subject: [PATCH 52/97] IPA_SUBDOMAINS: Rename _refresh_view() to
|
||||
_refresh_view_name()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This method got renamed in order to match better with what it does
|
||||
currently.
|
||||
|
||||
Related:
|
||||
https://pagure.io/SSSD/sssd/issue/3001
|
||||
|
||||
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/providers/ipa/ipa_subdomains.c | 7 ++++---
|
||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
|
||||
index 01a0ce812d861b24565d2f71f27d6b8ceb2965bc..bf6f6ab1fa8bfff7ea102dd219c9ddbbab065b2b 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains.c
|
||||
+++ b/src/providers/ipa/ipa_subdomains.c
|
||||
@@ -1808,7 +1808,7 @@ static void ipa_subdomains_refresh_ranges_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_certmap_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_master_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_slave_done(struct tevent_req *subreq);
|
||||
-static void ipa_subdomains_refresh_view_done(struct tevent_req *subreq);
|
||||
+static void ipa_subdomains_refresh_view_name_done(struct tevent_req *subreq);
|
||||
static void ipa_domain_refresh_resolution_order_done(struct tevent_req *subreq);
|
||||
|
||||
static struct tevent_req *
|
||||
@@ -2023,11 +2023,12 @@ static void ipa_subdomains_refresh_slave_done(struct tevent_req *subreq)
|
||||
return;
|
||||
}
|
||||
|
||||
- tevent_req_set_callback(subreq, ipa_subdomains_refresh_view_done, req);
|
||||
+ tevent_req_set_callback(subreq, ipa_subdomains_refresh_view_name_done,
|
||||
+ req);
|
||||
return;
|
||||
}
|
||||
|
||||
-static void ipa_subdomains_refresh_view_done(struct tevent_req *subreq)
|
||||
+static void ipa_subdomains_refresh_view_name_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct ipa_subdomains_refresh_state *state;
|
||||
struct tevent_req *req;
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,347 +0,0 @@
|
||||
From fb81f337b68c85471c3f5140850dccf549a2d0ac Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
||||
Date: Fri, 24 Mar 2017 17:46:04 +0100
|
||||
Subject: [PATCH 53/97] IPA: Get ipaDomainsResolutionOrder from IPA ID View
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
ipaDomainsResolutionOrder provides a list of domains that have to be
|
||||
looked up firstly during cache_req searches.
|
||||
|
||||
This commit only fetches this list from the server and stores its value
|
||||
at sysdb so we can make use of it later on this patch series.
|
||||
|
||||
There are no tests for newly introduced sysdb methods are those are
|
||||
basically only calling sysdb_update_domain_resolution_order(),
|
||||
sysdb_get_domain_resolution_order() and
|
||||
sysdb_get_use_domain_resolution_order() which are have tests written
|
||||
for.
|
||||
|
||||
Related:
|
||||
https://pagure.io/SSSD/sssd/issue/3001
|
||||
|
||||
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/db/sysdb.h | 9 ++
|
||||
src/db/sysdb_views.c | 66 ++++++++++++++
|
||||
src/providers/ipa/ipa_subdomains.c | 182 +++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 257 insertions(+)
|
||||
|
||||
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
|
||||
index 75a07d4d2effb028ec654342113f8478e1eba10e..62c561be9452a284a8ddf8ebb45720265852c8b0 100644
|
||||
--- a/src/db/sysdb.h
|
||||
+++ b/src/db/sysdb.h
|
||||
@@ -533,6 +533,15 @@ errno_t sysdb_update_view_name(struct sysdb_ctx *sysdb, const char *view_name);
|
||||
errno_t sysdb_get_view_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
|
||||
char **view_name);
|
||||
|
||||
+errno_t sysdb_update_view_domain_resolution_order(
|
||||
+ struct sysdb_ctx *sysdb,
|
||||
+ const char *domain_resolution_order);
|
||||
+
|
||||
+errno_t sysdb_get_view_domain_resolution_order(
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ struct sysdb_ctx *sysdb,
|
||||
+ const char **_domain_resolution_order);
|
||||
+
|
||||
static inline bool is_default_view(const char *view_name)
|
||||
{
|
||||
/* NULL is treated as default */
|
||||
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
|
||||
index 1c416dd14049237e9f35d52f154035e3ff861469..20db9b06183d68b33bb19f498513d7f5cf84b1cf 100644
|
||||
--- a/src/db/sysdb_views.c
|
||||
+++ b/src/db/sysdb_views.c
|
||||
@@ -22,6 +22,9 @@
|
||||
#include "util/util.h"
|
||||
#include "util/cert.h"
|
||||
#include "db/sysdb_private.h"
|
||||
+#include "db/sysdb_domain_resolution_order.h"
|
||||
+
|
||||
+#define SYSDB_VIEWS_BASE "cn=views,cn=sysdb"
|
||||
|
||||
/* In general is should not be possible that there is a view container without
|
||||
* a view name set. But to be on the safe side we return both information
|
||||
@@ -179,6 +182,69 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+errno_t
|
||||
+sysdb_get_view_domain_resolution_order(TALLOC_CTX *mem_ctx,
|
||||
+ struct sysdb_ctx *sysdb,
|
||||
+ const char **_domain_resolution_order)
|
||||
+{
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ struct ldb_dn *dn;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_VIEWS_BASE);
|
||||
+ if (dn == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_get_domain_resolution_order(mem_ctx, sysdb, dn,
|
||||
+ _domain_resolution_order);
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+errno_t
|
||||
+sysdb_update_view_domain_resolution_order(struct sysdb_ctx *sysdb,
|
||||
+ const char *domain_resolution_order)
|
||||
+{
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ struct ldb_dn *dn;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_VIEWS_BASE);
|
||||
+ if (dn == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_update_domain_resolution_order(sysdb, dn,
|
||||
+ domain_resolution_order);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "sysdb_update_domain_resolution_order() failed [%d]: [%s].\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
errno_t sysdb_delete_view_tree(struct sysdb_ctx *sysdb, const char *view_name)
|
||||
{
|
||||
struct ldb_dn *dn;
|
||||
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
|
||||
index bf6f6ab1fa8bfff7ea102dd219c9ddbbab065b2b..ef348adf4a36e870f44387bd700f5c2beea3bfd6 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains.c
|
||||
+++ b/src/providers/ipa/ipa_subdomains.c
|
||||
@@ -1684,6 +1684,151 @@ static errno_t ipa_subdomains_view_name_recv(struct tevent_req *req)
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+struct ipa_subdomains_view_domain_resolution_order_state {
|
||||
+ struct sss_domain_info *domain;
|
||||
+ const char *view_name;
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
+ipa_subdomains_view_domain_resolution_order_done(struct tevent_req *subreq);
|
||||
+
|
||||
+static struct tevent_req *
|
||||
+ipa_subdomains_view_domain_resolution_order_send(
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct ipa_subdomains_ctx *sd_ctx,
|
||||
+ struct sdap_handle *sh)
|
||||
+{
|
||||
+ struct ipa_subdomains_view_domain_resolution_order_state *state;
|
||||
+ struct tevent_req *subreq;
|
||||
+ struct tevent_req *req;
|
||||
+ const char *attrs[] = { IPA_DOMAIN_RESOLUTION_ORDER, NULL };
|
||||
+ char *ldap_basedn;
|
||||
+ char *base;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_create(mem_ctx, &state,
|
||||
+ struct ipa_subdomains_view_domain_resolution_order_state);
|
||||
+ if (req == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ state->domain = sd_ctx->be_ctx->domain;
|
||||
+ state->view_name = sd_ctx->ipa_id_ctx->view_name;
|
||||
+
|
||||
+ ret = domain_to_basedn(state, sd_ctx->be_ctx->domain->name, &ldap_basedn);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
|
||||
+ goto immediately;
|
||||
+ }
|
||||
+
|
||||
+ base = talloc_asprintf(state, "cn=%s,cn=views,cn=accounts,%s",
|
||||
+ sd_ctx->ipa_id_ctx->view_name, ldap_basedn);
|
||||
+ if (base == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto immediately;
|
||||
+ }
|
||||
+
|
||||
+ subreq = sdap_get_generic_send(
|
||||
+ state, ev, sd_ctx->sdap_id_ctx->opts, sh,
|
||||
+ base, LDAP_SCOPE_BASE, NULL, attrs, NULL, 0,
|
||||
+ dp_opt_get_int(sd_ctx->sdap_id_ctx->opts->basic,
|
||||
+ SDAP_ENUM_SEARCH_TIMEOUT),
|
||||
+ false);
|
||||
+ if (subreq == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto immediately;
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_set_callback(subreq, ipa_subdomains_view_domain_resolution_order_done,
|
||||
+ req);
|
||||
+
|
||||
+ return req;
|
||||
+
|
||||
+immediately:
|
||||
+ if (ret == EOK) {
|
||||
+ tevent_req_done(req);
|
||||
+ } else {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ }
|
||||
+ tevent_req_post(req, ev);
|
||||
+
|
||||
+ return req;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ipa_subdomains_view_domain_resolution_order_done(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct ipa_subdomains_view_domain_resolution_order_state *state;
|
||||
+ struct tevent_req *req;
|
||||
+ size_t reply_count;
|
||||
+ struct sysdb_attrs **reply;
|
||||
+ const char *domain_resolution_order;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_callback_data(subreq, struct tevent_req);
|
||||
+ state = tevent_req_data(req,
|
||||
+ struct ipa_subdomains_view_domain_resolution_order_state);
|
||||
+
|
||||
+ ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
|
||||
+ talloc_zfree(subreq);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to get view name [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (reply_count > 1) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "More than one object returned.\n");
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ } else if (reply_count == 0) {
|
||||
+ domain_resolution_order = NULL;
|
||||
+ } else {
|
||||
+ /* reply_count == 1 */
|
||||
+ ret = sysdb_attrs_get_string(reply[0], IPA_DOMAIN_RESOLUTION_ORDER,
|
||||
+ &domain_resolution_order);
|
||||
+ if (ret != EOK && ret != ENOENT) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Failed to get the view domains' resolution order "
|
||||
+ "configuration value for view [%s] [%d]: %s\n",
|
||||
+ state->view_name, ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ } else if (ret == ENOENT) {
|
||||
+ domain_resolution_order = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_update_view_domain_resolution_order(state->domain->sysdb,
|
||||
+ domain_resolution_order);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "sysdb_update_view_domain_resolution_order() [%d]: [%s].\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ if (ret != EOK) {
|
||||
+ tevent_req_error(req, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_done(req);
|
||||
+}
|
||||
+
|
||||
+static errno_t
|
||||
+ipa_subdomains_view_domain_resolution_order_recv(struct tevent_req *req)
|
||||
+{
|
||||
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
struct ipa_domain_resolution_order_state {
|
||||
struct sss_domain_info *domain;
|
||||
};
|
||||
@@ -1809,6 +1954,8 @@ static void ipa_subdomains_refresh_certmap_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_master_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_slave_done(struct tevent_req *subreq);
|
||||
static void ipa_subdomains_refresh_view_name_done(struct tevent_req *subreq);
|
||||
+static void ipa_subdomains_refresh_view_domain_resolution_order_done(
|
||||
+ struct tevent_req *subreq);
|
||||
static void ipa_domain_refresh_resolution_order_done(struct tevent_req *subreq);
|
||||
|
||||
static struct tevent_req *
|
||||
@@ -2047,6 +2194,41 @@ static void ipa_subdomains_refresh_view_name_done(struct tevent_req *subreq)
|
||||
return;
|
||||
}
|
||||
|
||||
+ subreq = ipa_subdomains_view_domain_resolution_order_send(
|
||||
+ state,
|
||||
+ state->ev,
|
||||
+ state->sd_ctx,
|
||||
+ sdap_id_op_handle(state->sdap_op));
|
||||
+ if (subreq == NULL) {
|
||||
+ tevent_req_error(req, ENOMEM);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ tevent_req_set_callback(subreq,
|
||||
+ ipa_subdomains_refresh_view_domain_resolution_order_done,
|
||||
+ req);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ipa_subdomains_refresh_view_domain_resolution_order_done(struct tevent_req *subreq)
|
||||
+{
|
||||
+ struct ipa_subdomains_refresh_state *state;
|
||||
+ struct tevent_req *req;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ req = tevent_req_callback_data(subreq, struct tevent_req);
|
||||
+ state = tevent_req_data(req, struct ipa_subdomains_refresh_state);
|
||||
+
|
||||
+ ret = ipa_subdomains_view_domain_resolution_order_recv(subreq);
|
||||
+ talloc_zfree(subreq);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Unable to get view domain_resolution order [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ tevent_req_error(req, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
subreq = ipa_domain_resolution_order_send(state, state->ev, state->sd_ctx,
|
||||
sdap_id_op_handle(state->sdap_op));
|
||||
if (subreq == NULL) {
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,37 +0,0 @@
|
||||
From 34228050af1e25706f61ec9df648852284b61c2b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
||||
Date: Tue, 21 Mar 2017 20:56:38 +0100
|
||||
Subject: [PATCH 54/97] DLINKLIST: Add DLIST_FOR_EACH_SAFE macro
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This macro, as DLIST_FOR_EACH, iterates over the whole list. The main
|
||||
difference between both is that in the _SAFE version the pointer to the
|
||||
next list node is stored, allowing us to delete the current node safely.
|
||||
|
||||
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/util/dlinklist.h | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/src/util/dlinklist.h b/src/util/dlinklist.h
|
||||
index 4f6aef830e914c22654970081263d43461c1750f..017c60468e66dbec15724d5f4832da412f42136b 100644
|
||||
--- a/src/util/dlinklist.h
|
||||
+++ b/src/util/dlinklist.h
|
||||
@@ -147,4 +147,9 @@ do { \
|
||||
#define DLIST_FOR_EACH(p, list) \
|
||||
for ((p) = (list); (p) != NULL; (p) = (p)->next)
|
||||
|
||||
+#define DLIST_FOR_EACH_SAFE(p, q, list) \
|
||||
+ for ((p) = (list), (q) = (p) != NULL ? (p)->next : NULL; \
|
||||
+ (p) != NULL; \
|
||||
+ (p) = (q), (q) = (p) != NULL ? (p)->next : NULL)
|
||||
+
|
||||
#endif /* _DLINKLIST_H */
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,795 +0,0 @@
|
||||
From 66c8e92eb5a4985bb7f64c349a53b08030a000cf Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
||||
Date: Sun, 26 Mar 2017 00:27:50 +0100
|
||||
Subject: [PATCH 55/97] CACHE_REQ: Make use of domainResolutionOrder
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
domainResolutionOrder has been introduced in the previous commits and
|
||||
allows the admin to set up a specific order which the domains will be
|
||||
resolved during a lookup and with this patch we can take advantage of
|
||||
this.
|
||||
|
||||
In order to have it working a new structure has been added
|
||||
(struct domain_resolution_order) to the responder context and will be
|
||||
used by the cache_req to perform the lookups based on this list.
|
||||
|
||||
As the ipaDomainResolutionOrder may be set globally on IPA or per View,
|
||||
SSSD does respect the following precedence order: View > Globally.
|
||||
|
||||
The way the list is built is quite simple, basically having the domains
|
||||
present on ipaDomainResolutionOrder as the first domains (in that
|
||||
specific order) and then appending the remaining domains to this list.
|
||||
The final result is a completely flat list with all the domains
|
||||
respecting the specified order (it's important to remember that the
|
||||
domains not specified won't follow any specific order, they're just
|
||||
"random" based on the domains list present in the responder context.
|
||||
|
||||
Related:
|
||||
https://pagure.io/SSSD/sssd/issue/3001
|
||||
|
||||
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
Makefile.am | 3 +
|
||||
src/responder/common/cache_req/cache_req.c | 89 +++++++-----
|
||||
src/responder/common/cache_req/cache_req_domain.c | 166 ++++++++++++++++++++++
|
||||
src/responder/common/cache_req/cache_req_domain.h | 46 ++++++
|
||||
src/responder/common/responder.h | 5 +
|
||||
src/responder/common/responder_common.c | 153 ++++++++++++++++++++
|
||||
src/responder/common/responder_get_domains.c | 14 ++
|
||||
src/tests/cmocka/common_mock_resp.c | 6 +
|
||||
src/tests/cmocka/common_mock_resp_dp.c | 7 +
|
||||
src/tests/cmocka/test_nss_srv.c | 4 +
|
||||
src/tests/cwrap/Makefile.am | 1 +
|
||||
11 files changed, 457 insertions(+), 37 deletions(-)
|
||||
create mode 100644 src/responder/common/cache_req/cache_req_domain.c
|
||||
create mode 100644 src/responder/common/cache_req/cache_req_domain.h
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 450785bf4c482cce1e1440f1336879150537888e..573b37c52fdeab1add4ea057e1e1844ea4d348a5 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -528,6 +528,7 @@ SSSD_CACHE_REQ_OBJ = \
|
||||
src/responder/common/cache_req/cache_req_result.c \
|
||||
src/responder/common/cache_req/cache_req_search.c \
|
||||
src/responder/common/cache_req/cache_req_data.c \
|
||||
+ src/responder/common/cache_req/cache_req_domain.c \
|
||||
src/responder/common/cache_req/plugins/cache_req_common.c \
|
||||
src/responder/common/cache_req/plugins/cache_req_enum_users.c \
|
||||
src/responder/common/cache_req/plugins/cache_req_enum_groups.c \
|
||||
@@ -689,6 +690,7 @@ dist_noinst_HEADERS = \
|
||||
src/responder/common/iface/responder_iface.h \
|
||||
src/responder/common/iface/responder_iface_generated.h \
|
||||
src/responder/common/cache_req/cache_req.h \
|
||||
+ src/responder/common/cache_req/cache_req_domain.h \
|
||||
src/responder/common/cache_req/cache_req_plugin.h \
|
||||
src/responder/common/cache_req/cache_req_private.h \
|
||||
src/responder/common/data_provider/rdp.h \
|
||||
@@ -2199,6 +2201,7 @@ responder_socket_access_tests_SOURCES = \
|
||||
src/responder/common/responder_common.c \
|
||||
src/responder/common/responder_packet.c \
|
||||
src/responder/common/responder_cmd.c \
|
||||
+ src/responder/common/cache_req/cache_req_domain.c \
|
||||
src/responder/common/data_provider/rdp_message.c \
|
||||
src/responder/common/data_provider/rdp_client.c \
|
||||
$(SSSD_RESPONDER_IFACE_OBJ) \
|
||||
diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c
|
||||
index aca150d69b398ceb1a52e5cd6a87d35dbc87020b..483126396f8addbad744ae03bfc739801cd0c18b 100644
|
||||
--- a/src/responder/common/cache_req/cache_req.c
|
||||
+++ b/src/responder/common/cache_req/cache_req.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "util/util.h"
|
||||
+#include "responder/common/responder.h"
|
||||
#include "responder/common/cache_req/cache_req_private.h"
|
||||
#include "responder/common/cache_req/cache_req_plugin.h"
|
||||
|
||||
@@ -316,7 +317,7 @@ struct cache_req_search_domains_state {
|
||||
struct cache_req *cr;
|
||||
|
||||
/* work data */
|
||||
- struct sss_domain_info *domain;
|
||||
+ struct cache_req_domain *cr_domain;
|
||||
struct sss_domain_info *selected_domain;
|
||||
struct cache_req_result **results;
|
||||
size_t num_results;
|
||||
@@ -330,13 +331,14 @@ static errno_t cache_req_search_domains_next(struct tevent_req *req);
|
||||
|
||||
static void cache_req_search_domains_done(struct tevent_req *subreq);
|
||||
|
||||
-struct tevent_req *cache_req_search_domains_send(TALLOC_CTX *mem_ctx,
|
||||
- struct tevent_context *ev,
|
||||
- struct cache_req *cr,
|
||||
- struct sss_domain_info *domain,
|
||||
- bool check_next,
|
||||
- bool bypass_cache,
|
||||
- bool bypass_dp)
|
||||
+struct tevent_req *
|
||||
+cache_req_search_domains_send(TALLOC_CTX *mem_ctx,
|
||||
+ struct tevent_context *ev,
|
||||
+ struct cache_req *cr,
|
||||
+ struct cache_req_domain *cr_domain,
|
||||
+ bool check_next,
|
||||
+ bool bypass_cache,
|
||||
+ bool bypass_dp)
|
||||
{
|
||||
struct tevent_req *req;
|
||||
struct cache_req_search_domains_state *state = NULL;
|
||||
@@ -352,7 +354,7 @@ struct tevent_req *cache_req_search_domains_send(TALLOC_CTX *mem_ctx,
|
||||
state->ev = ev;
|
||||
state->cr = cr;
|
||||
|
||||
- state->domain = domain;
|
||||
+ state->cr_domain = cr_domain;
|
||||
state->check_next = check_next;
|
||||
state->dp_success = true;
|
||||
state->bypass_cache = bypass_cache;
|
||||
@@ -378,6 +380,7 @@ static errno_t cache_req_search_domains_next(struct tevent_req *req)
|
||||
struct cache_req_search_domains_state *state;
|
||||
struct tevent_req *subreq;
|
||||
struct cache_req *cr;
|
||||
+ struct sss_domain_info *domain;
|
||||
uint32_t next_domain_flag;
|
||||
bool is_domain_valid;
|
||||
bool allow_no_fqn;
|
||||
@@ -389,11 +392,21 @@ static errno_t cache_req_search_domains_next(struct tevent_req *req)
|
||||
next_domain_flag = cr->plugin->get_next_domain_flags;
|
||||
allow_no_fqn = cr->plugin->allow_missing_fqn;
|
||||
|
||||
- while (state->domain != NULL) {
|
||||
+ while (state->cr_domain != NULL) {
|
||||
+ domain = state->cr_domain->domain;
|
||||
+ /* As the cr_domain list is a flatten version of the domains
|
||||
+ * list, we have to ensure to only go through the subdomains in
|
||||
+ * case it's specified in the plugin to do so.
|
||||
+ */
|
||||
+ if (next_domain_flag == 0 && IS_SUBDOMAIN(domain)) {
|
||||
+ state->cr_domain = state->cr_domain->next;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
/* Check if this domain is valid for this request. */
|
||||
- is_domain_valid = cache_req_validate_domain(cr, state->domain);
|
||||
+ is_domain_valid = cache_req_validate_domain(cr, domain);
|
||||
if (!is_domain_valid) {
|
||||
- state->domain = get_next_domain(state->domain, next_domain_flag);
|
||||
+ state->cr_domain = state->cr_domain->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -401,18 +414,18 @@ static errno_t cache_req_search_domains_next(struct tevent_req *req)
|
||||
* qualified names on domain less search. We do not descend into
|
||||
* subdomains here since those are implicitly qualified.
|
||||
*/
|
||||
- if (state->check_next && !allow_no_fqn && state->domain->fqnames) {
|
||||
- state->domain = get_next_domain(state->domain, 0);
|
||||
+ if (state->check_next && !allow_no_fqn && domain->fqnames) {
|
||||
+ state->cr_domain = state->cr_domain->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
- state->selected_domain = state->domain;
|
||||
+ state->selected_domain = domain;
|
||||
|
||||
- if (state->domain == NULL) {
|
||||
+ if (domain == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
- ret = cache_req_set_domain(cr, state->domain);
|
||||
+ ret = cache_req_set_domain(cr, domain);
|
||||
if (ret != EOK) {
|
||||
return ret;
|
||||
}
|
||||
@@ -427,8 +440,7 @@ static errno_t cache_req_search_domains_next(struct tevent_req *req)
|
||||
|
||||
/* we will continue with the following domain the next time */
|
||||
if (state->check_next) {
|
||||
- state->domain = get_next_domain(state->domain,
|
||||
- cr->plugin->get_next_domain_flags);
|
||||
+ state->cr_domain = state->cr_domain->next;
|
||||
}
|
||||
|
||||
return EAGAIN;
|
||||
@@ -625,11 +637,12 @@ static void cache_req_input_parsed(struct tevent_req *subreq);
|
||||
static errno_t cache_req_select_domains(struct tevent_req *req,
|
||||
const char *domain_name);
|
||||
|
||||
-static errno_t cache_req_search_domains(struct tevent_req *req,
|
||||
- struct sss_domain_info *domain,
|
||||
- bool check_next,
|
||||
- bool bypass_cache,
|
||||
- bool bypass_dp);
|
||||
+static errno_t
|
||||
+cache_req_search_domains(struct tevent_req *req,
|
||||
+ struct cache_req_domain *oredered_domain,
|
||||
+ bool check_next,
|
||||
+ bool bypass_cache,
|
||||
+ bool bypass_dp);
|
||||
|
||||
static void cache_req_done(struct tevent_req *subreq);
|
||||
|
||||
@@ -778,7 +791,7 @@ static errno_t cache_req_select_domains(struct tevent_req *req,
|
||||
const char *domain_name)
|
||||
{
|
||||
struct cache_req_state *state = NULL;
|
||||
- struct sss_domain_info *domain;
|
||||
+ struct cache_req_domain *cr_domain;
|
||||
bool check_next;
|
||||
bool bypass_cache;
|
||||
bool bypass_dp;
|
||||
@@ -798,29 +811,30 @@ static errno_t cache_req_select_domains(struct tevent_req *req,
|
||||
CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
|
||||
"Performing a single domain search\n");
|
||||
|
||||
- domain = responder_get_domain(state->cr->rctx, domain_name);
|
||||
- if (domain == NULL) {
|
||||
+ cr_domain = cache_req_domain_get_domain_by_name(
|
||||
+ state->cr->rctx->cr_domains, domain_name);
|
||||
+ if (cr_domain == NULL) {
|
||||
return ERR_DOMAIN_NOT_FOUND;
|
||||
}
|
||||
-
|
||||
check_next = false;
|
||||
} else {
|
||||
CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
|
||||
"Performing a multi-domain search\n");
|
||||
|
||||
- domain = state->cr->rctx->domains;
|
||||
+ cr_domain = state->cr->rctx->cr_domains;
|
||||
check_next = true;
|
||||
}
|
||||
|
||||
- return cache_req_search_domains(req, domain, check_next,
|
||||
+ return cache_req_search_domains(req, cr_domain, check_next,
|
||||
bypass_cache, bypass_dp);
|
||||
}
|
||||
|
||||
-static errno_t cache_req_search_domains(struct tevent_req *req,
|
||||
- struct sss_domain_info *domain,
|
||||
- bool check_next,
|
||||
- bool bypass_cache,
|
||||
- bool bypass_dp)
|
||||
+static errno_t
|
||||
+cache_req_search_domains(struct tevent_req *req,
|
||||
+ struct cache_req_domain *cr_domain,
|
||||
+ bool check_next,
|
||||
+ bool bypass_cache,
|
||||
+ bool bypass_dp)
|
||||
{
|
||||
struct tevent_req *subreq;
|
||||
struct cache_req_state *state = NULL;
|
||||
@@ -832,8 +846,9 @@ static errno_t cache_req_search_domains(struct tevent_req *req,
|
||||
bypass_cache ? "bypass" : "check",
|
||||
bypass_dp ? "bypass" : "check");
|
||||
|
||||
- subreq = cache_req_search_domains_send(state, state->ev, state->cr, domain,
|
||||
- check_next, bypass_cache, bypass_dp);
|
||||
+ subreq = cache_req_search_domains_send(state, state->ev, state->cr,
|
||||
+ cr_domain, check_next,
|
||||
+ bypass_cache, bypass_dp);
|
||||
if (subreq == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/cache_req_domain.c b/src/responder/common/cache_req/cache_req_domain.c
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bbabd695f1c6b6c29b7e61f571382ab9adfb0ea2
|
||||
--- /dev/null
|
||||
+++ b/src/responder/common/cache_req/cache_req_domain.c
|
||||
@@ -0,0 +1,166 @@
|
||||
+/*
|
||||
+ Authors:
|
||||
+ Fabiano Fidêncio <fidencio@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 "responder/common/cache_req/cache_req_domain.h"
|
||||
+
|
||||
+struct cache_req_domain *
|
||||
+cache_req_domain_get_domain_by_name(struct cache_req_domain *domains,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ struct cache_req_domain *dom;
|
||||
+ struct cache_req_domain *ret = NULL;
|
||||
+
|
||||
+ DLIST_FOR_EACH(dom, domains) {
|
||||
+ if (sss_domain_get_state(dom->domain) == DOM_DISABLED) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (strcasecmp(dom->domain->name, name) == 0 ||
|
||||
+ (dom->domain->flat_name != NULL &&
|
||||
+ strcasecmp(dom->domain->flat_name, name) == 0)) {
|
||||
+ ret = dom;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (ret == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "Unknown domains [%s].\n", name);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+void cache_req_domain_list_zfree(struct cache_req_domain **cr_domains)
|
||||
+{
|
||||
+ struct cache_req_domain *p, *q, *r;
|
||||
+
|
||||
+ DLIST_FOR_EACH_SAFE(p, q, *cr_domains) {
|
||||
+ r = p;
|
||||
+ DLIST_REMOVE(*cr_domains, p);
|
||||
+ talloc_zfree(r);
|
||||
+ }
|
||||
+
|
||||
+ *cr_domains = NULL;
|
||||
+}
|
||||
+
|
||||
+static struct cache_req_domain *
|
||||
+cache_req_domain_new_list_from_string_list(TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_domain_info *domains,
|
||||
+ char **resolution_order)
|
||||
+{
|
||||
+ struct cache_req_domain *cr_domains = NULL;
|
||||
+ struct cache_req_domain *cr_domain;
|
||||
+ struct sss_domain_info *dom;
|
||||
+ char *name;
|
||||
+ int flag = SSS_GND_ALL_DOMAINS;
|
||||
+ int i;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ if (resolution_order != NULL) {
|
||||
+ for (i = 0; resolution_order[i] != NULL; i++) {
|
||||
+ name = resolution_order[i];
|
||||
+ for (dom = domains; dom; dom = get_next_domain(dom, flag)) {
|
||||
+ if (strcasecmp(name, dom->name) != 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ cr_domain = talloc_zero(mem_ctx, struct cache_req_domain);
|
||||
+ if (cr_domain == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ cr_domain->domain = dom;
|
||||
+
|
||||
+ DLIST_ADD_END(cr_domains, cr_domain,
|
||||
+ struct cache_req_domain *);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (dom = domains; dom; dom = get_next_domain(dom, flag)) {
|
||||
+ if (string_in_list(dom->name, resolution_order, false)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ cr_domain = talloc_zero(mem_ctx, struct cache_req_domain);
|
||||
+ if (cr_domain == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ cr_domain->domain = dom;
|
||||
+
|
||||
+ DLIST_ADD_END(cr_domains, cr_domain, struct cache_req_domain *);
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ if (ret != EOK) {
|
||||
+ cache_req_domain_list_zfree(&cr_domains);
|
||||
+ }
|
||||
+
|
||||
+ return cr_domains;
|
||||
+}
|
||||
+
|
||||
+struct cache_req_domain *
|
||||
+cache_req_domain_new_list_from_domain_resolution_order(
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_domain_info *domains,
|
||||
+ const char *domain_resolution_order)
|
||||
+{
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ struct cache_req_domain *cr_domains = NULL;
|
||||
+ char **list = NULL;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (domain_resolution_order != NULL) {
|
||||
+ if (strcmp(domain_resolution_order, ":") != 0) {
|
||||
+ ret = split_on_separator(tmp_ctx, domain_resolution_order, ':',
|
||||
+ true, true, &list, NULL);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "split_on_separator() failed [%d]: [%s].\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ cr_domains = cache_req_domain_new_list_from_string_list(mem_ctx, domains,
|
||||
+ list);
|
||||
+ if (cr_domains == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "cache_req_domain_new_list_from_domain_resolution_order() "
|
||||
+ "failed [%d]: [%s].\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return cr_domains;
|
||||
+}
|
||||
diff --git a/src/responder/common/cache_req/cache_req_domain.h b/src/responder/common/cache_req/cache_req_domain.h
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..41c50e8c293d7b032cb2f05482c40e93e4f723dc
|
||||
--- /dev/null
|
||||
+++ b/src/responder/common/cache_req/cache_req_domain.h
|
||||
@@ -0,0 +1,46 @@
|
||||
+/*
|
||||
+ Authors:
|
||||
+ Fabiano Fidêncio <fidencio@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 _CACHE_REQ_DOMAIN_H_
|
||||
+#define _CACHE_REQ_DOMAIN_H_
|
||||
+
|
||||
+#include "responder/common/responder.h"
|
||||
+
|
||||
+struct cache_req_domain {
|
||||
+ struct sss_domain_info *domain;
|
||||
+
|
||||
+ struct cache_req_domain *prev;
|
||||
+ struct cache_req_domain *next;
|
||||
+};
|
||||
+
|
||||
+struct cache_req_domain *
|
||||
+cache_req_domain_get_domain_by_name(struct cache_req_domain *domains,
|
||||
+ const char *name);
|
||||
+
|
||||
+struct cache_req_domain *
|
||||
+cache_req_domain_new_list_from_domain_resolution_order(
|
||||
+ TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_domain_info *domains,
|
||||
+ const char *domain_resolution_order);
|
||||
+
|
||||
+void cache_req_domain_list_zfree(struct cache_req_domain **cr_domains);
|
||||
+
|
||||
+
|
||||
+#endif /* _CACHE_REQ_DOMAIN_H_ */
|
||||
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
|
||||
index 4d1048a1e0c9be2cad91317d51baf670ecb3307e..29e3f95caf484f43307c9c28d4abd3f50f360a95 100644
|
||||
--- a/src/responder/common/responder.h
|
||||
+++ b/src/responder/common/responder.h
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "sbus/sssd_dbus.h"
|
||||
#include "responder/common/negcache.h"
|
||||
#include "sss_client/sss_cli.h"
|
||||
+#include "responder/common/cache_req/cache_req_domain.h"
|
||||
|
||||
extern hash_table_t *dp_requests;
|
||||
|
||||
@@ -113,6 +114,8 @@ struct resp_ctx {
|
||||
int domains_timeout;
|
||||
int client_idle_timeout;
|
||||
|
||||
+ struct cache_req_domain *cr_domains;
|
||||
+
|
||||
time_t last_request_time;
|
||||
int idle_timeout;
|
||||
struct tevent_timer *idle;
|
||||
@@ -387,4 +390,6 @@ char *sss_resp_create_fqname(TALLOC_CTX *mem_ctx,
|
||||
bool name_is_upn,
|
||||
const char *orig_name);
|
||||
|
||||
+errno_t sss_resp_populate_cr_domains(struct resp_ctx *rctx);
|
||||
+
|
||||
#endif /* __SSS_RESPONDER_H__ */
|
||||
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
|
||||
index 76f43609651217e537ffa515aaf5b5caa98a2e90..1792a4c3771fa326c7cca31e1981dce315c03758 100644
|
||||
--- a/src/responder/common/responder_common.c
|
||||
+++ b/src/responder/common/responder_common.c
|
||||
@@ -1453,3 +1453,156 @@ fail:
|
||||
return ret;
|
||||
|
||||
}
|
||||
+
|
||||
+/* ====== Helper functions for the domain resolution order ======= */
|
||||
+static struct cache_req_domain *
|
||||
+sss_resp_new_cr_domains_from_ipa_id_view(TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_domain_info *domains,
|
||||
+ struct sysdb_ctx *sysdb)
|
||||
+{
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ struct cache_req_domain *cr_domains = NULL;
|
||||
+ const char *domain_resolution_order = NULL;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_get_view_domain_resolution_order(tmp_ctx, sysdb,
|
||||
+ &domain_resolution_order);
|
||||
+ if (ret != EOK && ret != ENOENT) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "sysdb_get_view_cache_req_domain() failed [%d]: [%s].\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* Using mem_ctx (which is rctx) directly here to avoid copying
|
||||
+ * this memory around. */
|
||||
+ cr_domains = cache_req_domain_new_list_from_domain_resolution_order(
|
||||
+ mem_ctx, domains, domain_resolution_order);
|
||||
+ if (cr_domains == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ DEBUG(SSSDBG_DEFAULT,
|
||||
+ "cache_req_domain_new_list_from_domain_resolution_order() "
|
||||
+ "failed [%d]: [%s].\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return cr_domains;
|
||||
+}
|
||||
+
|
||||
+static struct cache_req_domain *
|
||||
+sss_resp_new_cr_domains_from_ipa_config(TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_domain_info *domains,
|
||||
+ struct sysdb_ctx *sysdb,
|
||||
+ const char *domain)
|
||||
+{
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ struct cache_req_domain *cr_domains = NULL;
|
||||
+ const char *domain_resolution_order = NULL;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_domain_get_domain_resolution_order(tmp_ctx, sysdb, domain,
|
||||
+ &domain_resolution_order);
|
||||
+
|
||||
+ if (ret != EOK && ret != ENOENT) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "sysdb_domain_get_cache_req_domain() failed [%d]: [%s].\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* Using mem_ctx (which is rctx) directly here to avoid copying
|
||||
+ * this memory around. */
|
||||
+ cr_domains = cache_req_domain_new_list_from_domain_resolution_order(
|
||||
+ mem_ctx, domains, domain_resolution_order);
|
||||
+ if (cr_domains == NULL) {
|
||||
+ DEBUG(SSSDBG_DEFAULT,
|
||||
+ "cache_req_domain_new_list_from_domain_resolution_order() "
|
||||
+ "failed [%d]: [%s].\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return cr_domains;
|
||||
+}
|
||||
+
|
||||
+errno_t sss_resp_populate_cr_domains(struct resp_ctx *rctx)
|
||||
+{
|
||||
+ struct cache_req_domain *cr_domains = NULL;
|
||||
+ struct sss_domain_info *dom;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ for (dom = rctx->domains; dom != NULL; dom = dom->next) {
|
||||
+ if (dom->provider != NULL && strcmp(dom->provider, "ipa") == 0) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (dom == NULL) {
|
||||
+ cr_domains = cache_req_domain_new_list_from_domain_resolution_order(
|
||||
+ rctx, rctx->domains, NULL);
|
||||
+ if (cr_domains == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Failed to flatten the list of domains.\n");
|
||||
+ }
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (dom->has_views) {
|
||||
+ cr_domains = sss_resp_new_cr_domains_from_ipa_id_view(rctx,
|
||||
+ rctx->domains,
|
||||
+ dom->sysdb);
|
||||
+ if (cr_domains == NULL) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "Failed to use ipaDomainResolutionOrder set for the "
|
||||
+ "view \"%s\".\n"
|
||||
+ "Trying to fallback to use ipaDomainOrderResolution "
|
||||
+ "set in ipaConfig for the domain: %s.\n",
|
||||
+ dom->view_name, dom->name);
|
||||
+ } else {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ cr_domains = sss_resp_new_cr_domains_from_ipa_config(rctx, rctx->domains,
|
||||
+ dom->sysdb,
|
||||
+ dom->name);
|
||||
+ if (cr_domains == NULL) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "Failed to use ipaDomainResolutionOrder set in ipaConfig "
|
||||
+ "for the domain: \"%s\".\n"
|
||||
+ "No ipaDomainResolutionOrder will be followed.\n",
|
||||
+ dom->name);
|
||||
+ } else {
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ cr_domains = cache_req_domain_new_list_from_domain_resolution_order(
|
||||
+ rctx, rctx->domains, NULL);
|
||||
+ if (cr_domains == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to flatten the list of domains.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
+ ret = cr_domains != NULL ? EOK : ENOMEM;
|
||||
+
|
||||
+ cache_req_domain_list_zfree(&rctx->cr_domains);
|
||||
+ rctx->cr_domains = cr_domains;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/src/responder/common/responder_get_domains.c b/src/responder/common/responder_get_domains.c
|
||||
index 0f9c01214631200f9687635f6302fa5c07e8a1fe..8c90b7773e248e1dd6d846c5050e1931fc50c786 100644
|
||||
--- a/src/responder/common/responder_get_domains.c
|
||||
+++ b/src/responder/common/responder_get_domains.c
|
||||
@@ -192,6 +192,13 @@ struct tevent_req *sss_dp_get_domains_send(TALLOC_CTX *mem_ctx,
|
||||
|
||||
if (state->dom == NULL) {
|
||||
/* All domains were local */
|
||||
+ ret = sss_resp_populate_cr_domains(state->rctx);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "sss_resp_populate_cr_domains() failed [%d]: [%s]\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto immediately;
|
||||
+ }
|
||||
ret = EOK;
|
||||
goto immediately;
|
||||
}
|
||||
@@ -253,6 +260,13 @@ sss_dp_get_domains_process(struct tevent_req *subreq)
|
||||
if (state->dom == NULL) {
|
||||
/* All domains were local */
|
||||
set_time_of_last_request(state->rctx);
|
||||
+ ret = sss_resp_populate_cr_domains(state->rctx);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "sss_resp_populate_cr_domains() failed [%d]: [%s]\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto fail;
|
||||
+ }
|
||||
tevent_req_done(req);
|
||||
return;
|
||||
}
|
||||
diff --git a/src/tests/cmocka/common_mock_resp.c b/src/tests/cmocka/common_mock_resp.c
|
||||
index 88808b1b9394b7a9ee7e58b30b4fbd9d467493d3..175101fc51fd395d792b1fccaecdb327caef2b64 100644
|
||||
--- a/src/tests/cmocka/common_mock_resp.c
|
||||
+++ b/src/tests/cmocka/common_mock_resp.c
|
||||
@@ -51,6 +51,12 @@ mock_rctx(TALLOC_CTX *mem_ctx,
|
||||
rctx->ev = ev;
|
||||
rctx->domains = domains;
|
||||
rctx->pvt_ctx = pvt_ctx;
|
||||
+ if (domains != NULL) {
|
||||
+ ret = sss_resp_populate_cr_domains(rctx);
|
||||
+ if (ret != EOK) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
return rctx;
|
||||
}
|
||||
|
||||
diff --git a/src/tests/cmocka/common_mock_resp_dp.c b/src/tests/cmocka/common_mock_resp_dp.c
|
||||
index 5db5255ab61231870982c4b78a39504ae8954bcd..4b38a38e6f53499132f9fe14a0ec0af157cf85ca 100644
|
||||
--- a/src/tests/cmocka/common_mock_resp_dp.c
|
||||
+++ b/src/tests/cmocka/common_mock_resp_dp.c
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "util/util.h"
|
||||
+#include "responder/common/responder.h"
|
||||
#include "tests/cmocka/common_mock_resp.h"
|
||||
|
||||
/* Mock DP requests that finish immediatelly and return
|
||||
@@ -165,6 +166,12 @@ sss_dp_get_domains_send(TALLOC_CTX *mem_ctx,
|
||||
bool force,
|
||||
const char *hint)
|
||||
{
|
||||
+ errno_t ret;
|
||||
+ ret = sss_resp_populate_cr_domains(rctx);
|
||||
+ if (ret != EOK) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
return test_req_succeed_send(mem_ctx, rctx->ev);
|
||||
}
|
||||
|
||||
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
|
||||
index ede72b341b60842ad470df2794aa90ea9797e999..2f526660cbbbf2443dbae4e213c1336feb6c661e 100644
|
||||
--- a/src/tests/cmocka/test_nss_srv.c
|
||||
+++ b/src/tests/cmocka/test_nss_srv.c
|
||||
@@ -3440,6 +3440,10 @@ static int nss_subdom_test_setup(void **state)
|
||||
nss_test_ctx->tctx->confdb);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
+ ret = sss_resp_populate_cr_domains(nss_test_ctx->rctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ assert_non_null(nss_test_ctx->rctx->cr_domains);
|
||||
+
|
||||
nss_test_ctx->subdom = nss_test_ctx->tctx->dom->subdomains;
|
||||
|
||||
ret = store_group(nss_test_ctx, nss_test_ctx->subdom,
|
||||
diff --git a/src/tests/cwrap/Makefile.am b/src/tests/cwrap/Makefile.am
|
||||
index 4a4090df9296aadde308249f533e7ba246e92f93..c99ebde5f0fc18d1283392cbb307434579d5d811 100644
|
||||
--- a/src/tests/cwrap/Makefile.am
|
||||
+++ b/src/tests/cwrap/Makefile.am
|
||||
@@ -41,6 +41,7 @@ SSSD_CACHE_REQ_OBJ = \
|
||||
../../../src/responder/common/cache_req/cache_req_result.c \
|
||||
../../../src/responder/common/cache_req/cache_req_search.c \
|
||||
../../../src/responder/common/cache_req/cache_req_data.c \
|
||||
+ ../../../src/responder/common/cache_req/cache_req_domain.c \
|
||||
../../../src/responder/common/cache_req/plugins/cache_req_common.c \
|
||||
../../../src/responder/common/cache_req/plugins/cache_req_enum_users.c \
|
||||
../../../src/responder/common/cache_req/plugins/cache_req_enum_groups.c \
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,81 +0,0 @@
|
||||
From 1e437af958f59a0b8bf2f751d3c2ea28365ac64d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
||||
Date: Sun, 26 Mar 2017 01:49:53 +0100
|
||||
Subject: [PATCH 56/97] UTIL: Expose replace_char() as sss_replace_char()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This method is going to be used in the follow-up patch for replacing ','
|
||||
by ':' so we can keep the domain resolution order option consitent with
|
||||
the way it's set on IPA side and still keep consistent with the way
|
||||
lists are represented on sssd.conf file.
|
||||
|
||||
Related:
|
||||
https://pagure.io/SSSD/sssd/issue/3001
|
||||
|
||||
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/util/string_utils.c | 12 ++++++------
|
||||
src/util/util.h | 5 +++++
|
||||
2 files changed, 11 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/util/string_utils.c b/src/util/string_utils.c
|
||||
index 872b7e29e55e8628085affd07f3363019aae5ee9..1215ec96a57089a13f455812adf5a0b0812afa6d 100644
|
||||
--- a/src/util/string_utils.c
|
||||
+++ b/src/util/string_utils.c
|
||||
@@ -22,10 +22,10 @@
|
||||
|
||||
#include "util/util.h"
|
||||
|
||||
-static char *replace_char(TALLOC_CTX *mem_ctx,
|
||||
- const char *in,
|
||||
- const char match,
|
||||
- const char sub)
|
||||
+char *sss_replace_char(TALLOC_CTX *mem_ctx,
|
||||
+ const char *in,
|
||||
+ const char match,
|
||||
+ const char sub)
|
||||
{
|
||||
char *p;
|
||||
char *out;
|
||||
@@ -63,7 +63,7 @@ char * sss_replace_space(TALLOC_CTX *mem_ctx,
|
||||
return talloc_strdup(mem_ctx, orig_name);
|
||||
}
|
||||
|
||||
- return replace_char(mem_ctx, orig_name, ' ', subst);
|
||||
+ return sss_replace_char(mem_ctx, orig_name, ' ', subst);
|
||||
}
|
||||
|
||||
char * sss_reverse_replace_space(TALLOC_CTX *mem_ctx,
|
||||
@@ -81,7 +81,7 @@ char * sss_reverse_replace_space(TALLOC_CTX *mem_ctx,
|
||||
return talloc_strdup(mem_ctx, orig_name);
|
||||
}
|
||||
|
||||
- return replace_char(mem_ctx, orig_name, subst, ' ');
|
||||
+ return sss_replace_char(mem_ctx, orig_name, subst, ' ');
|
||||
}
|
||||
|
||||
errno_t guid_blob_to_string_buf(const uint8_t *blob, char *str_buf,
|
||||
diff --git a/src/util/util.h b/src/util/util.h
|
||||
index 82760940269ad8883e725e3a5cf463486c9cfd36..2170c5fb7cffda3910d2b58e33ec7abe3ec4a7d4 100644
|
||||
--- a/src/util/util.h
|
||||
+++ b/src/util/util.h
|
||||
@@ -600,6 +600,11 @@ errno_t name_to_well_known_sid(const char *dom, const char *name,
|
||||
const char **sid);
|
||||
|
||||
/* from string_utils.c */
|
||||
+char *sss_replace_char(TALLOC_CTX *mem_ctx,
|
||||
+ const char *in,
|
||||
+ const char match,
|
||||
+ const char sub);
|
||||
+
|
||||
char * sss_replace_space(TALLOC_CTX *mem_ctx,
|
||||
const char *orig_name,
|
||||
const char replace_char);
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,205 +0,0 @@
|
||||
From 16385568547351b5d2c562f3081f35f3341f695b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
||||
Date: Sun, 26 Mar 2017 03:00:14 +0200
|
||||
Subject: [PATCH 57/97] Add domain_resolution_order config option
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This is the local equivalent of option of ipaDomainResolutionOrder and
|
||||
has precedence over the ones set on IPA side making the precedence order
|
||||
to be like: Local > View > Globally.
|
||||
|
||||
As done for the IPA side configurations, the domains which were not
|
||||
explicitly set up will be apennded to the final of the
|
||||
domain_resolution_order list in the very same order they're presented in
|
||||
the "domains" option of [sssd] section in the config file. There's no
|
||||
guarantee of order for the subdomains though.
|
||||
|
||||
It's also important to mention that no expansion magic is performed on
|
||||
our side. It means that if 'example.com' is set it does *not* stand for
|
||||
all its subdomains DNS wise (like 'foo.example.com', 'bar.example.com',
|
||||
etc).
|
||||
|
||||
Related:
|
||||
https://pagure.io/SSSD/sssd/issue/3001
|
||||
|
||||
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/confdb/confdb.h | 1 +
|
||||
src/config/SSSDConfig/__init__.py.in | 1 +
|
||||
src/config/SSSDConfigTest.py | 7 ++++++-
|
||||
src/config/cfg_rules.ini | 1 +
|
||||
src/config/etc/sssd.api.conf | 1 +
|
||||
src/man/sssd.conf.5.xml | 20 ++++++++++++++++++++
|
||||
src/responder/common/responder.h | 1 +
|
||||
src/responder/common/responder_common.c | 27 +++++++++++++++++++++++++++
|
||||
8 files changed, 58 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
|
||||
index fb60675ca8beb2c2a157bf021ed9cad362742988..56a603652d6c8256735e7f8b125300ff7b254645 100644
|
||||
--- a/src/confdb/confdb.h
|
||||
+++ b/src/confdb/confdb.h
|
||||
@@ -74,6 +74,7 @@
|
||||
#define CONFDB_MONITOR_CERT_VERIFICATION "certificate_verification"
|
||||
#define CONFDB_MONITOR_DISABLE_NETLINK "disable_netlink"
|
||||
#define CONFDB_MONITOR_ENABLE_FILES_DOM "enable_files_domain"
|
||||
+#define CONFDB_MONITOR_DOMAIN_RESOLUTION_ORDER "domain_resolution_order"
|
||||
|
||||
/* Both monitor and domains */
|
||||
#define CONFDB_NAME_REGEX "re_expression"
|
||||
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
|
||||
index 29e9b4fae6835db4ccb9937fd93457d462e4a15d..0edc3ea84a1e8fb0f797546b4c223e22e22f70e9 100644
|
||||
--- a/src/config/SSSDConfig/__init__.py.in
|
||||
+++ b/src/config/SSSDConfig/__init__.py.in
|
||||
@@ -66,6 +66,7 @@ option_strings = {
|
||||
'override_space': _('All spaces in group or user names will be replaced with this character'),
|
||||
'disable_netlink' : _('Tune sssd to honor or ignore netlink state changes'),
|
||||
'enable_files_domain' : _('Enable or disable the implicit files domain'),
|
||||
+ 'domain_resolution_order': _('A specific order of the domains to be looked up'),
|
||||
|
||||
# [nss]
|
||||
'enum_cache_timeout' : _('Enumeration cache timeout length (seconds)'),
|
||||
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
|
||||
index 457a6f0a09e7139a05f29f8bef7e475fe3b58ec2..6899bf8ae04bf210546c8cbdba8235f094e23dc0 100755
|
||||
--- a/src/config/SSSDConfigTest.py
|
||||
+++ b/src/config/SSSDConfigTest.py
|
||||
@@ -94,6 +94,10 @@ class SSSDConfigTestValid(unittest.TestCase):
|
||||
self.assertTrue('default_domain_suffix' in new_options)
|
||||
self.assertEquals(new_options['default_domain_suffix'][0], str)
|
||||
|
||||
+ self.assertTrue('domain_resolution_order' in new_options)
|
||||
+ self.assertEquals(new_options['domain_resolution_order'][0], list)
|
||||
+ self.assertEquals(new_options['domain_resolution_order'][1], str)
|
||||
+
|
||||
del sssdconfig
|
||||
|
||||
def testDomains(self):
|
||||
@@ -314,7 +318,8 @@ class SSSDConfigTestSSSDService(unittest.TestCase):
|
||||
'certificate_verification',
|
||||
'override_space',
|
||||
'disable_netlink',
|
||||
- 'enable_files_domain']
|
||||
+ 'enable_files_domain',
|
||||
+ 'domain_resolution_order']
|
||||
|
||||
self.assertTrue(type(options) == dict,
|
||||
"Options should be a dictionary")
|
||||
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
|
||||
index 933ebccd828189d923d2186753dfbc0b5c0814ce..41efcea552a82c5492a0d21a8d0797ee42cdc8c7 100644
|
||||
--- a/src/config/cfg_rules.ini
|
||||
+++ b/src/config/cfg_rules.ini
|
||||
@@ -43,6 +43,7 @@ option = override_space
|
||||
option = config_file_version
|
||||
option = disable_netlink
|
||||
option = enable_files_domain
|
||||
+option = domain_resolution_order
|
||||
|
||||
[rule/allowed_nss_options]
|
||||
validator = ini_allowed_options
|
||||
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
|
||||
index 08cecf00367aaaab3794a48bd1e728421a996e49..6965028e1ca748f8b6677d9fc1faa66d5c307a0c 100644
|
||||
--- a/src/config/etc/sssd.api.conf
|
||||
+++ b/src/config/etc/sssd.api.conf
|
||||
@@ -32,6 +32,7 @@ certificate_verification = str, None, false
|
||||
override_space = str, None, false
|
||||
disable_netlink = bool, None, false
|
||||
enable_files_domain = str, None, false
|
||||
+domain_resolution_order = list, str, false
|
||||
|
||||
[nss]
|
||||
# Name service
|
||||
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
|
||||
index 1c27742cf0c1b6ffad23ab5b044bf4a168ed8f69..4fe13b85d511fb6a2ccc9b4de956710b05bc898c 100644
|
||||
--- a/src/man/sssd.conf.5.xml
|
||||
+++ b/src/man/sssd.conf.5.xml
|
||||
@@ -542,6 +542,26 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>domain_resolution_order</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Comma separated list of domains and subdomains
|
||||
+ representing the lookup order that will be
|
||||
+ followed.
|
||||
+ The list doesn't have to include all possible
|
||||
+ domains as the missing domains will be looked
|
||||
+ up based on the order they're presented in the
|
||||
+ <quote>domains</quote> configuration option.
|
||||
+ The subdomains which are not listed as part of
|
||||
+ <quote>lookup_order</quote> will be looked up
|
||||
+ in a random order for each parent domain.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Default: Not set
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</refsect2>
|
||||
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
|
||||
index 29e3f95caf484f43307c9c28d4abd3f50f360a95..4210307489fe25829a1674f254ecc7d185029698 100644
|
||||
--- a/src/responder/common/responder.h
|
||||
+++ b/src/responder/common/responder.h
|
||||
@@ -115,6 +115,7 @@ struct resp_ctx {
|
||||
int client_idle_timeout;
|
||||
|
||||
struct cache_req_domain *cr_domains;
|
||||
+ const char *domain_resolution_order;
|
||||
|
||||
time_t last_request_time;
|
||||
int idle_timeout;
|
||||
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
|
||||
index 1792a4c3771fa326c7cca31e1981dce315c03758..154d7dc7718c437d10e152fcba98161e2034fb14 100644
|
||||
--- a/src/responder/common/responder_common.c
|
||||
+++ b/src/responder/common/responder_common.c
|
||||
@@ -1163,6 +1163,19 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
|
||||
rctx->override_space = tmp[0];
|
||||
}
|
||||
|
||||
+ ret = confdb_get_string(rctx->cdb, rctx,
|
||||
+ CONFDB_MONITOR_CONF_ENTRY,
|
||||
+ CONFDB_MONITOR_DOMAIN_RESOLUTION_ORDER, NULL,
|
||||
+ &tmp);
|
||||
+ if (ret == EOK) {
|
||||
+ rctx->domain_resolution_order = sss_replace_char(rctx, tmp, ',', ':');
|
||||
+ } else {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "Cannot get the \"domain_resolution_order\" option.\n"
|
||||
+ "The set up lookup_order won't be followed [%d]: %s.\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ }
|
||||
+
|
||||
ret = sss_monitor_init(rctx, rctx->ev, monitor_intf,
|
||||
svc_name, svc_version, MT_SVC_SERVICE,
|
||||
rctx, &rctx->last_request_time,
|
||||
@@ -1546,6 +1559,20 @@ errno_t sss_resp_populate_cr_domains(struct resp_ctx *rctx)
|
||||
struct sss_domain_info *dom;
|
||||
errno_t ret;
|
||||
|
||||
+ if (rctx->domain_resolution_order != NULL) {
|
||||
+ cr_domains = cache_req_domain_new_list_from_domain_resolution_order(
|
||||
+ rctx, rctx->domains, rctx->domain_resolution_order);
|
||||
+
|
||||
+ if (cr_domains == NULL) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "Failed to use domain_resolution_order set in the config file.\n"
|
||||
+ "Trying to fallback to use ipaDomainOrderResolution setup by "
|
||||
+ "IPA.\n");
|
||||
+ } else {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
for (dom = rctx->domains; dom != NULL; dom = dom->next) {
|
||||
if (dom->provider != NULL && strcmp(dom->provider, "ipa") == 0) {
|
||||
break;
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,48 +0,0 @@
|
||||
From bd1fa0ec90be717c3b7796d74b6f243f40178d16 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Thu, 16 Mar 2017 12:38:08 +0100
|
||||
Subject: [PATCH 58/97] ssh: handle binary keys correctly
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3332
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/responder/ssh/ssh_reply.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/responder/ssh/ssh_reply.c b/src/responder/ssh/ssh_reply.c
|
||||
index 807f4ee079128b4a3f1719de890ffac6e0d5b2e0..7093e47253b5687bab387feed5299c2d0841d43c 100644
|
||||
--- a/src/responder/ssh/ssh_reply.c
|
||||
+++ b/src/responder/ssh/ssh_reply.c
|
||||
@@ -32,6 +32,11 @@
|
||||
#include "responder/common/cache_req/cache_req.h"
|
||||
#include "responder/ssh/ssh_private.h"
|
||||
|
||||
+/* Locally used flag for libldb's ldb_message_element structure to indicate
|
||||
+ * binary data. Since the related data is only used in memory it is safe. If
|
||||
+ * should be used with care if libldb's I/O operations are involved. */
|
||||
+#define SSS_EL_FLAG_BIN_DATA (1<<4)
|
||||
+
|
||||
static errno_t get_valid_certs_keys(TALLOC_CTX *mem_ctx,
|
||||
struct ssh_ctx *ssh_ctx,
|
||||
struct ldb_message_element *el_cert,
|
||||
@@ -148,7 +153,7 @@ static errno_t decode_and_add_base64_data(struct sss_packet *packet,
|
||||
}
|
||||
|
||||
for (d = 0; d < el->num_values; d++) {
|
||||
- if (skip_base64_decode) {
|
||||
+ if (skip_base64_decode || (el->flags & SSS_EL_FLAG_BIN_DATA)) {
|
||||
key = el->values[d].data;
|
||||
key_len = el->values[d].length;
|
||||
} else {
|
||||
@@ -233,6 +238,7 @@ ssh_get_output_keys(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
if (elements[i] != NULL) {
|
||||
+ elements[i]->flags |= SSS_EL_FLAG_BIN_DATA;
|
||||
num_keys += elements[i]->num_values;
|
||||
i++;
|
||||
}
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,52 +0,0 @@
|
||||
From 1b5d6b1afc9c3dc696b7b45f2d73b2634f42800a Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Thu, 16 Mar 2017 13:00:48 +0100
|
||||
Subject: [PATCH 59/97] ssh: add support for certificates from non-default
|
||||
views
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/responder/ssh/ssh_reply.c | 20 +++++++++++++++++++-
|
||||
1 file changed, 19 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/responder/ssh/ssh_reply.c b/src/responder/ssh/ssh_reply.c
|
||||
index 7093e47253b5687bab387feed5299c2d0841d43c..1bb9d331868cc18488718c24fd82f32af780b525 100644
|
||||
--- a/src/responder/ssh/ssh_reply.c
|
||||
+++ b/src/responder/ssh/ssh_reply.c
|
||||
@@ -204,7 +204,7 @@ ssh_get_output_keys(TALLOC_CTX *mem_ctx,
|
||||
uint32_t i = 0;
|
||||
errno_t ret;
|
||||
|
||||
- elements = talloc_zero_array(mem_ctx, struct ldb_message_element *, 5);
|
||||
+ elements = talloc_zero_array(mem_ctx, struct ldb_message_element *, 6);
|
||||
if (elements == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
@@ -244,6 +244,24 @@ ssh_get_output_keys(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
+ if (DOM_HAS_VIEWS(domain)) {
|
||||
+ user_cert = ldb_msg_find_element(msg, OVERRIDE_PREFIX SYSDB_USER_CERT);
|
||||
+ if (user_cert != NULL) {
|
||||
+ ret = get_valid_certs_keys(elements, ssh_ctx, user_cert,
|
||||
+ &elements[i]);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "get_valid_certs_keys failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (elements[i] != NULL) {
|
||||
+ elements[i]->flags |= SSS_EL_FLAG_BIN_DATA;
|
||||
+ num_keys += elements[i]->num_values;
|
||||
+ i++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
*_elements = elements;
|
||||
*_num_keys = num_keys;
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,60 +0,0 @@
|
||||
From 1c551b1373799643f3e9ba4f696d21b8fc57dafd Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Thu, 16 Mar 2017 20:43:08 +0100
|
||||
Subject: [PATCH 60/97] krb5: return to responder that pkinit is not available
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If pkinit is not available for a user but other authentication methods
|
||||
are SSSD should still fall back to local certificate based
|
||||
authentication if Smartcard credentials are provided.
|
||||
|
||||
Resolves https://pagure.io/SSSD/sssd/issue/3343
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/providers/krb5/krb5_child.c | 17 +++++++++++++----
|
||||
1 file changed, 13 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
|
||||
index 777a25f2a0ea434dde12d2396f6a35c2a1b86cd0..a4128dda6b0861a95dba223047d66c4158b1afb6 100644
|
||||
--- a/src/providers/krb5/krb5_child.c
|
||||
+++ b/src/providers/krb5/krb5_child.c
|
||||
@@ -42,6 +42,10 @@
|
||||
|
||||
#define SSSD_KRB5_CHANGEPW_PRINCIPAL "kadmin/changepw"
|
||||
|
||||
+#define IS_SC_AUTHTOK(tok) ( \
|
||||
+ sss_authtok_get_type((tok)) == SSS_AUTHTOK_TYPE_SC_PIN \
|
||||
+ || sss_authtok_get_type((tok)) == SSS_AUTHTOK_TYPE_SC_KEYPAD)
|
||||
+
|
||||
enum k5c_fast_opt {
|
||||
K5C_FAST_NEVER,
|
||||
K5C_FAST_TRY,
|
||||
@@ -1529,12 +1533,17 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
|
||||
* pre-auth module is missing or no Smartcard is inserted and only
|
||||
* pkinit is available KRB5_PREAUTH_FAILED is returned.
|
||||
* ERR_NO_AUTH_METHOD_AVAILABLE is used to indicate to the
|
||||
- * frontend that local authentication might be tried. */
|
||||
+ * frontend that local authentication might be tried.
|
||||
+ * Same is true if Smartcard credentials are given but only other
|
||||
+ * authentication methods are available. */
|
||||
if (kr->pd->cmd == SSS_PAM_AUTHENTICATE
|
||||
&& kerr == KRB5_PREAUTH_FAILED
|
||||
- && kr->password_prompting == false
|
||||
- && kr->otp == false
|
||||
- && kr->pkinit_prompting == false) {
|
||||
+ && kr->pkinit_prompting == false
|
||||
+ && (( kr->password_prompting == false
|
||||
+ && kr->otp == false)
|
||||
+ || ((kr->otp == true
|
||||
+ || kr->password_prompting == true)
|
||||
+ && IS_SC_AUTHTOK(kr->pd->authtok))) ) {
|
||||
return ERR_NO_AUTH_METHOD_AVAILABLE;
|
||||
}
|
||||
return kerr;
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,153 +0,0 @@
|
||||
From 415d93196533a6fcd90889c67396ef5af5bf791a Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Wed, 22 Mar 2017 14:13:05 +0100
|
||||
Subject: [PATCH 61/97] IPA: add mapped attributes to user from trusted domains
|
||||
|
||||
Allow the usage of the mapped attribute for the lookup of AD users on
|
||||
IPA clients as already used for the normal LDAP lookup.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/providers/ipa/ipa_s2n_exop.c | 33 ++++++++++++++++++++++++---------
|
||||
1 file changed, 24 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
|
||||
index c99312274073858e5e03f3e82c069dafc839eb61..05c32a24d61947e62884f460069083fb81f40fe0 100644
|
||||
--- a/src/providers/ipa/ipa_s2n_exop.c
|
||||
+++ b/src/providers/ipa/ipa_s2n_exop.c
|
||||
@@ -761,6 +761,7 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
|
||||
struct resp_attrs *simple_attrs,
|
||||
const char *view_name,
|
||||
struct sysdb_attrs *override_attrs,
|
||||
+ struct sysdb_attrs *mapped_attrs,
|
||||
bool update_initgr_timeout);
|
||||
|
||||
static errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx,
|
||||
@@ -1009,6 +1010,7 @@ struct ipa_s2n_get_list_state {
|
||||
struct resp_attrs *attrs;
|
||||
struct sss_domain_info *obj_domain;
|
||||
struct sysdb_attrs *override_attrs;
|
||||
+ struct sysdb_attrs *mapped_attrs;
|
||||
};
|
||||
|
||||
static errno_t ipa_s2n_get_list_step(struct tevent_req *req);
|
||||
@@ -1025,7 +1027,8 @@ static struct tevent_req *ipa_s2n_get_list_send(TALLOC_CTX *mem_ctx,
|
||||
int entry_type,
|
||||
enum request_types request_type,
|
||||
enum req_input_type list_type,
|
||||
- char **list)
|
||||
+ char **list,
|
||||
+ struct sysdb_attrs *mapped_attrs)
|
||||
{
|
||||
int ret;
|
||||
struct ipa_s2n_get_list_state *state;
|
||||
@@ -1057,6 +1060,7 @@ static struct tevent_req *ipa_s2n_get_list_send(TALLOC_CTX *mem_ctx,
|
||||
state->request_type = request_type;
|
||||
state->attrs = NULL;
|
||||
state->override_attrs = NULL;
|
||||
+ state->mapped_attrs = mapped_attrs;
|
||||
|
||||
ret = ipa_s2n_get_list_step(req);
|
||||
if (ret != EOK) {
|
||||
@@ -1288,7 +1292,8 @@ static errno_t ipa_s2n_get_list_save_step(struct tevent_req *req)
|
||||
|
||||
ret = ipa_s2n_save_objects(state->dom, &state->req_input, state->attrs,
|
||||
NULL, state->ipa_ctx->view_name,
|
||||
- state->override_attrs, false);
|
||||
+ state->override_attrs, state->mapped_attrs,
|
||||
+ false);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n");
|
||||
return ret;
|
||||
@@ -1704,7 +1709,7 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq)
|
||||
BE_REQ_GROUP,
|
||||
REQ_FULL_WITH_MEMBERS,
|
||||
REQ_INP_NAME,
|
||||
- missing_list);
|
||||
+ missing_list, NULL);
|
||||
if (subreq == NULL) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
"ipa_s2n_get_list_send failed.\n");
|
||||
@@ -1732,7 +1737,7 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq)
|
||||
BE_REQ_USER,
|
||||
REQ_FULL_WITH_MEMBERS,
|
||||
REQ_INP_NAME,
|
||||
- missing_list);
|
||||
+ missing_list, NULL);
|
||||
if (subreq == NULL) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
"ipa_s2n_get_list_send failed.\n");
|
||||
@@ -1810,7 +1815,7 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq)
|
||||
|
||||
if (ret == ENOENT || is_default_view(state->ipa_ctx->view_name)) {
|
||||
ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs,
|
||||
- state->simple_attrs, NULL, NULL, true);
|
||||
+ state->simple_attrs, NULL, NULL, NULL, true);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n");
|
||||
goto done;
|
||||
@@ -1978,6 +1983,7 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
|
||||
struct resp_attrs *simple_attrs,
|
||||
const char *view_name,
|
||||
struct sysdb_attrs *override_attrs,
|
||||
+ struct sysdb_attrs *mapped_attrs,
|
||||
bool update_initgr_timeout)
|
||||
{
|
||||
int ret;
|
||||
@@ -2305,6 +2311,15 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ if (mapped_attrs != NULL) {
|
||||
+ ret = sysdb_set_user_attr(dom, name, mapped_attrs,
|
||||
+ SYSDB_MOD_ADD);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_user_attr failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (gid_override_attrs != NULL) {
|
||||
ret = sysdb_set_user_attr(dom, name, gid_override_attrs,
|
||||
SYSDB_MOD_REP);
|
||||
@@ -2487,7 +2502,7 @@ static void ipa_s2n_get_list_done(struct tevent_req *subreq)
|
||||
&sid_str);
|
||||
if (ret == ENOENT) {
|
||||
ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs,
|
||||
- state->simple_attrs, NULL, NULL, true);
|
||||
+ state->simple_attrs, NULL, NULL, NULL, true);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n");
|
||||
goto fail;
|
||||
@@ -2525,7 +2540,7 @@ static void ipa_s2n_get_list_done(struct tevent_req *subreq)
|
||||
ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs,
|
||||
state->simple_attrs,
|
||||
state->ipa_ctx->view_name,
|
||||
- state->override_attrs, true);
|
||||
+ state->override_attrs, NULL, true);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n");
|
||||
tevent_req_error(req, ret);
|
||||
@@ -2561,7 +2576,7 @@ static void ipa_s2n_get_user_get_override_done(struct tevent_req *subreq)
|
||||
|
||||
ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs,
|
||||
state->simple_attrs, state->ipa_ctx->view_name,
|
||||
- override_attrs, true);
|
||||
+ override_attrs, NULL, true);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n");
|
||||
tevent_req_error(req, ret);
|
||||
@@ -2662,7 +2677,7 @@ struct tevent_req *ipa_get_subdom_acct_process_pac_send(TALLOC_CTX *mem_ctx,
|
||||
dp_opt_get_int(ipa_ctx->sdap_id_ctx->opts->basic,
|
||||
SDAP_SEARCH_TIMEOUT),
|
||||
BE_REQ_BY_SECID, REQ_FULL, REQ_INP_SECID,
|
||||
- state->missing_sids);
|
||||
+ state->missing_sids, NULL);
|
||||
if (subreq == NULL) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_get_list_send failed.\n");
|
||||
ret = ENOMEM;
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,209 +0,0 @@
|
||||
From 2cf7becc05996eb6d8a3352d3d7b97c75652e590 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Fri, 24 Mar 2017 15:40:41 +0100
|
||||
Subject: [PATCH 62/97] IPA: lookup AD users by certificates on IPA clients
|
||||
|
||||
Get a list of users mapped to a certificate back from the IPA server,
|
||||
look them up and store them together with the certificate used for the
|
||||
search as mapped attribute to the cache.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/providers/ipa/ipa_s2n_exop.c | 109 +++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 105 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
|
||||
index 05c32a24d61947e62884f460069083fb81f40fe0..8a3391b4093f1547d84fe44a0f24b1d063d1e28c 100644
|
||||
--- a/src/providers/ipa/ipa_s2n_exop.c
|
||||
+++ b/src/providers/ipa/ipa_s2n_exop.c
|
||||
@@ -52,7 +52,8 @@ enum response_types {
|
||||
RESP_USER,
|
||||
RESP_GROUP,
|
||||
RESP_USER_GROUPLIST,
|
||||
- RESP_GROUP_MEMBERS
|
||||
+ RESP_GROUP_MEMBERS,
|
||||
+ RESP_NAME_LIST
|
||||
};
|
||||
|
||||
/* ==Sid2Name Extended Operation============================================= */
|
||||
@@ -366,8 +367,8 @@ static errno_t s2n_encode_request(TALLOC_CTX *mem_ctx,
|
||||
break;
|
||||
case BE_REQ_BY_CERT:
|
||||
if (req_input->type == REQ_INP_CERT) {
|
||||
- ret = ber_printf(ber, "{ees}", INP_CERT, request_type,
|
||||
- req_input->inp.cert);
|
||||
+ ret = ber_printf(ber, "{ees}", INP_CERT, request_type,
|
||||
+ req_input->inp.cert);
|
||||
} else {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "Unexpected input type [%d].\n",
|
||||
req_input->type);
|
||||
@@ -463,6 +464,11 @@ done:
|
||||
* GroupMemberList ::= SEQUENCE OF OCTET STRING
|
||||
*/
|
||||
|
||||
+struct name_list {
|
||||
+ char *domain_name;
|
||||
+ char *name;
|
||||
+};
|
||||
+
|
||||
struct resp_attrs {
|
||||
enum response_types response_type;
|
||||
char *domain_name;
|
||||
@@ -475,6 +481,7 @@ struct resp_attrs {
|
||||
size_t ngroups;
|
||||
char **groups;
|
||||
struct sysdb_attrs *sysdb_attrs;
|
||||
+ char **name_list;
|
||||
};
|
||||
|
||||
static errno_t get_extra_attrs(BerElement *ber, struct resp_attrs *resp_attrs)
|
||||
@@ -782,6 +789,9 @@ static errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx,
|
||||
struct resp_attrs *attrs = NULL;
|
||||
char *sid_str;
|
||||
bool is_v1 = false;
|
||||
+ char **name_list = NULL;
|
||||
+ ber_len_t ber_len;
|
||||
+ char *fq_name = NULL;
|
||||
|
||||
if (retoid == NULL || retdata == NULL) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "Missing OID or data.\n");
|
||||
@@ -947,6 +957,53 @@ static errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx,
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
+ case RESP_NAME_LIST:
|
||||
+ tag = ber_scanf(ber, "{");
|
||||
+ if (tag == LBER_ERROR) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n");
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ while (ber_peek_tag(ber, &ber_len) == LBER_SEQUENCE) {
|
||||
+ tag = ber_scanf(ber, "{aa}", &domain_name, &name);
|
||||
+ if (tag == LBER_ERROR) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n");
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ fq_name = sss_create_internal_fqname(attrs, name, domain_name);
|
||||
+ if (fq_name == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "sss_create_internal_fqname failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ DEBUG(SSSDBG_TRACE_ALL, "[%s][%s][%s].\n", domain_name, name,
|
||||
+ fq_name);
|
||||
+
|
||||
+ ret = add_string_to_list(attrs, fq_name, &name_list);
|
||||
+ ber_memfree(domain_name);
|
||||
+ ber_memfree(name);
|
||||
+ talloc_free(fq_name);
|
||||
+ domain_name = NULL;
|
||||
+ name = NULL;
|
||||
+ fq_name = NULL;
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "add_to_name_list failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ tag = ber_scanf(ber, "}}");
|
||||
+ if (tag == LBER_ERROR) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n");
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ attrs->name_list = name_list;
|
||||
+ break;
|
||||
default:
|
||||
DEBUG(SSSDBG_OP_FAILURE, "Unexpected response type [%d].\n",
|
||||
type);
|
||||
@@ -955,7 +1012,7 @@ static errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
attrs->response_type = type;
|
||||
- if (type != RESP_SID) {
|
||||
+ if (type != RESP_SID && type != RESP_NAME_LIST) {
|
||||
attrs->domain_name = talloc_strdup(attrs, domain_name);
|
||||
if (attrs->domain_name == NULL) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
|
||||
@@ -969,6 +1026,7 @@ static errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx,
|
||||
done:
|
||||
ber_memfree(domain_name);
|
||||
ber_memfree(name);
|
||||
+ talloc_free(fq_name);
|
||||
ber_free(ber, 1);
|
||||
|
||||
if (ret == EOK) {
|
||||
@@ -1332,6 +1390,7 @@ struct ipa_s2n_get_user_state {
|
||||
struct resp_attrs *attrs;
|
||||
struct resp_attrs *simple_attrs;
|
||||
struct sysdb_attrs *override_attrs;
|
||||
+ struct sysdb_attrs *mapped_attrs;
|
||||
int exop_timeout;
|
||||
};
|
||||
|
||||
@@ -1384,6 +1443,11 @@ struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (entry_type == BE_REQ_BY_CERT) {
|
||||
+ /* Only REQ_SIMPLE is supported for BE_REQ_BY_CERT */
|
||||
+ state->request_type = REQ_SIMPLE;
|
||||
+ }
|
||||
+
|
||||
ret = s2n_encode_request(state, dom->name, entry_type, state->request_type,
|
||||
req_input, &bv_req);
|
||||
if (ret != EOK) {
|
||||
@@ -1785,6 +1849,43 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq)
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ if (state->simple_attrs->response_type == RESP_NAME_LIST
|
||||
+ && state->req_input->type == REQ_INP_CERT) {
|
||||
+ state->mapped_attrs = sysdb_new_attrs(state);
|
||||
+ if (state->mapped_attrs == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_attrs_add_base64_blob(state->mapped_attrs,
|
||||
+ SYSDB_USER_MAPPED_CERT,
|
||||
+ state->req_input->inp.cert);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_base64_blob failed.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ subreq = ipa_s2n_get_list_send(state, state->ev,
|
||||
+ state->ipa_ctx, state->dom,
|
||||
+ state->sh, state->exop_timeout,
|
||||
+ BE_REQ_USER,
|
||||
+ REQ_FULL_WITH_MEMBERS,
|
||||
+ REQ_INP_NAME,
|
||||
+ state->simple_attrs->name_list,
|
||||
+ state->mapped_attrs);
|
||||
+ if (subreq == NULL) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "ipa_s2n_get_list_send failed.\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ tevent_req_set_callback(subreq, ipa_s2n_get_list_done,
|
||||
+ req);
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
break;
|
||||
default:
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected request type.\n");
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 82843754193b177275ce16f2901edac2060a3998 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Fri, 24 Mar 2017 15:41:37 +0100
|
||||
Subject: [PATCH 63/97] IPA: enable AD user lookup by certificate
|
||||
|
||||
Without this the lookup by certificate for AD users on an IPA client
|
||||
will just error out.
|
||||
|
||||
Related to https://pagure.io/SSSD/sssd/issue/3050
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/providers/ipa/ipa_subdomains_id.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
|
||||
index 4777d7cfd97fed39b807a659fd1f9000c7ff8625..3530af94ef59397db72465fcb0c4a03117a4d8bd 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains_id.c
|
||||
+++ b/src/providers/ipa/ipa_subdomains_id.c
|
||||
@@ -399,6 +399,7 @@ struct tevent_req *ipa_get_subdom_acct_send(TALLOC_CTX *memctx,
|
||||
case BE_REQ_USER:
|
||||
case BE_REQ_GROUP:
|
||||
case BE_REQ_BY_SECID:
|
||||
+ case BE_REQ_BY_CERT:
|
||||
case BE_REQ_USER_AND_GROUP:
|
||||
ret = EOK;
|
||||
break;
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,242 +0,0 @@
|
||||
From 6324eaf1fb321c41ca9883966118df6d45259b7e Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 22 Mar 2017 12:53:17 +0100
|
||||
Subject: [PATCH 64/97] CONFDB: Introduce SSSD domain type to distinguish POSIX
|
||||
and application domains
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Related to:
|
||||
https://pagure.io/SSSD/sssd/issue/3310
|
||||
|
||||
Adds a new option that allows to distinguish domains that do contain
|
||||
POSIX users and groups and those that don't. The POSIX domains are the
|
||||
default. The non-POSIX domains are selected by selecting an
|
||||
"application" type domain.
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/confdb/confdb.c | 18 +++++++++++++++++-
|
||||
src/confdb/confdb.h | 15 +++++++++++++++
|
||||
src/config/SSSDConfig/__init__.py.in | 1 +
|
||||
src/config/SSSDConfigTest.py | 2 ++
|
||||
src/config/cfg_rules.ini | 1 +
|
||||
src/config/etc/sssd.api.conf | 1 +
|
||||
src/man/sssd.conf.5.xml | 33 +++++++++++++++++++++++++++++++++
|
||||
src/util/domain_info_utils.c | 14 ++++++++++++++
|
||||
src/util/util.h | 1 +
|
||||
9 files changed, 85 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
|
||||
index d82fd98ee02928b3c20df014528bd869ec946f92..70a1eb7b2c7e83dfa9d217a15c7d3d4c8580b891 100644
|
||||
--- a/src/confdb/confdb.c
|
||||
+++ b/src/confdb/confdb.c
|
||||
@@ -1367,6 +1367,22 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
|
||||
}
|
||||
}
|
||||
|
||||
+ domain->type = DOM_TYPE_POSIX;
|
||||
+ tmp = ldb_msg_find_attr_as_string(res->msgs[0],
|
||||
+ CONFDB_DOMAIN_TYPE,
|
||||
+ CONFDB_DOMAIN_TYPE_POSIX);
|
||||
+ if (tmp != NULL) {
|
||||
+ if (strcasecmp(tmp, CONFDB_DOMAIN_TYPE_POSIX) == 0) {
|
||||
+ domain->type = DOM_TYPE_POSIX;
|
||||
+ } else if (strcasecmp(tmp, CONFDB_DOMAIN_TYPE_APP) == 0) {
|
||||
+ domain->type = DOM_TYPE_APPLICATION;
|
||||
+ } else {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
+ "Invalid value %s for [%s]\n", tmp, CONFDB_DOMAIN_TYPE);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
ret = get_entry_as_uint32(res->msgs[0], &domain->subdomain_refresh_interval,
|
||||
CONFDB_DOMAIN_SUBDOMAIN_REFRESH, 14400);
|
||||
if (ret != EOK || domain->subdomain_refresh_interval == 0) {
|
||||
@@ -1444,7 +1460,7 @@ int confdb_get_domains(struct confdb_ctx *cdb,
|
||||
if (ret) {
|
||||
DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
"Error (%d [%s]) retrieving domain [%s], skipping!\n",
|
||||
- ret, sss_strerror(ret), domlist[i]);
|
||||
+ ret, sss_strerror(ret), domlist[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
|
||||
index 56a603652d6c8256735e7f8b125300ff7b254645..a4046610f3cdbdb832de8924bf4397fb0018f2db 100644
|
||||
--- a/src/confdb/confdb.h
|
||||
+++ b/src/confdb/confdb.h
|
||||
@@ -209,6 +209,9 @@
|
||||
#define CONFDB_DOMAIN_OFFLINE_TIMEOUT "offline_timeout"
|
||||
#define CONFDB_DOMAIN_SUBDOMAIN_INHERIT "subdomain_inherit"
|
||||
#define CONFDB_DOMAIN_CACHED_AUTH_TIMEOUT "cached_auth_timeout"
|
||||
+#define CONFDB_DOMAIN_TYPE "domain_type"
|
||||
+#define CONFDB_DOMAIN_TYPE_POSIX "posix"
|
||||
+#define CONFDB_DOMAIN_TYPE_APP "application"
|
||||
|
||||
/* Local Provider */
|
||||
#define CONFDB_LOCAL_DEFAULT_SHELL "default_shell"
|
||||
@@ -261,11 +264,23 @@ enum sss_domain_state {
|
||||
DOM_INCONSISTENT,
|
||||
};
|
||||
|
||||
+/** Whether the domain only supports looking up POSIX entries */
|
||||
+enum sss_domain_type {
|
||||
+ /** This is the default domain type. It resolves only entries
|
||||
+ * with the full POSIX set of attributes
|
||||
+ */
|
||||
+ DOM_TYPE_POSIX,
|
||||
+ /** In this mode, entries are typically resolved only by name */
|
||||
+ DOM_TYPE_APPLICATION,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* Data structure storing all of the basic features
|
||||
* of a domain.
|
||||
*/
|
||||
struct sss_domain_info {
|
||||
+ enum sss_domain_type type;
|
||||
+
|
||||
char *name;
|
||||
char *conn_name;
|
||||
char *provider;
|
||||
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
|
||||
index 0edc3ea84a1e8fb0f797546b4c223e22e22f70e9..070994bcd04604777019d264d12cb126d6638bfd 100644
|
||||
--- a/src/config/SSSDConfig/__init__.py.in
|
||||
+++ b/src/config/SSSDConfig/__init__.py.in
|
||||
@@ -148,6 +148,7 @@ option_strings = {
|
||||
'selinux_provider' : _('SELinux provider'),
|
||||
|
||||
# [domain]
|
||||
+ 'domain_type' : _('Whether the domain is usable by the OS or by applications'),
|
||||
'min_id' : _('Minimum user ID'),
|
||||
'max_id' : _('Maximum user ID'),
|
||||
'enumerate' : _('Enable enumerating all users/groups'),
|
||||
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
|
||||
index 6899bf8ae04bf210546c8cbdba8235f094e23dc0..9b3175962c697e314b3d5d94c2bc5beda537b66e 100755
|
||||
--- a/src/config/SSSDConfigTest.py
|
||||
+++ b/src/config/SSSDConfigTest.py
|
||||
@@ -510,6 +510,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
|
||||
'debug',
|
||||
'debug_level',
|
||||
'debug_timestamps',
|
||||
+ 'domain_type',
|
||||
'min_id',
|
||||
'max_id',
|
||||
'timeout',
|
||||
@@ -878,6 +879,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
|
||||
'debug',
|
||||
'debug_level',
|
||||
'debug_timestamps',
|
||||
+ 'domain_type',
|
||||
'min_id',
|
||||
'max_id',
|
||||
'timeout',
|
||||
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
|
||||
index 41efcea552a82c5492a0d21a8d0797ee42cdc8c7..3c857236eaa55b313d176bc4bb479918163b60d5 100644
|
||||
--- a/src/config/cfg_rules.ini
|
||||
+++ b/src/config/cfg_rules.ini
|
||||
@@ -311,6 +311,7 @@ option = subdomains_provider
|
||||
option = selinux_provider
|
||||
|
||||
# Options available to all domains
|
||||
+option = domain_type
|
||||
option = min_id
|
||||
option = max_id
|
||||
option = timeout
|
||||
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
|
||||
index 6965028e1ca748f8b6677d9fc1faa66d5c307a0c..a38b24208f89e4502e41625c540ea9958d5bbffe 100644
|
||||
--- a/src/config/etc/sssd.api.conf
|
||||
+++ b/src/config/etc/sssd.api.conf
|
||||
@@ -129,6 +129,7 @@ selinux_provider = str, None, false
|
||||
[domain]
|
||||
# Options available to all domains
|
||||
description = str, None, false
|
||||
+domain_type = str, None, false
|
||||
debug = int, None, false
|
||||
debug_level = int, None, false
|
||||
debug_timestamps = bool, None, false
|
||||
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
|
||||
index 4fe13b85d511fb6a2ccc9b4de956710b05bc898c..9abcff84a95ea1b27e36845e830cc125fdc89f90 100644
|
||||
--- a/src/man/sssd.conf.5.xml
|
||||
+++ b/src/man/sssd.conf.5.xml
|
||||
@@ -1512,6 +1512,39 @@ pam_account_locked_message = Account locked, please contact help desk.
|
||||
<quote>[domain/<replaceable>NAME</replaceable>]</quote>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
+ <term>domain_type (string)</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Specifies whether the domain is meant to be used
|
||||
+ by POSIX-aware clients such as the Name Service Switch
|
||||
+ or by applications that do not need POSIX data to be
|
||||
+ present or generated. Only objects from POSIX domains
|
||||
+ are available to the operating system interfaces and
|
||||
+ utilities.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Allowed values for this option are <quote>posix</quote>
|
||||
+ and <quote>application</quote>.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ POSIX domains are reachable by all services. Application
|
||||
+ domains are only reachable from the InfoPipe responder (see
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>sssd-ifp</refentrytitle>
|
||||
+ <manvolnum>5</manvolnum>
|
||||
+ </citerefentry>) and the PAM responder.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ NOTE: The application domains are currently well tested with
|
||||
+ <quote>id_provider=ldap</quote> only.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Default: posix
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
<term>min_id,max_id (integer)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
|
||||
index a7f118842aa8ba870143b2f2b425a3e3c0ea5a78..2af7852f03f89b61f5b9fd8a244e98fb27b7e6a2 100644
|
||||
--- a/src/util/domain_info_utils.c
|
||||
+++ b/src/util/domain_info_utils.c
|
||||
@@ -885,3 +885,17 @@ char *subdomain_create_conf_path(TALLOC_CTX *mem_ctx,
|
||||
subdomain->parent->name,
|
||||
subdomain->name);
|
||||
}
|
||||
+
|
||||
+const char *sss_domain_type_str(struct sss_domain_info *dom)
|
||||
+{
|
||||
+ if (dom == NULL) {
|
||||
+ return "BUG: Invalid domain";
|
||||
+ }
|
||||
+ switch (dom->type) {
|
||||
+ case DOM_TYPE_POSIX:
|
||||
+ return "POSIX";
|
||||
+ case DOM_TYPE_APPLICATION:
|
||||
+ return "Application";
|
||||
+ }
|
||||
+ return "Unknown";
|
||||
+}
|
||||
diff --git a/src/util/util.h b/src/util/util.h
|
||||
index 2170c5fb7cffda3910d2b58e33ec7abe3ec4a7d4..436550f5078cc173b8ed8cb58836d366f813146b 100644
|
||||
--- a/src/util/util.h
|
||||
+++ b/src/util/util.h
|
||||
@@ -539,6 +539,7 @@ enum sss_domain_state sss_domain_get_state(struct sss_domain_info *dom);
|
||||
void sss_domain_set_state(struct sss_domain_info *dom,
|
||||
enum sss_domain_state state);
|
||||
bool is_email_from_domain(const char *email, struct sss_domain_info *dom);
|
||||
+const char *sss_domain_type_str(struct sss_domain_info *dom);
|
||||
|
||||
struct sss_domain_info*
|
||||
sss_get_domain_by_sid_ldap_fallback(struct sss_domain_info *domain,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,531 +0,0 @@
|
||||
From 825e8bf2f73a815c2eceb36ae805145fcbacf74d Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Mon, 27 Mar 2017 09:48:46 +0200
|
||||
Subject: [PATCH 65/97] CONFDB: Allow configuring [application] sections as
|
||||
non-POSIX domains
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Related to:
|
||||
https://pagure.io/SSSD/sssd/issue/3310
|
||||
|
||||
Allows to add a new section:
|
||||
[application/$name]
|
||||
|
||||
This section internally (on the confdb level) expands to:
|
||||
[domain/$name]
|
||||
domain_type = application
|
||||
|
||||
The reasons to add this new section is two-fold. One, to make the
|
||||
configuration of application domains more explicit and two, to make it
|
||||
possible to share configuration between two domains, one POSIX and one
|
||||
non-POSIX by application domain's inherit_from option:
|
||||
[application/$name]
|
||||
inherit_from = posix_domain_name
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/confdb/confdb.c | 288 ++++++++++++++++++++++++++++++++++++++++++++---
|
||||
src/confdb/confdb.h | 4 +
|
||||
src/config/cfg_rules.ini | 9 +-
|
||||
src/man/sssd.conf.5.xml | 77 +++++++++++++
|
||||
src/monitor/monitor.c | 8 ++
|
||||
5 files changed, 368 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
|
||||
index 70a1eb7b2c7e83dfa9d217a15c7d3d4c8580b891..88e114457deac3ca50c291a131122624fb6f6fe4 100644
|
||||
--- a/src/confdb/confdb.c
|
||||
+++ b/src/confdb/confdb.c
|
||||
@@ -813,6 +813,50 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int confdb_get_domain_section(TALLOC_CTX *mem_ctx,
|
||||
+ struct confdb_ctx *cdb,
|
||||
+ const char *section,
|
||||
+ const char *name,
|
||||
+ struct ldb_result **_res)
|
||||
+{
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ int ret;
|
||||
+ struct ldb_result *res;
|
||||
+ struct ldb_dn *dn;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ dn = ldb_dn_new_fmt(tmp_ctx, cdb->ldb, "cn=%s,%s", name, section);
|
||||
+ if (dn == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn,
|
||||
+ LDB_SCOPE_BASE, NULL, NULL);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ ret = sysdb_error_to_errno(ret);
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (res->count == 0) {
|
||||
+ ret = ENOENT;
|
||||
+ goto done;
|
||||
+ } else if (res->count > 1) {
|
||||
+ ret = E2BIG;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ *_res = talloc_steal(mem_ctx, res);
|
||||
+ ret = EOK;
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int confdb_get_domain_internal(struct confdb_ctx *cdb,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const char *name,
|
||||
@@ -821,7 +865,6 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
|
||||
struct sss_domain_info *domain;
|
||||
struct ldb_result *res;
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
- struct ldb_dn *dn;
|
||||
const char *tmp;
|
||||
int ret, val;
|
||||
uint32_t entry_cache_timeout;
|
||||
@@ -833,23 +876,15 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
|
||||
tmp_ctx = talloc_new(mem_ctx);
|
||||
if (!tmp_ctx) return ENOMEM;
|
||||
|
||||
- dn = ldb_dn_new_fmt(tmp_ctx, cdb->ldb,
|
||||
- "cn=%s,%s", name, CONFDB_DOMAIN_BASEDN);
|
||||
- if (!dn) {
|
||||
- ret = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn,
|
||||
- LDB_SCOPE_BASE, NULL, NULL);
|
||||
- if (ret != LDB_SUCCESS) {
|
||||
- ret = EIO;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- if (res->count != 1) {
|
||||
+ ret = confdb_get_domain_section(tmp_ctx, cdb, CONFDB_DOMAIN_BASEDN,
|
||||
+ name, &res);
|
||||
+ if (ret == ENOENT) {
|
||||
DEBUG(SSSDBG_FATAL_FAILURE, "Unknown domain [%s]\n", name);
|
||||
- ret = ENOENT;
|
||||
+ goto done;
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
+ "Error %d: %s while retrieving %s\n",
|
||||
+ ret, sss_strerror(ret), name);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1841,3 +1876,222 @@ int confdb_ensure_files_domain(struct confdb_ctx *cdb,
|
||||
return activate_files_domain(cdb, implicit_files_dom_name);
|
||||
#endif /* ADD_FILES_DOMAIN */
|
||||
}
|
||||
+
|
||||
+static int confdb_get_parent_domain(TALLOC_CTX *mem_ctx,
|
||||
+ const char *name,
|
||||
+ struct confdb_ctx *cdb,
|
||||
+ struct ldb_result *app_dom,
|
||||
+ struct ldb_result **_parent_dom)
|
||||
+{
|
||||
+ const char *inherit_from;
|
||||
+
|
||||
+ inherit_from = ldb_msg_find_attr_as_string(app_dom->msgs[0],
|
||||
+ CONFDB_DOMAIN_INHERIT_FROM, NULL);
|
||||
+ if (inherit_from == NULL) {
|
||||
+ DEBUG(SSSDBG_CONF_SETTINGS,
|
||||
+ "%s does not inherit from any POSIX domain\n", name);
|
||||
+ *_parent_dom = NULL;
|
||||
+ return EOK;
|
||||
+ }
|
||||
+
|
||||
+ return confdb_get_domain_section(mem_ctx, cdb,
|
||||
+ CONFDB_DOMAIN_BASEDN, inherit_from,
|
||||
+ _parent_dom);
|
||||
+}
|
||||
+
|
||||
+static int confdb_add_app_domain(TALLOC_CTX *mem_ctx,
|
||||
+ struct confdb_ctx *cdb,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ char *cdb_path = NULL;
|
||||
+ const char *val[2] = { NULL, NULL };
|
||||
+ int ret;
|
||||
+
|
||||
+ cdb_path = talloc_asprintf(mem_ctx, CONFDB_DOMAIN_PATH_TMPL, name);
|
||||
+ if (cdb_path == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ val[0] = CONFDB_DOMAIN_TYPE_APP;
|
||||
+ ret = confdb_add_param(cdb, true, cdb_path, CONFDB_DOMAIN_TYPE, val);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add id_provider [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static int confdb_merge_parent_domain(const char *name,
|
||||
+ struct confdb_ctx *cdb,
|
||||
+ struct ldb_result *app_section)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int ldb_flag;
|
||||
+ struct ldb_result *parent_domain = NULL;
|
||||
+ struct ldb_message *replace_msg = NULL;
|
||||
+ struct ldb_message *app_msg = NULL;
|
||||
+ struct ldb_dn *domain_dn;
|
||||
+ TALLOC_CTX *tmp_ctx = NULL;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ domain_dn = ldb_dn_new_fmt(tmp_ctx,
|
||||
+ cdb->ldb,
|
||||
+ "%s=%s,%s",
|
||||
+ CONFDB_DOMAIN_ATTR,
|
||||
+ name,
|
||||
+ CONFDB_DOMAIN_BASEDN);
|
||||
+ if (domain_dn == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* Copy the parent domain parameters */
|
||||
+ ret = confdb_get_parent_domain(tmp_ctx, name, cdb,
|
||||
+ app_section, &parent_domain);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Cannot retrieve the parent domain [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (parent_domain != NULL) {
|
||||
+ replace_msg = ldb_msg_copy(tmp_ctx, parent_domain->msgs[0]);
|
||||
+ if (replace_msg == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ replace_msg->dn = domain_dn;
|
||||
+
|
||||
+ for (unsigned i = 0; i < replace_msg->num_elements; i++) {
|
||||
+ replace_msg->elements[i].flags = LDB_FLAG_MOD_ADD;
|
||||
+ }
|
||||
+
|
||||
+ ret = ldb_modify(cdb->ldb, replace_msg);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ ret = sysdb_error_to_errno(ret);
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Inheriting options from parent domain failed [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Finally, add any app-domain specific overrides */
|
||||
+ app_msg = ldb_msg_new(tmp_ctx);
|
||||
+ if (app_msg == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ app_msg->dn = domain_dn;
|
||||
+
|
||||
+ for (unsigned i = 0; i < app_section->msgs[0]->num_elements; i++) {
|
||||
+ struct ldb_message_element *el = NULL;
|
||||
+
|
||||
+ if (replace_msg != NULL) {
|
||||
+ el = ldb_msg_find_element(replace_msg,
|
||||
+ app_section->msgs[0]->elements[i].name);
|
||||
+ if (el == NULL) {
|
||||
+ /* Adding an element */
|
||||
+ ldb_flag = LDB_FLAG_MOD_ADD;
|
||||
+ } else {
|
||||
+ /* Overriding an element */
|
||||
+ ldb_flag = LDB_FLAG_MOD_REPLACE;
|
||||
+ }
|
||||
+ } else {
|
||||
+ /* If there was no domain to inherit from, just add all */
|
||||
+ ldb_flag = LDB_FLAG_MOD_ADD;
|
||||
+ }
|
||||
+
|
||||
+ ret = ldb_msg_add(app_msg,
|
||||
+ &app_section->msgs[0]->elements[i],
|
||||
+ ldb_flag);
|
||||
+ if (ret != EOK) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = ldb_modify(cdb->ldb, app_msg);
|
||||
+ if (ret != LDB_SUCCESS) {
|
||||
+ ret = sysdb_error_to_errno(ret);
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Adding app-specific options failed [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "Added a domain section for %s\n", name);
|
||||
+ ret = EOK;
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int confdb_expand_app_domains(struct confdb_ctx *cdb)
|
||||
+{
|
||||
+ int ret;
|
||||
+ char **domlist;
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ struct ldb_result *app_domain = NULL;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = confdb_get_string_as_list(cdb, tmp_ctx,
|
||||
+ CONFDB_MONITOR_CONF_ENTRY,
|
||||
+ CONFDB_MONITOR_ACTIVE_DOMAINS,
|
||||
+ &domlist);
|
||||
+ if (ret == ENOENT) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "No domains configured, fatal error!\n");
|
||||
+ goto done;
|
||||
+ } else if (ret != EOK ) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "Fatal error retrieving domains list!\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; domlist[i]; i++) {
|
||||
+ ret = confdb_get_domain_section(tmp_ctx, cdb,
|
||||
+ CONFDB_APP_DOMAIN_BASEDN, domlist[i],
|
||||
+ &app_domain);
|
||||
+ if (ret == ENOENT) {
|
||||
+ DEBUG(SSSDBG_TRACE_INTERNAL,
|
||||
+ "%s is not an app domain\n", domlist[i]);
|
||||
+ continue;
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
+ "Error %d: %s while retrieving %s\n",
|
||||
+ ret, sss_strerror(ret), domlist[i]);
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = confdb_add_app_domain(tmp_ctx, cdb, domlist[i]);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Cannot add the app domain section [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = confdb_merge_parent_domain(domlist[i], cdb, app_domain);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Cannot add options into the app domain section [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
|
||||
index a4046610f3cdbdb832de8924bf4397fb0018f2db..5a8d377c312f641f544b1c7cf38826192462ea3c 100644
|
||||
--- a/src/confdb/confdb.h
|
||||
+++ b/src/confdb/confdb.h
|
||||
@@ -164,6 +164,7 @@
|
||||
/* Domains */
|
||||
#define CONFDB_DOMAIN_PATH_TMPL "config/domain/%s"
|
||||
#define CONFDB_DOMAIN_BASEDN "cn=domain,cn=config"
|
||||
+#define CONFDB_APP_DOMAIN_BASEDN "cn=application,cn=config"
|
||||
#define CONFDB_DOMAIN_ID_PROVIDER "id_provider"
|
||||
#define CONFDB_DOMAIN_AUTH_PROVIDER "auth_provider"
|
||||
#define CONFDB_DOMAIN_ACCESS_PROVIDER "access_provider"
|
||||
@@ -212,6 +213,7 @@
|
||||
#define CONFDB_DOMAIN_TYPE "domain_type"
|
||||
#define CONFDB_DOMAIN_TYPE_POSIX "posix"
|
||||
#define CONFDB_DOMAIN_TYPE_APP "application"
|
||||
+#define CONFDB_DOMAIN_INHERIT_FROM "inherit_from"
|
||||
|
||||
/* Local Provider */
|
||||
#define CONFDB_LOCAL_DEFAULT_SHELL "default_shell"
|
||||
@@ -398,6 +400,8 @@ int confdb_get_domains(struct confdb_ctx *cdb,
|
||||
int confdb_ensure_files_domain(struct confdb_ctx *cdb,
|
||||
const char *implicit_files_dom_name);
|
||||
|
||||
+int confdb_expand_app_domains(struct confdb_ctx *cdb);
|
||||
+
|
||||
/**
|
||||
* Get a null-terminated linked-list of all domain names
|
||||
* @param[in] mem_ctx The parent memory context for the value list
|
||||
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
|
||||
index 3c857236eaa55b313d176bc4bb479918163b60d5..8fd2d2c5236246394353a88c50d1510bd6233f77 100644
|
||||
--- a/src/config/cfg_rules.ini
|
||||
+++ b/src/config/cfg_rules.ini
|
||||
@@ -12,6 +12,7 @@ section = secrets
|
||||
section = kcm
|
||||
section_re = ^secrets/users/[0-9]\+$
|
||||
section_re = ^domain/.*$
|
||||
+section_re = ^application/.*$
|
||||
|
||||
[rule/allowed_sssd_options]
|
||||
validator = ini_allowed_options
|
||||
@@ -286,7 +287,7 @@ option = responder_idle_timeout
|
||||
|
||||
[rule/allowed_domain_options]
|
||||
validator = ini_allowed_options
|
||||
-section_re = ^domain/.*$
|
||||
+section_re = ^(domain|application)/.*$
|
||||
|
||||
option = debug
|
||||
option = debug_level
|
||||
@@ -684,3 +685,9 @@ option = ldap_user_ssh_public_key
|
||||
option = ldap_user_uid_number
|
||||
option = ldap_user_uuid
|
||||
option = ldap_use_tokengroups
|
||||
+
|
||||
+[rule/allowed_application_options]
|
||||
+validator = ini_allowed_options
|
||||
+section_re = ^application/.*$
|
||||
+
|
||||
+option = inherit_from
|
||||
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
|
||||
index 9abcff84a95ea1b27e36845e830cc125fdc89f90..8294793c765bfa6bf481693c7d7f206950454681 100644
|
||||
--- a/src/man/sssd.conf.5.xml
|
||||
+++ b/src/man/sssd.conf.5.xml
|
||||
@@ -1539,6 +1539,10 @@ pam_account_locked_message = Account locked, please contact help desk.
|
||||
<quote>id_provider=ldap</quote> only.
|
||||
</para>
|
||||
<para>
|
||||
+ For an easy way to configure a non-POSIX domains, please
|
||||
+ see the <quote>Application domains</quote> section.
|
||||
+ </para>
|
||||
+ <para>
|
||||
Default: posix
|
||||
</para>
|
||||
</listitem>
|
||||
@@ -2692,6 +2696,79 @@ subdomain_inherit = ldap_purge_cache_timeout
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
+ <refsect2 id='app_domains'>
|
||||
+ <title>Application domains</title>
|
||||
+ <para>
|
||||
+ SSSD, with its D-Bus interface (see
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>sssd-ifp</refentrytitle>
|
||||
+ <manvolnum>5</manvolnum>
|
||||
+ </citerefentry>) is appealing to applications
|
||||
+ as a gateway to an LDAP directory where users and groups
|
||||
+ are stored. However, contrary to the traditional SSSD
|
||||
+ deployment where all users and groups either have POSIX
|
||||
+ attributes or those attributes can be inferred from the
|
||||
+ Windows SIDs, in many cases the users and groups in the
|
||||
+ application support scenario have no POSIX attributes.
|
||||
+ Instead of setting a
|
||||
+ <quote>[domain/<replaceable>NAME</replaceable>]</quote>
|
||||
+ section, the administrator can set up an
|
||||
+ <quote>[application/<replaceable>NAME</replaceable>]</quote>
|
||||
+ section that internally represents a domain with type
|
||||
+ <quote>application</quote> optionally inherits settings
|
||||
+ from a tradition SSSD domain.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Please note that the application domain must still be
|
||||
+ explicitly enabled in the <quote>domains</quote> parameter
|
||||
+ so that the lookup order between the application domain
|
||||
+ and its POSIX sibling domain is set correctly.
|
||||
+ </para>
|
||||
+ <variablelist>
|
||||
+ <title>Application domain parameters</title>
|
||||
+ <varlistentry>
|
||||
+ <term>inherit_from (string)</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ The SSSD POSIX-type domain the application
|
||||
+ domain inherits all settings from. The
|
||||
+ application domain can moreover add its own
|
||||
+ settings to the application settings that augment
|
||||
+ or override the <quote>sibling</quote>
|
||||
+ domain settings.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Default: Not set
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ </variablelist>
|
||||
+ <para>
|
||||
+ The following example illustrates the use of an application
|
||||
+ domain. In this setup, the POSIX domain is connected to an LDAP
|
||||
+ server and is used by the OS through the NSS responder. In addition,
|
||||
+ the application domains also requests the telephoneNumber attribute,
|
||||
+ stores it as the phone attribute in the cache and makes the phone
|
||||
+ attribute reachable through the D-Bus interface.
|
||||
+ </para>
|
||||
+<programlisting>
|
||||
+[sssd]
|
||||
+domains = appdom, posixdom
|
||||
+
|
||||
+[ifp]
|
||||
+user_attributes = +phone
|
||||
+
|
||||
+[domain/posixdom]
|
||||
+id_provider = ldap
|
||||
+ldap_uri = ldap://ldap.example.com
|
||||
+ldap_search_base = dc=example,dc=com
|
||||
+
|
||||
+[application/appdom]
|
||||
+inherit_from = posixdom
|
||||
+ldap_user_extra_attrs = phone:telephoneNumber
|
||||
+</programlisting>
|
||||
+ </refsect2>
|
||||
+
|
||||
<refsect2 id='local_domain'>
|
||||
<title>The local domain section</title>
|
||||
<para>
|
||||
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
|
||||
index 7e7b5a07d11aecf1c0b11592213b90d385fd5076..2753b46667f7ae0b022776862c67a327d3356d6d 100644
|
||||
--- a/src/monitor/monitor.c
|
||||
+++ b/src/monitor/monitor.c
|
||||
@@ -1064,6 +1064,14 @@ static int get_monitor_config(struct mt_ctx *ctx)
|
||||
/* Not fatal */
|
||||
}
|
||||
|
||||
+ ret = confdb_expand_app_domains(ctx->cdb);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "Failed to expand application domains\n");
|
||||
+ /* This must not be fatal so that SSSD keeps running and lets
|
||||
+ * admin correct the error.
|
||||
+ */
|
||||
+ }
|
||||
+
|
||||
ret = confdb_get_domains(ctx->cdb, &ctx->domains);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_FATAL_FAILURE, "No domains configured.\n");
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,976 +0,0 @@
|
||||
From cee85e8fb9534ec997e5388fce59f392cf029573 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Fri, 24 Mar 2017 10:39:12 +0100
|
||||
Subject: [PATCH 66/97] CACHE_REQ: Domain type selection in cache_req
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Related to:
|
||||
https://pagure.io/SSSD/sssd/issue/3310
|
||||
|
||||
Adds a new enumeration cache_req_dom_type. It is a tri-state that
|
||||
allows the caller to select which domains can be contacted - either only
|
||||
POSIX, only application domains or any type.
|
||||
|
||||
Not all plugins of cache_req have the new parameter added -- only those
|
||||
that are usable/useful in a non-POSIX environment. For example, it makes
|
||||
no sense to allow the selection for calls by ID because those are
|
||||
inherently POSIX-specific. Also, services or netgroups are supported
|
||||
only coming from POSIX domains.
|
||||
|
||||
At the moment, the patch should not change any behaviour as all calls
|
||||
default to contacting POSIX domains only.
|
||||
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/responder/common/cache_req/cache_req.c | 80 ++++++++++++++++++++--
|
||||
src/responder/common/cache_req/cache_req.h | 19 +++++
|
||||
src/responder/common/cache_req/cache_req_private.h | 3 +
|
||||
.../cache_req/plugins/cache_req_enum_groups.c | 4 +-
|
||||
.../common/cache_req/plugins/cache_req_enum_svc.c | 3 +-
|
||||
.../cache_req/plugins/cache_req_enum_users.c | 4 +-
|
||||
.../cache_req/plugins/cache_req_group_by_filter.c | 5 +-
|
||||
.../cache_req/plugins/cache_req_group_by_id.c | 4 +-
|
||||
.../cache_req/plugins/cache_req_group_by_name.c | 5 +-
|
||||
.../cache_req/plugins/cache_req_host_by_name.c | 4 +-
|
||||
.../plugins/cache_req_initgroups_by_name.c | 5 +-
|
||||
.../cache_req/plugins/cache_req_netgroup_by_name.c | 4 +-
|
||||
.../cache_req/plugins/cache_req_object_by_id.c | 4 +-
|
||||
.../cache_req/plugins/cache_req_object_by_name.c | 4 +-
|
||||
.../cache_req/plugins/cache_req_object_by_sid.c | 4 +-
|
||||
.../cache_req/plugins/cache_req_svc_by_name.c | 4 +-
|
||||
.../cache_req/plugins/cache_req_svc_by_port.c | 4 +-
|
||||
.../cache_req/plugins/cache_req_user_by_cert.c | 4 +-
|
||||
.../cache_req/plugins/cache_req_user_by_filter.c | 5 +-
|
||||
.../cache_req/plugins/cache_req_user_by_id.c | 4 +-
|
||||
.../cache_req/plugins/cache_req_user_by_name.c | 9 ++-
|
||||
src/responder/ifp/ifp_groups.c | 14 +++-
|
||||
src/responder/ifp/ifp_users.c | 19 +++--
|
||||
src/responder/ifp/ifpsrv_cmd.c | 3 +-
|
||||
src/responder/nss/nss_enum.c | 2 +-
|
||||
src/responder/nss/nss_get_object.c | 3 +-
|
||||
src/responder/pam/pamsrv_cmd.c | 5 +-
|
||||
src/responder/sudo/sudosrv_get_sudorules.c | 3 +-
|
||||
src/tests/cmocka/test_responder_cache_req.c | 62 ++++++++++++++---
|
||||
29 files changed, 246 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c
|
||||
index 483126396f8addbad744ae03bfc739801cd0c18b..3a5fecf34427437bbf95317e05c5bd8b07b4537d 100644
|
||||
--- a/src/responder/common/cache_req/cache_req.c
|
||||
+++ b/src/responder/common/cache_req/cache_req.c
|
||||
@@ -89,12 +89,31 @@ static errno_t cache_req_set_plugin(struct cache_req *cr,
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+static const char *
|
||||
+cache_req_dom_type_as_str(struct cache_req *cr)
|
||||
+{
|
||||
+ if (cr == NULL) {
|
||||
+ return "BUG: Invalid cache_req pointer\n";
|
||||
+ }
|
||||
+ switch (cr->req_dom_type) {
|
||||
+ case CACHE_REQ_POSIX_DOM:
|
||||
+ return "POSIX-only";
|
||||
+ case CACHE_REQ_APPLICATION_DOM:
|
||||
+ return "Application-only";
|
||||
+ case CACHE_REQ_ANY_DOM:
|
||||
+ return "Any";
|
||||
+ }
|
||||
+
|
||||
+ return "Unknown";
|
||||
+}
|
||||
+
|
||||
static struct cache_req *
|
||||
cache_req_create(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct cache_req_data *data,
|
||||
struct sss_nc_ctx *ncache,
|
||||
- int midpoint)
|
||||
+ int midpoint,
|
||||
+ enum cache_req_dom_type req_dom_type)
|
||||
{
|
||||
struct cache_req *cr;
|
||||
errno_t ret;
|
||||
@@ -108,6 +127,7 @@ cache_req_create(TALLOC_CTX *mem_ctx,
|
||||
cr->data = data;
|
||||
cr->ncache = ncache;
|
||||
cr->midpoint = midpoint;
|
||||
+ cr->req_dom_type = req_dom_type;
|
||||
cr->req_start = time(NULL);
|
||||
|
||||
/* It is perfectly fine to just overflow here. */
|
||||
@@ -145,8 +165,8 @@ cache_req_set_name(struct cache_req *cr, const char *name)
|
||||
}
|
||||
|
||||
static bool
|
||||
-cache_req_validate_domain(struct cache_req *cr,
|
||||
- struct sss_domain_info *domain)
|
||||
+cache_req_validate_domain_enumeration(struct cache_req *cr,
|
||||
+ struct sss_domain_info *domain)
|
||||
{
|
||||
if (!cr->plugin->require_enumeration) {
|
||||
return true;
|
||||
@@ -164,6 +184,52 @@ cache_req_validate_domain(struct cache_req *cr,
|
||||
return true;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+cache_req_validate_domain_type(struct cache_req *cr,
|
||||
+ struct sss_domain_info *domain)
|
||||
+{
|
||||
+ bool valid = false;
|
||||
+
|
||||
+ switch (cr->req_dom_type) {
|
||||
+ case CACHE_REQ_POSIX_DOM:
|
||||
+ valid = domain->type == DOM_TYPE_POSIX ? true : false;
|
||||
+ break;
|
||||
+ case CACHE_REQ_APPLICATION_DOM:
|
||||
+ valid = domain->type == DOM_TYPE_APPLICATION ? true : false;
|
||||
+ break;
|
||||
+ case CACHE_REQ_ANY_DOM:
|
||||
+ valid = true;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(SSSDBG_TRACE_INTERNAL,
|
||||
+ "Request type %s for domain %s type %s is %svalid\n",
|
||||
+ cache_req_dom_type_as_str(cr),
|
||||
+ domain->name,
|
||||
+ sss_domain_type_str(domain),
|
||||
+ valid ? "" : "not ");
|
||||
+ return valid;
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+cache_req_validate_domain(struct cache_req *cr,
|
||||
+ struct sss_domain_info *domain)
|
||||
+{
|
||||
+ bool ok;
|
||||
+
|
||||
+ ok = cache_req_validate_domain_enumeration(cr, domain);
|
||||
+ if (ok == false) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ ok = cache_req_validate_domain_type(cr, domain);
|
||||
+ if (ok == false) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static errno_t
|
||||
cache_req_is_well_known_object(TALLOC_CTX *mem_ctx,
|
||||
struct cache_req *cr,
|
||||
@@ -651,6 +717,7 @@ struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_nc_ctx *ncache,
|
||||
int midpoint,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
struct cache_req_data *data)
|
||||
{
|
||||
@@ -667,7 +734,8 @@ struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
state->ev = ev;
|
||||
- state->cr = cr = cache_req_create(state, rctx, data, ncache, midpoint);
|
||||
+ state->cr = cr = cache_req_create(state, rctx, data,
|
||||
+ ncache, midpoint, req_dom_type);
|
||||
if (state->cr == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto done;
|
||||
@@ -952,13 +1020,15 @@ cache_req_steal_data_and_send(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_nc_ctx *ncache,
|
||||
int cache_refresh_percent,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
struct cache_req_data *data)
|
||||
{
|
||||
struct tevent_req *req;
|
||||
|
||||
req = cache_req_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ req_dom_type, domain, data);
|
||||
if (req == NULL) {
|
||||
talloc_zfree(data);
|
||||
return NULL;
|
||||
diff --git a/src/responder/common/cache_req/cache_req.h b/src/responder/common/cache_req/cache_req.h
|
||||
index d0e5ff43921467fc191fd5cc7d5b49cc039b7f67..c04b2fba6f0445dcfcc9cfe1b5963ac975c39118 100644
|
||||
--- a/src/responder/common/cache_req/cache_req.h
|
||||
+++ b/src/responder/common/cache_req/cache_req.h
|
||||
@@ -57,6 +57,18 @@ enum cache_req_type {
|
||||
CACHE_REQ_SENTINEL
|
||||
};
|
||||
|
||||
+/* Whether to limit the request type to a certain domain type
|
||||
+ * (POSIX/non-POSIX)
|
||||
+ */
|
||||
+enum cache_req_dom_type {
|
||||
+ /* Only look up data in POSIX domains */
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
+ /* Only look up data in application domains */
|
||||
+ CACHE_REQ_APPLICATION_DOM,
|
||||
+ /* Look up data in any domain type */
|
||||
+ CACHE_REQ_ANY_DOM
|
||||
+};
|
||||
+
|
||||
/* Input data. */
|
||||
|
||||
struct cache_req_data;
|
||||
@@ -172,6 +184,7 @@ struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_nc_ctx *ncache,
|
||||
int midpoint,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
struct cache_req_data *data);
|
||||
|
||||
@@ -191,6 +204,7 @@ cache_req_user_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_nc_ctx *ncache,
|
||||
int cache_refresh_percent,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
const char *name);
|
||||
|
||||
@@ -228,6 +242,7 @@ cache_req_user_by_cert_send(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_nc_ctx *ncache,
|
||||
int cache_refresh_percent,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
const char *pem_cert);
|
||||
|
||||
@@ -240,6 +255,7 @@ cache_req_group_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_nc_ctx *ncache,
|
||||
int cache_refresh_percent,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
const char *name);
|
||||
|
||||
@@ -264,6 +280,7 @@ cache_req_initgr_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_nc_ctx *ncache,
|
||||
int cache_refresh_percent,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
const char *name);
|
||||
|
||||
@@ -274,6 +291,7 @@ struct tevent_req *
|
||||
cache_req_user_by_filter_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct resp_ctx *rctx,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
const char *filter);
|
||||
|
||||
@@ -284,6 +302,7 @@ struct tevent_req *
|
||||
cache_req_group_by_filter_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct resp_ctx *rctx,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
const char *filter);
|
||||
|
||||
diff --git a/src/responder/common/cache_req/cache_req_private.h b/src/responder/common/cache_req/cache_req_private.h
|
||||
index 2d3c1870795e4fd5667f603280edcee24f926220..851005c389f994b1bd2d04cda9b68df8b18492cc 100644
|
||||
--- a/src/responder/common/cache_req/cache_req_private.h
|
||||
+++ b/src/responder/common/cache_req/cache_req_private.h
|
||||
@@ -42,6 +42,8 @@ struct cache_req {
|
||||
struct sss_domain_info *domain;
|
||||
bool cache_first;
|
||||
bool bypass_cache;
|
||||
+ /* Only contact domains with this type */
|
||||
+ enum cache_req_dom_type req_dom_type;
|
||||
|
||||
/* Debug information */
|
||||
uint32_t reqid;
|
||||
@@ -108,6 +110,7 @@ cache_req_steal_data_and_send(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_nc_ctx *ncache,
|
||||
int cache_refresh_percent,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
struct cache_req_data *data);
|
||||
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_enum_groups.c b/src/responder/common/cache_req/plugins/cache_req_enum_groups.c
|
||||
index dbb40c98339cc9295e3678e05340396aff51ac78..49ce3508e678862e4389657187b9659ce90fbd1c 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_enum_groups.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_enum_groups.c
|
||||
@@ -96,5 +96,7 @@ cache_req_enum_groups_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_enum_svc.c b/src/responder/common/cache_req/plugins/cache_req_enum_svc.c
|
||||
index 28dea33c601f500b9c7af0de3eb9e1c342f03522..499b994738d62707b4e86d5a8383e3e2b82e8c57 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_enum_svc.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_enum_svc.c
|
||||
@@ -97,5 +97,6 @@ cache_req_enum_svc_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain, data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_enum_users.c b/src/responder/common/cache_req/plugins/cache_req_enum_users.c
|
||||
index 3b1a85841e3ed853cd329dfa9d762cb7a05cbd43..b635354be6e9d2e2e2af1a6f867ac68e6cf7f085 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_enum_users.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_enum_users.c
|
||||
@@ -96,5 +96,7 @@ cache_req_enum_users_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c b/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c
|
||||
index 6ce6ae0d63967ac50b813a47ac938251619948da..4377a476c36e5e03c8533bc62335b84fa1cee3ff 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c
|
||||
@@ -140,6 +140,7 @@ struct tevent_req *
|
||||
cache_req_group_by_filter_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct resp_ctx *rctx,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
const char *filter)
|
||||
{
|
||||
@@ -151,5 +152,7 @@ cache_req_group_by_filter_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, NULL,
|
||||
- 0, domain, data);
|
||||
+ 0,
|
||||
+ req_dom_type, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c
|
||||
index e98f76f8cd20742b81ae247df61db159d2584a17..ad5b7d890a42f29b586ab8e0943fef3dfab1162d 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c
|
||||
@@ -166,5 +166,7 @@ cache_req_group_by_id_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_name.c b/src/responder/common/cache_req/plugins/cache_req_group_by_name.c
|
||||
index af6f23ccfd68f952027462ba3e74ed7219d04651..de1e8f9442273acf386a2278b06f28ee63a7e3c6 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_group_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_name.c
|
||||
@@ -205,6 +205,7 @@ cache_req_group_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_nc_ctx *ncache,
|
||||
int cache_refresh_percent,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
const char *name)
|
||||
{
|
||||
@@ -216,5 +217,7 @@ cache_req_group_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ req_dom_type, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_host_by_name.c b/src/responder/common/cache_req/plugins/cache_req_host_by_name.c
|
||||
index 77b46831fec3abc4126ef9d9be67221469801094..1171cd63fac5cc1d36b31bf8a069f059705cae90 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_host_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_host_by_name.c
|
||||
@@ -117,5 +117,7 @@ cache_req_host_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c b/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c
|
||||
index 307b65a24282838b99c472b50a71f06865aed3f0..f100aefe5c92279cde7e3209c7f48f5e2b35f135 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c
|
||||
@@ -220,6 +220,7 @@ cache_req_initgr_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_nc_ctx *ncache,
|
||||
int cache_refresh_percent,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
const char *name)
|
||||
{
|
||||
@@ -231,5 +232,7 @@ cache_req_initgr_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ req_dom_type, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c b/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c
|
||||
index e49d6d84a41ce8dabf18c87373826f8e7b684bda..ab3e553d3ecb8ae09094dcfc938ed0ac01925327 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c
|
||||
@@ -150,5 +150,7 @@ cache_req_netgroup_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c
|
||||
index 046e313c83d1d4c75237b047be779201b8a5d3c0..9557bd15270b2eb1a0671f9ef91033efac29c3ac 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c
|
||||
@@ -134,5 +134,7 @@ cache_req_object_by_id_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_name.c b/src/responder/common/cache_req/plugins/cache_req_object_by_name.c
|
||||
index 74d2b3dea287e890b38e4d5bb176ad2dc6337b7e..e236d1fa4aadcd87b192d34ebaf5f9ad8908b6c2 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_object_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_object_by_name.c
|
||||
@@ -228,5 +228,7 @@ cache_req_object_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_sid.c b/src/responder/common/cache_req/plugins/cache_req_object_by_sid.c
|
||||
index ab577663111cfd424e7f46308b2621af7f1ca264..dfec79da07d669165205a767cab22c2254686134 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_object_by_sid.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_object_by_sid.c
|
||||
@@ -143,5 +143,7 @@ cache_req_object_by_sid_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c b/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c
|
||||
index ef13f097a8ae78ec9db5b7f6e14924b511578b34..b2bfb26ffed1a60ed8389fa89b0e728c8c6cf76c 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c
|
||||
@@ -175,5 +175,7 @@ cache_req_svc_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c b/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c
|
||||
index afa2eeeda12794de26e798aee4b88900bc87ed93..0e48437f4b64d26112be88af1eebc20f012b70fd 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c
|
||||
@@ -149,5 +149,7 @@ cache_req_svc_by_port_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_cert.c b/src/responder/common/cache_req/plugins/cache_req_user_by_cert.c
|
||||
index f237c8d0fe3faf5aea553480f3f92eb279209a20..286a34db276e0098060982c572e2a68ceceebf60 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_user_by_cert.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_cert.c
|
||||
@@ -105,6 +105,7 @@ cache_req_user_by_cert_send(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_nc_ctx *ncache,
|
||||
int cache_refresh_percent,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
const char *pem_cert)
|
||||
{
|
||||
@@ -117,5 +118,6 @@ cache_req_user_by_cert_send(TALLOC_CTX *mem_ctx,
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
cache_refresh_percent,
|
||||
- domain, data);
|
||||
+ req_dom_type, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c b/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c
|
||||
index eb71b42dad3a805298df0c8425409d571befb31b..c476814373cd784bf8dbbea1da7b010afe5bb4e4 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c
|
||||
@@ -140,6 +140,7 @@ struct tevent_req *
|
||||
cache_req_user_by_filter_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct resp_ctx *rctx,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
const char *filter)
|
||||
{
|
||||
@@ -151,5 +152,7 @@ cache_req_user_by_filter_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, NULL,
|
||||
- 0, domain, data);
|
||||
+ 0,
|
||||
+ req_dom_type, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c
|
||||
index fa783714b7c67ca029d18a223b64a3a69e3e6929..9ba73292e5dc518e86c6e00e7e493d6871f28e70 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c
|
||||
@@ -166,5 +166,7 @@ cache_req_user_by_id_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_name.c b/src/responder/common/cache_req/plugins/cache_req_user_by_name.c
|
||||
index 0670febdce2d51e0373045570dd07f56255db7bc..15da7d0d20b1ac97511a226daecc8ef7e7d2e7e4 100644
|
||||
--- a/src/responder/common/cache_req/plugins/cache_req_user_by_name.c
|
||||
+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_name.c
|
||||
@@ -210,6 +210,7 @@ cache_req_user_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
struct resp_ctx *rctx,
|
||||
struct sss_nc_ctx *ncache,
|
||||
int cache_refresh_percent,
|
||||
+ enum cache_req_dom_type req_dom_type,
|
||||
const char *domain,
|
||||
const char *name)
|
||||
{
|
||||
@@ -221,7 +222,9 @@ cache_req_user_by_name_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ req_dom_type, domain,
|
||||
+ data);
|
||||
}
|
||||
|
||||
struct tevent_req *
|
||||
@@ -243,5 +246,7 @@ cache_req_user_by_name_attrs_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache,
|
||||
- cache_refresh_percent, domain, data);
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, domain,
|
||||
+ data);
|
||||
}
|
||||
diff --git a/src/responder/ifp/ifp_groups.c b/src/responder/ifp/ifp_groups.c
|
||||
index 94d1e84cc9de75727d3c47c0a5a24790d21ce132..99908e96bd971bce4b4e9064a77d8413f837d743 100644
|
||||
--- a/src/responder/ifp/ifp_groups.c
|
||||
+++ b/src/responder/ifp/ifp_groups.c
|
||||
@@ -118,7 +118,9 @@ int ifp_groups_find_by_name(struct sbus_request *sbus_req,
|
||||
}
|
||||
|
||||
req = cache_req_group_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx,
|
||||
- ctx->rctx->ncache, 0, NULL, name);
|
||||
+ ctx->rctx->ncache, 0,
|
||||
+ CACHE_REQ_POSIX_DOM, NULL,
|
||||
+ name);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
@@ -271,6 +273,7 @@ static int ifp_groups_list_by_name_step(struct ifp_list_ctx *list_ctx)
|
||||
req = cache_req_group_by_filter_send(list_ctx,
|
||||
list_ctx->ctx->rctx->ev,
|
||||
list_ctx->ctx->rctx,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
list_ctx->dom->name,
|
||||
list_ctx->filter);
|
||||
if (req == NULL) {
|
||||
@@ -355,7 +358,8 @@ int ifp_groups_list_by_domain_and_name(struct sbus_request *sbus_req,
|
||||
}
|
||||
|
||||
req = cache_req_group_by_filter_send(list_ctx, ctx->rctx->ev, ctx->rctx,
|
||||
- domain, filter);
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
+ domain, filter);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
@@ -522,7 +526,10 @@ static struct tevent_req *resolv_ghosts_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
subreq = cache_req_group_by_name_send(state, ev, ctx->rctx,
|
||||
- ctx->rctx->ncache, 0, domain->name, name);
|
||||
+ ctx->rctx->ncache, 0,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
+ domain->name,
|
||||
+ name);
|
||||
if (subreq == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto immediately;
|
||||
@@ -601,6 +608,7 @@ errno_t resolv_ghosts_step(struct tevent_req *req)
|
||||
|
||||
subreq = cache_req_user_by_name_send(state, state->ev, state->ctx->rctx,
|
||||
state->ctx->rctx->ncache, 0,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
state->domain->name,
|
||||
state->ghosts[state->index]);
|
||||
if (subreq == NULL) {
|
||||
diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c
|
||||
index cc78300f31e863fcb5366e18a14abc597c6f7ddb..436bb268fa9c78d72fb744e0d338aa561a7d8764 100644
|
||||
--- a/src/responder/ifp/ifp_users.c
|
||||
+++ b/src/responder/ifp/ifp_users.c
|
||||
@@ -99,7 +99,9 @@ int ifp_users_find_by_name(struct sbus_request *sbus_req,
|
||||
}
|
||||
|
||||
req = cache_req_user_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx,
|
||||
- ctx->rctx->ncache, 0, NULL, name);
|
||||
+ ctx->rctx->ncache, 0,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
+ NULL, name);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
@@ -253,7 +255,9 @@ int ifp_users_find_by_cert(struct sbus_request *sbus_req, void *data,
|
||||
}
|
||||
|
||||
req = cache_req_user_by_cert_send(sbus_req, ctx->rctx->ev, ctx->rctx,
|
||||
- ctx->rctx->ncache, 0, NULL, derb64);
|
||||
+ ctx->rctx->ncache, 0,
|
||||
+ CACHE_REQ_POSIX_DOM, NULL,
|
||||
+ derb64);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
@@ -367,6 +371,7 @@ static int ifp_users_list_by_cert_step(struct ifp_list_ctx *list_ctx)
|
||||
list_ctx->ctx->rctx,
|
||||
list_ctx->ctx->rctx->ncache,
|
||||
0,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
list_ctx->dom->name,
|
||||
list_ctx->filter);
|
||||
if (req == NULL) {
|
||||
@@ -532,7 +537,9 @@ int ifp_users_find_by_name_and_cert(struct sbus_request *sbus_req, void *data,
|
||||
|
||||
if (name_and_cert_ctx->name != NULL) {
|
||||
req = cache_req_user_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx,
|
||||
- ctx->rctx->ncache, 0, NULL,
|
||||
+ ctx->rctx->ncache, 0,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
+ NULL,
|
||||
name_and_cert_ctx->name);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
@@ -614,6 +621,7 @@ static int ifp_users_find_by_name_and_cert_step(
|
||||
list_ctx->ctx->rctx,
|
||||
list_ctx->ctx->rctx->ncache,
|
||||
0,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
list_ctx->dom->name,
|
||||
list_ctx->filter);
|
||||
if (req == NULL) {
|
||||
@@ -774,6 +782,7 @@ static int ifp_users_list_by_name_step(struct ifp_list_ctx *list_ctx)
|
||||
req = cache_req_user_by_filter_send(list_ctx,
|
||||
list_ctx->ctx->rctx->ev,
|
||||
list_ctx->ctx->rctx,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
list_ctx->dom->name,
|
||||
list_ctx->filter);
|
||||
if (req == NULL) {
|
||||
@@ -858,6 +867,7 @@ int ifp_users_list_by_domain_and_name(struct sbus_request *sbus_req,
|
||||
}
|
||||
|
||||
req = cache_req_user_by_filter_send(list_ctx, ctx->rctx->ev, ctx->rctx,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
domain, filter);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
@@ -1102,7 +1112,8 @@ int ifp_users_user_update_groups_list(struct sbus_request *sbus_req,
|
||||
}
|
||||
|
||||
req = cache_req_initgr_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx,
|
||||
- ctx->rctx->ncache, 0, domain->name,
|
||||
+ ctx->rctx->ncache, 0,
|
||||
+ CACHE_REQ_POSIX_DOM, domain->name,
|
||||
username);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
diff --git a/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c
|
||||
index 07edcddffa1091f8bbcf79a25962aadc791bb890..118b5083b14bf5692c6fdd7ba90668fe514aa89d 100644
|
||||
--- a/src/responder/ifp/ifpsrv_cmd.c
|
||||
+++ b/src/responder/ifp/ifpsrv_cmd.c
|
||||
@@ -509,7 +509,8 @@ ifp_user_get_attr_lookup(struct tevent_req *subreq)
|
||||
}
|
||||
|
||||
subreq = cache_req_send(state, state->rctx->ev, state->rctx,
|
||||
- state->ncache, 0, state->domname, data);
|
||||
+ state->ncache, 0, CACHE_REQ_POSIX_DOM,
|
||||
+ state->domname, data);
|
||||
if (subreq == NULL) {
|
||||
tevent_req_error(req, ENOMEM);
|
||||
return;
|
||||
diff --git a/src/responder/nss/nss_enum.c b/src/responder/nss/nss_enum.c
|
||||
index b1cce2cde43ece735285c132d0127c142ee83cb0..aa7d8428f37e943a6b5904495c40ad4b8011b767 100644
|
||||
--- a/src/responder/nss/nss_enum.c
|
||||
+++ b/src/responder/nss/nss_enum.c
|
||||
@@ -93,7 +93,7 @@ nss_setent_internal_send(TALLOC_CTX *mem_ctx,
|
||||
/* Create new object. */
|
||||
state->enum_ctx->is_ready = false;
|
||||
subreq = cache_req_send(req, ev, cli_ctx->rctx, cli_ctx->rctx->ncache,
|
||||
- 0, NULL, data);
|
||||
+ 0, CACHE_REQ_POSIX_DOM, NULL, data);
|
||||
if (subreq == NULL) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send cache request!\n");
|
||||
ret = ENOMEM;
|
||||
diff --git a/src/responder/nss/nss_get_object.c b/src/responder/nss/nss_get_object.c
|
||||
index f83dd393c0e333d8914802e005672a15a51d5939..9058793ea2d72b57003a7219414af6a0f0c5b89e 100644
|
||||
--- a/src/responder/nss/nss_get_object.c
|
||||
+++ b/src/responder/nss/nss_get_object.c
|
||||
@@ -190,7 +190,8 @@ nss_get_object_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
subreq = cache_req_send(req, ev, cli_ctx->rctx, cli_ctx->rctx->ncache,
|
||||
- state->nss_ctx->cache_refresh_percent, NULL, data);
|
||||
+ state->nss_ctx->cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM, NULL, data);
|
||||
if (subreq == NULL) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send cache request!\n");
|
||||
ret = ENOMEM;
|
||||
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
|
||||
index ba2563c11885ff39681c2ef432acaedf26702b64..fa6d2cc10fe1404196f9d9221a469d7a9a768211 100644
|
||||
--- a/src/responder/pam/pamsrv_cmd.c
|
||||
+++ b/src/responder/pam/pamsrv_cmd.c
|
||||
@@ -1315,7 +1315,9 @@ static void pam_forwarder_cert_cb(struct tevent_req *req)
|
||||
|
||||
|
||||
req = cache_req_user_by_cert_send(preq, cctx->ev, cctx->rctx,
|
||||
- pctx->rctx->ncache, 0, NULL, cert);
|
||||
+ pctx->rctx->ncache, 0,
|
||||
+ CACHE_REQ_POSIX_DOM, NULL,
|
||||
+ cert);
|
||||
if (req == NULL) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "cache_req_user_by_cert_send failed.\n");
|
||||
ret = ENOMEM;
|
||||
@@ -1507,6 +1509,7 @@ static int pam_check_user_search(struct pam_auth_req *preq)
|
||||
preq->cctx->rctx,
|
||||
preq->cctx->rctx->ncache,
|
||||
0,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
preq->pd->domain,
|
||||
data);
|
||||
if (!dpreq) {
|
||||
diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
|
||||
index 52dfd5c709e48f0d4610a4b384962fbc2869312b..cfdbfc9c9c66d96f774822d6a4d4aaaf1327abe3 100644
|
||||
--- a/src/responder/sudo/sudosrv_get_sudorules.c
|
||||
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
|
||||
@@ -644,7 +644,8 @@ struct tevent_req *sudosrv_get_rules_send(TALLOC_CTX *mem_ctx,
|
||||
DEBUG(SSSDBG_TRACE_FUNC, "Running initgroups for [%s]\n", username);
|
||||
|
||||
subreq = cache_req_initgr_by_name_send(state, ev, sudo_ctx->rctx,
|
||||
- sudo_ctx->rctx->ncache, 0, NULL,
|
||||
+ sudo_ctx->rctx->ncache, 0,
|
||||
+ CACHE_REQ_POSIX_DOM, NULL,
|
||||
username);
|
||||
if (subreq == NULL) {
|
||||
ret = ENOMEM;
|
||||
diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c
|
||||
index 5f1e5350eaf1d85de376c94731f0bd678f884a1d..80086232fd437876c2b190fb972c2ee3194d9efd 100644
|
||||
--- a/src/tests/cmocka/test_responder_cache_req.c
|
||||
+++ b/src/tests/cmocka/test_responder_cache_req.c
|
||||
@@ -84,6 +84,28 @@ struct test_group {
|
||||
talloc_free(req_mem_ctx); \
|
||||
} while (0)
|
||||
|
||||
+#define run_cache_req_domtype(ctx, send_fn, done_fn, dom, crp, domtype, lookup, expret) do { \
|
||||
+ TALLOC_CTX *req_mem_ctx; \
|
||||
+ struct tevent_req *req; \
|
||||
+ errno_t ret; \
|
||||
+ \
|
||||
+ req_mem_ctx = talloc_new(global_talloc_context); \
|
||||
+ check_leaks_push(req_mem_ctx); \
|
||||
+ \
|
||||
+ req = send_fn(req_mem_ctx, ctx->tctx->ev, ctx->rctx, \
|
||||
+ ctx->ncache, crp, \
|
||||
+ domtype, \
|
||||
+ (dom == NULL ? NULL : dom->name), lookup); \
|
||||
+ assert_non_null(req); \
|
||||
+ tevent_req_set_callback(req, done_fn, ctx); \
|
||||
+ \
|
||||
+ ret = test_ev_loop(ctx->tctx); \
|
||||
+ assert_int_equal(ret, expret); \
|
||||
+ assert_true(check_leaks_pop(req_mem_ctx)); \
|
||||
+ \
|
||||
+ talloc_free(req_mem_ctx); \
|
||||
+} while (0)
|
||||
+
|
||||
struct cache_req_test_ctx {
|
||||
struct sss_test_ctx *tctx;
|
||||
struct resp_ctx *rctx;
|
||||
@@ -211,9 +233,11 @@ static void run_user_by_name(struct cache_req_test_ctx *test_ctx,
|
||||
int cache_refresh_percent,
|
||||
errno_t exp_ret)
|
||||
{
|
||||
- run_cache_req(test_ctx, cache_req_user_by_name_send,
|
||||
- cache_req_user_by_name_test_done, domain,
|
||||
- cache_refresh_percent, users[0].short_name, exp_ret);
|
||||
+ run_cache_req_domtype(test_ctx, cache_req_user_by_name_send,
|
||||
+ cache_req_user_by_name_test_done, domain,
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
+ users[0].short_name, exp_ret);
|
||||
}
|
||||
|
||||
static void run_user_by_upn(struct cache_req_test_ctx *test_ctx,
|
||||
@@ -221,9 +245,11 @@ static void run_user_by_upn(struct cache_req_test_ctx *test_ctx,
|
||||
int cache_refresh_percent,
|
||||
errno_t exp_ret)
|
||||
{
|
||||
- run_cache_req(test_ctx, cache_req_user_by_name_send,
|
||||
- cache_req_user_by_name_test_done, domain,
|
||||
- cache_refresh_percent, users[0].upn, exp_ret);
|
||||
+ run_cache_req_domtype(test_ctx, cache_req_user_by_name_send,
|
||||
+ cache_req_user_by_name_test_done, domain,
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
+ users[0].upn, exp_ret);
|
||||
}
|
||||
|
||||
static void run_user_by_id(struct cache_req_test_ctx *test_ctx,
|
||||
@@ -318,9 +344,11 @@ static void run_group_by_name(struct cache_req_test_ctx *test_ctx,
|
||||
int cache_refresh_percent,
|
||||
errno_t exp_ret)
|
||||
{
|
||||
- run_cache_req(test_ctx, cache_req_group_by_name_send,
|
||||
- cache_req_group_by_name_test_done, domain,
|
||||
- cache_refresh_percent, groups[0].short_name, exp_ret);
|
||||
+ run_cache_req_domtype(test_ctx, cache_req_group_by_name_send,
|
||||
+ cache_req_group_by_name_test_done, domain,
|
||||
+ cache_refresh_percent,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
+ groups[0].short_name, exp_ret);
|
||||
}
|
||||
|
||||
static void run_group_by_id(struct cache_req_test_ctx *test_ctx,
|
||||
@@ -605,7 +633,9 @@ void test_user_by_name_multiple_domains_parse(void **state)
|
||||
check_leaks_push(req_mem_ctx);
|
||||
|
||||
req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
|
||||
- test_ctx->rctx, test_ctx->ncache, 0,
|
||||
+ test_ctx->rctx, test_ctx->ncache,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
+ 0,
|
||||
NULL, input_fqn);
|
||||
assert_non_null(req);
|
||||
tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx);
|
||||
@@ -1119,7 +1149,8 @@ void test_group_by_name_multiple_domains_parse(void **state)
|
||||
|
||||
req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev,
|
||||
test_ctx->rctx, test_ctx->ncache, 0,
|
||||
- NULL, input_fqn);
|
||||
+ CACHE_REQ_POSIX_DOM, NULL,
|
||||
+ input_fqn);
|
||||
assert_non_null(req);
|
||||
tevent_req_set_callback(req, cache_req_group_by_name_test_done, test_ctx);
|
||||
|
||||
@@ -1421,6 +1452,7 @@ void test_user_by_recent_filter_valid(void **state)
|
||||
/* User TEST_USER is created with a DP callback. */
|
||||
req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev,
|
||||
test_ctx->rctx,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
test_ctx->tctx->dom->name,
|
||||
TEST_USER_PREFIX);
|
||||
assert_non_null(req);
|
||||
@@ -1463,6 +1495,7 @@ void test_users_by_recent_filter_valid(void **state)
|
||||
/* User TEST_USER1 and TEST_USER2 are created with a DP callback. */
|
||||
req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev,
|
||||
test_ctx->rctx,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
test_ctx->tctx->dom->name,
|
||||
TEST_USER_PREFIX);
|
||||
assert_non_null(req);
|
||||
@@ -1524,6 +1557,7 @@ void test_users_by_filter_filter_old(void **state)
|
||||
|
||||
req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev,
|
||||
test_ctx->rctx,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
test_ctx->tctx->dom->name,
|
||||
TEST_USER_PREFIX);
|
||||
assert_non_null(req);
|
||||
@@ -1559,6 +1593,7 @@ void test_users_by_filter_notfound(void **state)
|
||||
|
||||
req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev,
|
||||
test_ctx->rctx,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
test_ctx->tctx->dom->name,
|
||||
"nosuchuser*");
|
||||
assert_non_null(req);
|
||||
@@ -1592,6 +1627,7 @@ static void test_users_by_filter_multiple_domains_notfound(void **state)
|
||||
|
||||
req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev,
|
||||
test_ctx->rctx,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
domain->name,
|
||||
"nosuchuser*");
|
||||
assert_non_null(req);
|
||||
@@ -1636,6 +1672,7 @@ void test_group_by_recent_filter_valid(void **state)
|
||||
/* Group TEST_GROUP is created with a DP callback. */
|
||||
req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev,
|
||||
test_ctx->rctx,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
test_ctx->tctx->dom->name,
|
||||
TEST_USER_PREFIX);
|
||||
assert_non_null(req);
|
||||
@@ -1680,6 +1717,7 @@ void test_groups_by_recent_filter_valid(void **state)
|
||||
/* Group TEST_GROUP1 and TEST_GROUP2 are created with a DP callback. */
|
||||
req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev,
|
||||
test_ctx->rctx,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
test_ctx->tctx->dom->name,
|
||||
TEST_USER_PREFIX);
|
||||
assert_non_null(req);
|
||||
@@ -1738,6 +1776,7 @@ void test_groups_by_filter_notfound(void **state)
|
||||
|
||||
req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev,
|
||||
test_ctx->rctx,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
test_ctx->tctx->dom->name,
|
||||
"nosuchgroup*");
|
||||
assert_non_null(req);
|
||||
@@ -1770,6 +1809,7 @@ void test_groups_by_filter_multiple_domains_notfound(void **state)
|
||||
|
||||
req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev,
|
||||
test_ctx->rctx,
|
||||
+ CACHE_REQ_POSIX_DOM,
|
||||
domain->name,
|
||||
"nosuchgroup*");
|
||||
assert_non_null(req);
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,705 +0,0 @@
|
||||
From 35f0f5ff9dac790f6c947190fcdc00d01ae9077c Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Fri, 24 Mar 2017 12:44:09 +0100
|
||||
Subject: [PATCH 67/97] IFP: Search both POSIX and non-POSIX domains
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Related to:
|
||||
https://pagure.io/SSSD/sssd/issue/3310
|
||||
|
||||
Changes the behaviour of the InfoPipe responder so that both application
|
||||
and POSIX domains are searched. In general, the IFP responder uses the
|
||||
CACHE_REQ_ANY_DOM lookup type because we can't presume the intention of
|
||||
the caller. Therefore, deployments that combine both POSIX and non-POSIX
|
||||
domains must use fully qualified names or select the right domain order
|
||||
manually.
|
||||
|
||||
There is one change between the POSIX and non-POSIX users or groups -
|
||||
the object path. For the POSIX users, the object path includes the UID
|
||||
or GID. Because we don't have that for the non-POSIX objects, the object
|
||||
name is used in the path instead.
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/responder/ifp/ifp_groups.c | 135 ++++++++++++++++++++++-------------
|
||||
src/responder/ifp/ifp_users.c | 158 ++++++++++++++++++++++++++---------------
|
||||
src/responder/ifp/ifpsrv_cmd.c | 6 +-
|
||||
3 files changed, 194 insertions(+), 105 deletions(-)
|
||||
|
||||
diff --git a/src/responder/ifp/ifp_groups.c b/src/responder/ifp/ifp_groups.c
|
||||
index 99908e96bd971bce4b4e9064a77d8413f837d743..c568c62009cd4b777919dea048fd381a91bd3460 100644
|
||||
--- a/src/responder/ifp/ifp_groups.c
|
||||
+++ b/src/responder/ifp/ifp_groups.c
|
||||
@@ -35,25 +35,33 @@ char * ifp_groups_build_path_from_msg(TALLOC_CTX *mem_ctx,
|
||||
struct sss_domain_info *domain,
|
||||
struct ldb_message *msg)
|
||||
{
|
||||
- const char *gid;
|
||||
+ const char *key = NULL;
|
||||
|
||||
- gid = ldb_msg_find_attr_as_string(msg, SYSDB_GIDNUM, NULL);
|
||||
+ switch (domain->type) {
|
||||
+ case DOM_TYPE_APPLICATION:
|
||||
+ key = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
|
||||
+ break;
|
||||
+ case DOM_TYPE_POSIX:
|
||||
+ key = ldb_msg_find_attr_as_string(msg, SYSDB_GIDNUM, NULL);
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (gid == NULL) {
|
||||
+
|
||||
+ if (key == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- return sbus_opath_compose(mem_ctx, IFP_PATH_GROUPS, domain->name, gid);
|
||||
+ return sbus_opath_compose(mem_ctx, IFP_PATH_GROUPS, domain->name, key);
|
||||
}
|
||||
|
||||
-static errno_t ifp_groups_decompose_path(struct sss_domain_info *domains,
|
||||
+static errno_t ifp_groups_decompose_path(TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_domain_info *domains,
|
||||
const char *path,
|
||||
struct sss_domain_info **_domain,
|
||||
- gid_t *_gid)
|
||||
+ char **_key)
|
||||
{
|
||||
char **parts = NULL;
|
||||
struct sss_domain_info *domain;
|
||||
- gid_t gid;
|
||||
errno_t ret;
|
||||
|
||||
ret = sbus_opath_decompose_exact(NULL, path, IFP_PATH_GROUPS, 2, &parts);
|
||||
@@ -67,14 +75,8 @@ static errno_t ifp_groups_decompose_path(struct sss_domain_info *domains,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- gid = strtouint32(parts[1], NULL, 10);
|
||||
- ret = errno;
|
||||
- if (ret != EOK) {
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
*_domain = domain;
|
||||
- *_gid = gid;
|
||||
+ *_key = talloc_steal(mem_ctx, parts[1]);
|
||||
|
||||
done:
|
||||
talloc_free(parts);
|
||||
@@ -119,7 +121,7 @@ int ifp_groups_find_by_name(struct sbus_request *sbus_req,
|
||||
|
||||
req = cache_req_group_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx,
|
||||
ctx->rctx->ncache, 0,
|
||||
- CACHE_REQ_POSIX_DOM, NULL,
|
||||
+ CACHE_REQ_ANY_DOM, NULL,
|
||||
name);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
@@ -273,7 +275,7 @@ static int ifp_groups_list_by_name_step(struct ifp_list_ctx *list_ctx)
|
||||
req = cache_req_group_by_filter_send(list_ctx,
|
||||
list_ctx->ctx->rctx->ev,
|
||||
list_ctx->ctx->rctx,
|
||||
- CACHE_REQ_POSIX_DOM,
|
||||
+ CACHE_REQ_ANY_DOM,
|
||||
list_ctx->dom->name,
|
||||
list_ctx->filter);
|
||||
if (req == NULL) {
|
||||
@@ -358,7 +360,7 @@ int ifp_groups_list_by_domain_and_name(struct sbus_request *sbus_req,
|
||||
}
|
||||
|
||||
req = cache_req_group_by_filter_send(list_ctx, ctx->rctx->ev, ctx->rctx,
|
||||
- CACHE_REQ_POSIX_DOM,
|
||||
+ CACHE_REQ_ANY_DOM,
|
||||
domain, filter);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
@@ -412,16 +414,65 @@ done:
|
||||
}
|
||||
|
||||
static errno_t
|
||||
+ifp_groups_get_from_cache(struct sbus_request *sbus_req,
|
||||
+ struct sss_domain_info *domain,
|
||||
+ const char *key,
|
||||
+ struct ldb_message **_group)
|
||||
+{
|
||||
+ struct ldb_result *group_res;
|
||||
+ errno_t ret;
|
||||
+ gid_t gid;
|
||||
+
|
||||
+ switch (domain->type) {
|
||||
+ case DOM_TYPE_POSIX:
|
||||
+ gid = strtouint32(key, NULL, 10);
|
||||
+ ret = errno;
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid UID value\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_getgrgid_with_views(sbus_req, domain, gid, &group_res);
|
||||
+ if (ret == EOK && group_res->count == 0) {
|
||||
+ *_group = NULL;
|
||||
+ return ENOENT;
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup group %u@%s [%d]: %s\n",
|
||||
+ gid, domain->name, ret, sss_strerror(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+ break;
|
||||
+ case DOM_TYPE_APPLICATION:
|
||||
+ ret = sysdb_getgrnam_with_views(sbus_req, domain, key, &group_res);
|
||||
+ if (ret == EOK && group_res->count == 0) {
|
||||
+ *_group = NULL;
|
||||
+ return ENOENT;
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup group %s@%s [%d]: %s\n",
|
||||
+ key, domain->name, ret, sss_strerror(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (group_res->count > 1) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "More groups matched by the single key\n");
|
||||
+ return EIO;
|
||||
+ }
|
||||
+
|
||||
+ *_group = group_res->msgs[0];
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static errno_t
|
||||
ifp_groups_group_get(struct sbus_request *sbus_req,
|
||||
void *data,
|
||||
- gid_t *_gid,
|
||||
struct sss_domain_info **_domain,
|
||||
struct ldb_message **_group)
|
||||
{
|
||||
struct ifp_ctx *ctx;
|
||||
struct sss_domain_info *domain;
|
||||
- struct ldb_result *res;
|
||||
- uid_t gid;
|
||||
+ char *key;
|
||||
errno_t ret;
|
||||
|
||||
ctx = talloc_get_type(data, struct ifp_ctx);
|
||||
@@ -430,8 +481,9 @@ ifp_groups_group_get(struct sbus_request *sbus_req,
|
||||
return ERR_INTERNAL;
|
||||
}
|
||||
|
||||
- ret = ifp_groups_decompose_path(ctx->rctx->domains, sbus_req->path,
|
||||
- &domain, &gid);
|
||||
+ ret = ifp_groups_decompose_path(sbus_req,
|
||||
+ ctx->rctx->domains, sbus_req->path,
|
||||
+ &domain, &key);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to decompose object path"
|
||||
"[%s] [%d]: %s\n", sbus_req->path, ret, sss_strerror(ret));
|
||||
@@ -439,28 +491,15 @@ ifp_groups_group_get(struct sbus_request *sbus_req,
|
||||
}
|
||||
|
||||
if (_group != NULL) {
|
||||
- ret = sysdb_getgrgid_with_views(sbus_req, domain, gid, &res);
|
||||
- if (ret == EOK && res->count == 0) {
|
||||
- *_group = NULL;
|
||||
- ret = ENOENT;
|
||||
- }
|
||||
-
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup group %u@%s [%d]: %s\n",
|
||||
- gid, domain->name, ret, sss_strerror(ret));
|
||||
- } else {
|
||||
- *_group = res->msgs[0];
|
||||
- }
|
||||
+ ret = ifp_groups_get_from_cache(sbus_req, domain, key, _group);
|
||||
}
|
||||
|
||||
if (ret == EOK || ret == ENOENT) {
|
||||
- if (_gid != NULL) {
|
||||
- *_gid = gid;
|
||||
- }
|
||||
-
|
||||
if (_domain != NULL) {
|
||||
*_domain = domain;
|
||||
}
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve group from cache\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -513,7 +552,7 @@ static struct tevent_req *resolv_ghosts_send(TALLOC_CTX *mem_ctx,
|
||||
state->ctx = ctx;
|
||||
state->data = data;
|
||||
|
||||
- ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group);
|
||||
+ ret = ifp_groups_group_get(sbus_req, data, &domain, &group);
|
||||
if (ret != EOK) {
|
||||
goto immediately;
|
||||
}
|
||||
@@ -527,7 +566,7 @@ static struct tevent_req *resolv_ghosts_send(TALLOC_CTX *mem_ctx,
|
||||
|
||||
subreq = cache_req_group_by_name_send(state, ev, ctx->rctx,
|
||||
ctx->rctx->ncache, 0,
|
||||
- CACHE_REQ_POSIX_DOM,
|
||||
+ CACHE_REQ_ANY_DOM,
|
||||
domain->name,
|
||||
name);
|
||||
if (subreq == NULL) {
|
||||
@@ -561,7 +600,7 @@ static void resolv_ghosts_group_done(struct tevent_req *subreq)
|
||||
req = tevent_req_callback_data(subreq, struct tevent_req);
|
||||
state = tevent_req_data(req, struct resolv_ghosts_state);
|
||||
|
||||
- ret = ifp_groups_group_get(state->sbus_req, state->data, NULL,
|
||||
+ ret = ifp_groups_group_get(state->sbus_req, state->data,
|
||||
&state->domain, &group);
|
||||
if (ret != EOK) {
|
||||
goto done;
|
||||
@@ -608,7 +647,7 @@ errno_t resolv_ghosts_step(struct tevent_req *req)
|
||||
|
||||
subreq = cache_req_user_by_name_send(state, state->ev, state->ctx->rctx,
|
||||
state->ctx->rctx->ncache, 0,
|
||||
- CACHE_REQ_POSIX_DOM,
|
||||
+ CACHE_REQ_ANY_DOM,
|
||||
state->domain->name,
|
||||
state->ghosts[state->index]);
|
||||
if (subreq == NULL) {
|
||||
@@ -719,7 +758,7 @@ void ifp_groups_group_get_name(struct sbus_request *sbus_req,
|
||||
return;
|
||||
}
|
||||
|
||||
- ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &msg);
|
||||
+ ret = ifp_groups_group_get(sbus_req, data, &domain, &msg);
|
||||
if (ret != EOK) {
|
||||
*_out = NULL;
|
||||
return;
|
||||
@@ -744,7 +783,7 @@ void ifp_groups_group_get_gid_number(struct sbus_request *sbus_req,
|
||||
struct sss_domain_info *domain;
|
||||
errno_t ret;
|
||||
|
||||
- ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &msg);
|
||||
+ ret = ifp_groups_group_get(sbus_req, data, &domain, &msg);
|
||||
if (ret != EOK) {
|
||||
*_out = 0;
|
||||
return;
|
||||
@@ -763,7 +802,7 @@ void ifp_groups_group_get_unique_id(struct sbus_request *sbus_req,
|
||||
struct sss_domain_info *domain;
|
||||
errno_t ret;
|
||||
|
||||
- ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &msg);
|
||||
+ ret = ifp_groups_group_get(sbus_req, data, &domain, &msg);
|
||||
if (ret != EOK) {
|
||||
*_out = 0;
|
||||
return;
|
||||
@@ -803,7 +842,7 @@ ifp_groups_group_get_members(TALLOC_CTX *mem_ctx,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
- ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group);
|
||||
+ ret = ifp_groups_group_get(sbus_req, data, &domain, &group);
|
||||
if (ret != EOK) {
|
||||
goto done;
|
||||
}
|
||||
@@ -954,7 +993,7 @@ int ifp_cache_object_store_group(struct sbus_request *sbus_req,
|
||||
struct ldb_message *group;
|
||||
errno_t ret;
|
||||
|
||||
- ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group);
|
||||
+ ret = ifp_groups_group_get(sbus_req, data, &domain, &group);
|
||||
if (ret != EOK) {
|
||||
error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
|
||||
"group [%d]: %s\n", ret, sss_strerror(ret));
|
||||
@@ -973,7 +1012,7 @@ int ifp_cache_object_remove_group(struct sbus_request *sbus_req,
|
||||
struct ldb_message *group;
|
||||
errno_t ret;
|
||||
|
||||
- ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group);
|
||||
+ ret = ifp_groups_group_get(sbus_req, data, &domain, &group);
|
||||
if (ret != EOK) {
|
||||
error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
|
||||
"group [%d]: %s\n", ret, sss_strerror(ret));
|
||||
diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c
|
||||
index 436bb268fa9c78d72fb744e0d338aa561a7d8764..ce9557f94351b730ee46f3cbce31613cb5901942 100644
|
||||
--- a/src/responder/ifp/ifp_users.c
|
||||
+++ b/src/responder/ifp/ifp_users.c
|
||||
@@ -37,25 +37,33 @@ char * ifp_users_build_path_from_msg(TALLOC_CTX *mem_ctx,
|
||||
struct sss_domain_info *domain,
|
||||
struct ldb_message *msg)
|
||||
{
|
||||
- const char *uid;
|
||||
+ const char *key = NULL;
|
||||
|
||||
- uid = ldb_msg_find_attr_as_string(msg, SYSDB_UIDNUM, NULL);
|
||||
+ switch (domain->type) {
|
||||
+ case DOM_TYPE_APPLICATION:
|
||||
+ key = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
|
||||
+ break;
|
||||
+ case DOM_TYPE_POSIX:
|
||||
+ key = ldb_msg_find_attr_as_string(msg, SYSDB_UIDNUM, NULL);
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (uid == NULL) {
|
||||
+
|
||||
+ if (key == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- return sbus_opath_compose(mem_ctx, IFP_PATH_USERS, domain->name, uid);
|
||||
+ return sbus_opath_compose(mem_ctx, IFP_PATH_USERS, domain->name, key);
|
||||
}
|
||||
|
||||
-static errno_t ifp_users_decompose_path(struct sss_domain_info *domains,
|
||||
+static errno_t ifp_users_decompose_path(TALLOC_CTX *mem_ctx,
|
||||
+ struct sss_domain_info *domains,
|
||||
const char *path,
|
||||
struct sss_domain_info **_domain,
|
||||
- uid_t *_uid)
|
||||
+ char **_key)
|
||||
{
|
||||
char **parts = NULL;
|
||||
struct sss_domain_info *domain;
|
||||
- uid_t uid;
|
||||
errno_t ret;
|
||||
|
||||
ret = sbus_opath_decompose_exact(NULL, path, IFP_PATH_USERS, 2, &parts);
|
||||
@@ -69,14 +77,8 @@ static errno_t ifp_users_decompose_path(struct sss_domain_info *domains,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- uid = strtouint32(parts[1], NULL, 10);
|
||||
- ret = errno;
|
||||
- if (ret != EOK) {
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
*_domain = domain;
|
||||
- *_uid = uid;
|
||||
+ *_key = talloc_steal(mem_ctx, parts[1]);
|
||||
|
||||
done:
|
||||
talloc_free(parts);
|
||||
@@ -100,7 +102,7 @@ int ifp_users_find_by_name(struct sbus_request *sbus_req,
|
||||
|
||||
req = cache_req_user_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx,
|
||||
ctx->rctx->ncache, 0,
|
||||
- CACHE_REQ_POSIX_DOM,
|
||||
+ CACHE_REQ_ANY_DOM,
|
||||
NULL, name);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
@@ -256,7 +258,7 @@ int ifp_users_find_by_cert(struct sbus_request *sbus_req, void *data,
|
||||
|
||||
req = cache_req_user_by_cert_send(sbus_req, ctx->rctx->ev, ctx->rctx,
|
||||
ctx->rctx->ncache, 0,
|
||||
- CACHE_REQ_POSIX_DOM, NULL,
|
||||
+ CACHE_REQ_ANY_DOM, NULL,
|
||||
derb64);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
@@ -371,7 +373,7 @@ static int ifp_users_list_by_cert_step(struct ifp_list_ctx *list_ctx)
|
||||
list_ctx->ctx->rctx,
|
||||
list_ctx->ctx->rctx->ncache,
|
||||
0,
|
||||
- CACHE_REQ_POSIX_DOM,
|
||||
+ CACHE_REQ_ANY_DOM,
|
||||
list_ctx->dom->name,
|
||||
list_ctx->filter);
|
||||
if (req == NULL) {
|
||||
@@ -538,7 +540,7 @@ int ifp_users_find_by_name_and_cert(struct sbus_request *sbus_req, void *data,
|
||||
if (name_and_cert_ctx->name != NULL) {
|
||||
req = cache_req_user_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx,
|
||||
ctx->rctx->ncache, 0,
|
||||
- CACHE_REQ_POSIX_DOM,
|
||||
+ CACHE_REQ_ANY_DOM,
|
||||
NULL,
|
||||
name_and_cert_ctx->name);
|
||||
if (req == NULL) {
|
||||
@@ -621,7 +623,7 @@ static int ifp_users_find_by_name_and_cert_step(
|
||||
list_ctx->ctx->rctx,
|
||||
list_ctx->ctx->rctx->ncache,
|
||||
0,
|
||||
- CACHE_REQ_POSIX_DOM,
|
||||
+ CACHE_REQ_ANY_DOM,
|
||||
list_ctx->dom->name,
|
||||
list_ctx->filter);
|
||||
if (req == NULL) {
|
||||
@@ -782,7 +784,7 @@ static int ifp_users_list_by_name_step(struct ifp_list_ctx *list_ctx)
|
||||
req = cache_req_user_by_filter_send(list_ctx,
|
||||
list_ctx->ctx->rctx->ev,
|
||||
list_ctx->ctx->rctx,
|
||||
- CACHE_REQ_POSIX_DOM,
|
||||
+ CACHE_REQ_ANY_DOM,
|
||||
list_ctx->dom->name,
|
||||
list_ctx->filter);
|
||||
if (req == NULL) {
|
||||
@@ -867,7 +869,7 @@ int ifp_users_list_by_domain_and_name(struct sbus_request *sbus_req,
|
||||
}
|
||||
|
||||
req = cache_req_user_by_filter_send(list_ctx, ctx->rctx->ev, ctx->rctx,
|
||||
- CACHE_REQ_POSIX_DOM,
|
||||
+ CACHE_REQ_ANY_DOM,
|
||||
domain, filter);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
@@ -930,19 +932,69 @@ done:
|
||||
}
|
||||
|
||||
static errno_t
|
||||
+ifp_users_get_from_cache(struct sbus_request *sbus_req,
|
||||
+ struct sss_domain_info *domain,
|
||||
+ const char *key,
|
||||
+ struct ldb_message **_user)
|
||||
+{
|
||||
+ struct ldb_result *user_res;
|
||||
+ errno_t ret;
|
||||
+ uid_t uid;
|
||||
+
|
||||
+ switch (domain->type) {
|
||||
+ case DOM_TYPE_POSIX:
|
||||
+ uid = strtouint32(key, NULL, 10);
|
||||
+ ret = errno;
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid UID value\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_getpwuid_with_views(sbus_req, domain, uid, &user_res);
|
||||
+ if (ret == EOK && user_res->count == 0) {
|
||||
+ *_user = NULL;
|
||||
+ return ENOENT;
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup user %u@%s [%d]: %s\n",
|
||||
+ uid, domain->name, ret, sss_strerror(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+ break;
|
||||
+ case DOM_TYPE_APPLICATION:
|
||||
+ ret = sysdb_getpwnam_with_views(sbus_req, domain, key, &user_res);
|
||||
+ if (ret == EOK && user_res->count == 0) {
|
||||
+ *_user = NULL;
|
||||
+ return ENOENT;
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup user %s@%s [%d]: %s\n",
|
||||
+ key, domain->name, ret, sss_strerror(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (user_res->count > 1) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "More users matched by the single key\n");
|
||||
+ return EIO;
|
||||
+ }
|
||||
+
|
||||
+ *_user = user_res->msgs[0];
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static errno_t
|
||||
ifp_users_user_get(struct sbus_request *sbus_req,
|
||||
struct ifp_ctx *ifp_ctx,
|
||||
- uid_t *_uid,
|
||||
struct sss_domain_info **_domain,
|
||||
struct ldb_message **_user)
|
||||
{
|
||||
struct sss_domain_info *domain;
|
||||
- struct ldb_result *res;
|
||||
- uid_t uid;
|
||||
+ char *key;
|
||||
errno_t ret;
|
||||
|
||||
- ret = ifp_users_decompose_path(ifp_ctx->rctx->domains, sbus_req->path,
|
||||
- &domain, &uid);
|
||||
+ ret = ifp_users_decompose_path(sbus_req,
|
||||
+ ifp_ctx->rctx->domains, sbus_req->path,
|
||||
+ &domain, &key);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to decompose object path"
|
||||
"[%s] [%d]: %s\n", sbus_req->path, ret, sss_strerror(ret));
|
||||
@@ -950,28 +1002,15 @@ ifp_users_user_get(struct sbus_request *sbus_req,
|
||||
}
|
||||
|
||||
if (_user != NULL) {
|
||||
- ret = sysdb_getpwuid_with_views(sbus_req, domain, uid, &res);
|
||||
- if (ret == EOK && res->count == 0) {
|
||||
- *_user = NULL;
|
||||
- ret = ENOENT;
|
||||
- }
|
||||
-
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup user %u@%s [%d]: %s\n",
|
||||
- uid, domain->name, ret, sss_strerror(ret));
|
||||
- } else {
|
||||
- *_user = res->msgs[0];
|
||||
- }
|
||||
+ ret = ifp_users_get_from_cache(sbus_req, domain, key, _user);
|
||||
}
|
||||
|
||||
if (ret == EOK || ret == ENOENT) {
|
||||
- if (_uid != NULL) {
|
||||
- *_uid = uid;
|
||||
- }
|
||||
-
|
||||
if (_domain != NULL) {
|
||||
*_domain = domain;
|
||||
}
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve user from cache\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -1000,7 +1039,7 @@ static void ifp_users_get_as_string(struct sbus_request *sbus_req,
|
||||
return;
|
||||
}
|
||||
|
||||
- ret = ifp_users_user_get(sbus_req, ifp_ctx, NULL, &domain, &msg);
|
||||
+ ret = ifp_users_user_get(sbus_req, ifp_ctx, &domain, &msg);
|
||||
if (ret != EOK) {
|
||||
return;
|
||||
}
|
||||
@@ -1034,7 +1073,7 @@ static void ifp_users_get_name(struct sbus_request *sbus_req,
|
||||
return;
|
||||
}
|
||||
|
||||
- ret = ifp_users_user_get(sbus_req, ifp_ctx, NULL, &domain, &msg);
|
||||
+ ret = ifp_users_user_get(sbus_req, ifp_ctx, &domain, &msg);
|
||||
if (ret != EOK) {
|
||||
return;
|
||||
}
|
||||
@@ -1072,7 +1111,7 @@ static void ifp_users_get_as_uint32(struct sbus_request *sbus_req,
|
||||
return;
|
||||
}
|
||||
|
||||
- ret = ifp_users_user_get(sbus_req, ifp_ctx, NULL, &domain, &msg);
|
||||
+ ret = ifp_users_user_get(sbus_req, ifp_ctx, &domain, &msg);
|
||||
if (ret != EOK) {
|
||||
return;
|
||||
}
|
||||
@@ -1100,7 +1139,7 @@ int ifp_users_user_update_groups_list(struct sbus_request *sbus_req,
|
||||
return ERR_INTERNAL;
|
||||
}
|
||||
|
||||
- ret = ifp_users_user_get(sbus_req, data, NULL, &domain, &user);
|
||||
+ ret = ifp_users_user_get(sbus_req, data, &domain, &user);
|
||||
if (ret != EOK) {
|
||||
return ret;
|
||||
}
|
||||
@@ -1113,7 +1152,7 @@ int ifp_users_user_update_groups_list(struct sbus_request *sbus_req,
|
||||
|
||||
req = cache_req_initgr_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx,
|
||||
ctx->rctx->ncache, 0,
|
||||
- CACHE_REQ_POSIX_DOM, domain->name,
|
||||
+ CACHE_REQ_ANY_DOM, domain->name,
|
||||
username);
|
||||
if (req == NULL) {
|
||||
return ENOMEM;
|
||||
@@ -1235,7 +1274,7 @@ void ifp_users_user_get_groups(struct sbus_request *sbus_req,
|
||||
return;
|
||||
}
|
||||
|
||||
- ret = ifp_users_user_get(sbus_req, ifp_ctx, NULL, &domain, &user);
|
||||
+ ret = ifp_users_user_get(sbus_req, ifp_ctx, &domain, &user);
|
||||
if (ret != EOK) {
|
||||
return;
|
||||
}
|
||||
@@ -1268,7 +1307,7 @@ void ifp_users_user_get_groups(struct sbus_request *sbus_req,
|
||||
for (i = 0; i < res->count; i++) {
|
||||
gid = sss_view_ldb_msg_find_attr_as_uint64(domain, res->msgs[i],
|
||||
SYSDB_GIDNUM, 0);
|
||||
- if (gid == 0) {
|
||||
+ if (gid == 0 && domain->type == DOM_TYPE_POSIX) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1293,11 +1332,12 @@ void ifp_users_user_get_extra_attributes(struct sbus_request *sbus_req,
|
||||
{
|
||||
struct ifp_ctx *ifp_ctx;
|
||||
struct sss_domain_info *domain;
|
||||
+ struct ldb_message *base_user;
|
||||
+ const char *name;
|
||||
struct ldb_message **user;
|
||||
struct ldb_message_element *el;
|
||||
struct ldb_dn *basedn;
|
||||
size_t count;
|
||||
- uid_t uid;
|
||||
const char *filter;
|
||||
const char **extra;
|
||||
hash_table_t *table;
|
||||
@@ -1322,7 +1362,7 @@ void ifp_users_user_get_extra_attributes(struct sbus_request *sbus_req,
|
||||
return;
|
||||
}
|
||||
|
||||
- ret = ifp_users_user_get(sbus_req, data, &uid, &domain, NULL);
|
||||
+ ret = ifp_users_user_get(sbus_req, data, &domain, &base_user);
|
||||
if (ret != EOK) {
|
||||
return;
|
||||
}
|
||||
@@ -1333,9 +1373,15 @@ void ifp_users_user_get_extra_attributes(struct sbus_request *sbus_req,
|
||||
return;
|
||||
}
|
||||
|
||||
- filter = talloc_asprintf(sbus_req, "(&(%s=%s)(%s=%u))",
|
||||
+ name = ldb_msg_find_attr_as_string(base_user, SYSDB_NAME, NULL);
|
||||
+ if (name == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "A user with no name\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ filter = talloc_asprintf(sbus_req, "(&(%s=%s)(%s=%s))",
|
||||
SYSDB_OBJECTCLASS, SYSDB_USER_CLASS,
|
||||
- SYSDB_UIDNUM, uid);
|
||||
+ SYSDB_NAME, name);
|
||||
if (filter == NULL) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n");
|
||||
return;
|
||||
@@ -1351,7 +1397,7 @@ void ifp_users_user_get_extra_attributes(struct sbus_request *sbus_req,
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, "User %u not found!\n", uid);
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "User %s not found!\n", name);
|
||||
return;
|
||||
} else if (count > 1) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "More than one entry found!\n");
|
||||
@@ -1421,7 +1467,7 @@ int ifp_cache_object_store_user(struct sbus_request *sbus_req,
|
||||
struct ldb_message *user;
|
||||
errno_t ret;
|
||||
|
||||
- ret = ifp_users_user_get(sbus_req, data, NULL, &domain, &user);
|
||||
+ ret = ifp_users_user_get(sbus_req, data, &domain, &user);
|
||||
if (ret != EOK) {
|
||||
error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
|
||||
"user [%d]: %s\n", ret, sss_strerror(ret));
|
||||
@@ -1440,7 +1486,7 @@ int ifp_cache_object_remove_user(struct sbus_request *sbus_req,
|
||||
struct ldb_message *user;
|
||||
errno_t ret;
|
||||
|
||||
- ret = ifp_users_user_get(sbus_req, data, NULL, &domain, &user);
|
||||
+ ret = ifp_users_user_get(sbus_req, data, &domain, &user);
|
||||
if (ret != EOK) {
|
||||
error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
|
||||
"user [%d]: %s\n", ret, sss_strerror(ret));
|
||||
diff --git a/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c
|
||||
index 118b5083b14bf5692c6fdd7ba90668fe514aa89d..d10f35e41dbb1623a0b9de37a4c43363cbefc1a3 100644
|
||||
--- a/src/responder/ifp/ifpsrv_cmd.c
|
||||
+++ b/src/responder/ifp/ifpsrv_cmd.c
|
||||
@@ -508,8 +508,12 @@ ifp_user_get_attr_lookup(struct tevent_req *subreq)
|
||||
return;
|
||||
}
|
||||
|
||||
+ /* IFP serves both POSIX and application domains. Requests that need
|
||||
+ * to differentiate between the two must be qualified
|
||||
+ */
|
||||
subreq = cache_req_send(state, state->rctx->ev, state->rctx,
|
||||
- state->ncache, 0, CACHE_REQ_POSIX_DOM,
|
||||
+ state->ncache, 0,
|
||||
+ CACHE_REQ_ANY_DOM,
|
||||
state->domname, data);
|
||||
if (subreq == NULL) {
|
||||
tevent_req_error(req, ENOMEM);
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,57 +0,0 @@
|
||||
From b010f24f4d96d15c5c85021bb4aa83db25cd3df5 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 28 Mar 2017 14:07:29 +0200
|
||||
Subject: [PATCH 68/97] IFP: ListByName: Don't crash when no results are found
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If no results were found using the List command, the results variable
|
||||
was undefined which resulted in a crash.
|
||||
|
||||
Instead, only copy the results of the cache_req lookup returns EOK and
|
||||
we can presume that the results are valid.
|
||||
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
src/responder/ifp/ifp_users.c | 16 +++++++++-------
|
||||
1 file changed, 9 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c
|
||||
index ce9557f94351b730ee46f3cbce31613cb5901942..188194f2ab356d0e67b0f26b003f3a9ce48e6acd 100644
|
||||
--- a/src/responder/ifp/ifp_users.c
|
||||
+++ b/src/responder/ifp/ifp_users.c
|
||||
@@ -801,7 +801,7 @@ static void ifp_users_list_by_name_done(struct tevent_req *req)
|
||||
DBusError *error;
|
||||
struct ifp_list_ctx *list_ctx;
|
||||
struct sbus_request *sbus_req;
|
||||
- struct cache_req_result *result;
|
||||
+ struct cache_req_result *result = NULL;
|
||||
errno_t ret;
|
||||
|
||||
list_ctx = tevent_req_callback_data(req, struct ifp_list_ctx);
|
||||
@@ -816,12 +816,14 @@ static void ifp_users_list_by_name_done(struct tevent_req *req)
|
||||
return;
|
||||
}
|
||||
|
||||
- ret = ifp_users_list_copy(list_ctx, result->ldb_result);
|
||||
- if (ret != EOK) {
|
||||
- error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
|
||||
- "Failed to copy domain result");
|
||||
- sbus_request_fail_and_finish(sbus_req, error);
|
||||
- return;
|
||||
+ if (ret == EOK) {
|
||||
+ ret = ifp_users_list_copy(list_ctx, result->ldb_result);
|
||||
+ if (ret != EOK) {
|
||||
+ error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
|
||||
+ "Failed to copy domain result");
|
||||
+ sbus_request_fail_and_finish(sbus_req, error);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
|
||||
list_ctx->dom = get_next_domain(list_ctx->dom, SSS_GND_DESCEND);
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,58 +0,0 @@
|
||||
From 57eeec5d735c7a3bbe58299fded97414626d85f1 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Fri, 24 Mar 2017 20:36:06 +0100
|
||||
Subject: [PATCH 69/97] PAM: Remove unneeded memory context
|
||||
|
||||
Since we only store data into pam_ctx in get_public_domains(), it
|
||||
doesn't make sense to allow passing a separate memory context. It is
|
||||
always going to be pam_ctx, otherwise the memory hierarchy will cause
|
||||
issues anyway.
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
src/responder/pam/pamsrv.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
|
||||
index 816f2293130ff8761ca94b4a42ca93063c11ea35..ab3f4545520f3fcb2492a6089a039c46f0fb847f 100644
|
||||
--- a/src/responder/pam/pamsrv.c
|
||||
+++ b/src/responder/pam/pamsrv.c
|
||||
@@ -122,7 +122,7 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static errno_t get_public_domains(TALLOC_CTX *mem_ctx, struct pam_ctx *pctx)
|
||||
+static errno_t get_public_domains(struct pam_ctx *pctx)
|
||||
{
|
||||
char *domains_str = NULL;
|
||||
errno_t ret;
|
||||
@@ -137,7 +137,7 @@ static errno_t get_public_domains(TALLOC_CTX *mem_ctx, struct pam_ctx *pctx)
|
||||
|
||||
if (strcmp(domains_str, ALL_DOMAIMS_ARE_PUBLIC) == 0) { /* all */
|
||||
/* copy all domains */
|
||||
- ret = get_dom_names(mem_ctx,
|
||||
+ ret = get_dom_names(pctx,
|
||||
pctx->rctx->domains,
|
||||
&pctx->public_domains,
|
||||
&pctx->public_domains_count);
|
||||
@@ -149,7 +149,7 @@ static errno_t get_public_domains(TALLOC_CTX *mem_ctx, struct pam_ctx *pctx)
|
||||
pctx->public_domains = NULL;
|
||||
pctx->public_domains_count = 0;
|
||||
} else {
|
||||
- ret = split_on_separator(mem_ctx, domains_str, ',', true, false,
|
||||
+ ret = split_on_separator(pctx, domains_str, ',', true, false,
|
||||
&pctx->public_domains,
|
||||
&pctx->public_domains_count);
|
||||
if (ret != EOK) {
|
||||
@@ -212,7 +212,7 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- ret = get_public_domains(pctx, pctx);
|
||||
+ ret = get_public_domains(pctx);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_FATAL_FAILURE, "get_public_domains failed: %d:[%s].\n",
|
||||
ret, sss_strerror(ret));
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,452 +0,0 @@
|
||||
From 3e789aa0bd6b7bb6e62f91458b76753498030fb5 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Sun, 26 Mar 2017 18:28:41 +0200
|
||||
Subject: [PATCH 70/97] PAM: Add application services
|
||||
|
||||
Related to:
|
||||
https://pagure.io/SSSD/sssd/issue/3310
|
||||
|
||||
Adds a new PAM responder option 'pam_app_services'. This option can hold
|
||||
a list of PAM services that are allowed to contact the application
|
||||
non-POSIX domains. These services are NOT allowed to contact any of the
|
||||
POSIX domains.
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
src/confdb/confdb.h | 1 +
|
||||
src/config/SSSDConfig/__init__.py.in | 1 +
|
||||
src/config/cfg_rules.ini | 1 +
|
||||
src/config/etc/sssd.api.conf | 1 +
|
||||
src/man/sssd.conf.5.xml | 12 +++
|
||||
src/responder/pam/pamsrv.c | 33 +++++++
|
||||
src/responder/pam/pamsrv.h | 5 ++
|
||||
src/responder/pam/pamsrv_cmd.c | 26 +++++-
|
||||
src/tests/cmocka/test_pam_srv.c | 167 ++++++++++++++++++++++++++++++++++-
|
||||
9 files changed, 241 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
|
||||
index 5a8d377c312f641f544b1c7cf38826192462ea3c..8719c239362b371fcdb1b78956bcddde871f141b 100644
|
||||
--- a/src/confdb/confdb.h
|
||||
+++ b/src/confdb/confdb.h
|
||||
@@ -129,6 +129,7 @@
|
||||
#define CONFDB_PAM_CERT_AUTH "pam_cert_auth"
|
||||
#define CONFDB_PAM_CERT_DB_PATH "pam_cert_db_path"
|
||||
#define CONFDB_PAM_P11_CHILD_TIMEOUT "p11_child_timeout"
|
||||
+#define CONFDB_PAM_APP_SERVICES "pam_app_services"
|
||||
|
||||
/* SUDO */
|
||||
#define CONFDB_SUDO_CONF_ENTRY "config/sudo"
|
||||
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
|
||||
index 070994bcd04604777019d264d12cb126d6638bfd..a29d51e0ddffc520107a309d862346fb4d4f5f80 100644
|
||||
--- a/src/config/SSSDConfig/__init__.py.in
|
||||
+++ b/src/config/SSSDConfig/__init__.py.in
|
||||
@@ -102,6 +102,7 @@ option_strings = {
|
||||
'pam_cert_auth' : _('Allow certificate based/Smartcard authentication.'),
|
||||
'pam_cert_db_path' : _('Path to certificate databse with PKCS#11 modules.'),
|
||||
'p11_child_timeout' : _('How many seconds will pam_sss wait for p11_child to finish'),
|
||||
+ 'pam_app_services' : _('Which PAM services are permitted to contact application domains'),
|
||||
|
||||
# [sudo]
|
||||
'sudo_timed' : _('Whether to evaluate the time-based attributes in sudo rules'),
|
||||
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
|
||||
index 8fd2d2c5236246394353a88c50d1510bd6233f77..1a749db754cedd87f263f7ae596d6f8238bb4357 100644
|
||||
--- a/src/config/cfg_rules.ini
|
||||
+++ b/src/config/cfg_rules.ini
|
||||
@@ -119,6 +119,7 @@ option = pam_account_locked_message
|
||||
option = pam_cert_auth
|
||||
option = pam_cert_db_path
|
||||
option = p11_child_timeout
|
||||
+option = pam_app_services
|
||||
|
||||
[rule/allowed_sudo_options]
|
||||
validator = ini_allowed_options
|
||||
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
|
||||
index a38b24208f89e4502e41625c540ea9958d5bbffe..a1a0c2992925a4c7df86832117eec2a0cf7894c9 100644
|
||||
--- a/src/config/etc/sssd.api.conf
|
||||
+++ b/src/config/etc/sssd.api.conf
|
||||
@@ -73,6 +73,7 @@ pam_account_locked_message = str, None, false
|
||||
pam_cert_auth = bool, None, false
|
||||
pam_cert_db_path = str, None, false
|
||||
p11_child_timeout = int, None, false
|
||||
+pam_app_services = str, None, false
|
||||
|
||||
[sudo]
|
||||
# sudo service
|
||||
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
|
||||
index 8294793c765bfa6bf481693c7d7f206950454681..c4e30396f16c40db37af2f56ac218b6e37201ef7 100644
|
||||
--- a/src/man/sssd.conf.5.xml
|
||||
+++ b/src/man/sssd.conf.5.xml
|
||||
@@ -1325,6 +1325,18 @@ pam_account_locked_message = Account locked, please contact help desk.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>pam_app_services (string)</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Which PAM services are permitted to contact
|
||||
+ domains of type <quote>application</quote>
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Default: Not set
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect2>
|
||||
diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
|
||||
index ab3f4545520f3fcb2492a6089a039c46f0fb847f..79470823d18138da6ef9235e6336a3220ead1797 100644
|
||||
--- a/src/responder/pam/pamsrv.c
|
||||
+++ b/src/responder/pam/pamsrv.c
|
||||
@@ -166,6 +166,32 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static errno_t get_app_services(struct pam_ctx *pctx)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = confdb_get_string_as_list(pctx->rctx->cdb, pctx,
|
||||
+ CONFDB_PAM_CONF_ENTRY,
|
||||
+ CONFDB_PAM_APP_SERVICES,
|
||||
+ &pctx->app_services);
|
||||
+ if (ret == ENOENT) {
|
||||
+ pctx->app_services = talloc_zero_array(pctx, char *, 1);
|
||||
+ if (pctx->app_services == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+ /* Allocating an empty array makes it easier for the consumer
|
||||
+ * to iterate over it
|
||||
+ */
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Cannot read "CONFDB_PAM_APP_SERVICES" [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
static int pam_process_init(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct confdb_ctx *cdb,
|
||||
@@ -219,6 +245,13 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ ret = get_app_services(pctx);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "get_app_services failed: %d:[%s].\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
/* Enable automatic reconnection to the Data Provider */
|
||||
|
||||
/* FIXME: "retries" is too generic, either get it from a global config
|
||||
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
|
||||
index b3eb56441048ecdba82866a95f1d6d6d5e786c60..b569748fe2a2005cee5df34bef55e803175492a9 100644
|
||||
--- a/src/responder/pam/pamsrv.h
|
||||
+++ b/src/responder/pam/pamsrv.h
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "util/util.h"
|
||||
#include "sbus/sssd_dbus.h"
|
||||
#include "responder/common/responder.h"
|
||||
+#include "responder/common/cache_req/cache_req.h"
|
||||
|
||||
struct pam_auth_req;
|
||||
|
||||
@@ -42,6 +43,9 @@ struct pam_ctx {
|
||||
char **public_domains;
|
||||
int public_domains_count;
|
||||
|
||||
+ /* What services are permitted to access application domains */
|
||||
+ char **app_services;
|
||||
+
|
||||
bool cert_auth;
|
||||
int p11_child_debug_fd;
|
||||
char *nss_db;
|
||||
@@ -54,6 +58,7 @@ struct pam_auth_dp_req {
|
||||
struct pam_auth_req {
|
||||
struct cli_ctx *cctx;
|
||||
struct sss_domain_info *domain;
|
||||
+ enum cache_req_dom_type req_dom_type;
|
||||
|
||||
struct pam_data *pd;
|
||||
|
||||
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
|
||||
index fa6d2cc10fe1404196f9d9221a469d7a9a768211..f2b3c74b483e527932dda42279d14a9ac184b475 100644
|
||||
--- a/src/responder/pam/pamsrv_cmd.c
|
||||
+++ b/src/responder/pam/pamsrv_cmd.c
|
||||
@@ -1161,6 +1161,25 @@ static bool is_domain_public(char *name,
|
||||
return false;
|
||||
}
|
||||
|
||||
+static enum cache_req_dom_type
|
||||
+get_domain_request_type(struct pam_auth_req *preq,
|
||||
+ struct pam_ctx *pctx)
|
||||
+{
|
||||
+ enum cache_req_dom_type req_dom_type;
|
||||
+
|
||||
+ /* By default, only POSIX domains are to be contacted */
|
||||
+ req_dom_type = CACHE_REQ_POSIX_DOM;
|
||||
+
|
||||
+ for (int i = 0; pctx->app_services[i]; i++) {
|
||||
+ if (strcmp(pctx->app_services[i], preq->pd->service) == 0) {
|
||||
+ req_dom_type = CACHE_REQ_APPLICATION_DOM;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return req_dom_type;
|
||||
+}
|
||||
+
|
||||
static errno_t check_cert(TALLOC_CTX *mctx,
|
||||
struct tevent_context *ev,
|
||||
struct pam_ctx *pctx,
|
||||
@@ -1257,6 +1276,9 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ /* Determine what domain type to contact */
|
||||
+ preq->req_dom_type = get_domain_request_type(preq, pctx);
|
||||
+
|
||||
/* try backend first for authentication before doing local Smartcard
|
||||
* authentication */
|
||||
if (pd->cmd != SSS_PAM_AUTHENTICATE && may_do_cert_auth(pctx, pd)) {
|
||||
@@ -1316,7 +1338,7 @@ static void pam_forwarder_cert_cb(struct tevent_req *req)
|
||||
|
||||
req = cache_req_user_by_cert_send(preq, cctx->ev, cctx->rctx,
|
||||
pctx->rctx->ncache, 0,
|
||||
- CACHE_REQ_POSIX_DOM, NULL,
|
||||
+ preq->req_dom_type, NULL,
|
||||
cert);
|
||||
if (req == NULL) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "cache_req_user_by_cert_send failed.\n");
|
||||
@@ -1509,7 +1531,7 @@ static int pam_check_user_search(struct pam_auth_req *preq)
|
||||
preq->cctx->rctx,
|
||||
preq->cctx->rctx->ncache,
|
||||
0,
|
||||
- CACHE_REQ_POSIX_DOM,
|
||||
+ preq->req_dom_type,
|
||||
preq->pd->domain,
|
||||
data);
|
||||
if (!dpreq) {
|
||||
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
|
||||
index 847419658bb983e6548722d6fa6fb22c63ee86b8..d249b8f1ea48f1c17b461c3add9e8c63774e5f88 100644
|
||||
--- a/src/tests/cmocka/test_pam_srv.c
|
||||
+++ b/src/tests/cmocka/test_pam_srv.c
|
||||
@@ -186,6 +186,15 @@ struct pam_ctx *mock_pctx(TALLOC_CTX *mem_ctx)
|
||||
ret = sss_hash_create(pctx, 10, &pctx->id_table);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
+ /* Two NULLs so that tests can just assign a const to the first slot
|
||||
+ * should they need it. The code iterates until first NULL anyway
|
||||
+ */
|
||||
+ pctx->app_services = talloc_zero_array(pctx, char *, 2);
|
||||
+ if (pctx->app_services == NULL) {
|
||||
+ talloc_free(pctx);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
return pctx;
|
||||
}
|
||||
|
||||
@@ -495,8 +504,12 @@ int __wrap_pam_dp_send_req(struct pam_auth_req *preq, int timeout)
|
||||
return EOK;
|
||||
}
|
||||
|
||||
-static void mock_input_pam(TALLOC_CTX *mem_ctx, const char *name,
|
||||
- const char *pwd, const char *fa2)
|
||||
+static void mock_input_pam_ex(TALLOC_CTX *mem_ctx,
|
||||
+ const char *name,
|
||||
+ const char *pwd,
|
||||
+ const char *fa2,
|
||||
+ const char *svc,
|
||||
+ bool contact_dp)
|
||||
{
|
||||
size_t buf_size;
|
||||
uint8_t *m_buf;
|
||||
@@ -536,7 +549,10 @@ static void mock_input_pam(TALLOC_CTX *mem_ctx, const char *name,
|
||||
}
|
||||
}
|
||||
|
||||
- pi.pam_service = "pam_test_service";
|
||||
+ if (svc == NULL) {
|
||||
+ svc = "pam_test_service";
|
||||
+ }
|
||||
+ pi.pam_service = svc;
|
||||
pi.pam_service_size = strlen(pi.pam_service) + 1;
|
||||
pi.pam_tty = "/dev/tty";
|
||||
pi.pam_tty_size = strlen(pi.pam_tty) + 1;
|
||||
@@ -559,7 +575,17 @@ static void mock_input_pam(TALLOC_CTX *mem_ctx, const char *name,
|
||||
will_return(__wrap_sss_packet_get_body, buf_size);
|
||||
|
||||
mock_parse_inp(name, NULL, EOK);
|
||||
- mock_account_recv_simple();
|
||||
+ if (contact_dp) {
|
||||
+ mock_account_recv_simple();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void mock_input_pam(TALLOC_CTX *mem_ctx,
|
||||
+ const char *name,
|
||||
+ const char *pwd,
|
||||
+ const char *fa2)
|
||||
+{
|
||||
+ return mock_input_pam_ex(mem_ctx, name, pwd, fa2, NULL, true);
|
||||
}
|
||||
|
||||
static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name,
|
||||
@@ -2097,6 +2123,127 @@ void test_filter_response(void **state)
|
||||
talloc_free(pd);
|
||||
}
|
||||
|
||||
+static int pam_test_setup_appsvc_posix_dom(void **state)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = pam_test_setup(state);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* This config option is only read on startup, which is not executed
|
||||
+ * in test, so we can't just pass in a param
|
||||
+ */
|
||||
+ pam_test_ctx->pctx->app_services[0] = discard_const("app_svc");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void test_appsvc_posix_dom(void **state)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* The domain is POSIX, the request will skip over it */
|
||||
+ mock_input_pam_ex(pam_test_ctx, "pamuser", NULL, NULL, "app_svc", false);
|
||||
+ pam_test_ctx->exp_pam_status = PAM_USER_UNKNOWN;
|
||||
+
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+
|
||||
+ set_cmd_cb(test_pam_user_unknown_check);
|
||||
+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
|
||||
+ pam_test_ctx->pam_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = test_ev_loop(pam_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+}
|
||||
+
|
||||
+void test_not_appsvc_posix_dom(void **state)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* A different service than the app one can authenticate against a POSIX domain */
|
||||
+ mock_input_pam_ex(pam_test_ctx, "pamuser", NULL, NULL, "not_app_svc", true);
|
||||
+
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+
|
||||
+ set_cmd_cb(test_pam_simple_check);
|
||||
+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
|
||||
+ pam_test_ctx->pam_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(pam_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+}
|
||||
+
|
||||
+static int pam_test_setup_appsvc_app_dom(void **state)
|
||||
+{
|
||||
+ struct sss_test_conf_param dom_params[] = {
|
||||
+ { "domain_type", "application" },
|
||||
+ { NULL, NULL }, /* Sentinel */
|
||||
+ };
|
||||
+ struct sss_test_conf_param pam_params[] = {
|
||||
+ { NULL, NULL }, /* Sentinel */
|
||||
+ };
|
||||
+ struct sss_test_conf_param monitor_params[] = {
|
||||
+ { NULL, NULL }, /* Sentinel */
|
||||
+ };
|
||||
+
|
||||
+
|
||||
+ test_pam_setup(dom_params, pam_params, monitor_params, state);
|
||||
+ pam_test_setup_common();
|
||||
+
|
||||
+ /* This config option is only read on startup, which is not executed
|
||||
+ * in test, so we can't just pass in a param
|
||||
+ */
|
||||
+ pam_test_ctx->pctx->app_services[0] = discard_const("app_svc");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void test_appsvc_app_dom(void **state)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* The domain is POSIX, the request will skip over it */
|
||||
+ mock_input_pam_ex(pam_test_ctx, "pamuser", NULL, NULL, "app_svc", true);
|
||||
+
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+
|
||||
+ set_cmd_cb(test_pam_simple_check);
|
||||
+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
|
||||
+ pam_test_ctx->pam_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ /* Wait until the test finishes with EOK */
|
||||
+ ret = test_ev_loop(pam_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+}
|
||||
+
|
||||
+void test_not_appsvc_app_dom(void **state)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ /* A different service than the app one can authenticate against a POSIX domain */
|
||||
+ mock_input_pam_ex(pam_test_ctx, "pamuser", NULL, NULL, "not_app_svc", false);
|
||||
+
|
||||
+ pam_test_ctx->exp_pam_status = PAM_USER_UNKNOWN;
|
||||
+
|
||||
+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
|
||||
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
||||
+
|
||||
+ set_cmd_cb(test_pam_user_unknown_check);
|
||||
+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
|
||||
+ pam_test_ctx->pam_cmds);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = test_ev_loop(pam_test_ctx->tctx);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+}
|
||||
+
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
int rv;
|
||||
@@ -2216,6 +2363,18 @@ int main(int argc, const char *argv[])
|
||||
|
||||
cmocka_unit_test_setup_teardown(test_filter_response,
|
||||
pam_test_setup, pam_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_appsvc_posix_dom,
|
||||
+ pam_test_setup_appsvc_posix_dom,
|
||||
+ pam_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_not_appsvc_posix_dom,
|
||||
+ pam_test_setup_appsvc_posix_dom,
|
||||
+ pam_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_appsvc_app_dom,
|
||||
+ pam_test_setup_appsvc_app_dom,
|
||||
+ pam_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_not_appsvc_app_dom,
|
||||
+ pam_test_setup_appsvc_posix_dom,
|
||||
+ pam_test_teardown),
|
||||
};
|
||||
|
||||
/* Set debug level to invalid value so we can deside if -d 0 was used. */
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,152 +0,0 @@
|
||||
From 5f7f249f2a8a1c7284e991aa64dbf850d482b0aa Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 22 Mar 2017 13:00:31 +0100
|
||||
Subject: [PATCH 71/97] SYSDB: Allow storing non-POSIX users
|
||||
|
||||
Related to:
|
||||
https://pagure.io/SSSD/sssd/issue/3310
|
||||
|
||||
We already do the same for groups. If the user does not have UID number
|
||||
set but does have the POSIX: false attribute set, then we save the user
|
||||
with zero UID and the non-POSIX flag.
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
src/db/sysdb_ops.c | 32 ++++++++++++++++++++--------
|
||||
src/tests/sysdb-tests.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 79 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
|
||||
index 919f22370ff87eff2bf0bb569ca90f1ee699a61e..3cf9d903f25b9ccd506d7957c94040bdc7d658a3 100644
|
||||
--- a/src/db/sysdb_ops.c
|
||||
+++ b/src/db/sysdb_ops.c
|
||||
@@ -1855,6 +1855,7 @@ int sysdb_add_user(struct sss_domain_info *domain,
|
||||
struct sysdb_attrs *id_attrs;
|
||||
uint32_t id;
|
||||
int ret;
|
||||
+ bool posix;
|
||||
|
||||
if (domain->mpg) {
|
||||
if (gid != 0) {
|
||||
@@ -1926,7 +1927,28 @@ int sysdb_add_user(struct sss_domain_info *domain,
|
||||
/* Not fatal */
|
||||
}
|
||||
|
||||
- if (uid == 0) {
|
||||
+ if (!attrs) {
|
||||
+ attrs = sysdb_new_attrs(tmp_ctx);
|
||||
+ if (!attrs) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_attrs_get_bool(attrs, SYSDB_POSIX, &posix);
|
||||
+ if (ret == ENOENT) {
|
||||
+ posix = true;
|
||||
+ ret = sysdb_attrs_add_bool(attrs, SYSDB_POSIX, true);
|
||||
+ if (ret) {
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "Failed to add posix attribute.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "Failed to get posix attribute.\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (uid == 0 && posix == true) {
|
||||
ret = sysdb_get_new_id(domain, &id);
|
||||
if (ret) goto done;
|
||||
|
||||
@@ -1948,14 +1970,6 @@ int sysdb_add_user(struct sss_domain_info *domain,
|
||||
if (ret) goto done;
|
||||
}
|
||||
|
||||
- if (!attrs) {
|
||||
- attrs = sysdb_new_attrs(tmp_ctx);
|
||||
- if (!attrs) {
|
||||
- ret = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
if (!now) {
|
||||
now = time(NULL);
|
||||
}
|
||||
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
|
||||
index 1767dc3c734c6b2e5f74564debd603e2442f491b..6ec82ce4ca5c4f918bc9f3144c21f33b270ea47e 100644
|
||||
--- a/src/tests/sysdb-tests.c
|
||||
+++ b/src/tests/sysdb-tests.c
|
||||
@@ -1428,6 +1428,59 @@ START_TEST (test_sysdb_get_user_attr_subdomain)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
+START_TEST (test_sysdb_add_nonposix_user)
|
||||
+{
|
||||
+ struct sysdb_test_ctx *test_ctx;
|
||||
+ const char *get_attrs[] = { SYSDB_GIDNUM,
|
||||
+ SYSDB_UIDNUM,
|
||||
+ SYSDB_POSIX,
|
||||
+ NULL };
|
||||
+ struct ldb_result *res;
|
||||
+ const char *attrval;
|
||||
+ const char *username = "test_sysdb_add_nonposix_user";
|
||||
+ const char *fq_name;
|
||||
+ struct sysdb_attrs *user_attrs;
|
||||
+ int ret;
|
||||
+ uint64_t id;
|
||||
+
|
||||
+ /* Setup */
|
||||
+ ret = setup_sysdb_tests(&test_ctx);
|
||||
+ fail_if(ret != EOK, "Could not set up the test");
|
||||
+
|
||||
+ /* Create user */
|
||||
+ fq_name = sss_create_internal_fqname(test_ctx, username, test_ctx->domain->name);
|
||||
+ fail_if(fq_name == NULL, "Failed to create fq name.");
|
||||
+
|
||||
+ user_attrs = sysdb_new_attrs(test_ctx);
|
||||
+ fail_if(user_attrs == NULL);
|
||||
+
|
||||
+ ret = sysdb_attrs_add_bool(user_attrs, SYSDB_POSIX, false);
|
||||
+ fail_if(ret != EOK, "Could not add attribute");
|
||||
+
|
||||
+ ret = sysdb_add_user(test_ctx->domain, fq_name, 0, 0, "Gecos",
|
||||
+ "/home/userhome", "/bin/bash", NULL, user_attrs, 0, 0);
|
||||
+ fail_if(ret != EOK, "sysdb_add_user failed.");
|
||||
+
|
||||
+ /* Test */
|
||||
+ ret = sysdb_get_user_attr(test_ctx, test_ctx->domain, fq_name,
|
||||
+ get_attrs, &res);
|
||||
+ fail_if(ret != EOK, "Could not get user attributes.");
|
||||
+ fail_if(res->count != 1, "Invalid number of entries, expected 1, got %d",
|
||||
+ res->count);
|
||||
+
|
||||
+ attrval = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_POSIX, NULL);
|
||||
+ fail_if(strcasecmp(attrval, "false") != 0, "Got bad attribute value.");
|
||||
+
|
||||
+ id = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_UIDNUM, 123);
|
||||
+ fail_unless(id == 0, "Wrong UID value");
|
||||
+
|
||||
+ id = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_GIDNUM, 123);
|
||||
+ fail_unless(id == 0, "Wrong GID value");
|
||||
+
|
||||
+ talloc_free(test_ctx);
|
||||
+}
|
||||
+END_TEST
|
||||
+
|
||||
START_TEST (test_sysdb_add_group_member)
|
||||
{
|
||||
struct sysdb_test_ctx *test_ctx;
|
||||
@@ -7044,6 +7097,9 @@ Suite *create_sysdb_suite(void)
|
||||
/* Test GetUserAttr with subdomain user */
|
||||
tcase_add_test(tc_sysdb, test_sysdb_get_user_attr_subdomain);
|
||||
|
||||
+ /* Test adding a non-POSIX user */
|
||||
+ tcase_add_test(tc_sysdb, test_sysdb_add_nonposix_user);
|
||||
+
|
||||
/* ===== NETGROUP TESTS ===== */
|
||||
|
||||
/* Create a new netgroup */
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 901396366075dc3e3fcc0894345af1b51052ac69 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 28 Mar 2017 14:49:31 +0200
|
||||
Subject: [PATCH 72/97] SYSDB: Only generate new UID in local domain
|
||||
|
||||
To avoid issues where a user with no UID but without the posix=false
|
||||
flag was passed to sysdb, we only allow generating the new ID in the
|
||||
local domain. This might prevent bugs where non-POSIX users would get a
|
||||
UID created by sysdb which might allow accessing resources owned by that
|
||||
UID.
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
src/db/sysdb_ops.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
|
||||
index 3cf9d903f25b9ccd506d7957c94040bdc7d658a3..4d7b2abd8026c90aaf4e7be687102e459cf3690e 100644
|
||||
--- a/src/db/sysdb_ops.c
|
||||
+++ b/src/db/sysdb_ops.c
|
||||
@@ -1422,6 +1422,12 @@ int sysdb_get_new_id(struct sss_domain_info *domain,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
+ if (strcasecmp(domain->provider, "local") != 0) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Generating new ID is only supported in the local domain!\n");
|
||||
+ return ENOTSUP;
|
||||
+ }
|
||||
+
|
||||
base_dn = sysdb_domain_dn(tmp_ctx, domain);
|
||||
if (!base_dn) {
|
||||
talloc_zfree(tmp_ctx);
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,141 +0,0 @@
|
||||
From ed0cdfcacc44e4e13e1524e254efa744610a87c2 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 22 Mar 2017 13:06:08 +0100
|
||||
Subject: [PATCH 73/97] LDAP: save non-POSIX users in application domains
|
||||
|
||||
Related to:
|
||||
https://pagure.io/SSSD/sssd/issue/3310
|
||||
|
||||
If a user being saved by the LDAP provider does not have a UID or GID
|
||||
and the domain type is application, we save the user entry as non-POSIX.
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
src/providers/ldap/sdap_async_users.c | 72 +++++++++++++++++++++++++++--------
|
||||
1 file changed, 57 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
|
||||
index 3d957ab584865f74499bc732395388a78965fe5f..265cd7e4f7929c295d5bdcfbd781221b74601f13 100644
|
||||
--- a/src/providers/ldap/sdap_async_users.c
|
||||
+++ b/src/providers/ldap/sdap_async_users.c
|
||||
@@ -112,6 +112,28 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static errno_t sdap_set_non_posix_flag(struct sysdb_attrs *attrs,
|
||||
+ const char *pkey)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = sysdb_attrs_add_uint32(attrs, pkey, 0);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Failed to add a zero ID to a non-posix object!\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_attrs_add_bool(attrs, SYSDB_POSIX, false);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Error: Failed to mark objects as non-posix!\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
/* FIXME: support storing additional attributes */
|
||||
int sdap_save_user(TALLOC_CTX *memctx,
|
||||
struct sdap_options *opts,
|
||||
@@ -130,8 +152,8 @@ int sdap_save_user(TALLOC_CTX *memctx,
|
||||
const char *homedir;
|
||||
const char *shell;
|
||||
const char *orig_dn = NULL;
|
||||
- uid_t uid;
|
||||
- gid_t gid;
|
||||
+ uid_t uid = 0;
|
||||
+ gid_t gid = 0;
|
||||
struct sysdb_attrs *user_attrs;
|
||||
char *upn = NULL;
|
||||
size_t i;
|
||||
@@ -146,6 +168,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
|
||||
size_t c;
|
||||
char *p1;
|
||||
char *p2;
|
||||
+ bool is_posix = true;
|
||||
|
||||
DEBUG(SSSDBG_TRACE_FUNC, "Save user\n");
|
||||
|
||||
@@ -295,19 +318,29 @@ int sdap_save_user(TALLOC_CTX *memctx,
|
||||
ret = sysdb_attrs_get_uint32_t(attrs,
|
||||
opts->user_map[SDAP_AT_USER_UID].sys_name,
|
||||
&uid);
|
||||
- if (ret != EOK) {
|
||||
+ if (ret == ENOENT && dom->type == DOM_TYPE_APPLICATION) {
|
||||
+ DEBUG(SSSDBG_TRACE_INTERNAL,
|
||||
+ "Marking object as non-posix and setting ID=0!\n");
|
||||
+ ret = sdap_set_non_posix_flag(user_attrs,
|
||||
+ opts->user_map[SDAP_AT_USER_UID].sys_name);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ is_posix = false;
|
||||
+ } else if (ret != EOK) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- "no uid provided for [%s] in domain [%s].\n",
|
||||
+ "Cannot retrieve UID for [%s] in domain [%s].\n",
|
||||
user_name, dom->name);
|
||||
- ret = EINVAL;
|
||||
+ ret = ERR_NO_POSIX;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
- /* check that the uid is valid for this domain */
|
||||
- if (OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- "User [%s] filtered out! (uid out of range)\n",
|
||||
- user_name);
|
||||
+
|
||||
+ /* check that the uid is valid for this domain if the user is a POSIX one */
|
||||
+ if (is_posix == true && OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "User [%s] filtered out! (uid out of range)\n",
|
||||
+ user_name);
|
||||
ret = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
@@ -349,17 +382,26 @@ int sdap_save_user(TALLOC_CTX *memctx,
|
||||
ret = sysdb_attrs_get_uint32_t(attrs,
|
||||
opts->user_map[SDAP_AT_USER_GID].sys_name,
|
||||
&gid);
|
||||
- if (ret != EOK) {
|
||||
+ if (ret == ENOENT && dom->type == DOM_TYPE_APPLICATION) {
|
||||
+ DEBUG(SSSDBG_TRACE_INTERNAL,
|
||||
+ "Marking object as non-posix and setting ID=0!\n");
|
||||
+ ret = sdap_set_non_posix_flag(attrs,
|
||||
+ opts->user_map[SDAP_AT_USER_GID].sys_name);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ is_posix = false;
|
||||
+ } else if (ret != EOK) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- "no gid provided for [%s] in domain [%s].\n",
|
||||
- user_name, dom->name);
|
||||
- ret = EINVAL;
|
||||
+ "Cannot retrieve GID for [%s] in domain [%s].\n",
|
||||
+ user_name, dom->name);
|
||||
+ ret = ERR_NO_POSIX;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* check that the gid is valid for this domain */
|
||||
- if (IS_SUBDOMAIN(dom) == false &&
|
||||
+ if (is_posix == true && IS_SUBDOMAIN(dom) == false &&
|
||||
OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
"User [%s] filtered out! (primary gid out of range)\n",
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,254 +0,0 @@
|
||||
From 3e39806177e1cd383743ff596cb96df44a6ce8c9 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 22 Mar 2017 13:06:14 +0100
|
||||
Subject: [PATCH 74/97] LDAP: Relax search filters in application domains
|
||||
|
||||
Related to:
|
||||
https://pagure.io/SSSD/sssd/issue/3310
|
||||
|
||||
If a request comes towards an application domain, we can drop the part
|
||||
of the filter that asserts that the object has a valid UID/GID. Instead,
|
||||
we just search by name.
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
src/providers/ldap/ldap_id.c | 35 ++++++++++++++++++++++++----
|
||||
src/providers/ldap/sdap_async_enum.c | 7 +++++-
|
||||
src/providers/ldap/sdap_async_initgroups.c | 37 ++++++++++++++++++++++++------
|
||||
3 files changed, 66 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
|
||||
index 0bee0ca8d71abece6749fdb8393b9ceacb64417d..7400dc1f57e30cc6ae5f939ffa628a1e9dd47e06 100644
|
||||
--- a/src/providers/ldap/ldap_id.c
|
||||
+++ b/src/providers/ldap/ldap_id.c
|
||||
@@ -56,6 +56,7 @@ struct users_get_state {
|
||||
char *filter;
|
||||
const char **attrs;
|
||||
bool use_id_mapping;
|
||||
+ bool non_posix;
|
||||
|
||||
int dp_error;
|
||||
int sdap_ret;
|
||||
@@ -114,6 +115,10 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
||||
state->filter_value = filter_value;
|
||||
state->filter_type = filter_type;
|
||||
|
||||
+ if (state->domain->type == DOM_TYPE_APPLICATION) {
|
||||
+ state->non_posix = true;
|
||||
+ }
|
||||
+
|
||||
state->use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
|
||||
ctx->opts->idmap_ctx,
|
||||
sdom->dom->name,
|
||||
@@ -292,7 +297,13 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
||||
}
|
||||
}
|
||||
|
||||
- if (state->use_id_mapping || filter_type == BE_FILTER_SECID) {
|
||||
+ if (state->non_posix) {
|
||||
+ state->filter = talloc_asprintf(state,
|
||||
+ "(&%s(objectclass=%s)(%s=*))",
|
||||
+ user_filter,
|
||||
+ ctx->opts->user_map[SDAP_OC_USER].name,
|
||||
+ ctx->opts->user_map[SDAP_AT_USER_NAME].name);
|
||||
+ } else if (state->use_id_mapping || filter_type == BE_FILTER_SECID) {
|
||||
/* When mapping IDs or looking for SIDs, we don't want to limit
|
||||
* ourselves to users with a UID value. But there must be a SID to map
|
||||
* from.
|
||||
@@ -304,7 +315,8 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
||||
ctx->opts->user_map[SDAP_AT_USER_NAME].name,
|
||||
ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name);
|
||||
} else {
|
||||
- /* When not ID-mapping, make sure there is a non-NULL UID */
|
||||
+ /* When not ID-mapping or looking up POSIX users,
|
||||
+ * make sure there is a non-NULL UID */
|
||||
state->filter = talloc_asprintf(state,
|
||||
"(&%s(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))",
|
||||
user_filter,
|
||||
@@ -380,6 +392,7 @@ static void users_get_connect_done(struct tevent_req *subreq)
|
||||
* have no idea about POSIX attributes support, run a one-time check
|
||||
*/
|
||||
if (state->use_id_mapping == false &&
|
||||
+ state->non_posix == false &&
|
||||
state->ctx->opts->schema_type == SDAP_SCHEMA_AD &&
|
||||
state->ctx->srv_opts &&
|
||||
state->ctx->srv_opts->posix_checked == false) {
|
||||
@@ -650,6 +663,7 @@ struct groups_get_state {
|
||||
char *filter;
|
||||
const char **attrs;
|
||||
bool use_id_mapping;
|
||||
+ bool non_posix;
|
||||
|
||||
int dp_error;
|
||||
int sdap_ret;
|
||||
@@ -709,6 +723,10 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
|
||||
state->filter_value = filter_value;
|
||||
state->filter_type = filter_type;
|
||||
|
||||
+ if (state->domain->type == DOM_TYPE_APPLICATION) {
|
||||
+ state->non_posix = true;
|
||||
+ }
|
||||
+
|
||||
state->use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
|
||||
ctx->opts->idmap_ctx,
|
||||
sdom->dom->name,
|
||||
@@ -827,9 +845,11 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if (state->use_id_mapping || filter_type == BE_FILTER_SECID) {
|
||||
- /* When mapping IDs or looking for SIDs, we don't want to limit
|
||||
- * ourselves to groups with a GID value
|
||||
+ if (state->non_posix
|
||||
+ || state->use_id_mapping
|
||||
+ || filter_type == BE_FILTER_SECID) {
|
||||
+ /* When mapping IDs or looking for SIDs, or when in a non-POSIX domain,
|
||||
+ * we don't want to limit ourselves to groups with a GID value
|
||||
*/
|
||||
|
||||
state->filter = talloc_asprintf(state,
|
||||
@@ -1123,6 +1143,7 @@ struct groups_by_user_state {
|
||||
int filter_type;
|
||||
const char *extra_value;
|
||||
const char **attrs;
|
||||
+ bool non_posix;
|
||||
|
||||
int dp_error;
|
||||
int sdap_ret;
|
||||
@@ -1204,6 +1225,10 @@ static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx,
|
||||
state->domain = sdom->dom;
|
||||
state->sysdb = sdom->dom->sysdb;
|
||||
|
||||
+ if (state->domain->type == DOM_TYPE_APPLICATION) {
|
||||
+ state->non_posix = true;
|
||||
+ }
|
||||
+
|
||||
ret = build_attrs_from_map(state, ctx->opts->group_map, SDAP_OPTS_GROUP,
|
||||
NULL, &state->attrs, NULL);
|
||||
if (ret != EOK) goto fail;
|
||||
diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c
|
||||
index 3f65059e18d5c8b548da0babec867d27c3a64198..91e481c4e694126900c729e86d187fba355de0b8 100644
|
||||
--- a/src/providers/ldap/sdap_async_enum.c
|
||||
+++ b/src/providers/ldap/sdap_async_enum.c
|
||||
@@ -717,6 +717,7 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
|
||||
struct enum_groups_state *state;
|
||||
int ret;
|
||||
bool use_mapping;
|
||||
+ bool non_posix = false;
|
||||
char *oc_list;
|
||||
|
||||
req = tevent_req_create(memctx, &state, struct enum_groups_state);
|
||||
@@ -727,6 +728,10 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
|
||||
state->ctx = ctx;
|
||||
state->op = op;
|
||||
|
||||
+ if (sdom->dom->type == DOM_TYPE_APPLICATION) {
|
||||
+ non_posix = true;
|
||||
+ }
|
||||
+
|
||||
use_mapping = sdap_idmap_domain_has_algorithmic_mapping(
|
||||
ctx->opts->idmap_ctx,
|
||||
sdom->dom->name,
|
||||
@@ -749,7 +754,7 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if (use_mapping) {
|
||||
+ if (!non_posix && use_mapping) {
|
||||
/* If we're ID-mapping, check for the objectSID as well */
|
||||
state->filter = talloc_asprintf_append_buffer(
|
||||
state->filter, "(%s=*)",
|
||||
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
|
||||
index 79af7a3eda3fe8533933535c98c2b4b4698dfda2..c926ddcbefe471daa80505e139c3f19efa33b9ba 100644
|
||||
--- a/src/providers/ldap/sdap_async_initgroups.c
|
||||
+++ b/src/providers/ldap/sdap_async_initgroups.c
|
||||
@@ -376,7 +376,7 @@ struct sdap_initgr_rfc2307_state {
|
||||
struct sdap_handle *sh;
|
||||
const char **attrs;
|
||||
const char *name;
|
||||
- const char *base_filter;
|
||||
+ char *base_filter;
|
||||
const char *orig_dn;
|
||||
char *filter;
|
||||
int timeout;
|
||||
@@ -473,18 +473,32 @@ struct tevent_req *sdap_initgr_rfc2307_send(TALLOC_CTX *memctx,
|
||||
}
|
||||
|
||||
state->base_filter = talloc_asprintf(state,
|
||||
- "(&(%s=%s)(%s)(%s=*)(&(%s=*)(!(%s=0))))",
|
||||
+ "(&(%s=%s)(%s)(%s=*)",
|
||||
opts->group_map[SDAP_AT_GROUP_MEMBER].name,
|
||||
clean_name, oc_list,
|
||||
- opts->group_map[SDAP_AT_GROUP_NAME].name,
|
||||
- opts->group_map[SDAP_AT_GROUP_GID].name,
|
||||
- opts->group_map[SDAP_AT_GROUP_GID].name);
|
||||
+ opts->group_map[SDAP_AT_GROUP_NAME].name);
|
||||
if (!state->base_filter) {
|
||||
talloc_zfree(req);
|
||||
return NULL;
|
||||
}
|
||||
talloc_zfree(clean_name);
|
||||
|
||||
+ switch (domain->type) {
|
||||
+ case DOM_TYPE_APPLICATION:
|
||||
+ state->base_filter = talloc_asprintf_append(state->base_filter, ")");
|
||||
+ break;
|
||||
+ case DOM_TYPE_POSIX:
|
||||
+ state->base_filter = talloc_asprintf_append(state->base_filter,
|
||||
+ "(&(%s=*)(!(%s=0))))",
|
||||
+ opts->group_map[SDAP_AT_GROUP_GID].name,
|
||||
+ opts->group_map[SDAP_AT_GROUP_GID].name);
|
||||
+ break;
|
||||
+ }
|
||||
+ if (!state->base_filter) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
ret = sdap_initgr_rfc2307_next_base(req);
|
||||
|
||||
done:
|
||||
@@ -2666,6 +2680,7 @@ struct sdap_get_initgr_state {
|
||||
char *shortname;
|
||||
char *filter;
|
||||
int timeout;
|
||||
+ bool non_posix;
|
||||
|
||||
struct sysdb_attrs *orig_user;
|
||||
|
||||
@@ -2724,6 +2739,10 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ if (state->dom->type == DOM_TYPE_APPLICATION) {
|
||||
+ state->non_posix = true;
|
||||
+ }
|
||||
+
|
||||
use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
|
||||
id_ctx->opts->idmap_ctx,
|
||||
sdom->dom->name,
|
||||
@@ -2813,7 +2832,10 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
|
||||
}
|
||||
}
|
||||
|
||||
- if (use_id_mapping) {
|
||||
+ if (state->non_posix) {
|
||||
+ state->user_base_filter = talloc_asprintf_append(state->user_base_filter,
|
||||
+ ")");
|
||||
+ } else if (use_id_mapping) {
|
||||
/* When mapping IDs or looking for SIDs, we don't want to limit
|
||||
* ourselves to users with a UID value. But there must be a SID to map
|
||||
* from.
|
||||
@@ -2822,7 +2844,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
|
||||
"(%s=*))",
|
||||
id_ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name);
|
||||
} else {
|
||||
- /* When not ID-mapping, make sure there is a non-NULL UID */
|
||||
+ /* When not ID-mapping or looking up app users, make sure there
|
||||
+ * is a non-NULL UID */
|
||||
state->user_base_filter = talloc_asprintf_append(state->user_base_filter,
|
||||
"(&(%s=*)(!(%s=0))))",
|
||||
id_ctx->opts->user_map[SDAP_AT_USER_UID].name,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,353 +0,0 @@
|
||||
From 861ab44e8148208425b67c4711bc8fade10fd3ed Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 22 Mar 2017 13:01:18 +0100
|
||||
Subject: [PATCH 75/97] KRB5: Authenticate users in a non-POSIX domain using a
|
||||
MEMORY ccache
|
||||
|
||||
Related to:
|
||||
https://pagure.io/SSSD/sssd/issue/3310
|
||||
|
||||
The following changes were done to the Kerberos authentication code
|
||||
in order to support authentication in a non-POSIX environment:
|
||||
- delayed authentication is disabled in non-POSIX domains
|
||||
- when a user logs in in a non-POSIX domain, SSSD uses a
|
||||
MEMORY:$username ccache and destroys is then krb5_child finishes
|
||||
so that just the numeric result is used
|
||||
- krb5_child doesn't drop privileges in this configuration because
|
||||
there is nothing to drop privileges to
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
src/providers/krb5/krb5_auth.c | 62 ++++++++++++++++------
|
||||
src/providers/krb5/krb5_auth.h | 2 +
|
||||
src/providers/krb5/krb5_child.c | 32 +++++++++--
|
||||
src/providers/krb5/krb5_child_handler.c | 15 +++++-
|
||||
.../krb5/krb5_delayed_online_authentication.c | 7 +++
|
||||
src/providers/krb5/krb5_init.c | 3 ++
|
||||
6 files changed, 99 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
|
||||
index c2d6d7eeacc1f766024c4d629f25fd0f0be24e5e..2faf18d17a735476c20f9cc27b15be4a39cadc5c 100644
|
||||
--- a/src/providers/krb5/krb5_auth.c
|
||||
+++ b/src/providers/krb5/krb5_auth.c
|
||||
@@ -42,6 +42,8 @@
|
||||
#include "providers/krb5/krb5_utils.h"
|
||||
#include "providers/krb5/krb5_ccache.h"
|
||||
|
||||
+#define NON_POSIX_CCNAME_FMT "MEMORY:sssd_nonposix_dummy_%u"
|
||||
+
|
||||
static int krb5_mod_ccname(TALLOC_CTX *mem_ctx,
|
||||
struct sysdb_ctx *sysdb,
|
||||
struct sss_domain_info *domain,
|
||||
@@ -200,6 +202,7 @@ errno_t krb5_setup(TALLOC_CTX *mem_ctx,
|
||||
talloc_set_destructor((TALLOC_CTX *) kr, krb5_cleanup);
|
||||
|
||||
kr->pd = pd;
|
||||
+ kr->dom = dom;
|
||||
kr->krb5_ctx = krb5_ctx;
|
||||
|
||||
ret = get_krb_primary(krb5_ctx->name_to_primary,
|
||||
@@ -275,8 +278,11 @@ static void krb5_auth_cache_creds(struct krb5_ctx *krb5_ctx,
|
||||
return;
|
||||
}
|
||||
|
||||
- ret = add_user_to_delayed_online_authentication(krb5_ctx, pd, uid);
|
||||
- if (ret != EOK) {
|
||||
+ ret = add_user_to_delayed_online_authentication(krb5_ctx, domain, pd, uid);
|
||||
+ if (ret == ENOTSUP) {
|
||||
+ /* This error is not fatal */
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE, "Delayed authentication not supported\n");
|
||||
+ } else if (ret != EOK) {
|
||||
/* This error is not fatal */
|
||||
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
"add_user_to_delayed_online_authentication failed.\n");
|
||||
@@ -291,21 +297,43 @@ static errno_t krb5_auth_prepare_ccache_name(struct krb5child_req *kr,
|
||||
{
|
||||
const char *ccname_template;
|
||||
|
||||
- ccname_template = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_CCNAME_TMPL);
|
||||
+ switch (kr->dom->type) {
|
||||
+ case DOM_TYPE_POSIX:
|
||||
+ ccname_template = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_CCNAME_TMPL);
|
||||
|
||||
- kr->ccname = expand_ccname_template(kr, kr, ccname_template,
|
||||
- kr->krb5_ctx->illegal_path_re, true,
|
||||
- be_ctx->domain->case_sensitive);
|
||||
- if (kr->ccname == NULL) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "expand_ccname_template failed.\n");
|
||||
- return ENOMEM;
|
||||
- }
|
||||
+ kr->ccname = expand_ccname_template(kr, kr, ccname_template,
|
||||
+ kr->krb5_ctx->illegal_path_re, true,
|
||||
+ be_ctx->domain->case_sensitive);
|
||||
+ if (kr->ccname == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "expand_ccname_template failed.\n");
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
|
||||
- kr->old_ccname = ldb_msg_find_attr_as_string(user_msg,
|
||||
- SYSDB_CCACHE_FILE, NULL);
|
||||
- if (kr->old_ccname == NULL) {
|
||||
- DEBUG(SSSDBG_TRACE_LIBS,
|
||||
- "No ccache file for user [%s] found.\n", kr->pd->user);
|
||||
+ kr->old_ccname = ldb_msg_find_attr_as_string(user_msg,
|
||||
+ SYSDB_CCACHE_FILE, NULL);
|
||||
+ if (kr->old_ccname == NULL) {
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS,
|
||||
+ "No ccache file for user [%s] found.\n", kr->pd->user);
|
||||
+ }
|
||||
+ break;
|
||||
+ case DOM_TYPE_APPLICATION:
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ "Domain type application, will use in-memory ccache\n");
|
||||
+ /* We don't care about using cryptographic randomness, just
|
||||
+ * a non-predictable ccname, so using rand() here is fine
|
||||
+ */
|
||||
+ kr->ccname = talloc_asprintf(kr,
|
||||
+ NON_POSIX_CCNAME_FMT,
|
||||
+ rand() % UINT_MAX);
|
||||
+ if (kr->ccname == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ break;
|
||||
+ default:
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "Unsupported domain type\n");
|
||||
+ return EINVAL;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
@@ -617,7 +645,7 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
|
||||
kr->uid = sss_view_ldb_msg_find_attr_as_uint64(state->domain,
|
||||
res->msgs[0],
|
||||
SYSDB_UIDNUM, 0);
|
||||
- if (kr->uid == 0) {
|
||||
+ if (kr->uid == 0 && state->domain->type == DOM_TYPE_POSIX) {
|
||||
DEBUG(SSSDBG_CONF_SETTINGS,
|
||||
"UID for user [%s] not known.\n", pd->user);
|
||||
ret = ENOENT;
|
||||
@@ -627,7 +655,7 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
|
||||
kr->gid = sss_view_ldb_msg_find_attr_as_uint64(state->domain,
|
||||
res->msgs[0],
|
||||
SYSDB_GIDNUM, 0);
|
||||
- if (kr->gid == 0) {
|
||||
+ if (kr->gid == 0 && state->domain->type == DOM_TYPE_POSIX) {
|
||||
DEBUG(SSSDBG_CONF_SETTINGS,
|
||||
"GID for user [%s] not known.\n", pd->user);
|
||||
ret = ENOENT;
|
||||
diff --git a/src/providers/krb5/krb5_auth.h b/src/providers/krb5/krb5_auth.h
|
||||
index 75ad916e79b29043120543ab3c4c1bd27e09d913..8ad3aeff21e58f9055ae144eaa450992c6391ba6 100644
|
||||
--- a/src/providers/krb5/krb5_auth.h
|
||||
+++ b/src/providers/krb5/krb5_auth.h
|
||||
@@ -50,6 +50,7 @@
|
||||
struct krb5child_req {
|
||||
struct pam_data *pd;
|
||||
struct krb5_ctx *krb5_ctx;
|
||||
+ struct sss_domain_info *dom;
|
||||
|
||||
const char *ccname;
|
||||
const char *old_ccname;
|
||||
@@ -118,6 +119,7 @@ parse_krb5_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, ssize_t len,
|
||||
struct krb5_child_response **_res);
|
||||
|
||||
errno_t add_user_to_delayed_online_authentication(struct krb5_ctx *krb5_ctx,
|
||||
+ struct sss_domain_info *domain,
|
||||
struct pam_data *pd,
|
||||
uid_t uid);
|
||||
errno_t init_delayed_online_authentication(struct krb5_ctx *krb5_ctx,
|
||||
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
|
||||
index a4128dda6b0861a95dba223047d66c4158b1afb6..cbbc892bee0365892ac66d3654c974d325166b60 100644
|
||||
--- a/src/providers/krb5/krb5_child.c
|
||||
+++ b/src/providers/krb5/krb5_child.c
|
||||
@@ -80,6 +80,7 @@ struct krb5_req {
|
||||
char *ccname;
|
||||
char *keytab;
|
||||
bool validate;
|
||||
+ bool posix_domain;
|
||||
bool send_pac;
|
||||
bool use_enterprise_princ;
|
||||
char *fast_ccname;
|
||||
@@ -102,6 +103,16 @@ struct krb5_req {
|
||||
static krb5_context krb5_error_ctx;
|
||||
#define KRB5_CHILD_DEBUG(level, error) KRB5_DEBUG(level, krb5_error_ctx, error)
|
||||
|
||||
+static errno_t k5c_become_user(uid_t uid, gid_t gid, bool is_posix)
|
||||
+{
|
||||
+ if (is_posix == false) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ "Will not drop privileges for a non-POSIX user\n");
|
||||
+ return EOK;
|
||||
+ }
|
||||
+ return become_user(uid, gid);
|
||||
+}
|
||||
+
|
||||
static krb5_error_code set_lifetime_options(struct cli_opts *cli_opts,
|
||||
krb5_get_init_creds_opt *options)
|
||||
{
|
||||
@@ -1561,6 +1572,15 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
|
||||
DEBUG(SSSDBG_CONF_SETTINGS, "TGT validation is disabled.\n");
|
||||
}
|
||||
|
||||
+ /* In a non-POSIX environment, we only care about the return code from
|
||||
+ * krb5_child, so let's not even attempt to create the ccache
|
||||
+ */
|
||||
+ if (kr->posix_domain == false) {
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS,
|
||||
+ "Finished authentication in a non-POSIX domain\n");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
/* If kr->ccname is cache collection (DIR:/...), we want to work
|
||||
* directly with file ccache (DIR::/...), but cache collection
|
||||
* should be returned back to back end.
|
||||
@@ -2146,6 +2166,7 @@ static errno_t unpack_buffer(uint8_t *buf, size_t size,
|
||||
size_t p = 0;
|
||||
uint32_t len;
|
||||
uint32_t validate;
|
||||
+ uint32_t posix_domain;
|
||||
uint32_t send_pac;
|
||||
uint32_t use_enterprise_princ;
|
||||
struct pam_data *pd;
|
||||
@@ -2167,6 +2188,8 @@ static errno_t unpack_buffer(uint8_t *buf, size_t size,
|
||||
SAFEALIGN_COPY_UINT32_CHECK(&kr->gid, buf + p, size, &p);
|
||||
SAFEALIGN_COPY_UINT32_CHECK(&validate, buf + p, size, &p);
|
||||
kr->validate = (validate == 0) ? false : true;
|
||||
+ SAFEALIGN_COPY_UINT32_CHECK(&posix_domain, buf + p, size, &p);
|
||||
+ kr->posix_domain = (posix_domain == 0) ? false : true;
|
||||
SAFEALIGN_COPY_UINT32_CHECK(offline, buf + p, size, &p);
|
||||
SAFEALIGN_COPY_UINT32_CHECK(&send_pac, buf + p, size, &p);
|
||||
kr->send_pac = (send_pac == 0) ? false : true;
|
||||
@@ -2331,6 +2354,7 @@ static krb5_error_code check_fast_ccache(TALLOC_CTX *mem_ctx,
|
||||
krb5_context ctx,
|
||||
uid_t fast_uid,
|
||||
gid_t fast_gid,
|
||||
+ bool posix_domain,
|
||||
struct cli_opts *cli_opts,
|
||||
const char *primary,
|
||||
const char *realm,
|
||||
@@ -2420,7 +2444,7 @@ static krb5_error_code check_fast_ccache(TALLOC_CTX *mem_ctx,
|
||||
/* Try to carry on */
|
||||
}
|
||||
|
||||
- kerr = become_user(fast_uid, fast_gid);
|
||||
+ kerr = k5c_become_user(fast_uid, fast_gid, posix_domain);
|
||||
if (kerr != 0) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed: %d\n", kerr);
|
||||
exit(1);
|
||||
@@ -2572,7 +2596,7 @@ static int k5c_setup_fast(struct krb5_req *kr, bool demand)
|
||||
}
|
||||
|
||||
kerr = check_fast_ccache(kr, kr->ctx, kr->fast_uid, kr->fast_gid,
|
||||
- kr->cli_opts,
|
||||
+ kr->posix_domain, kr->cli_opts,
|
||||
fast_principal, fast_principal_realm,
|
||||
kr->keytab, &kr->fast_ccname);
|
||||
if (kerr != 0) {
|
||||
@@ -2773,7 +2797,7 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline)
|
||||
* the user who is logging in. The same applies to the offline case
|
||||
* the user who is logging in. The same applies to the offline case.
|
||||
*/
|
||||
- kerr = become_user(kr->uid, kr->gid);
|
||||
+ kerr = k5c_become_user(kr->uid, kr->gid, kr->posix_domain);
|
||||
if (kerr != 0) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
|
||||
return kerr;
|
||||
@@ -3075,7 +3099,7 @@ int main(int argc, const char *argv[])
|
||||
if ((sss_authtok_get_type(kr->pd->authtok) != SSS_AUTHTOK_TYPE_SC_PIN
|
||||
&& sss_authtok_get_type(kr->pd->authtok)
|
||||
!= SSS_AUTHTOK_TYPE_SC_KEYPAD)) {
|
||||
- kerr = become_user(kr->uid, kr->gid);
|
||||
+ kerr = k5c_become_user(kr->uid, kr->gid, kr->posix_domain);
|
||||
if (kerr != 0) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n");
|
||||
ret = EFAULT;
|
||||
diff --git a/src/providers/krb5/krb5_child_handler.c b/src/providers/krb5/krb5_child_handler.c
|
||||
index 680e67b089fcb32280352af24aae35af133a52f3..87e79a06e917aadb622455bccfc2e9c6769f70c2 100644
|
||||
--- a/src/providers/krb5/krb5_child_handler.c
|
||||
+++ b/src/providers/krb5/krb5_child_handler.c
|
||||
@@ -107,6 +107,7 @@ static errno_t create_send_buffer(struct krb5child_req *kr,
|
||||
uint32_t validate;
|
||||
uint32_t send_pac;
|
||||
uint32_t use_enterprise_principal;
|
||||
+ uint32_t posix_domain;
|
||||
size_t username_len = 0;
|
||||
errno_t ret;
|
||||
|
||||
@@ -131,6 +132,17 @@ static errno_t create_send_buffer(struct krb5child_req *kr,
|
||||
break;
|
||||
}
|
||||
|
||||
+ switch (kr->dom->type) {
|
||||
+ case DOM_TYPE_POSIX:
|
||||
+ posix_domain = 1;
|
||||
+ break;
|
||||
+ case DOM_TYPE_APPLICATION:
|
||||
+ posix_domain = 0;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
if (kr->pd->cmd == SSS_CMD_RENEW || kr->is_offline) {
|
||||
use_enterprise_principal = false;
|
||||
} else {
|
||||
@@ -151,7 +163,7 @@ static errno_t create_send_buffer(struct krb5child_req *kr,
|
||||
kr->pd->cmd == SSS_CMD_RENEW ||
|
||||
kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM ||
|
||||
kr->pd->cmd == SSS_PAM_CHAUTHTOK) {
|
||||
- buf->size += 4*sizeof(uint32_t) + strlen(kr->ccname) + strlen(keytab) +
|
||||
+ buf->size += 5*sizeof(uint32_t) + strlen(kr->ccname) + strlen(keytab) +
|
||||
sss_authtok_get_size(kr->pd->authtok);
|
||||
|
||||
buf->size += sizeof(uint32_t);
|
||||
@@ -182,6 +194,7 @@ static errno_t create_send_buffer(struct krb5child_req *kr,
|
||||
SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->uid, &rp);
|
||||
SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->gid, &rp);
|
||||
SAFEALIGN_COPY_UINT32(&buf->data[rp], &validate, &rp);
|
||||
+ SAFEALIGN_COPY_UINT32(&buf->data[rp], &posix_domain, &rp);
|
||||
SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->is_offline, &rp);
|
||||
SAFEALIGN_COPY_UINT32(&buf->data[rp], &send_pac, &rp);
|
||||
SAFEALIGN_COPY_UINT32(&buf->data[rp], &use_enterprise_principal, &rp);
|
||||
diff --git a/src/providers/krb5/krb5_delayed_online_authentication.c b/src/providers/krb5/krb5_delayed_online_authentication.c
|
||||
index bf2ef775573ba6bad79a99ad43b5d9748516e794..1cb7eade0e4cb9afbc4d031a07b3519ba08456d6 100644
|
||||
--- a/src/providers/krb5/krb5_delayed_online_authentication.c
|
||||
+++ b/src/providers/krb5/krb5_delayed_online_authentication.c
|
||||
@@ -234,6 +234,7 @@ static void delayed_online_authentication_callback(void *private_data)
|
||||
}
|
||||
|
||||
errno_t add_user_to_delayed_online_authentication(struct krb5_ctx *krb5_ctx,
|
||||
+ struct sss_domain_info *domain,
|
||||
struct pam_data *pd,
|
||||
uid_t uid)
|
||||
{
|
||||
@@ -242,6 +243,12 @@ errno_t add_user_to_delayed_online_authentication(struct krb5_ctx *krb5_ctx,
|
||||
hash_value_t value;
|
||||
struct pam_data *new_pd;
|
||||
|
||||
+ if (domain->type != DOM_TYPE_POSIX) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "Domain type does not support delayed authentication\n");
|
||||
+ return ENOTSUP;
|
||||
+ }
|
||||
+
|
||||
if (krb5_ctx->deferred_auth_ctx == NULL) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
"Missing context for delayed online authentication.\n");
|
||||
diff --git a/src/providers/krb5/krb5_init.c b/src/providers/krb5/krb5_init.c
|
||||
index 12c8dfcc49af75de619ec0858aaff81504698273..66ae68fb4773af3987f2062246bc6493107c74d5 100644
|
||||
--- a/src/providers/krb5/krb5_init.c
|
||||
+++ b/src/providers/krb5/krb5_init.c
|
||||
@@ -136,6 +136,9 @@ errno_t sssm_krb5_init(TALLOC_CTX *mem_ctx,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
+ /* Only needed to generate random ccache names for non-POSIX domains */
|
||||
+ srand(time(NULL) * getpid());
|
||||
+
|
||||
ret = sss_krb5_get_options(ctx, be_ctx->cdb, be_ctx->conf_path, &ctx->opts);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get krb5 options [%d]: %s\n",
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,210 +0,0 @@
|
||||
From 7d73049884e3a96ca3b00b5bd4104f4edd6287ab Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 29 Mar 2017 22:49:09 +0200
|
||||
Subject: [PATCH 76/97] KCM: Fix off-by-one error in secrets key parsing
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When parsing the secrets key, the code tried to protect against malformed keys
|
||||
or keys that are too short, but it did an error - the UUID stringified
|
||||
form is 36 bytes long, so the UUID_STR_SIZE is 37 because UUID_STR_SIZE
|
||||
accounts for the null terminator.
|
||||
|
||||
But the code, that was trying to assert that there are two characters after
|
||||
the UUID string (separator and at least a single character for the name)
|
||||
didn't take the NULL terminator (which strlen() doesn't return) into
|
||||
account and ended up rejecting all ccaches whose name is only a single
|
||||
character.
|
||||
|
||||
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
---
|
||||
src/responder/kcm/kcmsrv_ccache_json.c | 43 +++++++++-------
|
||||
src/tests/cmocka/test_kcm_json_marshalling.c | 75 ++++++++++++++++++++++++++++
|
||||
2 files changed, 101 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/src/responder/kcm/kcmsrv_ccache_json.c b/src/responder/kcm/kcmsrv_ccache_json.c
|
||||
index 40b64861c209206d6f60ccd0843857edee24a844..8199bc613e4204859438e1cd820f3f4b2123dd7e 100644
|
||||
--- a/src/responder/kcm/kcmsrv_ccache_json.c
|
||||
+++ b/src/responder/kcm/kcmsrv_ccache_json.c
|
||||
@@ -109,6 +109,28 @@ static const char *sec_key_create(TALLOC_CTX *mem_ctx,
|
||||
"%s%c%s", uuid_str, SEC_KEY_SEPARATOR, name);
|
||||
}
|
||||
|
||||
+static bool sec_key_valid(const char *sec_key)
|
||||
+{
|
||||
+ if (sec_key == NULL) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (strlen(sec_key) < UUID_STR_SIZE + 1) {
|
||||
+ /* One char for separator (at UUID_STR_SIZE, because strlen doesn't
|
||||
+ * include the '\0', but UUID_STR_SIZE does) and at least one for
|
||||
+ * the name */
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Key %s is too short\n", sec_key);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (sec_key[UUID_STR_SIZE - 1] != SEC_KEY_SEPARATOR) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Key doesn't contain the separator\n");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static errno_t sec_key_parse(TALLOC_CTX *mem_ctx,
|
||||
const char *sec_key,
|
||||
const char **_name,
|
||||
@@ -116,9 +138,7 @@ static errno_t sec_key_parse(TALLOC_CTX *mem_ctx,
|
||||
{
|
||||
char uuid_str[UUID_STR_SIZE];
|
||||
|
||||
- if (strlen(sec_key) < UUID_STR_SIZE + 2) {
|
||||
- /* One char for separator and at least one for the name */
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Key %s is too short\n", sec_key);
|
||||
+ if (!sec_key_valid(sec_key)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
@@ -143,14 +163,7 @@ errno_t sec_key_get_uuid(const char *sec_key,
|
||||
{
|
||||
char uuid_str[UUID_STR_SIZE];
|
||||
|
||||
- if (strlen(sec_key) < UUID_STR_SIZE + 2) {
|
||||
- /* One char for separator and at least one for the name */
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Key %s is too short\n", sec_key);
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (sec_key[UUID_STR_SIZE-1] != SEC_KEY_SEPARATOR) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Key doesn't contain the separator\n");
|
||||
+ if (!sec_key_valid(sec_key)) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
@@ -162,9 +175,7 @@ errno_t sec_key_get_uuid(const char *sec_key,
|
||||
|
||||
const char *sec_key_get_name(const char *sec_key)
|
||||
{
|
||||
- if (strlen(sec_key) < UUID_STR_SIZE + 2) {
|
||||
- /* One char for separator and at least one for the name */
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Key %s is too short\n", sec_key);
|
||||
+ if (!sec_key_valid(sec_key)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -174,9 +185,7 @@ const char *sec_key_get_name(const char *sec_key)
|
||||
bool sec_key_match_name(const char *sec_key,
|
||||
const char *name)
|
||||
{
|
||||
- if (strlen(sec_key) < UUID_STR_SIZE + 2) {
|
||||
- /* One char for separator and at least one for the name */
|
||||
- DEBUG(SSSDBG_MINOR_FAILURE, "Key %s is too short\n", sec_key);
|
||||
+ if (!sec_key_valid(sec_key) || name == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
diff --git a/src/tests/cmocka/test_kcm_json_marshalling.c b/src/tests/cmocka/test_kcm_json_marshalling.c
|
||||
index 8eff2f501066c70a8730cd3d4dc41b92d7a03e4c..108eaf55628029a6de8c23cd6486bdccc42c0364 100644
|
||||
--- a/src/tests/cmocka/test_kcm_json_marshalling.c
|
||||
+++ b/src/tests/cmocka/test_kcm_json_marshalling.c
|
||||
@@ -32,6 +32,12 @@
|
||||
|
||||
#define TEST_CREDS "TESTCREDS"
|
||||
|
||||
+#define TEST_UUID_STR "5f8f296b-02be-4e86-9235-500e82354186"
|
||||
+#define TEST_SEC_KEY_ONEDIGIT TEST_UUID_STR"-0"
|
||||
+#define TEST_SEC_KEY_MULTIDIGITS TEST_UUID_STR"-123456"
|
||||
+
|
||||
+#define TEST_SEC_KEY_NOSEP TEST_UUID_STR"+0"
|
||||
+
|
||||
const struct kcm_ccdb_ops ccdb_mem_ops;
|
||||
const struct kcm_ccdb_ops ccdb_sec_ops;
|
||||
|
||||
@@ -188,6 +194,72 @@ static void test_kcm_ccache_marshall_unmarshall(void **state)
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
assert_cc_equal(cc, cc2);
|
||||
+
|
||||
+ /* This key is exactly one byte shorter than it should be */
|
||||
+ ret = sec_kv_to_ccache(test_ctx,
|
||||
+ TEST_UUID_STR"-",
|
||||
+ (const char *) data,
|
||||
+ &owner,
|
||||
+ &cc2);
|
||||
+ assert_int_equal(ret, EINVAL);
|
||||
+}
|
||||
+
|
||||
+void test_sec_key_get_uuid(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ uuid_t uuid;
|
||||
+ char str_uuid[UUID_STR_SIZE];
|
||||
+
|
||||
+ uuid_clear(uuid);
|
||||
+ ret = sec_key_get_uuid(TEST_SEC_KEY_ONEDIGIT, uuid);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ uuid_unparse(uuid, str_uuid);
|
||||
+ assert_string_equal(TEST_UUID_STR, str_uuid);
|
||||
+
|
||||
+ ret = sec_key_get_uuid(TEST_SEC_KEY_NOSEP, uuid);
|
||||
+ assert_int_equal(ret, EINVAL);
|
||||
+
|
||||
+ ret = sec_key_get_uuid(TEST_UUID_STR, uuid);
|
||||
+ assert_int_equal(ret, EINVAL);
|
||||
+
|
||||
+ ret = sec_key_get_uuid(NULL, uuid);
|
||||
+ assert_int_equal(ret, EINVAL);
|
||||
+}
|
||||
+
|
||||
+void test_sec_key_get_name(void **state)
|
||||
+{
|
||||
+ const char *name;
|
||||
+
|
||||
+ name = sec_key_get_name(TEST_SEC_KEY_ONEDIGIT);
|
||||
+ assert_non_null(name);
|
||||
+ assert_string_equal(name, "0");
|
||||
+
|
||||
+ name = sec_key_get_name(TEST_SEC_KEY_MULTIDIGITS);
|
||||
+ assert_non_null(name);
|
||||
+ assert_string_equal(name, "123456");
|
||||
+
|
||||
+ name = sec_key_get_name(TEST_UUID_STR);
|
||||
+ assert_null(name);
|
||||
+
|
||||
+ name = sec_key_get_name(TEST_SEC_KEY_NOSEP);
|
||||
+ assert_null(name);
|
||||
+
|
||||
+ name = sec_key_get_name(NULL);
|
||||
+ assert_null(name);
|
||||
+}
|
||||
+
|
||||
+void test_sec_key_match_name(void **state)
|
||||
+{
|
||||
+ assert_true(sec_key_match_name(TEST_SEC_KEY_ONEDIGIT, "0"));
|
||||
+ assert_true(sec_key_match_name(TEST_SEC_KEY_MULTIDIGITS, "123456"));
|
||||
+
|
||||
+ assert_false(sec_key_match_name(TEST_SEC_KEY_MULTIDIGITS, "0"));
|
||||
+ assert_false(sec_key_match_name(TEST_SEC_KEY_ONEDIGIT, "123456"));
|
||||
+
|
||||
+ assert_false(sec_key_match_name(TEST_UUID_STR, "0"));
|
||||
+ assert_false(sec_key_match_name(TEST_SEC_KEY_NOSEP, "0"));
|
||||
+ assert_false(sec_key_match_name(TEST_SEC_KEY_ONEDIGIT, NULL));
|
||||
+ assert_false(sec_key_match_name(NULL, "0"));
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
@@ -205,6 +277,9 @@ int main(int argc, const char *argv[])
|
||||
cmocka_unit_test_setup_teardown(test_kcm_ccache_marshall_unmarshall,
|
||||
setup_kcm_marshalling,
|
||||
teardown_kcm_marshalling),
|
||||
+ cmocka_unit_test(test_sec_key_get_uuid),
|
||||
+ cmocka_unit_test(test_sec_key_get_name),
|
||||
+ cmocka_unit_test(test_sec_key_match_name),
|
||||
};
|
||||
|
||||
/* Set debug level to invalid value so we can deside if -d 0 was used. */
|
||||
--
|
||||
2.12.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,437 +0,0 @@
|
||||
From b800a6d09244359959404aca81c6796a58cafbcb Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Fri, 24 Feb 2017 12:23:01 +0100
|
||||
Subject: [PATCH 78/97] tcurl test: refactor so new options can be added more
|
||||
easily
|
||||
|
||||
Just to make the tool a little bit nicer and more flexible.
|
||||
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/tests/tcurl_test_tool.c | 334 +++++++++++++++++++++++++++-----------------
|
||||
1 file changed, 209 insertions(+), 125 deletions(-)
|
||||
|
||||
diff --git a/src/tests/tcurl_test_tool.c b/src/tests/tcurl_test_tool.c
|
||||
index 9a6266f89131ffd3a561e857af85df9854c44949..e5fc9705db415650d849b89c3d18e41574b7e28b 100644
|
||||
--- a/src/tests/tcurl_test_tool.c
|
||||
+++ b/src/tests/tcurl_test_tool.c
|
||||
@@ -28,26 +28,39 @@
|
||||
|
||||
struct tool_ctx {
|
||||
bool verbose;
|
||||
-
|
||||
- errno_t error;
|
||||
bool done;
|
||||
|
||||
size_t nreqs;
|
||||
};
|
||||
|
||||
+struct tool_options {
|
||||
+ int debug;
|
||||
+ int verbose;
|
||||
+
|
||||
+ enum tcurl_http_method method;
|
||||
+ const char *socket_path;
|
||||
+};
|
||||
+
|
||||
static void request_done(struct tevent_req *req)
|
||||
{
|
||||
- int http_code;
|
||||
+ struct tool_ctx *tool_ctx;
|
||||
struct sss_iobuf *outbuf;
|
||||
- struct tool_ctx *tool_ctx = tevent_req_callback_data(req,
|
||||
- struct tool_ctx);
|
||||
+ int http_code;
|
||||
+ errno_t ret;
|
||||
|
||||
- tool_ctx->error = tcurl_request_recv(tool_ctx, req, &outbuf, &http_code);
|
||||
+ tool_ctx = tevent_req_callback_data(req, struct tool_ctx);
|
||||
+
|
||||
+ ret = tcurl_request_recv(tool_ctx, req, &outbuf, &http_code);
|
||||
talloc_zfree(req);
|
||||
|
||||
- if (tool_ctx->error != EOK) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE, "HTTP request failed: %d\n", tool_ctx->error);
|
||||
+ tool_ctx->nreqs--;
|
||||
+ if (tool_ctx->nreqs == 0) {
|
||||
tool_ctx->done = true;
|
||||
+ }
|
||||
+
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "HTTP request failed [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
return;
|
||||
} else if (tool_ctx->verbose) {
|
||||
printf("Request HTTP code: %d\n", http_code);
|
||||
@@ -55,167 +68,171 @@ static void request_done(struct tevent_req *req)
|
||||
(const char *) sss_iobuf_get_data(outbuf));
|
||||
talloc_zfree(outbuf);
|
||||
}
|
||||
-
|
||||
- tool_ctx->nreqs--;
|
||||
- if (tool_ctx->nreqs == 0) {
|
||||
- tool_ctx->done = true;
|
||||
- }
|
||||
}
|
||||
|
||||
-int main(int argc, const char *argv[])
|
||||
+static errno_t
|
||||
+parse_options(poptContext pc, struct tool_options *opts)
|
||||
{
|
||||
int opt;
|
||||
- poptContext pc;
|
||||
-
|
||||
- int pc_debug = 0;
|
||||
- int pc_verbose = 0;
|
||||
- const char *socket_path = NULL;
|
||||
- const char *extra_arg_ptr;
|
||||
-
|
||||
- static const char *headers[] = {
|
||||
- "Content-type: application/octet-stream",
|
||||
- NULL,
|
||||
- };
|
||||
-
|
||||
- struct poptOption long_options[] = {
|
||||
- POPT_AUTOHELP
|
||||
- { "debug", '\0', POPT_ARG_INT, &pc_debug, 0,
|
||||
- "The debug level to run with", NULL },
|
||||
- { "socket-path", 's', POPT_ARG_STRING, &socket_path, 0,
|
||||
- "The path to the HTTP server socket", NULL },
|
||||
- { "get", 'g', POPT_ARG_NONE, NULL, 'g', "Perform a HTTP GET (default)", NULL },
|
||||
- { "put", 'p', POPT_ARG_NONE, NULL, 'p', "Perform a HTTP PUT", NULL },
|
||||
- { "post", 'o', POPT_ARG_NONE, NULL, 'o', "Perform a HTTP POST", NULL },
|
||||
- { "del", 'd', POPT_ARG_NONE, NULL, 'd', "Perform a HTTP DELETE", NULL },
|
||||
- { "verbose", 'v', POPT_ARG_NONE, NULL, 'v', "Print response code and body", NULL },
|
||||
- POPT_TABLEEND
|
||||
- };
|
||||
-
|
||||
- struct tevent_req *req;
|
||||
- struct tevent_context *ev;
|
||||
- enum tcurl_http_method method = TCURL_HTTP_GET;
|
||||
- struct tcurl_ctx *ctx;
|
||||
- struct tcurl_request *tcurl_req;
|
||||
- struct tool_ctx *tool_ctx;
|
||||
-
|
||||
- const char *urls[MAXREQ] = { 0 };
|
||||
- struct sss_iobuf **inbufs;
|
||||
-
|
||||
- size_t n_reqs = 0;
|
||||
-
|
||||
- debug_prg_name = argv[0];
|
||||
- pc = poptGetContext(NULL, argc, argv, long_options, 0);
|
||||
- poptSetOtherOptionHelp(pc, "HTTPDATA");
|
||||
|
||||
while ((opt = poptGetNextOpt(pc)) > 0) {
|
||||
switch (opt) {
|
||||
case 'g':
|
||||
- method = TCURL_HTTP_GET;
|
||||
+ opts->method = TCURL_HTTP_GET;
|
||||
break;
|
||||
case 'p':
|
||||
- method = TCURL_HTTP_PUT;
|
||||
+ opts->method = TCURL_HTTP_PUT;
|
||||
break;
|
||||
case 'o':
|
||||
- method = TCURL_HTTP_POST;
|
||||
+ opts->method = TCURL_HTTP_POST;
|
||||
break;
|
||||
case 'd':
|
||||
- method = TCURL_HTTP_DELETE;
|
||||
- break;
|
||||
- case 'v':
|
||||
- pc_verbose = 1;
|
||||
+ opts->method = TCURL_HTTP_DELETE;
|
||||
break;
|
||||
default:
|
||||
DEBUG(SSSDBG_FATAL_FAILURE, "Unexpected option\n");
|
||||
- return 1;
|
||||
+ return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
- DEBUG_CLI_INIT(pc_debug);
|
||||
-
|
||||
- tool_ctx = talloc_zero(NULL, struct tool_ctx);
|
||||
- if (tool_ctx == NULL) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Could not init tool context\n");
|
||||
- return 1;
|
||||
+ if (opt != -1) {
|
||||
+ poptPrintUsage(pc, stderr, 0);
|
||||
+ fprintf(stderr, "%s", poptStrerror(opt));
|
||||
+ return EINVAL;
|
||||
}
|
||||
|
||||
- inbufs = talloc_zero_array(tool_ctx, struct sss_iobuf *, MAXREQ);
|
||||
- if (inbufs == NULL) {
|
||||
- talloc_zfree(tool_ctx);
|
||||
- return 1;
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static errno_t
|
||||
+prepare_requests(TALLOC_CTX *mem_ctx,
|
||||
+ poptContext pc,
|
||||
+ struct tool_options *opts,
|
||||
+ struct tcurl_request ***_requests,
|
||||
+ size_t *_num_requests)
|
||||
+{
|
||||
+ struct tcurl_request **requests;
|
||||
+ const char *arg;
|
||||
+ const char *url;
|
||||
+ struct sss_iobuf *body;
|
||||
+ errno_t ret;
|
||||
+ size_t i;
|
||||
+
|
||||
+ static const char *headers[] = {
|
||||
+ "Content-type: application/octet-stream",
|
||||
+ NULL,
|
||||
+ };
|
||||
+
|
||||
+ requests = talloc_zero_array(mem_ctx, struct tcurl_request *, MAXREQ + 1);
|
||||
+ if (requests == NULL) {
|
||||
+ return ENOMEM;
|
||||
}
|
||||
|
||||
- while ((extra_arg_ptr = poptGetArg(pc)) != NULL) {
|
||||
- switch(method) {
|
||||
+ i = 0;
|
||||
+ while ((arg = poptGetArg(pc)) != NULL) {
|
||||
+ if (i >= MAXREQ) {
|
||||
+ fprintf(stderr, _("Too many requests!\n"));
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ switch (opts->method) {
|
||||
case TCURL_HTTP_GET:
|
||||
case TCURL_HTTP_DELETE:
|
||||
- case TCURL_HTTP_POST:
|
||||
- urls[n_reqs++] = extra_arg_ptr;
|
||||
+ url = arg;
|
||||
+ body = NULL;
|
||||
break;
|
||||
case TCURL_HTTP_PUT:
|
||||
- if (urls[n_reqs] == NULL) {
|
||||
- urls[n_reqs] = extra_arg_ptr;
|
||||
- } else {
|
||||
- inbufs[n_reqs] = sss_iobuf_init_readonly(
|
||||
- inbufs,
|
||||
- (uint8_t *) discard_const(extra_arg_ptr),
|
||||
- strlen(extra_arg_ptr));
|
||||
- if (inbufs[n_reqs] == NULL) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Could not init input buffer\n");
|
||||
- talloc_zfree(tool_ctx);
|
||||
- return 1;
|
||||
- }
|
||||
- n_reqs++;
|
||||
+ case TCURL_HTTP_POST:
|
||||
+ url = arg;
|
||||
+
|
||||
+ arg = poptGetArg(pc);
|
||||
+ if (arg == NULL) {
|
||||
+ body = NULL;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ body = sss_iobuf_init_readonly(requests,
|
||||
+ discard_const_p(uint8_t, arg),
|
||||
+ strlen(arg));
|
||||
+ if (body == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
}
|
||||
break;
|
||||
+ default:
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid method!\n");
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
}
|
||||
+
|
||||
+ requests[i] = tcurl_http(requests, opts->method, opts->socket_path,
|
||||
+ url, headers, body);
|
||||
+ if (requests[i] == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ i++;
|
||||
}
|
||||
|
||||
- if (opt != -1) {
|
||||
- poptPrintUsage(pc, stderr, 0);
|
||||
- fprintf(stderr, "%s", poptStrerror(opt));
|
||||
- talloc_zfree(tool_ctx);
|
||||
- return 1;
|
||||
+ *_requests = requests;
|
||||
+ *_num_requests = i;
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ if (ret != EOK) {
|
||||
+ talloc_free(requests);
|
||||
}
|
||||
|
||||
- if (!socket_path) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE, "Please specify the socket path\n");
|
||||
- poptPrintUsage(pc, stderr, 0);
|
||||
- talloc_zfree(tool_ctx);
|
||||
- return 1;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static errno_t
|
||||
+run_requests(struct tool_ctx *tool_ctx,
|
||||
+ struct tcurl_request **requests)
|
||||
+{
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ struct tcurl_ctx *tcurl_ctx;
|
||||
+ struct tevent_context *ev;
|
||||
+ struct tevent_req *req;
|
||||
+ errno_t ret;
|
||||
+ int i;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n");
|
||||
+ return ENOMEM;
|
||||
}
|
||||
|
||||
- tool_ctx->nreqs = n_reqs;
|
||||
- tool_ctx->verbose = !!pc_verbose;
|
||||
+ if (requests == NULL || requests[0] == NULL) {
|
||||
+ ret = EOK;
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
- ev = tevent_context_init(tool_ctx);
|
||||
+ ev = tevent_context_init(tmp_ctx);
|
||||
if (ev == NULL) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Could not init tevent context\n");
|
||||
- talloc_zfree(tool_ctx);
|
||||
- return 1;
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
- ctx = tcurl_init(tool_ctx, ev);
|
||||
- if (ctx == NULL) {
|
||||
+ tcurl_ctx = tcurl_init(tmp_ctx, ev);
|
||||
+ if (tcurl_ctx == NULL) {
|
||||
DEBUG(SSSDBG_FATAL_FAILURE, "Could not init tcurl context\n");
|
||||
- talloc_zfree(tool_ctx);
|
||||
- return 1;
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
- for (size_t i = 0; i < n_reqs; i++) {
|
||||
- tcurl_req = tcurl_http(tool_ctx, method, socket_path,
|
||||
- urls[i], headers, inbufs[i]);
|
||||
- if (tcurl_req == NULL) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE, "Unable to create TCURL request\n");
|
||||
- talloc_zfree(tool_ctx);
|
||||
- return 1;
|
||||
+ for (i = 0; requests[i] != NULL; i++) {
|
||||
+ req = tcurl_request_send(tmp_ctx, ev, tcurl_ctx, requests[i], 5);
|
||||
+ if (req == NULL) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "Could not create tevent request\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
- req = tcurl_request_send(tool_ctx, ev, ctx, tcurl_req, 10);
|
||||
- if (ctx == NULL) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE, "Could not create request\n");
|
||||
- talloc_zfree(tool_ctx);
|
||||
- return 1;
|
||||
- }
|
||||
tevent_req_set_callback(req, request_done, tool_ctx);
|
||||
}
|
||||
|
||||
@@ -226,11 +243,78 @@ int main(int argc, const char *argv[])
|
||||
if (tool_ctx->nreqs > 0) {
|
||||
DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
"The tool finished with some pending requests, fail!\n");
|
||||
- talloc_zfree(tool_ctx);
|
||||
- return 1;
|
||||
+ ret = EEXIST;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int main(int argc, const char *argv[])
|
||||
+{
|
||||
+ struct tool_options opts = { 0 };
|
||||
+ struct tool_ctx *tool_ctx;
|
||||
+ struct tcurl_request **requests;
|
||||
+ poptContext pc;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ struct poptOption long_options[] = {
|
||||
+ POPT_AUTOHELP
|
||||
+ { "debug", '\0', POPT_ARG_INT, &opts.debug, 0, "The debug level to run with", NULL },
|
||||
+ { "socket-path", 's', POPT_ARG_STRING, &opts.socket_path, 0, "The path to the HTTP server socket", NULL },
|
||||
+ { "get", 'g', POPT_ARG_NONE, NULL, 'g', "Perform a HTTP GET (default)", NULL },
|
||||
+ { "put", 'p', POPT_ARG_NONE, NULL, 'p', "Perform a HTTP PUT", NULL },
|
||||
+ { "post", 'o', POPT_ARG_NONE, NULL, 'o', "Perform a HTTP POST", NULL },
|
||||
+ { "del", 'd', POPT_ARG_NONE, NULL, 'd', "Perform a HTTP DELETE", NULL },
|
||||
+ { "verbose", 'v', POPT_ARG_NONE, &opts.verbose, '\0', "Print response code and body", NULL },
|
||||
+ POPT_TABLEEND
|
||||
+ };
|
||||
+
|
||||
+ pc = poptGetContext(NULL, argc, argv, long_options, 0);
|
||||
+ poptSetOtherOptionHelp(pc, "[URL HTTPDATA]*");
|
||||
+
|
||||
+ tool_ctx = talloc_zero(NULL, struct tool_ctx);
|
||||
+ if (tool_ctx == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Could not init tool context\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = parse_options(pc, &opts);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to parse options [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG_CLI_INIT(opts.debug);
|
||||
+ tool_ctx->verbose = opts.verbose;
|
||||
+
|
||||
+ ret = prepare_requests(tool_ctx, pc, &opts, &requests, &tool_ctx->nreqs);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to prepare requests [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = run_requests(tool_ctx, requests);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to issue requests [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
talloc_free(tool_ctx);
|
||||
poptFreeContext(pc);
|
||||
- return 0;
|
||||
+
|
||||
+ if (ret != EOK) {
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ return EXIT_SUCCESS;
|
||||
}
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,48 +0,0 @@
|
||||
From 36e49a842e257ac9bde71728ee3bef4299b6e6e2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Fri, 24 Feb 2017 12:23:22 +0100
|
||||
Subject: [PATCH 79/97] tcurl test: add support for raw output
|
||||
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/tests/tcurl_test_tool.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/src/tests/tcurl_test_tool.c b/src/tests/tcurl_test_tool.c
|
||||
index e5fc9705db415650d849b89c3d18e41574b7e28b..7d3bc19f0ec7e118e251247536d25c58fe009f54 100644
|
||||
--- a/src/tests/tcurl_test_tool.c
|
||||
+++ b/src/tests/tcurl_test_tool.c
|
||||
@@ -36,6 +36,7 @@ struct tool_ctx {
|
||||
struct tool_options {
|
||||
int debug;
|
||||
int verbose;
|
||||
+ int raw;
|
||||
|
||||
enum tcurl_http_method method;
|
||||
const char *socket_path;
|
||||
@@ -173,6 +174,13 @@ prepare_requests(TALLOC_CTX *mem_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ if (opts->raw) {
|
||||
+ ret = tcurl_req_enable_rawoutput(requests[i]);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -270,6 +278,7 @@ int main(int argc, const char *argv[])
|
||||
{ "put", 'p', POPT_ARG_NONE, NULL, 'p', "Perform a HTTP PUT", NULL },
|
||||
{ "post", 'o', POPT_ARG_NONE, NULL, 'o', "Perform a HTTP POST", NULL },
|
||||
{ "del", 'd', POPT_ARG_NONE, NULL, 'd', "Perform a HTTP DELETE", NULL },
|
||||
+ { "raw", 'r', POPT_ARG_NONE, &opts.raw, '\0', "Print raw protocol output", NULL },
|
||||
{ "verbose", 'v', POPT_ARG_NONE, &opts.verbose, '\0', "Print response code and body", NULL },
|
||||
POPT_TABLEEND
|
||||
};
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,61 +0,0 @@
|
||||
From 886e0f75e6f4c7877a23a3625f8a20c09109b09d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Mon, 27 Feb 2017 12:58:06 +0100
|
||||
Subject: [PATCH 80/97] tcurl test: add support for tls settings
|
||||
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/tests/tcurl_test_tool.c | 19 +++++++++++++++++++
|
||||
1 file changed, 19 insertions(+)
|
||||
|
||||
diff --git a/src/tests/tcurl_test_tool.c b/src/tests/tcurl_test_tool.c
|
||||
index 7d3bc19f0ec7e118e251247536d25c58fe009f54..9cec000fbf2e4eca2fdc5213c8b3b4cb10f1df1b 100644
|
||||
--- a/src/tests/tcurl_test_tool.c
|
||||
+++ b/src/tests/tcurl_test_tool.c
|
||||
@@ -37,9 +37,14 @@ struct tool_options {
|
||||
int debug;
|
||||
int verbose;
|
||||
int raw;
|
||||
+ int tls;
|
||||
+ int verify_peer;
|
||||
+ int verify_host;
|
||||
|
||||
enum tcurl_http_method method;
|
||||
const char *socket_path;
|
||||
+ const char *capath;
|
||||
+ const char *cacert;
|
||||
};
|
||||
|
||||
static void request_done(struct tevent_req *req)
|
||||
@@ -181,6 +186,14 @@ prepare_requests(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
+ if (opts->tls) {
|
||||
+ ret = tcurl_req_verify_peer(requests[i], opts->capath, opts->cacert,
|
||||
+ opts->verify_peer, opts->verify_host);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -280,6 +293,12 @@ int main(int argc, const char *argv[])
|
||||
{ "del", 'd', POPT_ARG_NONE, NULL, 'd', "Perform a HTTP DELETE", NULL },
|
||||
{ "raw", 'r', POPT_ARG_NONE, &opts.raw, '\0', "Print raw protocol output", NULL },
|
||||
{ "verbose", 'v', POPT_ARG_NONE, &opts.verbose, '\0', "Print response code and body", NULL },
|
||||
+ /* TLS */
|
||||
+ { "tls", '\0', POPT_ARG_NONE, &opts.tls, '\0', "Enable TLS", NULL },
|
||||
+ { "verify-peer", '\0', POPT_ARG_NONE, &opts.verify_peer, '\0', "Verify peer when TLS is enabled", NULL },
|
||||
+ { "verify-host", '\0', POPT_ARG_NONE, &opts.verify_host, '\0', "Verify host when TLS is enabled", NULL },
|
||||
+ { "capath", '\0', POPT_ARG_STRING, &opts.capath, '\0', "Path to CA directory where peer certificate is stored", NULL },
|
||||
+ { "cacert", '\0', POPT_ARG_STRING, &opts.cacert, '\0', "Path to CA certificate", NULL },
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,111 +0,0 @@
|
||||
From c2ea75da72b426d98ba489039e220d417bfb4c2a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Tue, 28 Feb 2017 13:32:31 +0100
|
||||
Subject: [PATCH 81/97] tcurl: add support for http basic auth
|
||||
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/tests/tcurl_test_tool.c | 14 ++++++++++++++
|
||||
src/util/tev_curl.c | 24 ++++++++++++++++++++++++
|
||||
src/util/tev_curl.h | 15 +++++++++++++++
|
||||
3 files changed, 53 insertions(+)
|
||||
|
||||
diff --git a/src/tests/tcurl_test_tool.c b/src/tests/tcurl_test_tool.c
|
||||
index 9cec000fbf2e4eca2fdc5213c8b3b4cb10f1df1b..4ceef8e06040ea0abd4d112a5b7845f436c69488 100644
|
||||
--- a/src/tests/tcurl_test_tool.c
|
||||
+++ b/src/tests/tcurl_test_tool.c
|
||||
@@ -45,6 +45,9 @@ struct tool_options {
|
||||
const char *socket_path;
|
||||
const char *capath;
|
||||
const char *cacert;
|
||||
+
|
||||
+ const char *username;
|
||||
+ const char *password;
|
||||
};
|
||||
|
||||
static void request_done(struct tevent_req *req)
|
||||
@@ -194,6 +197,14 @@ prepare_requests(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
+ if (opts->username != NULL && opts->password != NULL) {
|
||||
+ ret = tcurl_req_http_basic_auth(requests[i], opts->username,
|
||||
+ opts->password);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -299,6 +310,9 @@ int main(int argc, const char *argv[])
|
||||
{ "verify-host", '\0', POPT_ARG_NONE, &opts.verify_host, '\0', "Verify host when TLS is enabled", NULL },
|
||||
{ "capath", '\0', POPT_ARG_STRING, &opts.capath, '\0', "Path to CA directory where peer certificate is stored", NULL },
|
||||
{ "cacert", '\0', POPT_ARG_STRING, &opts.cacert, '\0', "Path to CA certificate", NULL },
|
||||
+ /* BASIC AUTH */
|
||||
+ { "username", '\0', POPT_ARG_STRING, &opts.username, '\0', "Username for basic authentication", NULL },
|
||||
+ { "password", '\0', POPT_ARG_STRING, &opts.password, '\0', "Password for basic authentication", NULL },
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
diff --git a/src/util/tev_curl.c b/src/util/tev_curl.c
|
||||
index c155f4c038d4215933ee30d41c694ad4a14ae132..8faf07c714b636a0351be365597de68d2f68a1be 100644
|
||||
--- a/src/util/tev_curl.c
|
||||
+++ b/src/util/tev_curl.c
|
||||
@@ -1092,3 +1092,27 @@ errno_t tcurl_req_set_client_cert(struct tcurl_request *tcurl_req,
|
||||
|
||||
return EOK;
|
||||
}
|
||||
+
|
||||
+errno_t tcurl_req_http_basic_auth(struct tcurl_request *tcurl_req,
|
||||
+ const char *username,
|
||||
+ const char *password)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = tcurl_set_option(tcurl_req, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = tcurl_set_option(tcurl_req, CURLOPT_USERNAME, username);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = tcurl_set_option(tcurl_req, CURLOPT_PASSWORD, password);
|
||||
+ if (ret != EOK) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
diff --git a/src/util/tev_curl.h b/src/util/tev_curl.h
|
||||
index 933abcb9b531412737e8fcf391644d828b125cf8..c733127b3686b5665f53cf53ea72674e0d7af64e 100644
|
||||
--- a/src/util/tev_curl.h
|
||||
+++ b/src/util/tev_curl.h
|
||||
@@ -243,4 +243,19 @@ errno_t tcurl_req_set_client_cert(struct tcurl_request *tcurl_req,
|
||||
const char *cert,
|
||||
const char *key);
|
||||
|
||||
+/**
|
||||
+ * @brief Force HTTP basic authentication with @username and @password.
|
||||
+ *
|
||||
+ * @param[in] tcurl_request
|
||||
+ * @param[in] username
|
||||
+ * @param[in] password
|
||||
+ *
|
||||
+ * @returns errno code
|
||||
+ *
|
||||
+ * @see tcurl_http
|
||||
+ */
|
||||
+errno_t tcurl_req_http_basic_auth(struct tcurl_request *tcurl_req,
|
||||
+ const char *username,
|
||||
+ const char *password);
|
||||
+
|
||||
#endif /* __TEV_CURL_H */
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,62 +0,0 @@
|
||||
From d1ed11fc50922aab2332758a9300f3fbf814f112 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Fri, 10 Mar 2017 12:11:12 +0100
|
||||
Subject: [PATCH 82/97] tcurl test: allow to set custom headers
|
||||
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/tests/tcurl_test_tool.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/tests/tcurl_test_tool.c b/src/tests/tcurl_test_tool.c
|
||||
index 4ceef8e06040ea0abd4d112a5b7845f436c69488..63a3e26b561781795873c2a4d72ac071a4da9939 100644
|
||||
--- a/src/tests/tcurl_test_tool.c
|
||||
+++ b/src/tests/tcurl_test_tool.c
|
||||
@@ -40,6 +40,7 @@ struct tool_options {
|
||||
int tls;
|
||||
int verify_peer;
|
||||
int verify_host;
|
||||
+ const char **headers;
|
||||
|
||||
enum tcurl_http_method method;
|
||||
const char *socket_path;
|
||||
@@ -121,13 +122,14 @@ prepare_requests(TALLOC_CTX *mem_ctx,
|
||||
size_t *_num_requests)
|
||||
{
|
||||
struct tcurl_request **requests;
|
||||
+ struct sss_iobuf *body;
|
||||
+ const char **headers;
|
||||
const char *arg;
|
||||
const char *url;
|
||||
- struct sss_iobuf *body;
|
||||
errno_t ret;
|
||||
size_t i;
|
||||
|
||||
- static const char *headers[] = {
|
||||
+ static const char *default_headers[] = {
|
||||
"Content-type: application/octet-stream",
|
||||
NULL,
|
||||
};
|
||||
@@ -137,6 +139,8 @@ prepare_requests(TALLOC_CTX *mem_ctx,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
+ headers = opts->headers == NULL ? default_headers : opts->headers;
|
||||
+
|
||||
i = 0;
|
||||
while ((arg = poptGetArg(pc)) != NULL) {
|
||||
if (i >= MAXREQ) {
|
||||
@@ -302,6 +306,9 @@ int main(int argc, const char *argv[])
|
||||
{ "put", 'p', POPT_ARG_NONE, NULL, 'p', "Perform a HTTP PUT", NULL },
|
||||
{ "post", 'o', POPT_ARG_NONE, NULL, 'o', "Perform a HTTP POST", NULL },
|
||||
{ "del", 'd', POPT_ARG_NONE, NULL, 'd', "Perform a HTTP DELETE", NULL },
|
||||
+#ifdef POPT_ARG_ARGV
|
||||
+ { "header", 'h', POPT_ARG_ARGV, &opts.headers, '\0', "Add HTTP header", NULL },
|
||||
+#endif
|
||||
{ "raw", 'r', POPT_ARG_NONE, &opts.raw, '\0', "Print raw protocol output", NULL },
|
||||
{ "verbose", 'v', POPT_ARG_NONE, &opts.verbose, '\0', "Print response code and body", NULL },
|
||||
/* TLS */
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,52 +0,0 @@
|
||||
From ae6b11229d9961e26922918183c7c1de7780b8d6 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Mon, 13 Mar 2017 13:30:48 +0100
|
||||
Subject: [PATCH 83/97] tcurl test: add support for client certificate
|
||||
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/tests/tcurl_test_tool.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/src/tests/tcurl_test_tool.c b/src/tests/tcurl_test_tool.c
|
||||
index 63a3e26b561781795873c2a4d72ac071a4da9939..fbc2790357b131ebb21b4be041688e5f699d73e7 100644
|
||||
--- a/src/tests/tcurl_test_tool.c
|
||||
+++ b/src/tests/tcurl_test_tool.c
|
||||
@@ -47,6 +47,9 @@ struct tool_options {
|
||||
const char *capath;
|
||||
const char *cacert;
|
||||
|
||||
+ const char *clientcert;
|
||||
+ const char *clientkey;
|
||||
+
|
||||
const char *username;
|
||||
const char *password;
|
||||
};
|
||||
@@ -201,6 +204,14 @@ prepare_requests(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
+ if (opts->clientcert != NULL) {
|
||||
+ ret = tcurl_req_set_client_cert(requests[i], opts->clientcert,
|
||||
+ opts->clientkey);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (opts->username != NULL && opts->password != NULL) {
|
||||
ret = tcurl_req_http_basic_auth(requests[i], opts->username,
|
||||
opts->password);
|
||||
@@ -317,6 +328,8 @@ int main(int argc, const char *argv[])
|
||||
{ "verify-host", '\0', POPT_ARG_NONE, &opts.verify_host, '\0', "Verify host when TLS is enabled", NULL },
|
||||
{ "capath", '\0', POPT_ARG_STRING, &opts.capath, '\0', "Path to CA directory where peer certificate is stored", NULL },
|
||||
{ "cacert", '\0', POPT_ARG_STRING, &opts.cacert, '\0', "Path to CA certificate", NULL },
|
||||
+ { "clientcert", '\0', POPT_ARG_STRING, &opts.clientcert, '\0', "Path to client's certificate", NULL },
|
||||
+ { "clientkey", '\0', POPT_ARG_STRING, &opts.clientkey, '\0', "Path to client's private key", NULL },
|
||||
/* BASIC AUTH */
|
||||
{ "username", '\0', POPT_ARG_STRING, &opts.username, '\0', "Username for basic authentication", NULL },
|
||||
{ "password", '\0', POPT_ARG_STRING, &opts.password, '\0', "Password for basic authentication", NULL },
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,114 +0,0 @@
|
||||
From 6698d40512e55e7c2d03e14c227c51b1edc77ffa Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Tue, 28 Mar 2017 15:24:01 +0200
|
||||
Subject: [PATCH 84/97] ci: do not build secrets on rhel6
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We require newer libcurl version than is available on rhel6. We don't
|
||||
ship secrets responder in rhel6 so we just disable its build.
|
||||
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
contrib/ci/configure.sh | 1 +
|
||||
contrib/sssd.spec.in | 15 +++++++++++++++
|
||||
src/tests/intg/test_secrets.py | 4 ++++
|
||||
3 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/contrib/ci/configure.sh b/contrib/ci/configure.sh
|
||||
index 7590743c2aa5fe31bcdf1a3e92a3f482dbec699b..9d18d0c187561a2dc3bc47d3e8913626e7ff3046 100644
|
||||
--- a/contrib/ci/configure.sh
|
||||
+++ b/contrib/ci/configure.sh
|
||||
@@ -38,6 +38,7 @@ if [[ "$DISTRO_BRANCH" == -redhat-redhatenterprise*-6.*- ||
|
||||
"--disable-cifs-idmap-plugin"
|
||||
"--with-syslog=syslog"
|
||||
"--without-python3-bindings"
|
||||
+ "--without-secrets"
|
||||
"--without-kcm"
|
||||
)
|
||||
fi
|
||||
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
|
||||
index af14d4e3d6b9ffeb4696f1517113b8daa575cb99..39a974edebba3dbcd7625d1729b4a7330eaa8a27 100644
|
||||
--- a/contrib/sssd.spec.in
|
||||
+++ b/contrib/sssd.spec.in
|
||||
@@ -112,6 +112,12 @@
|
||||
%global enable_systemtap_opt --enable-systemtap
|
||||
%endif
|
||||
|
||||
+%if (0%{?fedora} || 0%{?epel} >= 7)
|
||||
+ %global with_secrets 1
|
||||
+%else
|
||||
+ %global with_secret_responder --without-secrets
|
||||
+%endif
|
||||
+
|
||||
%if (0%{?fedora} >= 23 || 0%{?rhel} >= 7)
|
||||
%global with_kcm 1
|
||||
%global with_kcm_option --with-kcm
|
||||
@@ -220,8 +226,10 @@ BuildRequires: libsmbclient-devel
|
||||
%if (0%{?enable_systemtap} == 1)
|
||||
BuildRequires: systemtap-sdt-devel
|
||||
%endif
|
||||
+%if (0%{?with_secrets} == 1)
|
||||
BuildRequires: http-parser-devel
|
||||
BuildRequires: jansson-devel
|
||||
+%endif
|
||||
BuildRequires: libuuid-devel
|
||||
BuildRequires: libcurl-devel
|
||||
|
||||
@@ -727,6 +735,7 @@ autoreconf -ivf
|
||||
%{?with_python3_option} \
|
||||
%{?enable_polkit_rules_option} \
|
||||
%{?enable_systemtap_opt} \
|
||||
+ %{?with_secret_responder} \
|
||||
%{?with_kcm_option} \
|
||||
%{?experimental}
|
||||
|
||||
@@ -865,7 +874,9 @@ done
|
||||
%{_libexecdir}/%{servicename}/sssd_nss
|
||||
%{_libexecdir}/%{servicename}/sssd_pam
|
||||
%{_libexecdir}/%{servicename}/sssd_autofs
|
||||
+%if (0%{?with_secrets} == 1)
|
||||
%{_libexecdir}/%{servicename}/sssd_secrets
|
||||
+%endif
|
||||
%{_libexecdir}/%{servicename}/sssd_ssh
|
||||
%{_libexecdir}/%{servicename}/sssd_sudo
|
||||
%{_libexecdir}/%{servicename}/p11_child
|
||||
@@ -900,7 +911,9 @@ done
|
||||
%dir %{_localstatedir}/cache/krb5rcache
|
||||
%attr(700,sssd,sssd) %dir %{dbpath}
|
||||
%attr(755,sssd,sssd) %dir %{mcpath}
|
||||
+%if (0%{?with_secrets} == 1)
|
||||
%attr(700,root,root) %dir %{secdbpath}
|
||||
+%endif
|
||||
%ghost %attr(0644,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/passwd
|
||||
%ghost %attr(0644,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/group
|
||||
%ghost %attr(0644,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/initgroups
|
||||
@@ -933,7 +946,9 @@ done
|
||||
%{_mandir}/man5/sssd.conf.5*
|
||||
%{_mandir}/man5/sssd-simple.5*
|
||||
%{_mandir}/man5/sssd-sudo.5*
|
||||
+%if (0%{?with_secrets} == 1)
|
||||
%{_mandir}/man5/sssd-secrets.5*
|
||||
+%endif
|
||||
%{_mandir}/man5/sss_rpcidmapd.5*
|
||||
%{_mandir}/man8/sssd.8*
|
||||
%{_mandir}/man8/sss_cache.8*
|
||||
diff --git a/src/tests/intg/test_secrets.py b/src/tests/intg/test_secrets.py
|
||||
index d71c1904558cc6f8a6eee36c4049582705bc30ac..202f43e61cb0e4986394ad2b32da5abdcb0be3e9 100644
|
||||
--- a/src/tests/intg/test_secrets.py
|
||||
+++ b/src/tests/intg/test_secrets.py
|
||||
@@ -46,6 +46,10 @@ def create_sssd_secrets_fixture(request):
|
||||
raise Exception("failed to regenerate confdb")
|
||||
|
||||
resp_path = os.path.join(config.LIBEXEC_PATH, "sssd", "sssd_secrets")
|
||||
+ if not os.access(resp_path, os.X_OK):
|
||||
+ # It would be cleaner to use pytest.mark.skipif on the package level
|
||||
+ # but upstream insists on supporting RHEL-6.
|
||||
+ pytest.skip("No Secrets responder, skipping")
|
||||
|
||||
secpid = os.fork()
|
||||
assert secpid >= 0
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,64 +0,0 @@
|
||||
From 793f2573b2beaf8b48eab850429482acf68ec2b1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Wed, 22 Mar 2017 12:32:31 +0100
|
||||
Subject: [PATCH 85/97] build: make curl required by secrets
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Also remove --disable-libcurl since it doesn't make sense.
|
||||
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
configure.ac | 6 +++++-
|
||||
src/external/libcurl.m4 | 16 ++--------------
|
||||
2 files changed, 7 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index cf5e2557ef0a1bd6374200aa33abea6c509d03aa..80d8ea9ff5785b0d76edbb04f454d0dd8c8a1e6d 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -201,9 +201,13 @@ if test x$with_secrets = xyes; then
|
||||
fi
|
||||
|
||||
if test x$with_kcm = xyes; then
|
||||
- m4_include([src/external/libcurl.m4])
|
||||
m4_include([src/external/libuuid.m4])
|
||||
fi
|
||||
+
|
||||
+if test x$with_kcm = xyes -o x$with_secrets = xyes; then
|
||||
+ m4_include([src/external/libcurl.m4])
|
||||
+fi
|
||||
+
|
||||
# This variable is defined by external/libcurl.m4, but conditionals
|
||||
# must be always evaluated
|
||||
AM_CONDITIONAL([BUILD_WITH_LIBCURL],
|
||||
diff --git a/src/external/libcurl.m4 b/src/external/libcurl.m4
|
||||
index b420b04ad806bd1251f086b773ffe480d39f8bd3..42be308cd1e4b04e736daf887be9b75ea92db80e 100644
|
||||
--- a/src/external/libcurl.m4
|
||||
+++ b/src/external/libcurl.m4
|
||||
@@ -1,17 +1,5 @@
|
||||
-AC_ARG_ENABLE([curl],
|
||||
- [AS_HELP_STRING([--disable-curl-support],
|
||||
- [do not build with libcurl support])],
|
||||
- [enable_libcurl=$enableval],
|
||||
- [enable_libcurl=yes])
|
||||
-
|
||||
-found_libcurl="no"
|
||||
-AS_IF([test x$enable_libcurl = xyes],
|
||||
- [PKG_CHECK_MODULES([CURL],
|
||||
- [libcurl],
|
||||
- [found_libcurl=yes],
|
||||
- [AC_MSG_ERROR([
|
||||
-The libcurl development library was not found.])
|
||||
- ])])
|
||||
+PKG_CHECK_MODULES([CURL], [libcurl], [found_libcurl=yes],
|
||||
+ [AC_MSG_ERROR([The libcurl development library was not found.])])
|
||||
|
||||
AS_IF([test x"$found_libcurl" = xyes],
|
||||
CFLAGS="$CFLAGS $CURL_CFLAGS"
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,458 +0,0 @@
|
||||
From df99d709c8cbef3c378c111944d83b7345e4c1ea Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Wed, 22 Feb 2017 10:38:56 +0100
|
||||
Subject: [PATCH 86/97] secrets: use tcurl in proxy provider
|
||||
|
||||
We switch from http-parser to libcurl for an http client. This gaves us many
|
||||
features for free such as tls and http basic authentication support instead
|
||||
of implementing it on our own.
|
||||
|
||||
Resolves:
|
||||
https://pagure.io/SSSD/sssd/issue/3192
|
||||
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
Makefile.am | 3 +
|
||||
src/responder/secrets/providers.c | 20 +++
|
||||
src/responder/secrets/proxy.c | 246 ++++++++++++++++++++++-----------
|
||||
src/responder/secrets/secsrv_private.h | 5 +
|
||||
4 files changed, 191 insertions(+), 83 deletions(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 573b37c52fdeab1add4ea057e1e1844ea4d348a5..4a414f77df999b8b1d81f663fcc18dbd2d6d2dc4 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -1486,6 +1486,8 @@ sssd_secrets_SOURCES = \
|
||||
src/responder/secrets/local.c \
|
||||
src/responder/secrets/proxy.c \
|
||||
src/util/sss_sockets.c \
|
||||
+ src/util/sss_iobuf.c \
|
||||
+ src/util/tev_curl.c \
|
||||
$(SSSD_RESPONDER_OBJ) \
|
||||
$(SSSD_RESOLV_OBJ) \
|
||||
$(NULL)
|
||||
@@ -1497,6 +1499,7 @@ sssd_secrets_LDADD = \
|
||||
$(SYSTEMD_DAEMON_LIBS) \
|
||||
$(CARES_LIBS) \
|
||||
$(SSSD_INTERNAL_LTLIBS) \
|
||||
+ $(CURL_LIBS) \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
diff --git a/src/responder/secrets/providers.c b/src/responder/secrets/providers.c
|
||||
index 94831c73036d269addca45c0117811a2c68873fd..80a443d91135447ec8ce8d424b692a6d7e26a907 100644
|
||||
--- a/src/responder/secrets/providers.c
|
||||
+++ b/src/responder/secrets/providers.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "responder/secrets/secsrv_private.h"
|
||||
#include "responder/secrets/secsrv_local.h"
|
||||
#include "responder/secrets/secsrv_proxy.h"
|
||||
+#include "util/sss_iobuf.h"
|
||||
#include <jansson.h>
|
||||
|
||||
typedef int (*url_mapper_fn)(struct sec_req_ctx *secreq,
|
||||
@@ -387,6 +388,25 @@ int sec_http_reply_with_headers(TALLOC_CTX *mem_ctx, struct sec_data *reply,
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+errno_t sec_http_reply_iobuf(TALLOC_CTX *mem_ctx,
|
||||
+ struct sec_data *reply,
|
||||
+ int response_code,
|
||||
+ struct sss_iobuf *response)
|
||||
+{
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "HTTP reply %d\n", response_code);
|
||||
+
|
||||
+ reply->data = (char *)sss_iobuf_get_data(response);
|
||||
+ reply->length = sss_iobuf_get_len(response);
|
||||
+
|
||||
+ talloc_steal(mem_ctx, reply->data);
|
||||
+
|
||||
+ if (reply->data == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
enum sec_http_status_codes sec_errno_to_http_status(errno_t err)
|
||||
{
|
||||
DEBUG(SSSDBG_TRACE_LIBS, "Request errno: %d\n", err);
|
||||
diff --git a/src/responder/secrets/proxy.c b/src/responder/secrets/proxy.c
|
||||
index 3ed03e6086d0de0f6f80de227ffc65ef4067db4f..fe2f0134e233d9a98f499fe563abe0af69762514 100644
|
||||
--- a/src/responder/secrets/proxy.c
|
||||
+++ b/src/responder/secrets/proxy.c
|
||||
@@ -23,10 +23,15 @@
|
||||
#include "util/crypto/sss_crypto.h"
|
||||
#include "resolv/async_resolv.h"
|
||||
#include "util/sss_sockets.h"
|
||||
+#include "util/sss_iobuf.h"
|
||||
+#include "util/tev_curl.h"
|
||||
+
|
||||
+#define SEC_PROXY_TIMEOUT 5
|
||||
|
||||
struct proxy_context {
|
||||
struct resolv_ctx *resctx;
|
||||
struct confdb_ctx *cdb;
|
||||
+ struct tcurl_ctx *tcurl;
|
||||
};
|
||||
|
||||
enum proxy_auth_type {
|
||||
@@ -216,103 +221,177 @@ int proxy_sec_map_url(TALLOC_CTX *mem_ctx, struct sec_req_ctx *secreq,
|
||||
return EOK;
|
||||
}
|
||||
|
||||
-int proxy_sec_map_headers(TALLOC_CTX *mem_ctx, struct sec_req_ctx *secreq,
|
||||
- struct proxy_cfg *pcfg, char **req_headers)
|
||||
+static errno_t proxy_http_append_header(TALLOC_CTX *mem_ctx,
|
||||
+ const char *name,
|
||||
+ const char *value,
|
||||
+ const char ***_headers,
|
||||
+ size_t *_num_headers)
|
||||
{
|
||||
- int ret;
|
||||
-
|
||||
- for (int i = 0; i < secreq->num_headers; i++) {
|
||||
- bool forward = false;
|
||||
- for (int j = 0; pcfg->fwd_headers[j]; j++) {
|
||||
- if (strcasecmp(secreq->headers[i].name,
|
||||
- pcfg->fwd_headers[j]) == 0) {
|
||||
- forward = true;
|
||||
+ const char **headers = *_headers;
|
||||
+ size_t num_headers = *_num_headers;
|
||||
+
|
||||
+ num_headers++;
|
||||
+ headers = talloc_realloc(mem_ctx, headers, const char *,
|
||||
+ num_headers + 1);
|
||||
+ if (headers == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ headers[num_headers - 1] = talloc_asprintf(headers, "%s: %s", name, value);
|
||||
+ if (headers[num_headers - 1] == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ headers[num_headers] = NULL;
|
||||
+
|
||||
+ *_headers = headers;
|
||||
+ *_num_headers = num_headers;
|
||||
+
|
||||
+ return EOK;
|
||||
+}
|
||||
+
|
||||
+static const char **
|
||||
+proxy_http_create_headers(TALLOC_CTX *mem_ctx,
|
||||
+ struct sec_req_ctx *secreq,
|
||||
+ struct proxy_cfg *pcfg)
|
||||
+{
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ const char **headers;
|
||||
+ size_t num_headers;
|
||||
+ errno_t ret;
|
||||
+ int i, j;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ headers = talloc_zero_array(tmp_ctx, const char *, 1);
|
||||
+ if (headers == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ num_headers = 0;
|
||||
+ for (i = 0; i < secreq->num_headers; i++) {
|
||||
+ for (j = 0; pcfg->fwd_headers[j]; j++) {
|
||||
+ if (strcasecmp(secreq->headers[i].name, pcfg->fwd_headers[j]) == 0) {
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "Forwarding header %s: %s\n",
|
||||
+ secreq->headers[i].name, secreq->headers[i].value);
|
||||
+
|
||||
+ ret = proxy_http_append_header(tmp_ctx, secreq->headers[i].name,
|
||||
+ secreq->headers[i].value,
|
||||
+ &headers, &num_headers);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
break;
|
||||
}
|
||||
}
|
||||
- if (forward) {
|
||||
- DEBUG(SSSDBG_TRACE_LIBS, "Forwarding header %s:%s\n",
|
||||
- secreq->headers[i].name, secreq->headers[i].value);
|
||||
-
|
||||
- ret = sec_http_append_header(mem_ctx, req_headers,
|
||||
- secreq->headers[i].name,
|
||||
- secreq->headers[i].value);
|
||||
- if (ret) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- "Couldn't append header %s\n", secreq->headers[i].name);
|
||||
- return ret;
|
||||
- }
|
||||
- }
|
||||
}
|
||||
|
||||
if (pcfg->auth_type == PAT_HEADER) {
|
||||
- DEBUG(SSSDBG_TRACE_LIBS,
|
||||
- "Forwarding header %s\n", pcfg->auth.header.name);
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "Forwarding header %s\n",
|
||||
+ pcfg->auth.header.name);
|
||||
|
||||
- ret = sec_http_append_header(mem_ctx, req_headers,
|
||||
- pcfg->auth.header.name,
|
||||
- pcfg->auth.header.value);
|
||||
- if (ret) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- "Couldn't append header %s\n", pcfg->auth.header.name);
|
||||
- return ret;
|
||||
+ ret = proxy_http_append_header(tmp_ctx, pcfg->auth.header.name,
|
||||
+ pcfg->auth.header.value,
|
||||
+ &headers, &num_headers);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
}
|
||||
}
|
||||
|
||||
- return EOK;
|
||||
+ talloc_steal(mem_ctx, headers);
|
||||
+
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+
|
||||
+ if (ret != EOK) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return headers;
|
||||
}
|
||||
|
||||
-static int proxy_http_create_request(TALLOC_CTX *mem_ctx,
|
||||
- struct sec_req_ctx *secreq,
|
||||
- struct proxy_cfg *pcfg,
|
||||
- const char *http_uri,
|
||||
- struct sec_data **http_req)
|
||||
+static errno_t proxy_http_create_request(TALLOC_CTX *mem_ctx,
|
||||
+ struct sec_req_ctx *secreq,
|
||||
+ struct proxy_cfg *pcfg,
|
||||
+ const char *url,
|
||||
+ struct tcurl_request **_tcurl_req)
|
||||
{
|
||||
- struct sec_data *req;
|
||||
- int ret;
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ struct tcurl_request *tcurl_req;
|
||||
+ enum tcurl_http_method method;
|
||||
+ struct sss_iobuf *body;
|
||||
+ const char **headers;
|
||||
+ errno_t ret;
|
||||
|
||||
- req = talloc_zero(mem_ctx, struct sec_data);
|
||||
- if (!req) return ENOMEM;
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!\n");
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
|
||||
- /* Request-Line */
|
||||
- req->data = talloc_asprintf(req, "%s %s HTTP/1.1\r\n",
|
||||
- http_method_str(secreq->method), http_uri);
|
||||
- if (!req->data) {
|
||||
+ headers = proxy_http_create_headers(tmp_ctx, secreq, pcfg);
|
||||
+ if (headers == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to construct HTTP headers!\n");
|
||||
ret = ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
- /* Headers */
|
||||
- ret = proxy_sec_map_headers(req, secreq, pcfg, &req->data);
|
||||
- if (ret) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Couldn't map headers\n");
|
||||
+ body = sss_iobuf_init_readonly(tmp_ctx, (uint8_t *)secreq->body.data,
|
||||
+ secreq->body.length);
|
||||
+ if (body == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create HTTP body!\n");
|
||||
+ ret = ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
- /* CRLF separator before body */
|
||||
- req->data = talloc_strdup_append_buffer(req->data, "\r\n");
|
||||
-
|
||||
- req->length = strlen(req->data);
|
||||
+ switch (secreq->method) {
|
||||
+ case HTTP_GET:
|
||||
+ method = TCURL_HTTP_GET;
|
||||
+ break;
|
||||
+ case HTTP_PUT:
|
||||
+ method = TCURL_HTTP_PUT;
|
||||
+ break;
|
||||
+ case HTTP_POST:
|
||||
+ method = TCURL_HTTP_POST;
|
||||
+ break;
|
||||
+ case HTTP_DELETE:
|
||||
+ method = TCURL_HTTP_DELETE;
|
||||
+ break;
|
||||
+ default:
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected HTTP method: %d\n",
|
||||
+ secreq->method);
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
- /* Message-Body */
|
||||
- if (secreq->body.length > 0) {
|
||||
- req->data = talloc_realloc_size(req, req->data,
|
||||
- req->length + secreq->body.length);
|
||||
- if (!req->data) {
|
||||
- ret = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
+ tcurl_req = tcurl_http(tmp_ctx, method, NULL, url, headers, body);
|
||||
+ if (tcurl_req == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create TCURL request!\n");
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
- memcpy(&req->data[req->length],
|
||||
- secreq->body.data, secreq->body.length);
|
||||
- req->length += secreq->body.length;
|
||||
+ /* TCURL will return response buffer also with headers. */
|
||||
+ ret = tcurl_req_enable_rawoutput(tcurl_req);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
- *http_req = req;
|
||||
+ talloc_steal(tcurl_req, body);
|
||||
+ *_tcurl_req = talloc_steal(mem_ctx, tcurl_req);
|
||||
+
|
||||
ret = EOK;
|
||||
|
||||
done:
|
||||
- if (ret) talloc_free(req);
|
||||
+ talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -911,8 +990,8 @@ struct tevent_req *proxy_secret_req(TALLOC_CTX *mem_ctx,
|
||||
{
|
||||
struct tevent_req *req, *subreq;
|
||||
struct proxy_secret_state *state;
|
||||
+ struct tcurl_request *tcurl_req;
|
||||
struct proxy_context *pctx;
|
||||
- struct sec_data *http_req;
|
||||
char *http_uri;
|
||||
int ret;
|
||||
|
||||
@@ -942,9 +1021,8 @@ struct tevent_req *proxy_secret_req(TALLOC_CTX *mem_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
-
|
||||
ret = proxy_http_create_request(state, state->secreq, state->pcfg,
|
||||
- http_uri, &http_req);
|
||||
+ http_uri, &tcurl_req);
|
||||
if (ret) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
"proxy_http_create_request failed [%d]: %s\n",
|
||||
@@ -952,10 +1030,9 @@ struct tevent_req *proxy_secret_req(TALLOC_CTX *mem_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
-
|
||||
- subreq = proxy_http_req_send(pctx, state, ev, state->secreq,
|
||||
- http_uri, http_req);
|
||||
- if (!subreq) {
|
||||
+ subreq = tcurl_request_send(mem_ctx, ev, pctx->tcurl, tcurl_req,
|
||||
+ SEC_PROXY_TIMEOUT);
|
||||
+ if (subreq == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
@@ -981,32 +1058,30 @@ static void proxy_secret_req_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req;
|
||||
struct proxy_secret_state *state;
|
||||
- struct proxy_http_reply *reply = NULL;
|
||||
+ struct sss_iobuf *response;
|
||||
+ int http_code;
|
||||
int ret;
|
||||
|
||||
req = tevent_req_callback_data(subreq, struct tevent_req);
|
||||
state = tevent_req_data(req, struct proxy_secret_state);
|
||||
|
||||
- ret = proxy_http_req_recv(subreq, state, &reply);
|
||||
+ ret = tcurl_request_recv(state, subreq, &response, &http_code);
|
||||
talloc_zfree(subreq);
|
||||
|
||||
if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- "proxy_http request failed [%d]: %s\n",
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "proxy_http request failed [%d]: %s\n",
|
||||
ret, sss_strerror(ret));
|
||||
tevent_req_error(req, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
- ret = sec_http_reply_with_headers(state->secreq, &state->secreq->reply,
|
||||
- reply->status_code, reply->reason_phrase,
|
||||
- reply->headers, reply->num_headers,
|
||||
- &reply->body);
|
||||
+ ret = sec_http_reply_iobuf(state->secreq, &state->secreq->reply,
|
||||
+ http_code, response);
|
||||
if (ret == EOK) {
|
||||
tevent_req_done(req);
|
||||
} else {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
- "sec_http_reply_with_headers request failed [%d]: %s\n",
|
||||
+ "sec_http_reply_iobuf request failed [%d]: %s\n",
|
||||
ret, sss_strerror(ret));
|
||||
tevent_req_error(req, ret);
|
||||
}
|
||||
@@ -1034,6 +1109,11 @@ int proxy_secrets_provider_handle(struct sec_ctx *sctx,
|
||||
|
||||
pctx->resctx = sctx->resctx;
|
||||
pctx->cdb = sctx->rctx->cdb;
|
||||
+ pctx->tcurl = tcurl_init(pctx, sctx->rctx->ev);
|
||||
+ if (pctx->tcurl == NULL) {
|
||||
+ talloc_free(pctx);
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
|
||||
handle->context = pctx;
|
||||
|
||||
diff --git a/src/responder/secrets/secsrv_private.h b/src/responder/secrets/secsrv_private.h
|
||||
index a8544f656517a17fe4576247779bff4850beaf97..2e68628f61a0a8e79cd48fb5a510221e6fc36c70 100644
|
||||
--- a/src/responder/secrets/secsrv_private.h
|
||||
+++ b/src/responder/secrets/secsrv_private.h
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "config.h"
|
||||
#include "responder/common/responder.h"
|
||||
#include "responder/secrets/secsrv.h"
|
||||
+#include "util/sss_iobuf.h"
|
||||
#include <http_parser.h>
|
||||
|
||||
struct sec_kvp {
|
||||
@@ -129,6 +130,10 @@ int sec_http_reply_with_headers(TALLOC_CTX *mem_ctx, struct sec_data *reply,
|
||||
int status_code, const char *reason,
|
||||
struct sec_kvp *headers, int num_headers,
|
||||
struct sec_data *body);
|
||||
+errno_t sec_http_reply_iobuf(TALLOC_CTX *mem_ctx,
|
||||
+ struct sec_data *reply,
|
||||
+ int response_code,
|
||||
+ struct sss_iobuf *response);
|
||||
enum sec_http_status_codes sec_errno_to_http_status(errno_t err);
|
||||
|
||||
int sec_json_to_simple_secret(TALLOC_CTX *mem_ctx,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,611 +0,0 @@
|
||||
From 06744bf5a47d5971a338281c8243b11cf72dac90 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Tue, 28 Feb 2017 14:14:40 +0100
|
||||
Subject: [PATCH 87/97] secrets: remove http-parser code in proxy provider
|
||||
|
||||
We switche to libcurl in previous patch. This just removes the unused code.
|
||||
|
||||
Resolves:
|
||||
https://pagure.io/SSSD/sssd/issue/3192
|
||||
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/responder/secrets/proxy.c | 581 ------------------------------------------
|
||||
1 file changed, 581 deletions(-)
|
||||
|
||||
diff --git a/src/responder/secrets/proxy.c b/src/responder/secrets/proxy.c
|
||||
index fe2f0134e233d9a98f499fe563abe0af69762514..3c495716010ac468c9e2f1fb6356529a8dbdc614 100644
|
||||
--- a/src/responder/secrets/proxy.c
|
||||
+++ b/src/responder/secrets/proxy.c
|
||||
@@ -395,587 +395,6 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-struct proxy_http_request {
|
||||
- struct sec_data *data;
|
||||
- size_t written;
|
||||
-};
|
||||
-
|
||||
-struct proxy_http_reply {
|
||||
- http_parser parser;
|
||||
- bool complete;
|
||||
-
|
||||
- int status_code;
|
||||
- char *reason_phrase;
|
||||
- struct sec_kvp *headers;
|
||||
- int num_headers;
|
||||
- struct sec_data body;
|
||||
-
|
||||
- size_t received;
|
||||
-};
|
||||
-
|
||||
-struct proxy_http_req_state {
|
||||
- struct tevent_context *ev;
|
||||
-
|
||||
- char *proxyname;
|
||||
- int port;
|
||||
-
|
||||
- struct resolv_hostent *hostent;
|
||||
- int hostidx;
|
||||
-
|
||||
- int sd;
|
||||
- struct tevent_fd *fde;
|
||||
-
|
||||
- struct proxy_http_request request;
|
||||
- struct proxy_http_reply *reply;
|
||||
-};
|
||||
-
|
||||
-static int proxy_http_req_state_destroy(void *data);
|
||||
-static void proxy_http_req_gethostname_done(struct tevent_req *subreq);
|
||||
-static void proxy_http_req_connect_step(struct tevent_req *req);
|
||||
-static void proxy_http_req_connect_done(struct tevent_req *subreq);
|
||||
-static void proxy_fd_handler(struct tevent_context *ev, struct tevent_fd *fde,
|
||||
- uint16_t flags, void *ptr);
|
||||
-
|
||||
-struct tevent_req *proxy_http_req_send(struct proxy_context *pctx,
|
||||
- TALLOC_CTX *mem_ctx,
|
||||
- struct tevent_context *ev,
|
||||
- struct sec_req_ctx *secreq,
|
||||
- const char *http_uri,
|
||||
- struct sec_data *http_req)
|
||||
-{
|
||||
- struct proxy_http_req_state *state;
|
||||
- struct http_parser_url parsed;
|
||||
- struct tevent_req *req, *subreq;
|
||||
- int ret;
|
||||
-
|
||||
- req = tevent_req_create(mem_ctx, &state, struct proxy_http_req_state);
|
||||
- if (!req) return NULL;
|
||||
-
|
||||
- state->ev = ev;
|
||||
- state->request.data = http_req;
|
||||
- state->sd = -1;
|
||||
- talloc_set_destructor((TALLOC_CTX *)state,
|
||||
- proxy_http_req_state_destroy);
|
||||
-
|
||||
- /* STEP1: reparse URL to get hostname and port */
|
||||
- ret = http_parser_parse_url(http_uri, strlen(http_uri), 0, &parsed);
|
||||
- if (ret) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse URL [%s]: %d: %s\n",
|
||||
- http_uri, ret, sss_strerror(ret));
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- if (!(parsed.field_set & (1 << UF_HOST))) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "No UF_HOST flag found\n");
|
||||
- ret = EINVAL;
|
||||
- goto done;
|
||||
- }
|
||||
- state->proxyname =
|
||||
- talloc_strndup(state,
|
||||
- &http_uri[parsed.field_data[UF_HOST].off],
|
||||
- parsed.field_data[UF_HOST].len);
|
||||
- if (!state->proxyname) {
|
||||
- ret = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
- DEBUG(SSSDBG_TRACE_LIBS, "proxy name: %s\n", state->proxyname);
|
||||
-
|
||||
- if (parsed.field_set & (1 << UF_PORT)) {
|
||||
- state->port = parsed.port;
|
||||
- } else if (parsed.field_set & (1 << UF_SCHEMA)) {
|
||||
- uint16_t off = parsed.field_data[UF_SCHEMA].off;
|
||||
- uint16_t len = parsed.field_data[UF_SCHEMA].len;
|
||||
-
|
||||
- if ((len == 5) &&
|
||||
- (strncmp("https", &http_uri[off], len) == 0)) {
|
||||
- state->port = 443;
|
||||
- } else if ((len == 4) &&
|
||||
- (strncmp("http", &http_uri[off], len) == 0)) {
|
||||
- state->port = 80;
|
||||
- }
|
||||
- }
|
||||
- DEBUG(SSSDBG_TRACE_LIBS, "proxy port: %d\n", state->port);
|
||||
-
|
||||
- /* STEP2: resolve hostname first */
|
||||
- subreq = resolv_gethostbyname_send(state, ev, pctx->resctx,
|
||||
- state->proxyname, IPV4_FIRST,
|
||||
- default_host_dbs);
|
||||
- if (subreq == NULL) {
|
||||
- ret = ENOMEM;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- tevent_req_set_callback(subreq, proxy_http_req_gethostname_done, req);
|
||||
-
|
||||
- return req;
|
||||
-
|
||||
-done:
|
||||
- if (ret == EOK) {
|
||||
- tevent_req_done(req);
|
||||
- } else {
|
||||
- tevent_req_error(req, ret);
|
||||
- }
|
||||
- tevent_req_post(req, ev);
|
||||
-
|
||||
- return req;
|
||||
-}
|
||||
-
|
||||
-static void proxy_http_req_gethostname_done(struct tevent_req *subreq)
|
||||
-{
|
||||
- struct tevent_req *req;
|
||||
- struct proxy_http_req_state *state;
|
||||
- int resolv_status;
|
||||
- int ret;
|
||||
-
|
||||
- req = tevent_req_callback_data(subreq, struct tevent_req);
|
||||
- state = tevent_req_data(req, struct proxy_http_req_state);
|
||||
-
|
||||
- ret = resolv_gethostbyname_recv(subreq, state, &resolv_status, NULL,
|
||||
- &state->hostent);
|
||||
- talloc_zfree(subreq);
|
||||
- if (ret != EOK) {
|
||||
- if (ret == ENOENT) {
|
||||
- /* Empty result, just quit */
|
||||
- DEBUG(SSSDBG_TRACE_INTERNAL, "No hostent found\n");
|
||||
- } else {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- "Could not resolve fqdn for this machine, error [%d]: %s, "
|
||||
- "resolver returned: [%d]: %s\n", ret, strerror(ret),
|
||||
- resolv_status, resolv_strerror(resolv_status));
|
||||
- }
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- /* EOK */
|
||||
- DEBUG(SSSDBG_TRACE_INTERNAL, "Found fqdn: %s\n", state->hostent->name);
|
||||
-
|
||||
- /* STEP3: connect to one of the servers */
|
||||
- proxy_http_req_connect_step(req);
|
||||
- return;
|
||||
-
|
||||
-done:
|
||||
- if (ret == EOK) {
|
||||
- tevent_req_done(req);
|
||||
- } else {
|
||||
- tevent_req_error(req, ret);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void proxy_http_req_connect_step(struct tevent_req *req)
|
||||
-{
|
||||
- struct proxy_http_req_state *state;
|
||||
- struct sockaddr_storage *sockaddr;
|
||||
- char *ipaddr;
|
||||
- struct tevent_req *subreq;
|
||||
- int ret;
|
||||
-
|
||||
- state = tevent_req_data(req, struct proxy_http_req_state);
|
||||
-
|
||||
- if (!state->hostent->addr_list[state->hostidx]) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "No more addresses to try.\n");
|
||||
- ret = ERR_SEC_NO_PROXY;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- sockaddr = resolv_get_sockaddr_address_index(state, state->hostent,
|
||||
- state->port, state->hostidx);
|
||||
- if (sockaddr == NULL) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, "resolv_get_sockaddr_address() failed\n");
|
||||
- ret = EIO;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- if (DEBUG_IS_SET(SSSDBG_TRACE_FUNC)) {
|
||||
- ipaddr = resolv_get_string_address_index(state, state->hostent,
|
||||
- state->hostidx);
|
||||
- if (!ipaddr) {
|
||||
- ret = EFAULT;
|
||||
- goto done;
|
||||
- }
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, "Connecting to %s:%d\n",
|
||||
- ipaddr, state->port);
|
||||
- }
|
||||
-
|
||||
- /* increase idx for next attempt */
|
||||
- state->hostidx++;
|
||||
-
|
||||
- subreq = sssd_async_socket_init_send(state, state->ev, sockaddr,
|
||||
- sizeof(struct sockaddr_storage),
|
||||
- SEC_NET_TIMEOUT);
|
||||
- if (!subreq) {
|
||||
- ret = EIO;
|
||||
- goto done;
|
||||
- }
|
||||
- tevent_req_set_callback(subreq, proxy_http_req_connect_done, req);
|
||||
- return;
|
||||
-
|
||||
-done:
|
||||
- if (ret == EOK) {
|
||||
- tevent_req_done(req);
|
||||
- } else {
|
||||
- tevent_req_error(req, ret);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void proxy_http_req_connect_done(struct tevent_req *subreq)
|
||||
-{
|
||||
- struct tevent_req *req;
|
||||
- struct proxy_http_req_state *state;
|
||||
- int ret;
|
||||
-
|
||||
- req = tevent_req_callback_data(subreq, struct tevent_req);
|
||||
- state = tevent_req_data(req, struct proxy_http_req_state);
|
||||
-
|
||||
- ret = sssd_async_socket_init_recv(subreq, &state->sd);
|
||||
- talloc_zfree(subreq);
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- "sssd_async_socket_init request failed: [%d]: %s.\n",
|
||||
- ret, sss_strerror(ret));
|
||||
-
|
||||
- /* try next server if any */
|
||||
- proxy_http_req_connect_step(req);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /* EOK */
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, "Connected to %s\n", state->hostent->name);
|
||||
-
|
||||
- state->fde = tevent_add_fd(state->ev, state, state->sd,
|
||||
- TEVENT_FD_WRITE, proxy_fd_handler,
|
||||
- req);
|
||||
- if (!state->fde) {
|
||||
- ret = EIO;
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- return;
|
||||
-
|
||||
-done:
|
||||
- if (ret == EOK) {
|
||||
- tevent_req_done(req);
|
||||
- } else {
|
||||
- tevent_req_error(req, ret);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-
|
||||
-int proxy_http_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
|
||||
- struct proxy_http_reply **reply)
|
||||
-{
|
||||
- struct proxy_http_req_state *state =
|
||||
- tevent_req_data(req, struct proxy_http_req_state);
|
||||
-
|
||||
- TEVENT_REQ_RETURN_ON_ERROR(req);
|
||||
-
|
||||
- *reply = talloc_move(mem_ctx, &state->reply);
|
||||
-
|
||||
- return EOK;
|
||||
-}
|
||||
-
|
||||
-static int proxy_http_req_state_destroy(void *data)
|
||||
-{
|
||||
- struct proxy_http_req_state *state =
|
||||
- talloc_get_type(data, struct proxy_http_req_state);
|
||||
-
|
||||
- if (!state) return 0;
|
||||
-
|
||||
- if (state->sd != -1) {
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, "closing socket [%d]\n", state->sd);
|
||||
- close(state->sd);
|
||||
- state->sd = -1;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int proxy_wire_send(int fd, struct proxy_http_request *req)
|
||||
-{
|
||||
- struct sec_data data;
|
||||
- int ret;
|
||||
-
|
||||
- data.data = req->data->data + req->written;
|
||||
- data.length = req->data->length - req->written;
|
||||
-
|
||||
- ret = sec_send_data(fd, &data);
|
||||
- if (ret != EOK && ret != EAGAIN) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
- "sec_send_data failed [%d]: %s\n", ret, sss_strerror(ret));
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- req->written = req->data->length - data.length;
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static void proxy_fd_send(void *data)
|
||||
-{
|
||||
- struct proxy_http_req_state *state;
|
||||
- struct tevent_req * req;
|
||||
- int ret;
|
||||
-
|
||||
- req = talloc_get_type(data, struct tevent_req);
|
||||
- state = tevent_req_data(req, struct proxy_http_req_state);
|
||||
-
|
||||
- ret = proxy_wire_send(state->sd, &state->request);
|
||||
- if (ret == EAGAIN) {
|
||||
- /* not all data was sent, loop again */
|
||||
- return;
|
||||
- }
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE, "Failed to send data, aborting!\n");
|
||||
- tevent_req_error(req, ret);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /* ok all sent, wait for reply now */
|
||||
- TEVENT_FD_NOT_WRITEABLE(state->fde);
|
||||
- TEVENT_FD_READABLE(state->fde);
|
||||
- return;
|
||||
-}
|
||||
-
|
||||
-static bool ph_received_data(struct proxy_http_reply *reply, size_t length)
|
||||
-{
|
||||
- reply->received += length;
|
||||
- if (reply->received > SEC_REQUEST_MAX_SIZE) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE, "Request too big, aborting!\n");
|
||||
- return true;
|
||||
- }
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
-static void ph_append_string(TALLOC_CTX *memctx, char **dest,
|
||||
- const char *src, size_t len)
|
||||
-{
|
||||
- if (*dest) {
|
||||
- *dest = talloc_strndup_append_buffer(*dest, src, len);
|
||||
- } else {
|
||||
- *dest = talloc_strndup(memctx, src, len);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static int ph_on_message_begin(http_parser *parser)
|
||||
-{
|
||||
- DEBUG(SSSDBG_TRACE_INTERNAL, "HTTP Message parsing begins\n");
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-#if ((HTTP_PARSER_VERSION_MAJOR >= 2) && (HTTP_PARSER_VERSION_MINOR >= 2))
|
||||
-static int ph_on_status(http_parser *parser, const char *at, size_t length)
|
||||
-{
|
||||
- struct proxy_http_reply *reply =
|
||||
- talloc_get_type(parser->data, struct proxy_http_reply);
|
||||
-
|
||||
- if (ph_received_data(reply, length)) return -1;
|
||||
-
|
||||
- ph_append_string(reply, &reply->reason_phrase, at, length);
|
||||
- if (!reply->reason_phrase) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
- "Failed to store reason phrase, aborting client!\n");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
-static int ph_on_header_field(http_parser *parser,
|
||||
- const char *at, size_t length)
|
||||
-{
|
||||
- struct proxy_http_reply *reply =
|
||||
- talloc_get_type(parser->data, struct proxy_http_reply);
|
||||
- int n = reply->num_headers;
|
||||
-
|
||||
- if (ph_received_data(reply, length)) return -1;
|
||||
-
|
||||
- if (!reply->headers) {
|
||||
- reply->headers = talloc_zero_array(reply, struct sec_kvp, 10);
|
||||
- } else if ((n % 10 == 0) &&
|
||||
- (reply->headers[n - 1].value)) {
|
||||
- reply->headers = talloc_realloc(reply, reply->headers,
|
||||
- struct sec_kvp, n + 10);
|
||||
- if (reply->headers) {
|
||||
- memset(&reply->headers[n], 0, sizeof(struct sec_kvp) * 10);
|
||||
- }
|
||||
- }
|
||||
- if (!reply->headers) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
- "Failed to store headers, aborting client!\n");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- if (!n || reply->headers[n - 1].value) {
|
||||
- /* new field */
|
||||
- n++;
|
||||
- }
|
||||
- ph_append_string(reply->headers, &reply->headers[n - 1].name, at, length);
|
||||
- if (!reply->headers[n - 1].name) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
- "Failed to store header name, aborting client!\n");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int ph_on_header_value(http_parser *parser,
|
||||
- const char *at, size_t length)
|
||||
-{
|
||||
- struct proxy_http_reply *reply =
|
||||
- talloc_get_type(parser->data, struct proxy_http_reply);
|
||||
- int n = reply->num_headers;
|
||||
-
|
||||
- if (ph_received_data(reply, length)) return -1;
|
||||
-
|
||||
- if (!reply->headers) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
- "Invalid headers pointer, aborting client!\n");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- if (reply->headers[n].name && !reply->headers[n].value) {
|
||||
- /* we increment on new value */
|
||||
- n = ++reply->num_headers;
|
||||
- }
|
||||
-
|
||||
- ph_append_string(reply->headers, &reply->headers[n - 1].value, at, length);
|
||||
- if (!reply->headers[n - 1].value) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
- "Failed to store header value, aborting client!\n");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int ph_on_headers_complete(http_parser *parser)
|
||||
-{
|
||||
- /* TODO: if message has no body we should return 1 */
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int ph_on_body(http_parser *parser, const char *at, size_t length)
|
||||
-{
|
||||
- struct proxy_http_reply *reply =
|
||||
- talloc_get_type(parser->data, struct proxy_http_reply);
|
||||
-
|
||||
- if (ph_received_data(reply, length)) return -1;
|
||||
-
|
||||
- /* FIXME: body may be binary */
|
||||
- ph_append_string(reply, &reply->body.data, at, length);
|
||||
- if (!reply->body.data) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
- "Failed to store body, aborting!\n");
|
||||
- return -1;
|
||||
- }
|
||||
- reply->body.length += length;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int ph_on_message_complete(http_parser *parser)
|
||||
-{
|
||||
- struct proxy_http_reply *reply =
|
||||
- talloc_get_type(parser->data, struct proxy_http_reply);
|
||||
-
|
||||
- reply->status_code = parser->status_code;
|
||||
- reply->complete = true;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static http_parser_settings ph_callbacks = {
|
||||
- .on_message_begin = ph_on_message_begin,
|
||||
-#if ((HTTP_PARSER_VERSION_MAJOR >= 2) && (HTTP_PARSER_VERSION_MINOR >= 2))
|
||||
- .on_status = ph_on_status,
|
||||
-#endif
|
||||
- .on_header_field = ph_on_header_field,
|
||||
- .on_header_value = ph_on_header_value,
|
||||
- .on_headers_complete = ph_on_headers_complete,
|
||||
- .on_body = ph_on_body,
|
||||
- .on_message_complete = ph_on_message_complete
|
||||
-};
|
||||
-
|
||||
-static void proxy_fd_recv(void *data)
|
||||
-{
|
||||
- char buffer[SEC_PACKET_MAX_RECV_SIZE];
|
||||
- struct sec_data packet = { buffer,
|
||||
- SEC_PACKET_MAX_RECV_SIZE };
|
||||
- struct proxy_http_req_state *state;
|
||||
- struct tevent_req *req;
|
||||
- bool must_complete = false;
|
||||
- int ret;
|
||||
-
|
||||
- req = talloc_get_type(data, struct tevent_req);
|
||||
- state = tevent_req_data(req, struct proxy_http_req_state);
|
||||
-
|
||||
- if (!state->reply) {
|
||||
- /* A new reply */
|
||||
- state->reply = talloc_zero(state, struct proxy_http_reply);
|
||||
- if (!state->reply) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE, "Failed to allocate reply, aborting!\n");
|
||||
- tevent_req_error(req, ENOMEM);
|
||||
- return;
|
||||
- }
|
||||
- http_parser_init(&state->reply->parser, HTTP_RESPONSE);
|
||||
- state->reply->parser.data = state->reply;
|
||||
- }
|
||||
-
|
||||
- ret = sec_recv_data(state->sd, &packet);
|
||||
- switch (ret) {
|
||||
- case ENODATA:
|
||||
- DEBUG(SSSDBG_TRACE_ALL, "Server closed connection.\n");
|
||||
- /* if we got no content length and the request is not complete,
|
||||
- * then 0 length will indicate EOF to the parser, otherwise we
|
||||
- * have an error */
|
||||
- must_complete = true;
|
||||
- break;
|
||||
- case EAGAIN:
|
||||
- DEBUG(SSSDBG_TRACE_ALL,
|
||||
- "Interrupted before any data could be read, retry later\n");
|
||||
- return;
|
||||
- case EOK:
|
||||
- /* all fine */
|
||||
- break;
|
||||
- default:
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
- "Failed to receive data (%d, %s), aborting\n",
|
||||
- ret, sss_strerror(ret));
|
||||
- tevent_req_error(req, EIO);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- ret = http_parser_execute(&state->reply->parser, &ph_callbacks,
|
||||
- packet.data, packet.length);
|
||||
- if (ret != packet.length) {
|
||||
- DEBUG(SSSDBG_FATAL_FAILURE,
|
||||
- "Failed to parse request, aborting!\n");
|
||||
- tevent_req_error(req, EIO);
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- if (!state->reply->complete) {
|
||||
- if (must_complete) {
|
||||
- tevent_req_error(req, EIO);
|
||||
- }
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /* do not read anymore, server is done sending */
|
||||
- TEVENT_FD_NOT_READABLE(state->fde);
|
||||
- tevent_req_done(req);
|
||||
-}
|
||||
-
|
||||
-static void proxy_fd_handler(struct tevent_context *ev, struct tevent_fd *fde,
|
||||
- uint16_t flags, void *data)
|
||||
-{
|
||||
- if (flags & TEVENT_FD_READ) {
|
||||
- proxy_fd_recv(data);
|
||||
- } else if (flags & TEVENT_FD_WRITE) {
|
||||
- proxy_fd_send(data);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
struct proxy_secret_state {
|
||||
struct tevent_context *ev;
|
||||
struct sec_req_ctx *secreq;
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,253 +0,0 @@
|
||||
From 720e1a5b95a953a0f1c8315bbb7c9c1edf9fb417 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Tue, 28 Feb 2017 11:47:32 +0100
|
||||
Subject: [PATCH 88/97] secrets: allow to configure certificate check
|
||||
|
||||
Some users may want to use TLS with unverified peer (for example if
|
||||
they use self-signed certificate) or if unverified hostname (if
|
||||
certificate hostname does not match with the real hostname). On the
|
||||
other side it may be useful to point to a directory containing custom
|
||||
certificate authorities.
|
||||
|
||||
This patch add three new options to secrets responder:
|
||||
verify_peer => peer's certificate must be valid
|
||||
verify_host => hostnames must match
|
||||
capath => path to directory containing CA certs
|
||||
cacert => ca certificate
|
||||
cert => client certificate
|
||||
key => client private key
|
||||
|
||||
Resolves:
|
||||
https://pagure.io/SSSD/sssd/issue/3192
|
||||
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/config/SSSDConfig/__init__.py.in | 6 +++
|
||||
src/config/cfg_rules.ini | 6 +++
|
||||
src/config/etc/sssd.api.conf | 6 +++
|
||||
src/man/sssd-secrets.5.xml | 76 ++++++++++++++++++++++++++++++++++++
|
||||
src/responder/secrets/proxy.c | 55 ++++++++++++++++++++++++++
|
||||
5 files changed, 149 insertions(+)
|
||||
|
||||
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
|
||||
index a29d51e0ddffc520107a309d862346fb4d4f5f80..54ad722f07ef91a13a0df278ffd2b1c166bc8d36 100644
|
||||
--- a/src/config/SSSDConfig/__init__.py.in
|
||||
+++ b/src/config/SSSDConfig/__init__.py.in
|
||||
@@ -137,6 +137,12 @@ option_strings = {
|
||||
'forward_headers': _('The list of the headers to forward to the Custodia server together with the request'),
|
||||
'username': _('The username to use when authenticating to a Custodia server using basic_auth'),
|
||||
'password': _('The password to use when authenticating to a Custodia server using basic_auth'),
|
||||
+ 'verify_peer': _('If true peer\'s certificate is verified if proxy_url uses https protocol'),
|
||||
+ 'verify_host': _('If false peer\'s certificate may contain different hostname then proxy_url when https protocol is used'),
|
||||
+ 'capath': _('Path to directory where certificate authority certificates are stored'),
|
||||
+ 'cacert': _('Path to file containing server\'s CA certificate'),
|
||||
+ 'cert': _('Path to file containing client\'s certificate'),
|
||||
+ 'key': _('Path to file containing client\'s private key'),
|
||||
|
||||
# [provider]
|
||||
'id_provider' : _('Identity provider'),
|
||||
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
|
||||
index 1a749db754cedd87f263f7ae596d6f8238bb4357..e47ff33242d6a9e5979fe0eb8eea14c2af28685a 100644
|
||||
--- a/src/config/cfg_rules.ini
|
||||
+++ b/src/config/cfg_rules.ini
|
||||
@@ -265,6 +265,12 @@ option = auth_header_value
|
||||
option = forward_headers
|
||||
option = username
|
||||
option = password
|
||||
+option = verify_peer
|
||||
+option = verify_host
|
||||
+option = capath
|
||||
+option = cacert
|
||||
+option = cert
|
||||
+option = key
|
||||
|
||||
# KCM responder
|
||||
[rule/allowed_kcm_options]
|
||||
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
|
||||
index a1a0c2992925a4c7df86832117eec2a0cf7894c9..f86589ecefa0b9e046aba781ded107f8e94395d6 100644
|
||||
--- a/src/config/etc/sssd.api.conf
|
||||
+++ b/src/config/etc/sssd.api.conf
|
||||
@@ -114,6 +114,12 @@ auth_header_value = str, None, false
|
||||
forward_headers = list, None, false
|
||||
username = str, None, false
|
||||
password = str, None, false
|
||||
+verify_peer = bool, None, false
|
||||
+verify_host = bool, None, false
|
||||
+capath = str, None, false
|
||||
+cacert = str, None, false
|
||||
+cert = str, None, false
|
||||
+key = str, None, false
|
||||
|
||||
[provider]
|
||||
#Available provider types
|
||||
diff --git a/src/man/sssd-secrets.5.xml b/src/man/sssd-secrets.5.xml
|
||||
index 80e9c405921e1fb46a3d172d9873deebfa5ed2ce..44a86c3fb56a8bdebebd01e9f49ad171986282a4 100644
|
||||
--- a/src/man/sssd-secrets.5.xml
|
||||
+++ b/src/man/sssd-secrets.5.xml
|
||||
@@ -273,6 +273,82 @@ systemctl enable sssd-secrets.service
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>verify_peer (boolean)</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Whether peer's certificate should be verified and valid
|
||||
+ if HTTPS protocol is used with the proxy provider.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Default: true
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>verify_host (boolean)</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Whether peer's hostname must match with hostname in
|
||||
+ its certificate if HTTPS protocol is used with the
|
||||
+ proxy provider.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Default: true
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>capath (string)</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Path to directory containing stored certificate authority
|
||||
+ certificates. System default path is used if this option is
|
||||
+ not set.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Default: not set
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>cacert (string)</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Path to file containing server's certificate authority
|
||||
+ certificate. If this option is not set then the CA's
|
||||
+ certificate is looked up in <quote>capath</quote>.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Default: not set
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>cert (string)</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Path to file containing client's certificate if required
|
||||
+ by the server. This file may also contain private key or
|
||||
+ the private key may be in separate file set with
|
||||
+ <quote>key</quote>.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Default: not set
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>key (string)</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Path to file containing client's private key.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ Default: not set
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<refsect1 id='restapi'>
|
||||
diff --git a/src/responder/secrets/proxy.c b/src/responder/secrets/proxy.c
|
||||
index 3c495716010ac468c9e2f1fb6356529a8dbdc614..240a1de1e431d511a1eca24d8b463c37ba893e7b 100644
|
||||
--- a/src/responder/secrets/proxy.c
|
||||
+++ b/src/responder/secrets/proxy.c
|
||||
@@ -59,6 +59,13 @@ struct proxy_cfg {
|
||||
struct pat_basic_auth basic;
|
||||
struct pat_header header;
|
||||
} auth;
|
||||
+
|
||||
+ char *key;
|
||||
+ char *cert;
|
||||
+ char *cacert;
|
||||
+ char *capath;
|
||||
+ bool verify_peer;
|
||||
+ bool verify_host;
|
||||
};
|
||||
|
||||
static int proxy_get_config_string(struct proxy_context *pctx,
|
||||
@@ -129,6 +136,38 @@ static int proxy_sec_get_cfg(struct proxy_context *pctx,
|
||||
}
|
||||
}
|
||||
|
||||
+ ret = confdb_get_bool(pctx->cdb, secreq->cfg_section, "verify_peer",
|
||||
+ true, &cfg->verify_peer);
|
||||
+ if (ret) goto done;
|
||||
+ DEBUG(SSSDBG_CONF_SETTINGS, "verify_peer: %s\n",
|
||||
+ (&cfg->verify_peer ? "true" : "false"));
|
||||
+
|
||||
+ ret = confdb_get_bool(pctx->cdb, secreq->cfg_section, "verify_host",
|
||||
+ true, &cfg->verify_host);
|
||||
+ if (ret) goto done;
|
||||
+ DEBUG(SSSDBG_CONF_SETTINGS, "verify_host: %s\n",
|
||||
+ (&cfg->verify_host ? "true" : "false"));
|
||||
+
|
||||
+ ret = proxy_get_config_string(pctx, cfg, false, secreq,
|
||||
+ "capath", &cfg->capath);
|
||||
+ if (ret) goto done;
|
||||
+ DEBUG(SSSDBG_CONF_SETTINGS, "capath: %s\n", cfg->capath);
|
||||
+
|
||||
+ ret = proxy_get_config_string(pctx, cfg, false, secreq,
|
||||
+ "cacert", &cfg->cacert);
|
||||
+ if (ret) goto done;
|
||||
+ DEBUG(SSSDBG_CONF_SETTINGS, "cacert: %s\n", cfg->cacert);
|
||||
+
|
||||
+ ret = proxy_get_config_string(pctx, cfg, false, secreq,
|
||||
+ "cert", &cfg->cert);
|
||||
+ if (ret) goto done;
|
||||
+ DEBUG(SSSDBG_CONF_SETTINGS, "cert: %s\n", cfg->cert);
|
||||
+
|
||||
+ ret = proxy_get_config_string(pctx, cfg, false, secreq,
|
||||
+ "key", &cfg->key);
|
||||
+ if (ret) goto done;
|
||||
+ DEBUG(SSSDBG_CONF_SETTINGS, "key: %s\n", cfg->key);
|
||||
+
|
||||
ret = confdb_get_string_as_list(pctx->cdb, cfg, secreq->cfg_section,
|
||||
"forward_headers", &cfg->fwd_headers);
|
||||
if ((ret != 0) && (ret != ENOENT)) goto done;
|
||||
@@ -385,6 +424,22 @@ static errno_t proxy_http_create_request(TALLOC_CTX *mem_ctx,
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ /* Set TLS settings to verify peer.
|
||||
+ * This has no effect for HTTP protocol so we can set it anyway. */
|
||||
+ ret = tcurl_req_verify_peer(tcurl_req, pcfg->capath, pcfg->cacert,
|
||||
+ pcfg->verify_peer, pcfg->verify_host);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* Set client's certificate if required. */
|
||||
+ if (pcfg->cert != NULL) {
|
||||
+ ret = tcurl_req_set_client_cert(tcurl_req, pcfg->cert, pcfg->key);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
talloc_steal(tcurl_req, body);
|
||||
*_tcurl_req = talloc_steal(mem_ctx, tcurl_req);
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,38 +0,0 @@
|
||||
From af026ea6a6e812b7d6c5c889dda64ba7b7c433ee Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Tue, 28 Feb 2017 13:58:20 +0100
|
||||
Subject: [PATCH 89/97] secrets: support HTTP basic authentication with proxy
|
||||
provider
|
||||
|
||||
Even though configuration options auth_type = basic, username and password
|
||||
are read they were not used anywhere prior this patch.
|
||||
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/responder/secrets/proxy.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/src/responder/secrets/proxy.c b/src/responder/secrets/proxy.c
|
||||
index 240a1de1e431d511a1eca24d8b463c37ba893e7b..fd96e985c897e2cb470a9b5d6eecbd34350fb7d2 100644
|
||||
--- a/src/responder/secrets/proxy.c
|
||||
+++ b/src/responder/secrets/proxy.c
|
||||
@@ -440,6 +440,15 @@ static errno_t proxy_http_create_request(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Set basic authentication if required. */
|
||||
+ if (pcfg->auth_type == PAT_BASIC_AUTH) {
|
||||
+ ret = tcurl_req_http_basic_auth(tcurl_req, pcfg->auth.basic.username,
|
||||
+ pcfg->auth.basic.password);
|
||||
+ if (ret != EOK) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
talloc_steal(tcurl_req, body);
|
||||
*_tcurl_req = talloc_steal(mem_ctx, tcurl_req);
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,28 +0,0 @@
|
||||
From db826f57b4c2ee814823057cc536386889f7aa1d Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Wed, 15 Mar 2017 13:27:59 +0100
|
||||
Subject: [PATCH 90/97] secrets: fix debug message
|
||||
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/responder/secrets/secsrv_cmd.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/responder/secrets/secsrv_cmd.c b/src/responder/secrets/secsrv_cmd.c
|
||||
index 70679ec0398fca25cfb0525772f539526a0eb3ff..b88680c3d7c3105d160de5c78e6d981b852318b9 100644
|
||||
--- a/src/responder/secrets/secsrv_cmd.c
|
||||
+++ b/src/responder/secrets/secsrv_cmd.c
|
||||
@@ -451,7 +451,8 @@ int sec_send_data(int fd, struct sec_data *data)
|
||||
|
||||
data->length -= len;
|
||||
data->data += len;
|
||||
- DEBUG(SSSDBG_TRACE_INTERNAL, "sent %zu bytes\n", data->length);
|
||||
+ DEBUG(SSSDBG_TRACE_INTERNAL, "sent %zu bytes, %zu bytes remaining\n",
|
||||
+ len, data->length);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,111 +0,0 @@
|
||||
From 13d720de13e490850c1139eea865bcd5195a2630 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Wed, 15 Mar 2017 15:15:08 +0100
|
||||
Subject: [PATCH 91/97] secrets: always add Content-Length header
|
||||
|
||||
If custodia server does not reply with Content-Length header, curl may
|
||||
wait for non-existing body of http reply if such body does not exist
|
||||
(for example during POST operation when creating a container).
|
||||
|
||||
Reviewed-by: Simo Sorce <simo@redhat.com>
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
---
|
||||
src/responder/secrets/providers.c | 72 ++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 68 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/responder/secrets/providers.c b/src/responder/secrets/providers.c
|
||||
index 80a443d91135447ec8ce8d424b692a6d7e26a907..a27fb720b394e7c76d1b65f656146bcd00755449 100644
|
||||
--- a/src/responder/secrets/providers.c
|
||||
+++ b/src/responder/secrets/providers.c
|
||||
@@ -388,20 +388,84 @@ int sec_http_reply_with_headers(TALLOC_CTX *mem_ctx, struct sec_data *reply,
|
||||
return EOK;
|
||||
}
|
||||
|
||||
+static errno_t
|
||||
+sec_http_iobuf_split(struct sss_iobuf *response,
|
||||
+ const char **headers,
|
||||
+ const char **body)
|
||||
+{
|
||||
+ const char *data = (const char *)sss_iobuf_get_data(response);
|
||||
+ char *delim;
|
||||
+
|
||||
+ /* The last header ends with \r\n and then comes \r\n again as a separator
|
||||
+ * of body from headers. We can use this to find this point. */
|
||||
+ delim = strstr(data, "\r\n\r\n");
|
||||
+ if (delim == NULL) {
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Skip to the body delimiter. */
|
||||
+ delim = delim + sizeof("\r\n") - 1;
|
||||
+
|
||||
+ /* Replace \r\n with zeros turning data into:
|
||||
+ * from HEADER\r\nBODY into HEADER\0\0BODY format. */
|
||||
+ delim[0] = '\0';
|
||||
+ delim[1] = '\0';
|
||||
+
|
||||
+ /* Split the buffer. */
|
||||
+ *headers = data;
|
||||
+ *body = delim + 2;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const char *
|
||||
+sec_http_iobuf_add_content_length(TALLOC_CTX *mem_ctx,
|
||||
+ const char *headers,
|
||||
+ size_t body_len)
|
||||
+{
|
||||
+ /* If Content-Length is already present we do nothing. */
|
||||
+ if (strstr(headers, "Content-Length:") != NULL) {
|
||||
+ return headers;
|
||||
+ }
|
||||
+
|
||||
+ return talloc_asprintf(mem_ctx, "%sContent-Length: %zu\r\n",
|
||||
+ headers, body_len);
|
||||
+}
|
||||
+
|
||||
errno_t sec_http_reply_iobuf(TALLOC_CTX *mem_ctx,
|
||||
struct sec_data *reply,
|
||||
int response_code,
|
||||
struct sss_iobuf *response)
|
||||
{
|
||||
+ const char *headers;
|
||||
+ const char *body;
|
||||
+ size_t body_len;
|
||||
+ errno_t ret;
|
||||
+
|
||||
DEBUG(SSSDBG_TRACE_LIBS, "HTTP reply %d\n", response_code);
|
||||
|
||||
- reply->data = (char *)sss_iobuf_get_data(response);
|
||||
- reply->length = sss_iobuf_get_len(response);
|
||||
+ ret = sec_http_iobuf_split(response, &headers, &body);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Unexpected HTTP reply, returning what we got from server\n");
|
||||
+ reply->data = (char *)sss_iobuf_get_data(response);
|
||||
+ reply->length = sss_iobuf_get_len(response);
|
||||
|
||||
- talloc_steal(mem_ctx, reply->data);
|
||||
+ return EOK;
|
||||
+ }
|
||||
|
||||
+ /* Add Content-Length header if not present so client does not await
|
||||
+ * not-existing incoming data. */
|
||||
+ body_len = strlen(body);
|
||||
+ headers = sec_http_iobuf_add_content_length(mem_ctx, headers, body_len);
|
||||
+ if (headers == NULL) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ reply->length = strlen(headers) + sizeof("\r\n") - 1 + body_len;
|
||||
+ reply->data = talloc_asprintf(mem_ctx, "%s\r\n%s", headers, body);
|
||||
if (reply->data == NULL) {
|
||||
- return EINVAL;
|
||||
+ return ENOMEM;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,39 +0,0 @@
|
||||
From 18e4fe9d836e8f7bee52724374ffc0011172329f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Tue, 28 Mar 2017 15:26:52 +0200
|
||||
Subject: [PATCH 92/97] sss_iobuf: fix 'read' shadows a global declaration
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/util/sss_iobuf.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/util/sss_iobuf.c b/src/util/sss_iobuf.c
|
||||
index fc288d2df2bfaaba393dd490d4da8976de804cb5..518713e4cc3dd99627a3a4450f235cbbc69ed3a2 100644
|
||||
--- a/src/util/sss_iobuf.c
|
||||
+++ b/src/util/sss_iobuf.c
|
||||
@@ -188,15 +188,15 @@ errno_t sss_iobuf_read_len(struct sss_iobuf *iobuf,
|
||||
size_t len,
|
||||
uint8_t *_buf)
|
||||
{
|
||||
- size_t read;
|
||||
+ size_t read_bytes;
|
||||
errno_t ret;
|
||||
|
||||
- ret = sss_iobuf_read(iobuf, len, _buf, &read);
|
||||
+ ret = sss_iobuf_read(iobuf, len, _buf, &read_bytes);
|
||||
if (ret != EOK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
- if (read != len) {
|
||||
+ if (read_bytes != len) {
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,28 +0,0 @@
|
||||
From dc186bfe90665c13d589b3b4efd9009293e62c46 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Wed, 29 Mar 2017 13:28:49 +0200
|
||||
Subject: [PATCH 93/97] configure: fix typo
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/external/libhttp_parser.m4 | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/external/libhttp_parser.m4 b/src/external/libhttp_parser.m4
|
||||
index 504bdf0f66c95b3d224c677a205a46e6f8b44726..3a5ef0dbbc63423ad8e960d72e97ec4fb4481dd1 100644
|
||||
--- a/src/external/libhttp_parser.m4
|
||||
+++ b/src/external/libhttp_parser.m4
|
||||
@@ -17,6 +17,6 @@ AS_IF([test x"$found_http_parser" != xyes],
|
||||
],
|
||||
[-L$sss_extra_libdir -lhttp_parser_strict])],
|
||||
[AC_MSG_ERROR([
|
||||
-You must have the header file http_parse.h installed to build sssd
|
||||
+You must have the header file http_parser.h installed to build sssd
|
||||
with secrets responder. If you want to build sssd without secret responder
|
||||
then specify --without-secrets when running configure.])])])
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,87 +0,0 @@
|
||||
From 5231ba679402eeb0705a3ecd41f97fdd67d42a69 Mon Sep 17 00:00:00 2001
|
||||
From: David Kupka <dkupka@redhat.com>
|
||||
Date: Fri, 31 Mar 2017 21:31:23 +0200
|
||||
Subject: [PATCH 94/97] libsss_certmap: Accept certificate with data before
|
||||
header
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
According to RFC 7468 parser must not fail when some data are present
|
||||
before the encapsulation boundary. sss_cert_pem_to_der didn't respect
|
||||
this and refused valid input. Changing it's code to first locate
|
||||
the certificate header fixes the issue.
|
||||
|
||||
Resolves:
|
||||
https://pagure.io/SSSD/sssd/issue/3354
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
|
||||
---
|
||||
src/tests/cmocka/test_cert_utils.c | 16 ++++++++++++++++
|
||||
src/util/cert/nss/cert.c | 9 +++++----
|
||||
2 files changed, 21 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/tests/cmocka/test_cert_utils.c b/src/tests/cmocka/test_cert_utils.c
|
||||
index 5830131754e4cf318273151b586ef36d6a349829..8003d8daa7063773cf8b37c46ac8759e3a38736f 100644
|
||||
--- a/src/tests/cmocka/test_cert_utils.c
|
||||
+++ b/src/tests/cmocka/test_cert_utils.c
|
||||
@@ -128,6 +128,13 @@ const uint8_t test_cert_der[] = {
|
||||
"lBPDhfTVcWXQwN385uycW/ARtSzzSME2jKKWSIQ=\n" \
|
||||
"-----END CERTIFICATE-----\n"
|
||||
|
||||
+#define TEST_CERT_PEM_WITH_METADATA "Bag Attributes\n" \
|
||||
+" friendlyName: ipa-devel\n" \
|
||||
+" localKeyID: 8E 0D 04 1F BC 13 73 54 00 8F 65 57 D7 A8 AF 34 0C 18 B3 99\n" \
|
||||
+"subject= /O=IPA.DEVEL/CN=ipa-devel.ipa.devel\n" \
|
||||
+"issuer= /O=IPA.DEVEL/CN=Certificate Authority\n" \
|
||||
+TEST_CERT_PEM
|
||||
+
|
||||
#define TEST_CERT_DERB64 \
|
||||
"MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \
|
||||
"REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA0Mjgx" \
|
||||
@@ -219,6 +226,15 @@ void test_sss_cert_pem_to_der(void **state)
|
||||
assert_memory_equal(der, test_cert_der, der_size);
|
||||
|
||||
talloc_free(der);
|
||||
+
|
||||
+ /* https://pagure.io/SSSD/sssd/issue/3354
|
||||
+ https://tools.ietf.org/html/rfc7468#section-2 */
|
||||
+ ret = sss_cert_pem_to_der(ts, TEST_CERT_PEM_WITH_METADATA, &der, &der_size);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+ assert_int_equal(sizeof(test_cert_der), der_size);
|
||||
+ assert_memory_equal(der, test_cert_der, der_size);
|
||||
+
|
||||
+ talloc_free(der);
|
||||
}
|
||||
|
||||
void test_sss_cert_derb64_to_pem(void **state)
|
||||
diff --git a/src/util/cert/nss/cert.c b/src/util/cert/nss/cert.c
|
||||
index 9d31cfe9b584aa4f87a60ffec03dcf391fe43067..93d4e04220be71ce5823b077525d9f6676e5b763 100644
|
||||
--- a/src/util/cert/nss/cert.c
|
||||
+++ b/src/util/cert/nss/cert.c
|
||||
@@ -147,16 +147,17 @@ errno_t sss_cert_pem_to_der(TALLOC_CTX *mem_ctx, const char *pem,
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
+ if ((pem = strstr(pem, NS_CERT_HEADER)) == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing PEM header.");
|
||||
+ return EINVAL;
|
||||
+ }
|
||||
+
|
||||
pem_len = strlen(pem);
|
||||
if (pem_len <= NS_CERT_HEADER_LEN + NS_CERT_TRAILER_LEN) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "PEM data too short.\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
- if (strncmp(pem, NS_CERT_HEADER, NS_CERT_HEADER_LEN) != 0) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Wrong PEM header.\n");
|
||||
- return EINVAL;
|
||||
- }
|
||||
if (pem[NS_CERT_HEADER_LEN] != '\n') {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Missing newline in PEM data.\n");
|
||||
return EINVAL;
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,48 +0,0 @@
|
||||
From 84fecc2fd535030bc56b5046ba2a1ba95c46bc34 Mon Sep 17 00:00:00 2001
|
||||
From: Lukas Slebodnik <lslebodn@redhat.com>
|
||||
Date: Fri, 24 Mar 2017 10:37:50 +0100
|
||||
Subject: [PATCH 95/97] BUILD: Fix compilation of libsss_certmap with libcrypto
|
||||
|
||||
CC src/lib/certmap/libsss_certmap_la-sss_cert_content_nss.lo
|
||||
src/lib/certmap/sss_cert_content_nss.c:25:18:
|
||||
fatal error: cert.h: No such file or directory
|
||||
#include <cert.h>
|
||||
^
|
||||
compilation terminated.
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
Makefile.am | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 4a414f77df999b8b1d81f663fcc18dbd2d6d2dc4..5264183cd199be464e5e99d2ab31ba4fcd77c5ec 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -1787,7 +1787,6 @@ libsss_certmap_la_DEPENDENCIES = src/lib/certmap/sss_certmap.exports
|
||||
libsss_certmap_la_SOURCES = \
|
||||
src/lib/certmap/sss_certmap.c \
|
||||
src/lib/certmap/sss_certmap_attr_names.c \
|
||||
- src/lib/certmap/sss_cert_content_nss.c \
|
||||
src/lib/certmap/sss_certmap_krb5_match.c \
|
||||
src/lib/certmap/sss_certmap_ldap_mapping.c \
|
||||
src/util/util_ext.c \
|
||||
@@ -1806,6 +1805,7 @@ libsss_certmap_la_LDFLAGS = \
|
||||
|
||||
if HAVE_NSS
|
||||
libsss_certmap_la_SOURCES += \
|
||||
+ src/lib/certmap/sss_cert_content_nss.c \
|
||||
src/util/crypto/nss/nss_base64.c \
|
||||
src/util/cert/nss/cert.c \
|
||||
src/util/crypto/nss/nss_util.c \
|
||||
@@ -1814,6 +1814,7 @@ libsss_certmap_la_CFLAGS += $(NSS_CFLAGS)
|
||||
libsss_certmap_la_LIBADD += $(NSS_LIBS)
|
||||
else
|
||||
libsss_certmap_la_SOURCES += \
|
||||
+ src/lib/certmap/sss_cert_content_crypto.c \
|
||||
src/util/crypto/libcrypto/crypto_base64.c \
|
||||
src/util/cert/libcrypto/cert.c \
|
||||
$(NULL)
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,68 +0,0 @@
|
||||
From 05c2c3047912fca1c1a35ab1c8d3157b05383495 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Mon, 3 Apr 2017 12:56:01 +0200
|
||||
Subject: [PATCH 96/97] responders: do not leak selinux context on clients
|
||||
destruction
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The SELinux context created in get_client_cred is not talloc bound and
|
||||
we were leaking it if available with each client's destruction.
|
||||
|
||||
Resolves:
|
||||
https://pagure.io/SSSD/sssd/issue/3360
|
||||
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/responder/common/responder_common.c | 20 +++++++++++++++++++-
|
||||
1 file changed, 19 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
|
||||
index 154d7dc7718c437d10e152fcba98161e2034fb14..67e1deefdfde19c95a68029b11099579d851513f 100644
|
||||
--- a/src/responder/common/responder_common.c
|
||||
+++ b/src/responder/common/responder_common.c
|
||||
@@ -97,7 +97,7 @@ static errno_t get_client_cred(struct cli_ctx *cctx)
|
||||
SEC_CTX secctx;
|
||||
int ret;
|
||||
|
||||
- cctx->creds = talloc(cctx, struct cli_creds);
|
||||
+ cctx->creds = talloc_zero(cctx, struct cli_creds);
|
||||
if (!cctx->creds) return ENOMEM;
|
||||
|
||||
#ifdef HAVE_UCRED
|
||||
@@ -464,6 +464,22 @@ static void client_fd_handler(struct tevent_context *ev,
|
||||
|
||||
static errno_t setup_client_idle_timer(struct cli_ctx *cctx);
|
||||
|
||||
+static int cli_ctx_destructor(struct cli_ctx *cctx)
|
||||
+{
|
||||
+ if (cctx->creds == NULL) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (cctx->creds->selinux_ctx == NULL) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ SELINUX_context_free(cctx->creds->selinux_ctx);
|
||||
+ cctx->creds->selinux_ctx = NULL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
struct accept_fd_ctx {
|
||||
struct resp_ctx *rctx;
|
||||
bool is_private;
|
||||
@@ -520,6 +536,8 @@ static void accept_fd_handler(struct tevent_context *ev,
|
||||
return;
|
||||
}
|
||||
|
||||
+ talloc_set_destructor(cctx, cli_ctx_destructor);
|
||||
+
|
||||
len = sizeof(cctx->addr);
|
||||
cctx->cfd = accept(fd, (struct sockaddr *)&cctx->addr, &len);
|
||||
if (cctx->cfd == -1) {
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,88 +0,0 @@
|
||||
From b07bcd8b99590bd404733fa7ff1add37c55126bc Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Mon, 3 Apr 2017 12:09:44 +0200
|
||||
Subject: [PATCH 97/97] ipa_s2n_get_acct_info_send: provide correct req_input
|
||||
name
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
To avoid crash.
|
||||
|
||||
Resolves:
|
||||
https://pagure.io/SSSD/sssd/issue/3358
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/providers/ipa/ipa_s2n_exop.c | 40 ++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 36 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
|
||||
index 8a3391b4093f1547d84fe44a0f24b1d063d1e28c..2173db357700499a6140aa61841e443139981483 100644
|
||||
--- a/src/providers/ipa/ipa_s2n_exop.c
|
||||
+++ b/src/providers/ipa/ipa_s2n_exop.c
|
||||
@@ -1054,6 +1054,33 @@ static const char *ipa_s2n_reqtype2str(enum request_types request_type)
|
||||
return "Unknown request type";
|
||||
}
|
||||
|
||||
+static const char *ipa_s2n_reqinp2str(TALLOC_CTX *mem_ctx,
|
||||
+ struct req_input *req_input)
|
||||
+{
|
||||
+ const char *str = NULL;
|
||||
+
|
||||
+ switch (req_input->type) {
|
||||
+ case REQ_INP_NAME:
|
||||
+ str = talloc_strdup(mem_ctx, req_input->inp.name);
|
||||
+ break;
|
||||
+ case REQ_INP_SECID:
|
||||
+ str = talloc_strdup(mem_ctx, req_input->inp.secid);
|
||||
+ break;
|
||||
+ case REQ_INP_CERT:
|
||||
+ str = talloc_strdup(mem_ctx, req_input->inp.cert);
|
||||
+ break;
|
||||
+ case REQ_INP_ID:
|
||||
+ str = talloc_asprintf(mem_ctx, "%u", req_input->inp.id);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (str == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory!\n");
|
||||
+ }
|
||||
+
|
||||
+ return str;
|
||||
+}
|
||||
+
|
||||
struct ipa_s2n_get_list_state {
|
||||
struct tevent_context *ev;
|
||||
struct ipa_id_ctx *ipa_ctx;
|
||||
@@ -1410,6 +1437,7 @@ struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_req *req;
|
||||
struct tevent_req *subreq;
|
||||
struct berval *bv_req = NULL;
|
||||
+ const char *input;
|
||||
int ret = EFAULT;
|
||||
bool is_v1 = false;
|
||||
|
||||
@@ -1454,10 +1482,14 @@ struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, "Sending request_type: [%s] for trust user [%s] "
|
||||
- "to IPA server\n",
|
||||
- ipa_s2n_reqtype2str(state->request_type),
|
||||
- req_input->inp.name);
|
||||
+ if (DEBUG_IS_SET(SSSDBG_TRACE_FUNC)) {
|
||||
+ input = ipa_s2n_reqinp2str(state, req_input);
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ "Sending request_type: [%s] for trust user [%s] to IPA server\n",
|
||||
+ ipa_s2n_reqtype2str(state->request_type),
|
||||
+ input);
|
||||
+ talloc_zfree(input);
|
||||
+ }
|
||||
|
||||
subreq = ipa_s2n_exop_send(state, state->ev, state->sh, is_v1,
|
||||
state->exop_timeout, bv_req);
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,210 +0,0 @@
|
||||
From 78a08d30b5fbf6e1e3b589e0cf67022e0c1faa33 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
|
||||
Date: Wed, 8 Feb 2017 12:01:37 +0100
|
||||
Subject: [PATCH] selinux: Do not fail if SELinux is not managed
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Previously we failed if semanage_is_managed returned 0 or -1 (not
|
||||
managed or error). With this patch we only fail in case of error and
|
||||
continue normally if selinux is not managed by libsemanage at all.
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/3297
|
||||
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
Makefile.am | 1 +
|
||||
src/providers/ipa/selinux_child.c | 9 ++++--
|
||||
src/util/sss_semanage.c | 61 +++++++++++++++++++++++++--------------
|
||||
src/util/util_errors.c | 1 +
|
||||
src/util/util_errors.h | 1 +
|
||||
5 files changed, 49 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 5264183cd..d45c0ff75 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -4040,6 +4040,7 @@ selinux_child_SOURCES = \
|
||||
src/util/atomic_io.c \
|
||||
src/util/util.c \
|
||||
src/util/util_ext.c \
|
||||
+ src/util/util_errors.c
|
||||
$(NULL)
|
||||
selinux_child_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c
|
||||
index 380005c7a..f8dd3954a 100644
|
||||
--- a/src/providers/ipa/selinux_child.c
|
||||
+++ b/src/providers/ipa/selinux_child.c
|
||||
@@ -174,14 +174,19 @@ static bool seuser_needs_update(struct input_buffer *ibuf)
|
||||
|
||||
ret = get_seuser(ibuf, ibuf->username, &db_seuser, &db_mls_range);
|
||||
DEBUG(SSSDBG_TRACE_INTERNAL,
|
||||
- "get_seuser: ret: %d seuser: %s mls: %s\n",
|
||||
- ret, db_seuser ? db_seuser : "unknown",
|
||||
+ "get_seuser: ret: %d msg: [%s] seuser: %s mls: %s\n",
|
||||
+ ret, sss_strerror(ret),
|
||||
+ db_seuser ? db_seuser : "unknown",
|
||||
db_mls_range ? db_mls_range : "unknown");
|
||||
if (ret == EOK && db_seuser && db_mls_range &&
|
||||
strcmp(db_seuser, ibuf->seuser) == 0 &&
|
||||
strcmp(db_mls_range, ibuf->mls_range) == 0) {
|
||||
needs_update = false;
|
||||
}
|
||||
+ /* OR */
|
||||
+ if (ret == ERR_SELINUX_NOT_MANAGED) {
|
||||
+ needs_update = false;
|
||||
+ }
|
||||
|
||||
talloc_free(db_seuser);
|
||||
talloc_free(db_mls_range);
|
||||
diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c
|
||||
index fe06bee1d..0da97aad4 100644
|
||||
--- a/src/util/sss_semanage.c
|
||||
+++ b/src/util/sss_semanage.c
|
||||
@@ -73,7 +73,7 @@ static void sss_semanage_close(semanage_handle_t *handle)
|
||||
semanage_handle_destroy(handle);
|
||||
}
|
||||
|
||||
-static semanage_handle_t *sss_semanage_init(void)
|
||||
+static int sss_semanage_init(semanage_handle_t **_handle)
|
||||
{
|
||||
int ret;
|
||||
semanage_handle_t *handle = NULL;
|
||||
@@ -81,7 +81,8 @@ static semanage_handle_t *sss_semanage_init(void)
|
||||
handle = semanage_handle_create();
|
||||
if (!handle) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n");
|
||||
- return NULL;
|
||||
+ ret = EIO;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
semanage_msg_set_callback(handle,
|
||||
@@ -89,28 +90,41 @@ static semanage_handle_t *sss_semanage_init(void)
|
||||
NULL);
|
||||
|
||||
ret = semanage_is_managed(handle);
|
||||
- if (ret != 1) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "SELinux policy not managed\n");
|
||||
- goto fail;
|
||||
+ if (ret == 0) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "SELinux policy not managed via libsemanage\n");
|
||||
+ ret = ERR_SELINUX_NOT_MANAGED;
|
||||
+ goto done;
|
||||
+ } else if (ret == -1) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Call to semanage_is_managed failed\n");
|
||||
+ ret = EIO;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
ret = semanage_access_check(handle);
|
||||
if (ret < SEMANAGE_CAN_READ) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot read SELinux policy store\n");
|
||||
- goto fail;
|
||||
+ ret = EACCES;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
ret = semanage_connect(handle);
|
||||
if (ret != 0) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
"Cannot estabilish SELinux management connection\n");
|
||||
- goto fail;
|
||||
+ ret = EIO;
|
||||
+ goto done;
|
||||
}
|
||||
|
||||
- return handle;
|
||||
-fail:
|
||||
- sss_semanage_close(handle);
|
||||
- return NULL;
|
||||
+ ret = EOK;
|
||||
+
|
||||
+done:
|
||||
+ if (ret != EOK) {
|
||||
+ sss_semanage_close(handle);
|
||||
+ } else {
|
||||
+ *_handle = handle;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int sss_semanage_user_add(semanage_handle_t *handle,
|
||||
@@ -228,10 +242,11 @@ int set_seuser(const char *login_name, const char *seuser_name,
|
||||
return EOK;
|
||||
}
|
||||
|
||||
- handle = sss_semanage_init();
|
||||
- if (!handle) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init SELinux management\n");
|
||||
- ret = EIO;
|
||||
+ ret = sss_semanage_init(&handle);
|
||||
+ if (ret == ERR_SELINUX_NOT_MANAGED) {
|
||||
+ goto done;
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux handle\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -295,10 +310,11 @@ int del_seuser(const char *login_name)
|
||||
int ret;
|
||||
int exists = 0;
|
||||
|
||||
- handle = sss_semanage_init();
|
||||
- if (!handle) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init SELinux management\n");
|
||||
- ret = EIO;
|
||||
+ ret = sss_semanage_init(&handle);
|
||||
+ if (ret == ERR_SELINUX_NOT_MANAGED) {
|
||||
+ goto done;
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux handle\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -377,10 +393,11 @@ int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name,
|
||||
semanage_seuser_t *sm_user = NULL;
|
||||
semanage_seuser_key_t *sm_key = NULL;
|
||||
|
||||
- sm_handle = sss_semanage_init();
|
||||
- if (sm_handle == NULL) {
|
||||
+ ret = sss_semanage_init(&sm_handle);
|
||||
+ if (ret == ERR_SELINUX_NOT_MANAGED) {
|
||||
+ goto done;
|
||||
+ } else if (ret != EOK) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux handle\n");
|
||||
- ret = EIO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
|
||||
index 466a3b406..97eaf160f 100644
|
||||
--- a/src/util/util_errors.c
|
||||
+++ b/src/util/util_errors.c
|
||||
@@ -75,6 +75,7 @@ struct err_string error_to_str[] = {
|
||||
{ "Cannot connect to system bus" }, /* ERR_NO_SYSBUS */
|
||||
{ "LDAP search returned a referral" }, /* ERR_REFERRAL */
|
||||
{ "Error setting SELinux user context" }, /* ERR_SELINUX_CONTEXT */
|
||||
+ { "SELinux is not managed by libsemanage" }, /* ERR_SELINUX_NOT_MANAGED */
|
||||
{ "Username format not allowed by re_expression" }, /* ERR_REGEX_NOMATCH */
|
||||
{ "Time specification not supported" }, /* ERR_TIMESPEC_NOT_SUPPORTED */
|
||||
{ "Invalid SSSD configuration detected" }, /* ERR_INVALID_CONFIG */
|
||||
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
|
||||
index 2f90c0a5d..4a250bf03 100644
|
||||
--- a/src/util/util_errors.h
|
||||
+++ b/src/util/util_errors.h
|
||||
@@ -97,6 +97,7 @@ enum sssd_errors {
|
||||
ERR_NO_SYSBUS,
|
||||
ERR_REFERRAL,
|
||||
ERR_SELINUX_CONTEXT,
|
||||
+ ERR_SELINUX_NOT_MANAGED,
|
||||
ERR_REGEX_NOMATCH,
|
||||
ERR_TIMESPEC_NOT_SUPPORTED,
|
||||
ERR_INVALID_CONFIG,
|
||||
--
|
||||
2.12.2
|
||||
|
@ -1,38 +0,0 @@
|
||||
From 6a611406e805a1707ca0b9e86b6aa96e02e43ecc Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Thu, 6 Apr 2017 11:23:43 +0200
|
||||
Subject: [PATCH 099/135] DP: Fix typo
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
||||
---
|
||||
src/providers/data_provider/dp_target_id.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/providers/data_provider/dp_target_id.c b/src/providers/data_provider/dp_target_id.c
|
||||
index 0bca9bac27b68a8b905a668992cb8f7650023f65..2088f9529cab83794ac793c7fd5a320f479dbf11 100644
|
||||
--- a/src/providers/data_provider/dp_target_id.c
|
||||
+++ b/src/providers/data_provider/dp_target_id.c
|
||||
@@ -210,7 +210,7 @@ static errno_t dp_initgroups(struct sbus_request *sbus_req,
|
||||
|
||||
ret = sysdb_initgroups(sbus_req, domain, data->filter_value, &res);
|
||||
if (ret == ENOENT || (ret == EOK && res->count == 0)) {
|
||||
- /* There is no point in concacting NSS responder. Proceed as usual. */
|
||||
+ /* There is no point in contacting NSS responder. Proceed as usual. */
|
||||
return EAGAIN;
|
||||
} else if (ret != EOK) {
|
||||
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get initgroups [%d]: %s\n",
|
||||
@@ -274,7 +274,7 @@ errno_t dp_get_account_info_handler(struct sbus_request *sbus_req,
|
||||
}
|
||||
|
||||
if ((data->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_INITGROUPS) {
|
||||
- ret = dp_initgroups(sbus_req, dp_cli, key, dp_flags, data);
|
||||
+ ret = dp_initgroups(sbus_req, dp_cli, key, dp_flags, data);
|
||||
if (ret != EAGAIN) {
|
||||
goto done;
|
||||
}
|
||||
--
|
||||
2.12.2
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user