import sssd-2.3.0-9.el8

This commit is contained in:
CentOS Sources 2020-11-03 06:51:17 -05:00 committed by Andrew Lukoshko
parent 20a068d984
commit f61586ecc1
77 changed files with 23793 additions and 68899 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/sssd-2.2.3.tar.gz
SOURCES/sssd-2.3.0.tar.gz

View File

@ -1 +1 @@
c2b457f85586750f5b22bfedd4cbca5b6f8fdb88 SOURCES/sssd-2.2.3.tar.gz
61b8704c33ea80104fa9d94017c704e333c3c552 SOURCES/sssd-2.3.0.tar.gz

View File

@ -1,35 +0,0 @@
From b626651847e188e89a332b8ac4bfaaa5047e1b3d Mon Sep 17 00:00:00 2001
From: Tomas Halman <thalman@redhat.com>
Date: Tue, 10 Dec 2019 16:30:32 +0100
Subject: [PATCH] INI: sssctl config-check command error messages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In case of parsing error sssctl config-check command does not give
proper error messages with line number. With this patch the error
message is printed again.
Resolves:
https://pagure.io/SSSD/sssd/issue/4129
Reviewed-by: Michal Židek <mzidek@redhat.com>
---
src/util/sss_ini.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/util/sss_ini.c b/src/util/sss_ini.c
index e3699805d..5d91602cd 100644
--- a/src/util/sss_ini.c
+++ b/src/util/sss_ini.c
@@ -865,6 +865,7 @@ int sss_ini_read_sssd_conf(struct sss_ini *self,
ret = sss_ini_parse(self);
if (ret != EOK) {
+ sss_ini_config_print_errors(self->error_list);
DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse configuration.\n");
return ERR_INI_PARSE_FAILED;
}
--
2.20.1

View File

@ -0,0 +1,114 @@
From a7c755672cd277497da3df4714f6d9457b6ac5ae Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 28 May 2020 15:02:43 +0200
Subject: [PATCH] ad_gpo_ndr.c: more ndr updates
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch add another update to the ndr code which was previously
updated by commit c031adde4f532f39845a0efd78693600f1f8b2f4 and
1fdd8fa2fded1985fbfc6aa67394eebcdbb6a2fc.
As missing update in ndr_pull_security_ace() cased
a failure in ad_gpo_parse_sd(). A unit-test for ad_gpo_parse_sd() was
added to prevent similar issues in future.
Resolves: https://github.com/SSSD/sssd/issues/5183
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/providers/ad/ad_gpo_ndr.c | 1 +
src/tests/cmocka/test_ad_gpo.c | 57 ++++++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+)
diff --git a/src/providers/ad/ad_gpo_ndr.c b/src/providers/ad/ad_gpo_ndr.c
index acd7b77c8..71d6d40f2 100644
--- a/src/providers/ad/ad_gpo_ndr.c
+++ b/src/providers/ad/ad_gpo_ndr.c
@@ -317,6 +317,7 @@ ndr_pull_security_ace(struct ndr_pull *ndr,
ndr->offset += pad;
}
if (ndr_flags & NDR_BUFFERS) {
+ NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type));
NDR_CHECK(ndr_pull_security_ace_object_ctr
(ndr, NDR_BUFFERS, &r->object));
}
diff --git a/src/tests/cmocka/test_ad_gpo.c b/src/tests/cmocka/test_ad_gpo.c
index 97f70408a..d1f7a6915 100644
--- a/src/tests/cmocka/test_ad_gpo.c
+++ b/src/tests/cmocka/test_ad_gpo.c
@@ -347,6 +347,60 @@ void test_ad_gpo_ace_includes_host_sid_true(void **state)
group_size, ace_dom_sid, true);
}
+uint8_t test_sid_data[] = {
+0x01, 0x00, 0x04, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x34, 0x01, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00,
+0xbd, 0x00, 0x0e, 0x00, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x00,
+0xda, 0x0e, 0xba, 0x60, 0x0f, 0xa2, 0xf4, 0x55, 0xb5, 0x57, 0x47, 0xf8, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x0a, 0x24, 0x00, 0xff, 0x00, 0x0f, 0x00, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0x15, 0x00, 0x00, 0x00, 0xda, 0x0e, 0xba, 0x60, 0x0f, 0xa2, 0xf4, 0x55, 0xb5, 0x57, 0x47, 0xf8,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0xbd, 0x00, 0x0e, 0x00, 0x01, 0x05, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x00, 0xda, 0x0e, 0xba, 0x60, 0x0f, 0xa2, 0xf4, 0x55,
+0xb5, 0x57, 0x47, 0xf8, 0x07, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x24, 0x00, 0xff, 0x00, 0x0f, 0x00,
+0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x00, 0xda, 0x0e, 0xba, 0x60,
+0x0f, 0xa2, 0xf4, 0x55, 0xb5, 0x57, 0x47, 0xf8, 0x07, 0x02, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00,
+0xbd, 0x00, 0x0e, 0x00, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x00,
+0xda, 0x0e, 0xba, 0x60, 0x0f, 0xa2, 0xf4, 0x55, 0xb5, 0x57, 0x47, 0xf8, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x0a, 0x14, 0x00, 0xff, 0x00, 0x0f, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0xff, 0x00, 0x0f, 0x00, 0x01, 0x01, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x05, 0x12, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x94, 0x00, 0x02, 0x00,
+0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0b, 0x00, 0x00, 0x00, 0x05, 0x02, 0x28, 0x00,
+0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8f, 0xfd, 0xac, 0xed, 0xb3, 0xff, 0xd1, 0x11,
+0xb4, 0x1d, 0x00, 0xa0, 0xc9, 0x68, 0xf9, 0x39, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0x0b, 0x00, 0x00, 0x00, 0x00, 0x02, 0x14, 0x00, 0x94, 0x00, 0x02, 0x00, 0x01, 0x01, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00
+};
+
+void test_ad_gpo_parse_sd(void **state)
+{
+ int ret;
+ struct security_descriptor *sd = NULL;
+
+ ret = ad_gpo_parse_sd(test_ctx, NULL, 0, &sd);
+ assert_int_equal(ret, EINVAL);
+
+ ret = ad_gpo_parse_sd(test_ctx, test_sid_data, sizeof(test_sid_data), &sd);
+ assert_int_equal(ret, EOK);
+ assert_non_null(sd);
+ assert_int_equal(sd->revision, 1);
+ assert_int_equal(sd->type, 39940);
+ assert_null(sd->owner_sid);
+ assert_null(sd->group_sid);
+ assert_null(sd->sacl);
+ assert_non_null(sd->dacl);
+ assert_int_equal(sd->dacl->revision, 4);
+ assert_int_equal(sd->dacl->size, 308);
+ assert_int_equal(sd->dacl->num_aces, 10);
+ assert_int_equal(sd->dacl->aces[0].type, 0);
+ assert_int_equal(sd->dacl->aces[0].flags, 0);
+ assert_int_equal(sd->dacl->aces[0].size, 36);
+ assert_int_equal(sd->dacl->aces[0].access_mask, 917693);
+ /* There are more components and ACEs in the security_descriptor struct
+ * which are not checked here. */
+
+ talloc_free(sd);
+}
+
int main(int argc, const char *argv[])
{
poptContext pc;
@@ -385,6 +439,9 @@ int main(int argc, const char *argv[])
cmocka_unit_test_setup_teardown(test_ad_gpo_ace_includes_host_sid_true,
ad_gpo_test_setup,
ad_gpo_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ad_gpo_parse_sd,
+ ad_gpo_test_setup,
+ ad_gpo_test_teardown),
};
/* Set debug level to invalid value so we can decide if -d 0 was used. */
--
2.21.1

View File

@ -1,42 +0,0 @@
From 21cb9fb28db1f2eb4ee770eb029bfe20233e4392 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 12 Dec 2019 13:10:16 +0100
Subject: [PATCH] certmap: mention special regex characters in man page
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since some of the matching rules use regular expressions some characters
must be escaped so that they can be used a ordinary characters in the
rules.
Related to https://pagure.io/SSSD/sssd/issue/4127
Reviewed-by: Michal Židek <mzidek@redhat.com>
---
src/man/sss-certmap.5.xml | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/man/sss-certmap.5.xml b/src/man/sss-certmap.5.xml
index db258d14a..10343625e 100644
--- a/src/man/sss-certmap.5.xml
+++ b/src/man/sss-certmap.5.xml
@@ -92,6 +92,15 @@
<para>
Example: &lt;SUBJECT&gt;.*,DC=MY,DC=DOMAIN
</para>
+ <para>
+ Please note that the characters "^.[$()|*+?{\" have a
+ special meaning in regular expressions and must be
+ escaped with the help of the '\' character so that they
+ are matched as ordinary characters.
+ </para>
+ <para>
+ Example: &lt;SUBJECT&gt;^CN=.* \(Admin\),DC=MY,DC=DOMAIN$
+ </para>
</listitem>
</varlistentry>
<varlistentry>
--
2.20.1

View File

@ -0,0 +1,39 @@
From 532b75c937d767caf60bb00f1a525ae7f6c70cc6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 20 May 2020 12:07:13 +0200
Subject: [PATCH] test: avoid endian issues in network tests
Reviewed-by: Alexey Tikhonov <atikhonov@redhat.com>
---
src/tests/cmocka/test_nss_srv.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
index 2c91d0a23..3cd7809cf 100644
--- a/src/tests/cmocka/test_nss_srv.c
+++ b/src/tests/cmocka/test_nss_srv.c
@@ -35,6 +35,7 @@
#include "util/util_sss_idmap.h"
#include "util/crypto/sss_crypto.h"
#include "util/crypto/nss/nss_util.h"
+#include "util/sss_endian.h"
#include "db/sysdb_private.h" /* new_subdomain() */
#include "db/sysdb_iphosts.h"
#include "db/sysdb_ipnetworks.h"
@@ -5308,7 +5309,13 @@ struct netent test_netent = {
.n_name = discard_const("test_network"),
.n_aliases = discard_const(test_netent_aliases),
.n_addrtype = AF_INET,
+#if (__BYTE_ORDER == __LITTLE_ENDIAN)
.n_net = 0x04030201 /* 1.2.3.4 */
+#elif (__BYTE_ORDER == __BIG_ENDIAN)
+ .n_net = 0x01020304 /* 1.2.3.4 */
+#else
+ #error "unknow endianess"
+#endif
};
static void mock_input_netbyname(const char *name)
--
2.21.1

View File

@ -1,98 +0,0 @@
From 580d61884b6c0a81357d8f9fa69fe69d1f017185 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 6 Dec 2019 12:29:49 +0100
Subject: [PATCH] ldap_child: do not try PKINIT
if the PKINIT plugin is installed and pkinit_identities is set in
/etc/krb5.conf libkrb5 will try to do PKINIT although ldap_child only
wants to authenticate with a keytab. As a result ldap_child might try to
access a Smartcard which is either not allowed at all or might cause
unexpected delays.
To avoid this the current patch sets pkinit_identities for LDAP child
explicitly to make the PKINIT plugin fail because if installed libkrb5
will always use it.
It turned out the setting pre-authentication options requires some
internal flags to be set and krb5_get_init_creds_opt_alloc() must be
used to initialize the options struct.
Related to https://pagure.io/SSSD/sssd/issue/4126
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
---
src/providers/ldap/ldap_child.c | 30 ++++++++++++++++++++++--------
1 file changed, 22 insertions(+), 8 deletions(-)
diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c
index 408d64db4..b081df90f 100644
--- a/src/providers/ldap/ldap_child.c
+++ b/src/providers/ldap/ldap_child.c
@@ -277,7 +277,7 @@ static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx,
krb5_ccache ccache = NULL;
krb5_principal kprinc;
krb5_creds my_creds;
- krb5_get_init_creds_opt options;
+ krb5_get_init_creds_opt *options = NULL;
krb5_error_code krberr;
krb5_timestamp kdc_time_offset;
int canonicalize = 0;
@@ -392,19 +392,32 @@ static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx,
}
memset(&my_creds, 0, sizeof(my_creds));
- memset(&options, 0, sizeof(options));
- krb5_get_init_creds_opt_set_address_list(&options, NULL);
- krb5_get_init_creds_opt_set_forwardable(&options, 0);
- krb5_get_init_creds_opt_set_proxiable(&options, 0);
- krb5_get_init_creds_opt_set_tkt_life(&options, lifetime);
+ krberr = krb5_get_init_creds_opt_alloc(context, &options);
+ if (krberr != 0) {
+ DEBUG(SSSDBG_OP_FAILURE, "krb5_get_init_creds_opt_alloc failed.\n");
+ goto done;
+ }
+
+ krb5_get_init_creds_opt_set_address_list(options, NULL);
+ krb5_get_init_creds_opt_set_forwardable(options, 0);
+ krb5_get_init_creds_opt_set_proxiable(options, 0);
+ krb5_get_init_creds_opt_set_tkt_life(options, lifetime);
+ krberr = krb5_get_init_creds_opt_set_pa(context, options,
+ "X509_user_identity", "");
+ if (krberr != 0) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "krb5_get_init_creds_opt_set_pa failed [%d], ignored.\n",
+ krberr);
+ }
+
tmp_str = getenv("KRB5_CANONICALIZE");
if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) {
DEBUG(SSSDBG_CONF_SETTINGS, "Will canonicalize principals\n");
canonicalize = 1;
}
- sss_krb5_get_init_creds_opt_set_canonicalize(&options, canonicalize);
+ sss_krb5_get_init_creds_opt_set_canonicalize(options, canonicalize);
ccname_file = talloc_asprintf(tmp_ctx, "%s/ccache_%s",
DB_PATH, realm_name);
@@ -433,7 +446,7 @@ static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx,
}
krberr = krb5_get_init_creds_keytab(context, &my_creds, kprinc,
- keytab, 0, NULL, &options);
+ keytab, 0, NULL, options);
if (krberr != 0) {
DEBUG(SSSDBG_OP_FAILURE,
"krb5_get_init_creds_keytab() failed: %d\n", krberr);
@@ -513,6 +526,7 @@ static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx,
*expire_time_out = my_creds.times.endtime - kdc_time_offset;
done:
+ krb5_get_init_creds_opt_free(context, options);
if (krberr != 0) {
if (*_krb5_msg == NULL) {
/* no custom error message provided hence get one from libkrb5 */
--
2.20.1

View File

@ -0,0 +1,137 @@
From 61f4aaa56ea876fb75c1366c938818b7799408ab Mon Sep 17 00:00:00 2001
From: Tomas Halman <thalman@redhat.com>
Date: Wed, 29 Apr 2020 16:40:36 +0200
Subject: [PATCH] sssctl: sssctl config-check alternative config file
The sssctl config-check now allows to specify alternative config
file so it can be tested before rewriting system configuration.
sssctl config-check -c ./sssd.conf
Configuration snippets are looked up in the same place under
conf.d directory. It would be in ./conf.d/ for the example above.
Resolves:
https://github.com/SSSD/sssd/issues/5142
Reviewed-by: Pawel Polawski <ppolawsk@redhat.com>
---
src/confdb/confdb.h | 6 ++--
src/tools/sssctl/sssctl_config.c | 56 ++++++++++++++++++++++++++++----
2 files changed, 53 insertions(+), 9 deletions(-)
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 0a5593232..a2b58e12a 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -40,8 +40,10 @@
#define CONFDB_DEFAULT_CFG_FILE_VER 2
#define CONFDB_FILE "config.ldb"
-#define SSSD_CONFIG_FILE SSSD_CONF_DIR"/sssd.conf"
-#define CONFDB_DEFAULT_CONFIG_DIR SSSD_CONF_DIR"/conf.d"
+#define SSSD_CONFIG_FILE_NAME "sssd.conf"
+#define SSSD_CONFIG_FILE SSSD_CONF_DIR"/"SSSD_CONFIG_FILE_NAME
+#define CONFDB_DEFAULT_CONFIG_DIR_NAME "conf.d"
+#define CONFDB_DEFAULT_CONFIG_DIR SSSD_CONF_DIR"/"CONFDB_DEFAULT_CONFIG_DIR_NAME
#define SSSD_MIN_ID 1
#define SSSD_LOCAL_MINID 1000
#define CONFDB_DEFAULT_SHELL_FALLBACK "/bin/sh"
diff --git a/src/tools/sssctl/sssctl_config.c b/src/tools/sssctl/sssctl_config.c
index 74395b61c..de9f3de6e 100644
--- a/src/tools/sssctl/sssctl_config.c
+++ b/src/tools/sssctl/sssctl_config.c
@@ -34,6 +34,29 @@
#ifdef HAVE_LIBINI_CONFIG_V1_3
+
+static char *sssctl_config_snippet_path(TALLOC_CTX *ctx, const char *path)
+{
+ char *tmp = NULL;
+ const char delimiter = '/';
+ char *dpos = NULL;
+
+ tmp = talloc_strdup(ctx, path);
+ if (!tmp) {
+ return NULL;
+ }
+
+ dpos = strrchr(tmp, delimiter);
+ if (dpos != NULL) {
+ ++dpos;
+ *dpos = '\0';
+ } else {
+ *tmp = '\0';
+ }
+
+ return talloc_strdup_append(tmp, CONFDB_DEFAULT_CONFIG_DIR_NAME);
+}
+
errno_t sssctl_config_check(struct sss_cmdline *cmdline,
struct sss_tool_ctx *tool_ctx,
void *pvt)
@@ -47,8 +70,15 @@ errno_t sssctl_config_check(struct sss_cmdline *cmdline,
size_t num_ra_error, num_ra_success;
char **strs = NULL;
TALLOC_CTX *tmp_ctx = NULL;
-
- ret = sss_tool_popt(cmdline, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL);
+ const char *config_path = NULL;
+ const char *config_snippet_path = NULL;
+ struct poptOption long_options[] = {
+ {"config", 'c', POPT_ARG_STRING, &config_path,
+ 0, _("Specify a non-default config file"), NULL},
+ POPT_TABLEEND
+ };
+
+ ret = sss_tool_popt(cmdline, long_options, SSS_TOOL_OPT_OPTIONAL, NULL, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command arguments\n");
return ret;
@@ -62,17 +92,29 @@ errno_t sssctl_config_check(struct sss_cmdline *cmdline,
goto done;
}
+ if (config_path != NULL) {
+ config_snippet_path = sssctl_config_snippet_path(tmp_ctx, config_path);
+ if (config_snippet_path == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create snippet path\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ } else {
+ config_path = SSSD_CONFIG_FILE;
+ config_snippet_path = CONFDB_DEFAULT_CONFIG_DIR;
+ }
+
ret = sss_ini_read_sssd_conf(init_data,
- SSSD_CONFIG_FILE,
- CONFDB_DEFAULT_CONFIG_DIR);
+ config_path,
+ config_snippet_path);
if (ret == ERR_INI_OPEN_FAILED) {
- PRINT("Failed to open %s\n", SSSD_CONFIG_FILE);
+ PRINT("Failed to open %s\n", config_path);
goto done;
}
if (!sss_ini_exists(init_data)) {
- PRINT("File %1$s does not exist.\n", SSSD_CONFIG_FILE);
+ PRINT("File %1$s does not exist.\n", config_path);
}
if (ret == ERR_INI_INVALID_PERMISSION) {
@@ -83,7 +125,7 @@ errno_t sssctl_config_check(struct sss_cmdline *cmdline,
if (ret == ERR_INI_PARSE_FAILED) {
PRINT("Failed to load configuration from %s.\n",
- SSSD_CONFIG_FILE);
+ config_path);
goto done;
}
--
2.21.1

View File

@ -0,0 +1,664 @@
From 375887543daf26003ff7d900cf6a69d0c0b58523 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Wed, 27 May 2020 22:33:50 +0200
Subject: [PATCH] DEBUG: only open child process log files when required
There was no reason to keep child process log files open permanently.
This patch:
- helps to avoid issue when SIGHUP was ignored for child process logs;
- somewhat reduces code duplication.
Resolves: https://github.com/SSSD/sssd/issues/4667
Reviewed-by: Pawel Polawski <ppolawsk@redhat.com>
---
src/providers/ad/ad_gpo.c | 17 +++--------------
src/providers/ad/ad_init.c | 7 -------
src/providers/ad/ad_machine_pw_renewal.c | 2 +-
src/providers/ipa/ipa_init.c | 7 -------
src/providers/ipa/ipa_selinux.c | 17 +----------------
src/providers/krb5/krb5_child_handler.c | 2 +-
src/providers/krb5/krb5_common.h | 1 -
src/providers/krb5/krb5_init_shared.c | 8 --------
src/providers/ldap/ldap_common.c | 3 ---
src/providers/ldap/ldap_common.h | 6 ------
src/providers/ldap/ldap_init.c | 7 -------
src/providers/ldap/sdap_child_helpers.c | 10 +---------
src/responder/pam/pamsrv.c | 1 -
src/responder/pam/pamsrv.h | 2 --
src/responder/pam/pamsrv_cmd.c | 2 +-
src/responder/pam/pamsrv_p11.c | 9 ++-------
src/responder/ssh/ssh_private.h | 1 -
src/responder/ssh/ssh_reply.c | 4 ++--
src/responder/ssh/sshsrv.c | 10 ----------
src/tests/cmocka/test_cert_utils.c | 12 ++++++------
src/util/cert.h | 2 +-
src/util/cert/cert_common_p11_child.c | 9 ++++-----
src/util/child_common.c | 21 +++++++++++++++++----
src/util/child_common.h | 6 ++----
24 files changed, 42 insertions(+), 124 deletions(-)
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index f17917552..bbe8d8a1e 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -99,15 +99,14 @@
#define GPO_CHILD SSSD_LIBEXEC_PATH"/gpo_child"
#endif
+#define GPO_CHILD_LOG_FILE "gpo_child"
+
/* If INI_PARSE_IGNORE_NON_KVP is not defined, use 0 (no effect) */
#ifndef INI_PARSE_IGNORE_NON_KVP
#define INI_PARSE_IGNORE_NON_KVP 0
#warning INI_PARSE_IGNORE_NON_KVP not defined.
#endif
-/* fd used by the gpo_child process for logging */
-int gpo_child_debug_fd = -1;
-
/* == common data structures and declarations ============================= */
struct gp_som {
@@ -1618,13 +1617,6 @@ ad_gpo_access_check(TALLOC_CTX *mem_ctx,
return ret;
}
-#define GPO_CHILD_LOG_FILE "gpo_child"
-
-static errno_t gpo_child_init(void)
-{
- return child_debug_init(GPO_CHILD_LOG_FILE, &gpo_child_debug_fd);
-}
-
/*
* This function retrieves the raw policy_setting_value for the input key from
* the GPO_Result object in the sysdb cache. It then parses the raw value and
@@ -1808,9 +1800,6 @@ ad_gpo_access_send(TALLOC_CTX *mem_ctx,
hash_value_t val;
enum gpo_map_type gpo_map_type;
- /* setup logging for gpo child */
- gpo_child_init();
-
req = tevent_req_create(mem_ctx, &state, struct ad_gpo_access_state);
if (req == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
@@ -4763,7 +4752,7 @@ gpo_fork_child(struct tevent_req *req)
if (pid == 0) { /* child */
exec_child_ex(state,
pipefd_to_child, pipefd_from_child,
- GPO_CHILD, gpo_child_debug_fd, NULL, false,
+ GPO_CHILD, GPO_CHILD_LOG_FILE, NULL, false,
STDIN_FILENO, AD_GPO_CHILD_OUT_FILENO);
/* We should never get here */
diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c
index 05535fcb0..704e63a06 100644
--- a/src/providers/ad/ad_init.c
+++ b/src/providers/ad/ad_init.c
@@ -402,13 +402,6 @@ static errno_t ad_init_misc(struct be_ctx *be_ctx,
sdap_id_ctx->opts->sdom->pvt = ad_id_ctx;
- ret = sdap_setup_child();
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "sdap_setup_child() failed [%d]: %s\n",
- ret, sss_strerror(ret));
- return ret;
- }
-
ret = ad_init_srv_plugin(be_ctx, ad_options);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup SRV plugin [%d]: %s\n",
diff --git a/src/providers/ad/ad_machine_pw_renewal.c b/src/providers/ad/ad_machine_pw_renewal.c
index e0db5fad5..ce9bbe6f3 100644
--- a/src/providers/ad/ad_machine_pw_renewal.c
+++ b/src/providers/ad/ad_machine_pw_renewal.c
@@ -185,7 +185,7 @@ ad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx,
child_pid = fork();
if (child_pid == 0) { /* child */
exec_child_ex(state, pipefd_to_child, pipefd_from_child,
- renewal_data->prog_path, -1,
+ renewal_data->prog_path, NULL,
extra_args, true,
STDIN_FILENO, STDERR_FILENO);
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index cdfd11d7a..d8d592653 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -571,13 +571,6 @@ static errno_t ipa_init_misc(struct be_ctx *be_ctx,
return ret;
}
- ret = sdap_setup_child();
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup sdap child [%d]: %s\n",
- ret, sss_strerror(ret));
- return ret;
- }
-
if (dp_opt_get_bool(ipa_options->basic, IPA_SERVER_MODE)) {
ret = ipa_init_server_mode(be_ctx, ipa_options, ipa_id_ctx);
if (ret != EOK) {
diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c
index 630f68ad5..9ae37b90d 100644
--- a/src/providers/ipa/ipa_selinux.c
+++ b/src/providers/ipa/ipa_selinux.c
@@ -51,9 +51,6 @@
#include <selinux/selinux.h>
-/* fd used by the selinux_child process for logging */
-int selinux_child_debug_fd = -1;
-
static struct tevent_req *
ipa_get_selinux_send(TALLOC_CTX *mem_ctx,
struct be_ctx *be_ctx,
@@ -565,7 +562,6 @@ struct selinux_child_state {
struct child_io_fds *io;
};
-static errno_t selinux_child_init(void);
static errno_t selinux_child_create_buffer(struct selinux_child_state *state);
static errno_t selinux_fork_child(struct selinux_child_state *state);
static void selinux_child_step(struct tevent_req *subreq);
@@ -602,12 +598,6 @@ static struct tevent_req *selinux_child_send(TALLOC_CTX *mem_ctx,
state->io->read_from_child_fd = -1;
talloc_set_destructor((void *) state->io, child_io_destructor);
- ret = selinux_child_init();
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Failed to init the child\n");
- goto immediately;
- }
-
ret = selinux_child_create_buffer(state);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Failed to create the send buffer\n");
@@ -638,11 +628,6 @@ immediately:
return req;
}
-static errno_t selinux_child_init(void)
-{
- return child_debug_init(SELINUX_CHILD_LOG_FILE, &selinux_child_debug_fd);
-}
-
static errno_t selinux_child_create_buffer(struct selinux_child_state *state)
{
size_t rp;
@@ -712,7 +697,7 @@ static errno_t selinux_fork_child(struct selinux_child_state *state)
if (pid == 0) { /* child */
exec_child(state, pipefd_to_child, pipefd_from_child,
- SELINUX_CHILD, selinux_child_debug_fd);
+ SELINUX_CHILD, SELINUX_CHILD_LOG_FILE);
DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec selinux_child: [%d][%s].\n",
ret, sss_strerror(ret));
return ret;
diff --git a/src/providers/krb5/krb5_child_handler.c b/src/providers/krb5/krb5_child_handler.c
index b7fb54499..8546285b2 100644
--- a/src/providers/krb5/krb5_child_handler.c
+++ b/src/providers/krb5/krb5_child_handler.c
@@ -465,7 +465,7 @@ static errno_t fork_child(struct tevent_req *req)
if (pid == 0) { /* child */
exec_child_ex(state,
pipefd_to_child, pipefd_from_child,
- KRB5_CHILD, state->kr->krb5_ctx->child_debug_fd,
+ KRB5_CHILD, KRB5_CHILD_LOG_FILE,
krb5_child_extra_args, false,
STDIN_FILENO, STDOUT_FILENO);
diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
index 493d12e5f..f198e2684 100644
--- a/src/providers/krb5/krb5_common.h
+++ b/src/providers/krb5/krb5_common.h
@@ -124,7 +124,6 @@ struct krb5_ctx {
struct dp_option *opts;
struct krb5_service *service;
struct krb5_service *kpasswd_service;
- int child_debug_fd;
sss_regexp_t *illegal_path_re;
diff --git a/src/providers/krb5/krb5_init_shared.c b/src/providers/krb5/krb5_init_shared.c
index afe15b365..ea3d32805 100644
--- a/src/providers/krb5/krb5_init_shared.c
+++ b/src/providers/krb5/krb5_init_shared.c
@@ -71,14 +71,6 @@ errno_t krb5_child_init(struct krb5_ctx *krb5_auth_ctx,
goto done;
}
- krb5_auth_ctx->child_debug_fd = -1; /* -1 means not initialized */
- ret = child_debug_init(KRB5_CHILD_LOG_FILE,
- &krb5_auth_ctx->child_debug_fd);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Could not set krb5_child debugging!\n");
- goto done;
- }
-
ret = parse_krb5_map_user(krb5_auth_ctx,
dp_opt_get_cstring(krb5_auth_ctx->opts,
KRB5_MAP_USER),
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index 9d7806a2f..2133db36f 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -35,9 +35,6 @@
#include "providers/ldap/sdap_idmap.h"
-/* a fd the child process would log into */
-int ldap_child_debug_fd = -1;
-
errno_t ldap_id_setup_tasks(struct sdap_id_ctx *ctx)
{
return sdap_id_setup_tasks(ctx->be, ctx, ctx->opts->sdom,
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 63ee5dd84..13e6d4871 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -44,9 +44,6 @@
#define LDAP_ENUM_PURGE_TIMEOUT 10800
-/* a fd the child process would log into */
-extern int ldap_child_debug_fd;
-
struct sdap_id_ctx;
struct sdap_id_conn_ctx {
@@ -342,9 +339,6 @@ sdap_ipnetwork_handler_recv(TALLOC_CTX *mem_ctx,
struct tevent_req *req,
struct dp_reply_std *data);
-/* setup child logging */
-int sdap_setup_child(void);
-
errno_t string_to_shadowpw_days(const char *s, long *d);
diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c
index 1be5d13de..de64e5985 100644
--- a/src/providers/ldap/ldap_init.c
+++ b/src/providers/ldap/ldap_init.c
@@ -419,13 +419,6 @@ static errno_t ldap_init_misc(struct be_ctx *be_ctx,
return ret;
}
- ret = sdap_setup_child();
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup sdap child [%d]: %s\n",
- ret, sss_strerror(ret));
- return ret;
- }
-
/* Setup SRV lookup plugin */
ret = be_fo_set_dns_srv_lookup_plugin(be_ctx, NULL);
if (ret != EOK) {
diff --git a/src/providers/ldap/sdap_child_helpers.c b/src/providers/ldap/sdap_child_helpers.c
index a03d28c9c..9d25aea8b 100644
--- a/src/providers/ldap/sdap_child_helpers.c
+++ b/src/providers/ldap/sdap_child_helpers.c
@@ -111,7 +111,7 @@ static errno_t sdap_fork_child(struct tevent_context *ev,
if (pid == 0) { /* child */
exec_child(child,
pipefd_to_child, pipefd_from_child,
- LDAP_CHILD, ldap_child_debug_fd);
+ LDAP_CHILD, LDAP_CHILD_LOG_FILE);
/* We should never get here */
DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Could not exec LDAP child\n");
@@ -512,11 +512,3 @@ static errno_t set_tgt_child_timeout(struct tevent_req *req,
return EOK;
}
-
-
-
-/* Setup child logging */
-int sdap_setup_child(void)
-{
- return child_debug_init(LDAP_CHILD_LOG_FILE, &ldap_child_debug_fd);
-}
diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
index a4c9ebbbb..dde44a472 100644
--- a/src/responder/pam/pamsrv.c
+++ b/src/responder/pam/pamsrv.c
@@ -277,7 +277,6 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
goto done;
}
- pctx->p11_child_debug_fd = -1;
if (pctx->cert_auth) {
ret = p11_child_init(pctx);
if (ret != EOK) {
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index 24bd9764d..478d91b93 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -54,7 +54,6 @@ struct pam_ctx {
char **app_services;
bool cert_auth;
- int p11_child_debug_fd;
char *nss_db;
struct sss_certmap_ctx *sss_certmap_ctx;
char **smartcard_services;
@@ -110,7 +109,6 @@ void sss_cai_check_users(struct cert_auth_info **list, size_t *_cert_count,
struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
- int child_debug_fd,
const char *nss_db,
time_t timeout,
const char *verify_opts,
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index ddde9eda2..1cd901f15 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -1404,7 +1404,7 @@ static errno_t check_cert(TALLOC_CTX *mctx,
return ret;
}
- req = pam_check_cert_send(mctx, ev, pctx->p11_child_debug_fd,
+ req = pam_check_cert_send(mctx, ev,
pctx->nss_db, p11_child_timeout,
cert_verification_opts, pctx->sss_certmap_ctx,
uri, pd);
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index 8e276b200..3f0afaeff 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -242,7 +242,7 @@ errno_t p11_child_init(struct pam_ctx *pctx)
return ret;
}
- return child_debug_init(P11_CHILD_LOG_FILE, &pctx->p11_child_debug_fd);
+ return EOK;
}
static inline bool
@@ -705,7 +705,6 @@ static void p11_child_timeout(struct tevent_context *ev,
struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
- int child_debug_fd,
const char *nss_db,
time_t timeout,
const char *verify_opts,
@@ -838,14 +837,10 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
goto done;
}
- if (child_debug_fd == -1) {
- child_debug_fd = STDERR_FILENO;
- }
-
child_pid = fork();
if (child_pid == 0) { /* child */
exec_child_ex(state, pipefd_to_child, pipefd_from_child,
- P11_CHILD_PATH, child_debug_fd, extra_args, false,
+ P11_CHILD_PATH, P11_CHILD_LOG_FILE, extra_args, false,
STDIN_FILENO, STDOUT_FILENO);
/* We should never get here */
diff --git a/src/responder/ssh/ssh_private.h b/src/responder/ssh/ssh_private.h
index 028ccd616..5aa7e37d6 100644
--- a/src/responder/ssh/ssh_private.h
+++ b/src/responder/ssh/ssh_private.h
@@ -36,7 +36,6 @@ struct ssh_ctx {
char *ca_db;
bool use_cert_keys;
- int p11_child_debug_fd;
time_t certmap_last_read;
struct sss_certmap_ctx *sss_certmap_ctx;
char **cert_rules;
diff --git a/src/responder/ssh/ssh_reply.c b/src/responder/ssh/ssh_reply.c
index 97914266d..edeb28765 100644
--- a/src/responder/ssh/ssh_reply.c
+++ b/src/responder/ssh/ssh_reply.c
@@ -249,7 +249,7 @@ struct tevent_req *ssh_get_output_keys_send(TALLOC_CTX *mem_ctx,
: state->user_cert_override;
subreq = cert_to_ssh_key_send(state, state->ev,
- state->ssh_ctx->p11_child_debug_fd,
+ P11_CHILD_LOG_FILE,
state->p11_child_timeout,
state->ssh_ctx->ca_db,
state->ssh_ctx->sss_certmap_ctx,
@@ -335,7 +335,7 @@ void ssh_get_output_keys_done(struct tevent_req *subreq)
goto done;
}
- subreq = cert_to_ssh_key_send(state, state->ev, -1,
+ subreq = cert_to_ssh_key_send(state, state->ev, NULL,
state->p11_child_timeout,
state->ssh_ctx->ca_db,
state->ssh_ctx->sss_certmap_ctx,
diff --git a/src/responder/ssh/sshsrv.c b/src/responder/ssh/sshsrv.c
index 7765e91b8..6072a702c 100644
--- a/src/responder/ssh/sshsrv.c
+++ b/src/responder/ssh/sshsrv.c
@@ -126,16 +126,6 @@ int ssh_process_init(TALLOC_CTX *mem_ctx,
goto fail;
}
- ssh_ctx->p11_child_debug_fd = -1;
- if (ssh_ctx->use_cert_keys) {
- ret = child_debug_init(P11_CHILD_LOG_FILE,
- &ssh_ctx->p11_child_debug_fd);
- if (ret != EOK) {
- DEBUG(SSSDBG_FATAL_FAILURE,
- "Failed to setup p11_child logging, ignored.\n");
- }
- }
-
ret = schedule_get_domains_task(rctx, rctx->ev, rctx, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n");
diff --git a/src/tests/cmocka/test_cert_utils.c b/src/tests/cmocka/test_cert_utils.c
index 848ed1a8d..1ff20576a 100644
--- a/src/tests/cmocka/test_cert_utils.c
+++ b/src/tests/cmocka/test_cert_utils.c
@@ -391,7 +391,7 @@ void test_cert_to_ssh_key_send(void **state)
ev = tevent_context_init(ts);
assert_non_null(ev);
- req = cert_to_ssh_key_send(ts, ev, -1, P11_CHILD_TIMEOUT,
+ req = cert_to_ssh_key_send(ts, ev, NULL, P11_CHILD_TIMEOUT,
#ifdef HAVE_NSS
"sql:" ABS_BUILD_DIR "/src/tests/test_CA/p11_nssdb",
#else
@@ -465,7 +465,7 @@ void test_cert_to_ssh_2keys_send(void **state)
ev = tevent_context_init(ts);
assert_non_null(ev);
- req = cert_to_ssh_key_send(ts, ev, -1, P11_CHILD_TIMEOUT,
+ req = cert_to_ssh_key_send(ts, ev, NULL, P11_CHILD_TIMEOUT,
#ifdef HAVE_NSS
"sql:" ABS_BUILD_DIR "/src/tests/test_CA/p11_nssdb",
#else
@@ -548,7 +548,7 @@ void test_cert_to_ssh_2keys_invalid_send(void **state)
ev = tevent_context_init(ts);
assert_non_null(ev);
- req = cert_to_ssh_key_send(ts, ev, -1, P11_CHILD_TIMEOUT,
+ req = cert_to_ssh_key_send(ts, ev, NULL, P11_CHILD_TIMEOUT,
#ifdef HAVE_NSS
"sql:" ABS_BUILD_DIR "/src/tests/test_CA/p11_nssdb",
#else
@@ -614,7 +614,7 @@ void test_ec_cert_to_ssh_key_send(void **state)
ev = tevent_context_init(ts);
assert_non_null(ev);
- req = cert_to_ssh_key_send(ts, ev, -1, P11_CHILD_TIMEOUT,
+ req = cert_to_ssh_key_send(ts, ev, NULL, P11_CHILD_TIMEOUT,
#ifdef HAVE_NSS
"sql:" ABS_BUILD_DIR "/src/tests/test_ECC_CA/p11_ecc_nssdb",
#else
@@ -691,7 +691,7 @@ void test_cert_to_ssh_2keys_with_certmap_send(void **state)
ev = tevent_context_init(ts);
assert_non_null(ev);
- req = cert_to_ssh_key_send(ts, ev, -1, P11_CHILD_TIMEOUT,
+ req = cert_to_ssh_key_send(ts, ev, NULL, P11_CHILD_TIMEOUT,
#ifdef HAVE_NSS
"sql:" ABS_BUILD_DIR "/src/tests/test_CA/p11_nssdb",
#else
@@ -769,7 +769,7 @@ void test_cert_to_ssh_2keys_with_certmap_2_send(void **state)
ev = tevent_context_init(ts);
assert_non_null(ev);
- req = cert_to_ssh_key_send(ts, ev, -1, P11_CHILD_TIMEOUT,
+ req = cert_to_ssh_key_send(ts, ev, NULL, P11_CHILD_TIMEOUT,
#ifdef HAVE_NSS
"sql:" ABS_BUILD_DIR "/src/tests/test_CA/p11_nssdb",
#else
diff --git a/src/util/cert.h b/src/util/cert.h
index d038a99f6..16dda37b3 100644
--- a/src/util/cert.h
+++ b/src/util/cert.h
@@ -57,7 +57,7 @@ errno_t get_ssh_key_from_derb64(TALLOC_CTX *mem_ctx, const char *derb64,
struct tevent_req *cert_to_ssh_key_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
- int child_debug_fd, time_t timeout,
+ const char *logfile, time_t timeout,
const char *ca_db,
struct sss_certmap_ctx *sss_certmap_ctx,
size_t cert_count,
diff --git a/src/util/cert/cert_common_p11_child.c b/src/util/cert/cert_common_p11_child.c
index 1846ff89a..18a331f23 100644
--- a/src/util/cert/cert_common_p11_child.c
+++ b/src/util/cert/cert_common_p11_child.c
@@ -24,7 +24,7 @@
struct cert_to_ssh_key_state {
struct tevent_context *ev;
- int child_debug_fd;
+ const char *logfile;
time_t timeout;
const char **extra_args;
const char **certs;
@@ -45,7 +45,7 @@ static void cert_to_ssh_key_done(int child_status,
struct tevent_req *cert_to_ssh_key_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
- int child_debug_fd, time_t timeout,
+ const char *logfile, time_t timeout,
const char *ca_db,
struct sss_certmap_ctx *sss_certmap_ctx,
size_t cert_count,
@@ -70,8 +70,7 @@ struct tevent_req *cert_to_ssh_key_send(TALLOC_CTX *mem_ctx,
}
state->ev = ev;
- state->child_debug_fd = (child_debug_fd == -1) ? STDERR_FILENO
- : child_debug_fd;
+ state->logfile = logfile;
state->timeout = timeout;
state->io = talloc(state, struct child_io_fds);
if (state->io == NULL) {
@@ -205,7 +204,7 @@ static errno_t cert_to_ssh_key_step(struct tevent_req *req)
child_pid = fork();
if (child_pid == 0) { /* child */
exec_child_ex(state, pipefd_to_child, pipefd_from_child, P11_CHILD_PATH,
- state->child_debug_fd, state->extra_args, false,
+ state->logfile, state->extra_args, false,
STDIN_FILENO, STDOUT_FILENO);
/* We should never get here */
DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Could not exec p11 child\n");
diff --git a/src/util/child_common.c b/src/util/child_common.c
index 3a07580c2..5cac725ca 100644
--- a/src/util/child_common.c
+++ b/src/util/child_common.c
@@ -47,6 +47,8 @@ struct sss_child_ctx {
struct sss_sigchild_ctx *sigchld_ctx;
};
+static errno_t child_debug_init(const char *logfile, int *debug_fd);
+
static void sss_child_handler(struct tevent_context *ev,
struct tevent_signal *se,
int signum,
@@ -725,13 +727,24 @@ fail:
void exec_child_ex(TALLOC_CTX *mem_ctx,
int *pipefd_to_child, int *pipefd_from_child,
- const char *binary, int debug_fd,
+ const char *binary, const char *logfile,
const char *extra_argv[], bool extra_args_only,
int child_in_fd, int child_out_fd)
{
int ret;
errno_t err;
char **argv;
+ int debug_fd = -1;
+
+ if (logfile) {
+ ret = child_debug_init(logfile, &debug_fd);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "child_debug_init() failed.\n");
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ debug_fd = STDERR_FILENO;
+ }
close(pipefd_to_child[1]);
ret = dup2(pipefd_to_child[0], child_in_fd);
@@ -767,10 +780,10 @@ void exec_child_ex(TALLOC_CTX *mem_ctx,
void exec_child(TALLOC_CTX *mem_ctx,
int *pipefd_to_child, int *pipefd_from_child,
- const char *binary, int debug_fd)
+ const char *binary, const char *logfile)
{
exec_child_ex(mem_ctx, pipefd_to_child, pipefd_from_child,
- binary, debug_fd, NULL, false,
+ binary, logfile, NULL, false,
STDIN_FILENO, STDOUT_FILENO);
}
@@ -803,7 +816,7 @@ int child_io_destructor(void *ptr)
return EOK;
}
-errno_t child_debug_init(const char *logfile, int *debug_fd)
+static errno_t child_debug_init(const char *logfile, int *debug_fd)
{
int ret;
FILE *debug_filep;
diff --git a/src/util/child_common.h b/src/util/child_common.h
index 37116e2a7..92d66a500 100644
--- a/src/util/child_common.h
+++ b/src/util/child_common.h
@@ -106,7 +106,7 @@ void fd_nonblocking(int fd);
/* Never returns EOK, ether returns an error, or doesn't return on success */
void exec_child_ex(TALLOC_CTX *mem_ctx,
int *pipefd_to_child, int *pipefd_from_child,
- const char *binary, int debug_fd,
+ const char *binary, const char *logfile,
const char *extra_argv[], bool extra_args_only,
int child_in_fd, int child_out_fd);
@@ -115,10 +115,8 @@ void exec_child_ex(TALLOC_CTX *mem_ctx,
*/
void exec_child(TALLOC_CTX *mem_ctx,
int *pipefd_to_child, int *pipefd_from_child,
- const char *binary, int debug_fd);
+ const char *binary, const char *logfile);
int child_io_destructor(void *ptr);
-errno_t child_debug_init(const char *logfile, int *debug_fd);
-
#endif /* __CHILD_COMMON_H__ */
--
2.21.3

View File

@ -1,52 +0,0 @@
From 2c13d8bd00f1e8ff30e9fc81f183f6450303ac30 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Wed, 11 Dec 2019 18:42:49 +0100
Subject: [PATCH] util/watchdog: fixed watchdog implementation
In case watchdog detected locked process and this process was parent
process it just sent SIGTERM to the whole group of processes, including
itself.
This handling was wrong: generic `server_setup()` installs custom
libtevent handler for SIGTERM signal so this signal is only processed
in the context of tevent mainloop. But if tevent mainloop is stuck
(exactly the case that triggers WD) then event is not processed
and this made watchdog useless.
`watchdog_handler()` and `watchdog_detect_timeshift()` were amended to do
unconditional `_exit()` after optionally sending a signal to the group.
Resolves: https://pagure.io/SSSD/sssd/issue/4089
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/util/util_watchdog.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/util/util_watchdog.c b/src/util/util_watchdog.c
index a07275b19..38c248271 100644
--- a/src/util/util_watchdog.c
+++ b/src/util/util_watchdog.c
@@ -54,9 +54,8 @@ static void watchdog_detect_timeshift(void)
if (write(watchdog_ctx.pipefd[1], "1", 1) != 1) {
if (getpid() == getpgrp()) {
kill(-getpgrp(), SIGTERM);
- } else {
- _exit(1);
}
+ _exit(1);
}
}
}
@@ -75,9 +74,8 @@ static void watchdog_handler(int sig)
if (__sync_add_and_fetch(&watchdog_ctx.ticks, 1) > WATCHDOG_MAX_TICKS) {
if (getpid() == getpgrp()) {
kill(-getpgrp(), SIGTERM);
- } else {
- _exit(1);
}
+ _exit(1);
}
}
--
2.20.1

View File

@ -0,0 +1,64 @@
From e58853f9ce63fae0c8b219b79be65c760a2f3e7e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 5 Jun 2020 13:57:59 +0200
Subject: [PATCH] DEBUG: use new exec_child(_ex) interface in tests
Resolves: https://github.com/SSSD/sssd/issues/4667
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
---
src/tests/cmocka/test_child_common.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/tests/cmocka/test_child_common.c b/src/tests/cmocka/test_child_common.c
index 5cf460b50..87cae3405 100644
--- a/src/tests/cmocka/test_child_common.c
+++ b/src/tests/cmocka/test_child_common.c
@@ -97,7 +97,7 @@ void test_exec_child(void **state)
exec_child(child_tctx,
child_tctx->pipefd_to_child,
child_tctx->pipefd_from_child,
- CHILD_DIR"/"TEST_BIN, 2);
+ CHILD_DIR"/"TEST_BIN, NULL);
} else {
do {
errno = 0;
@@ -168,7 +168,7 @@ static void extra_args_test(struct child_test_ctx *child_tctx,
exec_child_ex(child_tctx,
child_tctx->pipefd_to_child,
child_tctx->pipefd_from_child,
- CHILD_DIR"/"TEST_BIN, 2, extra_args,
+ CHILD_DIR"/"TEST_BIN, NULL, extra_args,
extra_args_only,
STDIN_FILENO, STDOUT_FILENO);
} else {
@@ -291,7 +291,7 @@ void test_exec_child_handler(void **state)
exec_child(child_tctx,
child_tctx->pipefd_to_child,
child_tctx->pipefd_from_child,
- CHILD_DIR"/"TEST_BIN, 2);
+ CHILD_DIR"/"TEST_BIN, NULL);
}
ret = child_handler_setup(child_tctx->test_ctx->ev, child_pid,
@@ -341,7 +341,7 @@ void test_exec_child_echo(void **state)
exec_child_ex(child_tctx,
child_tctx->pipefd_to_child,
child_tctx->pipefd_from_child,
- CHILD_DIR"/"TEST_BIN, 2, NULL, false,
+ CHILD_DIR"/"TEST_BIN, NULL, NULL, false,
STDIN_FILENO, 3);
}
@@ -474,7 +474,7 @@ void test_sss_child(void **state)
exec_child(child_tctx,
child_tctx->pipefd_to_child,
child_tctx->pipefd_from_child,
- CHILD_DIR"/"TEST_BIN, 2);
+ CHILD_DIR"/"TEST_BIN, NULL);
}
ret = sss_child_register(child_tctx, sc_ctx,
--
2.21.3

View File

@ -1,56 +0,0 @@
From 1d4a7ffdcf8b303a40058db49d5e1be4bfb8271a Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Mon, 9 Dec 2019 17:20:28 +0100
Subject: [PATCH 5/7] providers/krb5: got rid of unused code
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Michal Židek <mzidek@redhat.com>
---
src/providers/krb5/krb5_common.c | 10 ----------
src/providers/krb5/krb5_common.h | 7 -------
2 files changed, 17 deletions(-)
diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
index bfda561c1..5c11c347b 100644
--- a/src/providers/krb5/krb5_common.c
+++ b/src/providers/krb5/krb5_common.c
@@ -1133,16 +1133,6 @@ void remove_krb5_info_files_callback(void *pvt)
talloc_free(ctx);
}
-void krb5_finalize(struct tevent_context *ev,
- struct tevent_signal *se,
- int signum,
- int count,
- void *siginfo,
- void *private_data)
-{
- orderly_shutdown(0);
-}
-
errno_t krb5_get_simple_upn(TALLOC_CTX *mem_ctx, struct krb5_ctx *krb5_ctx,
struct sss_domain_info *dom, const char *username,
const char *user_dom, char **_upn)
diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
index cc9313115..493d12e5f 100644
--- a/src/providers/krb5/krb5_common.h
+++ b/src/providers/krb5/krb5_common.h
@@ -196,13 +196,6 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
void remove_krb5_info_files_callback(void *pvt);
-void krb5_finalize(struct tevent_context *ev,
- struct tevent_signal *se,
- int signum,
- int count,
- void *siginfo,
- void *private_data);
-
errno_t remove_krb5_info_files(TALLOC_CTX *mem_ctx, const char *realm);
errno_t krb5_get_simple_upn(TALLOC_CTX *mem_ctx, struct krb5_ctx *krb5_ctx,
--
2.20.1

View File

@ -0,0 +1,60 @@
From 88e92967a7b4e3e4501b17f21812467effa331c7 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Tue, 16 Jun 2020 13:51:28 +0200
Subject: [PATCH] NEGCACHE: skip permanent entries in [users/groups] reset
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Files provider calling `sss_ncache_reset_[users/groups]()`
during cache rebuilding was breaking neg-cache prepopulation.
Resolves: https://github.com/SSSD/sssd/issues/1024
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/responder/common/negcache.c | 9 +++++++++
src/responder/common/negcache.h | 1 +
2 files changed, 10 insertions(+)
diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index d9545aef6..ce1c0ab8c 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -900,12 +900,21 @@ static int delete_prefix(struct tdb_context *tdb,
TDB_DATA key, TDB_DATA data, void *state)
{
const char *prefix = (const char *) state;
+ unsigned long long int timestamp;
+ char *ep = NULL;
if (strncmp((char *)key.dptr, prefix, strlen(prefix) - 1) != 0) {
/* not interested in this key */
return 0;
}
+ errno = 0;
+ timestamp = strtoull((const char *)data.dptr, &ep, 10);
+ if ((errno == 0) && (*ep == '\0') && (timestamp == 0)) {
+ /* skip permanent entries */
+ return 0;
+ }
+
return tdb_delete(tdb, key);
}
diff --git a/src/responder/common/negcache.h b/src/responder/common/negcache.h
index a80412215..4dcfb5e8f 100644
--- a/src/responder/common/negcache.h
+++ b/src/responder/common/negcache.h
@@ -146,6 +146,7 @@ int sss_ncache_set_locate_uid(struct sss_nc_ctx *ctx,
uid_t uid);
int sss_ncache_reset_permanent(struct sss_nc_ctx *ctx);
+/* sss_ncache_reset_[users/groups] skips permanent entries */
int sss_ncache_reset_users(struct sss_nc_ctx *ctx);
int sss_ncache_reset_groups(struct sss_nc_ctx *ctx);
--
2.21.3

View File

@ -1,84 +0,0 @@
From e41e9b37e4d3fcd8544fb6c591dafbaef0954438 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Mon, 9 Dec 2019 17:48:14 +0100
Subject: [PATCH 6/7] data_provider_be: got rid of duplicating SIGTERM handler
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It was wrong to install two libtevent SIGTERM handlers both of which did
orderly_shutdown()->exit(). Naturally only one of the handlers was executed
(as process was terminated with exit()) and libtevent docs doesn't say
anything about order of execution. But chances are, be_process_finalize()
was executed first so default_quit() was not executed and main_ctx was not
freed.
Moreover there is just no reason to have separate be_process_finalize()
at all: default server handler default_quit() frees main_ctx. And be_ctx
is linked to main_ctx so will be freed by default handler as well.
Resolves: https://pagure.io/SSSD/sssd/issue/4088
Reviewed-by: Michal Židek <mzidek@redhat.com>
---
src/providers/data_provider_be.c | 37 --------------------------------
1 file changed, 37 deletions(-)
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index cfcf0268d..ce00231ff 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -445,36 +445,6 @@ be_register_monitor_iface(struct sbus_connection *conn, struct be_ctx *be_ctx)
return sbus_connection_add_path_map(be_ctx->mon_conn, paths);
}
-static void be_process_finalize(struct tevent_context *ev,
- struct tevent_signal *se,
- int signum,
- int count,
- void *siginfo,
- void *private_data)
-{
- struct be_ctx *be_ctx;
-
- be_ctx = talloc_get_type(private_data, struct be_ctx);
- talloc_free(be_ctx);
- orderly_shutdown(0);
-}
-
-static errno_t be_process_install_sigterm_handler(struct be_ctx *be_ctx)
-{
- struct tevent_signal *sige;
-
- BlockSignals(false, SIGTERM);
-
- sige = tevent_add_signal(be_ctx->ev, be_ctx, SIGTERM, SA_SIGINFO,
- be_process_finalize, be_ctx);
- if (sige == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_signal failed.\n");
- return ENOMEM;
- }
-
- return EOK;
-}
-
static void dp_initialized(struct tevent_req *req);
errno_t be_process_init(TALLOC_CTX *mem_ctx,
@@ -566,13 +536,6 @@ errno_t be_process_init(TALLOC_CTX *mem_ctx,
goto done;
}
- /* Install signal handler */
- ret = be_process_install_sigterm_handler(be_ctx);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "be_install_sigterm_handler failed.\n");
- goto done;
- }
-
req = dp_init_send(be_ctx, be_ctx->ev, be_ctx, be_ctx->uid, be_ctx->gid);
if (req == NULL) {
ret = ENOMEM;
--
2.20.1

View File

@ -0,0 +1,46 @@
From 144e78dfebc0fd01feb6c11a37f81d01146cf33a Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Fri, 12 Jun 2020 19:10:33 +0200
Subject: [PATCH] util/inotify: fixed CLANG_WARNING
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixed following warning:
```
sssd-2.3.1/src/util/inotify.c:346:17: warning: Value stored to 'ret' is never read
# ret = EOK;
# ^ ~~~
```
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/util/inotify.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/util/inotify.c b/src/util/inotify.c
index ffc15ad4d..cf3e3d84d 100644
--- a/src/util/inotify.c
+++ b/src/util/inotify.c
@@ -319,7 +319,9 @@ static void snotify_internal_cb(struct tevent_context *ev,
in_event = (const struct inotify_event *) ptr;
- //debug_flags(in_event->mask, in_event->name);
+#if 0
+ debug_flags(in_event->mask, in_event->name);
+#endif
if (snctx->wctx->dir_wd == in_event->wd) {
ret = process_dir_event(snctx, in_event);
@@ -343,7 +345,6 @@ static void snotify_internal_cb(struct tevent_context *ev,
} else {
DEBUG(SSSDBG_MINOR_FAILURE,
"Unknown watch %d\n", in_event->wd);
- ret = EOK;
}
}
}
--
2.21.3

View File

@ -1,32 +0,0 @@
From 3f52de891cba55230730602d41c3811cf1b17d96 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Mon, 9 Dec 2019 18:26:56 +0100
Subject: [PATCH 7/7] util/server: improved debug at shutdown
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Relates: https://pagure.io/SSSD/sssd/issue/4088
Reviewed-by: Michal Židek <mzidek@redhat.com>
---
src/util/server.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/util/server.c b/src/util/server.c
index ee57ac128..33524066e 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -242,7 +242,8 @@ void orderly_shutdown(int status)
kill(-getpgrp(), SIGTERM);
}
#endif
- if (status == 0) sss_log(SSS_LOG_INFO, "Shutting down");
+ DEBUG(SSSDBG_IMPORTANT_INFO, "Shutting down (status = %d)", status);
+ sss_log(SSS_LOG_INFO, "Shutting down (status = %d)", status);
exit(status);
}
--
2.20.1

View File

@ -0,0 +1,97 @@
From 0c5711f9bae1cb46d4cd3fbe5d86d8688087be13 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Fri, 12 Jun 2020 20:45:23 +0200
Subject: [PATCH] util/inotify: fixed bug in inotify event processing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Error was spotted with the help of the following warning:
```
Error: CLANG_WARNING:
sssd-2.3.1/src/util/inotify.c:327:21: warning: Value stored to 'rewatch' is never read
# rewatch = true;
# ^ ~~~~
```
First part of the issue was that EAGAIN returned by the process_dir_event()
didn't trigger snotify_rewatch() (as suggested by the comments).
Fixing this part is already enough to resolve issue #1031 (as it was
reported).
Another part of the issue was that process_file_event() return code wasn't
checked against EAGAIN (again, as suggested by the DEBUG message).
Strictly speaking, I'm not sure if this part is really required or
if processing DIR events would cover all cases, but rebuilding watches
on IN_IGNORED won't hurt.
Resolves: https://github.com/SSSD/sssd/issues/1031
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/util/inotify.c | 30 +++++++++++++-----------------
1 file changed, 13 insertions(+), 17 deletions(-)
diff --git a/src/util/inotify.c b/src/util/inotify.c
index cf3e3d84d..a3c33eddb 100644
--- a/src/util/inotify.c
+++ b/src/util/inotify.c
@@ -286,7 +286,7 @@ static void snotify_internal_cb(struct tevent_context *ev,
struct snotify_ctx *snctx;
ssize_t len;
errno_t ret;
- bool rewatch;
+ bool rewatch = false;
snctx = talloc_get_type(data, struct snotify_ctx);
if (snctx == NULL) {
@@ -305,7 +305,7 @@ static void snotify_internal_cb(struct tevent_context *ev,
} else {
DEBUG(SSSDBG_TRACE_INTERNAL, "All inotify events processed\n");
}
- return;
+ break;
}
if ((size_t) len < sizeof(struct inotify_event)) {
@@ -325,26 +325,22 @@ static void snotify_internal_cb(struct tevent_context *ev,
if (snctx->wctx->dir_wd == in_event->wd) {
ret = process_dir_event(snctx, in_event);
- if (ret == EAGAIN) {
- rewatch = true;
- /* Continue with the loop and read all the events from
- * this descriptor first, then rewatch when done
- */
- } else if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- "Failed to process inotify event\n");
- continue;
- }
} else if (snctx->wctx->file_wd == in_event->wd) {
ret = process_file_event(snctx, in_event);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- "Failed to process inotify event\n");
- continue;
- }
} else {
DEBUG(SSSDBG_MINOR_FAILURE,
"Unknown watch %d\n", in_event->wd);
+ ret = EOK;
+ }
+
+ if (ret == EAGAIN) {
+ rewatch = true;
+ /* Continue with the loop and read all the events from
+ * this descriptor first, then rewatch when done
+ */
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Failed to process inotify event\n");
}
}
}
--
2.21.3

View File

@ -1,52 +0,0 @@
From 26e33b1984cce3549df170f58f8221201ad54cfd Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Tue, 7 Jan 2020 16:29:05 +0100
Subject: [PATCH] util/sss_ptr_hash: fixed double free in
sss_ptr_hash_delete_cb()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Calling data->callback(value->ptr) in sss_ptr_hash_delete_cb() could lead
to freeing of value->ptr and thus to destruction of value->spy that is
attached to value->ptr.
In turn sss_ptr_hash_spy_destructor() calls sss_ptr_hash_delete() ->
hash_delete() -> sss_ptr_hash_delete_cb() again and in this recursive
execution hash entry was actually deleted and value was freed.
When stack was unwound back to "first" sss_ptr_hash_delete_cb() it tried
to free value again => double free.
To prevent this bug value and hence spy are now freed before execution of
data->callback(value->ptr).
Resolves: https://pagure.io/SSSD/sssd/issue/4135
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/util/sss_ptr_hash.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/util/sss_ptr_hash.c b/src/util/sss_ptr_hash.c
index c7403ffa6..8f9762cb9 100644
--- a/src/util/sss_ptr_hash.c
+++ b/src/util/sss_ptr_hash.c
@@ -154,13 +154,13 @@ sss_ptr_hash_delete_cb(hash_entry_t *item,
callback_entry.value.type = HASH_VALUE_PTR;
callback_entry.value.ptr = value->ptr;
+ /* Free value, this also will disable spy */
+ talloc_free(value);
+
/* Switch to the input value and call custom callback. */
if (data->callback != NULL) {
data->callback(&callback_entry, deltype, data->pvt);
}
-
- /* Free value. */
- talloc_free(value);
}
hash_table_t *sss_ptr_hash_create(TALLOC_CTX *mem_ctx,
--
2.20.1

View File

@ -0,0 +1,46 @@
From 02fbf47a85228c131f1b0575da091a01da700189 Mon Sep 17 00:00:00 2001
From: vinay mishra <vmishra@redhat.com>
Date: Mon, 18 May 2020 10:32:55 +0530
Subject: [PATCH] Replaced 'enter' with 'insert'
Resolves: https://github.com/SSSD/sssd/issues/5164
Signed-off-by: vinay mishra <vmishra@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/sss_client/pam_sss.c | 4 ++--
src/tests/intg/test_pam_responder.py | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index d4f0a8917..69b440774 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -2422,8 +2422,8 @@ static int get_authtok_for_password_change(pam_handle_t *pamh,
return PAM_SUCCESS;
}
-#define SC_ENTER_LABEL_FMT "Please enter smart card labeled\n %s"
-#define SC_ENTER_FMT "Please enter smart card"
+#define SC_ENTER_LABEL_FMT "Please insert smart card labeled\n %s"
+#define SC_ENTER_FMT "Please insert smart card"
static int check_login_token_name(pam_handle_t *pamh, struct pam_items *pi,
int retries, bool quiet_mode)
diff --git a/src/tests/intg/test_pam_responder.py b/src/tests/intg/test_pam_responder.py
index 9b5e650ca..7a2458339 100644
--- a/src/tests/intg/test_pam_responder.py
+++ b/src/tests/intg/test_pam_responder.py
@@ -512,7 +512,7 @@ def test_require_sc_auth_no_cert(simple_pam_cert_auth_no_cert, env_for_sssctl):
assert end_time > start_time and \
(end_time - start_time) >= 20 and \
(end_time - start_time) < 40
- assert out.find("Please enter smart card\nPlease enter smart card") != -1
+ assert out.find("Please insert smart card\nPlease insert smart card") != -1
assert err.find("pam_authenticate for user [user1]: Authentication " +
"service cannot retrieve authentication info") != -1
--
2.21.3

View File

@ -1,195 +0,0 @@
From bd201746f8cf0e95615b3e98868555451b5e66b8 Mon Sep 17 00:00:00 2001
From: Tomas Halman <thalman@redhat.com>
Date: Mon, 2 Dec 2019 11:11:52 +0100
Subject: [PATCH] sdap: Add randomness to ldap connection timeout
In case of mass deployment, mass registration of IPA clients roughly on
the same time leads to regular CPU load spikes on IPA servers, the load
spikes are caused by all/most clients refreshing their LDAP connections
(ldap_connection_expire_timeout) every 15 minutes.
This patch introduces new random value (from 0 up to
ldap_connection_expire_offset) that is added to the timeout.
Resolves:
https://pagure.io/SSSD/sssd/issue/3630
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
---
src/config/cfg_rules.ini | 1 +
src/config/etc/sssd.api.d/sssd-ad.conf | 1 +
src/config/etc/sssd.api.d/sssd-ipa.conf | 1 +
src/config/etc/sssd.api.d/sssd-ldap.conf | 1 +
src/man/sssd-ldap.5.xml | 19 +++++++++++++++++++
src/providers/ad/ad_opts.c | 1 +
src/providers/ipa/ipa_opts.c | 1 +
src/providers/ldap/ldap_opts.c | 1 +
src/providers/ldap/sdap.h | 1 +
src/providers/ldap/sdap_async_connection.c | 12 ++++++++++++
10 files changed, 39 insertions(+)
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index 8c73c89ac..c56d5a668 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -600,6 +600,7 @@ option = ldap_chpass_dns_service_name
option = ldap_chpass_update_last_change
option = ldap_chpass_uri
option = ldap_connection_expire_timeout
+option = ldap_connection_expire_offset
option = ldap_default_authtok
option = ldap_default_authtok_type
option = ldap_default_bind_dn
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index 80e329b3b..aaa0b2345 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -58,6 +58,7 @@ ldap_deref = str, None, false
ldap_page_size = int, None, false
ldap_deref_threshold = int, None, false
ldap_connection_expire_timeout = int, None, false
+ldap_connection_expire_offset = int, None, false
ldap_disable_paging = bool, None, false
krb5_confd_path = str, None, false
wildcard_limit = int, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index e2d46db75..7ed153d36 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -52,6 +52,7 @@ ldap_deref = str, None, false
ldap_page_size = int, None, false
ldap_deref_threshold = int, None, false
ldap_connection_expire_timeout = int, None, false
+ldap_connection_expire_offset = int, None, false
ldap_disable_paging = bool, None, false
krb5_confd_path = str, None, false
wildcard_limit = int, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index 01c1d7f12..4f73e901e 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -36,6 +36,7 @@ ldap_deref_threshold = int, None, false
ldap_sasl_canonicalize = bool, None, false
ldap_sasl_minssf = int, None, false
ldap_connection_expire_timeout = int, None, false
+ldap_connection_expire_offset = int, None, false
ldap_disable_paging = bool, None, false
ldap_disable_range_retrieval = bool, None, false
wildcard_limit = int, None, false
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index 6d1ae23ec..f8bb973c7 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -509,12 +509,31 @@
the two values (this value vs. the TGT lifetime)
will be used.
</para>
+ <para>
+ This timeout can be extended of a random
+ value specified by
+ <emphasis>ldap_connection_expire_offset</emphasis>
+ </para>
<para>
Default: 900 (15 minutes)
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>ldap_connection_expire_offset (integer)</term>
+ <listitem>
+ <para>
+ Random offset between 0 and configured value
+ is added to
+ <emphasis>ldap_connection_expire_timeout</emphasis>.
+ </para>
+ <para>
+ Default: 0
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>ldap_page_size (integer)</term>
<listitem>
diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c
index cd568e466..1293219ee 100644
--- a/src/providers/ad/ad_opts.c
+++ b/src/providers/ad/ad_opts.c
@@ -137,6 +137,7 @@ struct dp_option ad_def_ldap_opts[] = {
{ "ldap_deref_threshold", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER },
{ "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ldap_connection_expire_timeout", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER },
+ { "ldap_connection_expire_offset", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER },
{ "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER },
{ "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000200000LL }, NULL_NUMBER },
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
index 7974cb8ea..4fafa073d 100644
--- a/src/providers/ipa/ipa_opts.c
+++ b/src/providers/ipa/ipa_opts.c
@@ -147,6 +147,7 @@ struct dp_option ipa_def_ldap_opts[] = {
{ "ldap_deref_threshold", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER },
{ "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ldap_connection_expire_timeout", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER },
+ { "ldap_connection_expire_offset", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER },
{ "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER },
{ "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000200000LL }, NULL_NUMBER },
diff --git a/src/providers/ldap/ldap_opts.c b/src/providers/ldap/ldap_opts.c
index a20ec0d86..ffd0c6baa 100644
--- a/src/providers/ldap/ldap_opts.c
+++ b/src/providers/ldap/ldap_opts.c
@@ -107,6 +107,7 @@ struct dp_option default_basic_opts[] = {
{ "ldap_deref_threshold", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER },
{ "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ldap_connection_expire_timeout", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER },
+ { "ldap_connection_expire_offset", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER },
{ "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER },
{ "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000200000LL }, NULL_NUMBER },
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index d0a19a660..f27b3c480 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -221,6 +221,7 @@ enum sdap_basic_opt {
SDAP_DEREF_THRESHOLD,
SDAP_SASL_CANONICALIZE,
SDAP_EXPIRE_TIMEOUT,
+ SDAP_EXPIRE_OFFSET,
SDAP_DISABLE_PAGING,
SDAP_IDMAP_LOWER,
SDAP_IDMAP_UPPER,
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index 0260cba6f..7438d14a7 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -1803,6 +1803,8 @@ static void sdap_cli_auth_step(struct tevent_req *req)
struct tevent_req *subreq;
time_t now;
int expire_timeout;
+ int expire_offset;
+
const char *sasl_mech = dp_opt_get_string(state->opts->basic,
SDAP_SASL_MECH);
const char *user_dn = dp_opt_get_string(state->opts->basic,
@@ -1832,6 +1834,16 @@ static void sdap_cli_auth_step(struct tevent_req *req)
*/
now = time(NULL);
expire_timeout = dp_opt_get_int(state->opts->basic, SDAP_EXPIRE_TIMEOUT);
+ expire_offset = dp_opt_get_int(state->opts->basic, SDAP_EXPIRE_OFFSET);
+ if (expire_offset > 0) {
+ expire_timeout += sss_rand() % (expire_offset + 1);
+ } else if (expire_offset < 0) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Negative value [%d] of ldap_connection_expire_offset "
+ "is not allowed.\n",
+ expire_offset);
+ }
+
DEBUG(SSSDBG_CONF_SETTINGS, "expire timeout is %d\n", expire_timeout);
if (!state->sh->expire_time
|| (state->sh->expire_time > (now + expire_timeout))) {
--
2.20.1

View File

@ -0,0 +1,166 @@
From aac4dbb17f3e19a2fbeefb38b3319827d3bf820e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 13 May 2020 13:13:43 +0200
Subject: [PATCH] NSS client: preserve errno during _nss_sss_end* calls
glibc does not expect that errno is changed by some of the calls
provided by nss modules. This caused at least issues when
_nss_sss_endpwent() is called in compat mode. According to
https://pubs.opengroup.org/onlinepubs/9699919799/functions/endpwent.html
endpwent() should only set errno in the case of an error. Since there is
no other way to report an error we will set errno in the case of an
error but preserve it otherwise. This should cause no issues because
glibc is taking precautions as well tracked by
https://sourceware.org/bugzilla/show_bug.cgi?id=25976.
To be on the safe side the other _nss_sss_end* calls will show the same
behavior.
Resolves: https://github.com/SSSD/sssd/issues/5153
Reviewed-by: Alexey Tikhonov <atikhonov@redhat.com>
---
src/sss_client/nss_group.c | 3 +++
src/sss_client/nss_hosts.c | 4 +++-
src/sss_client/nss_ipnetworks.c | 4 +++-
src/sss_client/nss_netgroup.c | 3 +++
src/sss_client/nss_passwd.c | 3 +++
src/sss_client/nss_services.c | 3 +++
6 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/sss_client/nss_group.c b/src/sss_client/nss_group.c
index 5ab2bdf78..4a201bf09 100644
--- a/src/sss_client/nss_group.c
+++ b/src/sss_client/nss_group.c
@@ -735,6 +735,7 @@ enum nss_status _nss_sss_endgrent(void)
{
enum nss_status nret;
int errnop;
+ int saved_errno = errno;
sss_nss_lock();
@@ -745,6 +746,8 @@ enum nss_status _nss_sss_endgrent(void)
NULL, NULL, NULL, &errnop);
if (nret != NSS_STATUS_SUCCESS) {
errno = errnop;
+ } else {
+ errno = saved_errno;
}
sss_nss_unlock();
diff --git a/src/sss_client/nss_hosts.c b/src/sss_client/nss_hosts.c
index 5e279468b..aa2676286 100644
--- a/src/sss_client/nss_hosts.c
+++ b/src/sss_client/nss_hosts.c
@@ -565,6 +565,7 @@ _nss_sss_endhostent(void)
{
enum nss_status nret;
int errnop;
+ int saved_errno = errno;
sss_nss_lock();
@@ -575,9 +576,10 @@ _nss_sss_endhostent(void)
NULL, NULL, NULL, &errnop);
if (nret != NSS_STATUS_SUCCESS) {
errno = errnop;
+ } else {
+ errno = saved_errno;
}
sss_nss_unlock();
-
return nret;
}
diff --git a/src/sss_client/nss_ipnetworks.c b/src/sss_client/nss_ipnetworks.c
index 15fee6039..08070499d 100644
--- a/src/sss_client/nss_ipnetworks.c
+++ b/src/sss_client/nss_ipnetworks.c
@@ -510,6 +510,7 @@ _nss_sss_endnetent(void)
{
enum nss_status nret;
int errnop;
+ int saved_errno = errno;
sss_nss_lock();
@@ -520,10 +521,11 @@ _nss_sss_endnetent(void)
NULL, NULL, NULL, &errnop);
if (nret != NSS_STATUS_SUCCESS) {
errno = errnop;
+ } else {
+ errno = saved_errno;
}
sss_nss_unlock();
-
return nret;
}
diff --git a/src/sss_client/nss_netgroup.c b/src/sss_client/nss_netgroup.c
index 3a1834a31..2fc88f8ae 100644
--- a/src/sss_client/nss_netgroup.c
+++ b/src/sss_client/nss_netgroup.c
@@ -309,6 +309,7 @@ enum nss_status _nss_sss_endnetgrent(struct __netgrent *result)
{
enum nss_status nret;
int errnop;
+ int saved_errno = errno;
sss_nss_lock();
@@ -319,6 +320,8 @@ enum nss_status _nss_sss_endnetgrent(struct __netgrent *result)
NULL, NULL, NULL, &errnop);
if (nret != NSS_STATUS_SUCCESS) {
errno = errnop;
+ } else {
+ errno = saved_errno;
}
sss_nss_unlock();
diff --git a/src/sss_client/nss_passwd.c b/src/sss_client/nss_passwd.c
index 96368bd6e..c386dd370 100644
--- a/src/sss_client/nss_passwd.c
+++ b/src/sss_client/nss_passwd.c
@@ -455,6 +455,7 @@ enum nss_status _nss_sss_endpwent(void)
{
enum nss_status nret;
int errnop;
+ int saved_errno = errno;
sss_nss_lock();
@@ -465,6 +466,8 @@ enum nss_status _nss_sss_endpwent(void)
NULL, NULL, NULL, &errnop);
if (nret != NSS_STATUS_SUCCESS) {
errno = errnop;
+ } else {
+ errno = saved_errno;
}
sss_nss_unlock();
diff --git a/src/sss_client/nss_services.c b/src/sss_client/nss_services.c
index 13cb4c3ab..f8c2092cb 100644
--- a/src/sss_client/nss_services.c
+++ b/src/sss_client/nss_services.c
@@ -484,6 +484,7 @@ _nss_sss_endservent(void)
{
enum nss_status nret;
int errnop;
+ int saved_errno = errno;
sss_nss_lock();
@@ -494,6 +495,8 @@ _nss_sss_endservent(void)
NULL, NULL, NULL, &errnop);
if (nret != NSS_STATUS_SUCCESS) {
errno = errnop;
+ } else {
+ errno = saved_errno;
}
sss_nss_unlock();
--
2.21.3

View File

@ -1,55 +0,0 @@
From 9beb736aac6aa21433a4541fb56e4fa7d7dbc462 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 26 Sep 2019 20:24:34 +0200
Subject: [PATCH 10/13] ad: allow booleans for ad_inherit_opts_if_needed()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Currently ad_inherit_opts_if_needed() can only handle strings. With this
patch it can handle boolean options as well.
Related to https://pagure.io/SSSD/sssd/issue/4131
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/providers/ad/ad_common.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index 5540066d4..600e3ceb2 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -1479,9 +1479,26 @@ errno_t ad_inherit_opts_if_needed(struct dp_option *parent_opts,
const char *parent_val = NULL;
char *dummy = NULL;
char *option_list[2] = { NULL, NULL };
-
- parent_val = dp_opt_get_cstring(parent_opts, opt_id);
- if (parent_val != NULL) {
+ bool is_default = true;
+
+ switch (parent_opts[opt_id].type) {
+ case DP_OPT_STRING:
+ parent_val = dp_opt_get_cstring(parent_opts, opt_id);
+ break;
+ case DP_OPT_BOOL:
+ /* For booleans it is hard to say if the option is set or not since
+ * both possible values are valid ones. So we check if the value is
+ * different from the default and skip if it is the default. In this
+ * case the sub-domain option would either be the default as well or
+ * manully set and in both cases we do not have to change it. */
+ is_default = (parent_opts[opt_id].val.boolean
+ == parent_opts[opt_id].def_val.boolean);
+ break;
+ default:
+ DEBUG(SSSDBG_TRACE_FUNC, "Unsupported type, skipping.\n");
+ }
+
+ if (parent_val != NULL || !is_default) {
ret = confdb_get_string(cdb, NULL, subdom_conf_path,
parent_opts[opt_id].opt_name, NULL, &dummy);
if (ret != EOK) {
--
2.20.1

View File

@ -1,438 +0,0 @@
From da0be382d95f0bdbc6ad5ccb68503456c2ee858b Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 26 Sep 2019 20:27:09 +0200
Subject: [PATCH 11/13] ad: add ad_use_ldaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
With this new boolean option the AD provider should only use the LDAPS
port 636 and the Global Catalog port 3629 which is TLS protected as
well.
Related to https://pagure.io/SSSD/sssd/issue/4131
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/config/SSSDConfig/__init__.py.in | 1 +
src/config/cfg_rules.ini | 1 +
src/config/etc/sssd.api.d/sssd-ad.conf | 1 +
src/man/sssd-ad.5.xml | 20 +++++++++++++++++++
src/providers/ad/ad_common.c | 24 +++++++++++++++++++----
src/providers/ad/ad_common.h | 8 +++++++-
src/providers/ad/ad_init.c | 8 +++++++-
src/providers/ad/ad_opts.c | 1 +
src/providers/ad/ad_srv.c | 16 ++++++++++++---
src/providers/ad/ad_srv.h | 3 ++-
src/providers/ad/ad_subdomains.c | 21 ++++++++++++++++++--
src/providers/ipa/ipa_subdomains_server.c | 4 ++--
12 files changed, 94 insertions(+), 14 deletions(-)
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index eba89b461..84631862a 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -252,6 +252,7 @@ option_strings = {
'ad_site' : _('a particular site to be used by the client'),
'ad_maximum_machine_account_password_age' : _('Maximum age in days before the machine account password should be renewed'),
'ad_machine_account_password_renewal_opts' : _('Option for tuning the machine account renewal task'),
+ 'ad_use_ldaps' : _('Use LDAPS port for LDAP and Global Catalog requests'),
# [provider/krb5]
'krb5_kdcip' : _('Kerberos server address'),
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index c56d5a668..1034a1fd6 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -464,6 +464,7 @@ option = ad_machine_account_password_renewal_opts
option = ad_maximum_machine_account_password_age
option = ad_server
option = ad_site
+option = ad_use_ldaps
# IPA provider specific options
option = ipa_anchor_uuid
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index aaa0b2345..a2af72603 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -20,6 +20,7 @@ ad_gpo_default_right = str, None, false
ad_site = str, None, false
ad_maximum_machine_account_password_age = int, None, false
ad_machine_account_password_renewal_opts = str, None, false
+ad_use_ldaps = bool, None, false
ldap_uri = str, None, false
ldap_backup_uri = str, None, false
ldap_search_base = str, None, false
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index fdcb4e4b9..ade56cd6d 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -1015,6 +1015,26 @@ ad_gpo_map_deny = +my_pam_service
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>ad_use_ldaps (bool)</term>
+ <listitem>
+ <para>
+ By default SSSD uses the plain LDAP port 389 and the
+ Global Catalog port 3628. If this option is set to
+ True SSSD will use the LDAPS port 636 and Global
+ Catalog port 3629 with LDAPS protection. Since AD
+ does not allow to have multiple encryption layers on
+ a single connection and we still want to use
+ SASL/GSSAPI or SASL/GSS-SPNEGO for authentication
+ the SASL security property maxssf is set to 0 (zero)
+ for those connections.
+ </para>
+ <para>
+ Default: False
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>dyndns_update (boolean)</term>
<listitem>
diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index 600e3ceb2..a2369166a 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -729,6 +729,7 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
const char *ad_gc_service,
const char *ad_domain,
bool use_kdcinfo,
+ bool ad_use_ldaps,
size_t n_lookahead_primary,
size_t n_lookahead_backup,
struct ad_service **_service)
@@ -746,6 +747,16 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
goto done;
}
+ if (ad_use_ldaps) {
+ service->ldap_scheme = "ldaps";
+ service->port = LDAPS_PORT;
+ service->gc_port = AD_GC_LDAPS_PORT;
+ } else {
+ service->ldap_scheme = "ldap";
+ service->port = LDAP_PORT;
+ service->gc_port = AD_GC_PORT;
+ }
+
service->sdap = talloc_zero(service, struct sdap_service);
service->gc = talloc_zero(service, struct sdap_service);
if (!service->sdap || !service->gc) {
@@ -927,7 +938,8 @@ ad_resolve_callback(void *private_data, struct fo_server *server)
goto done;
}
- new_uri = talloc_asprintf(service->sdap, "ldap://%s", srv_name);
+ new_uri = talloc_asprintf(service->sdap, "%s://%s", service->ldap_scheme,
+ srv_name);
if (!new_uri) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy URI\n");
ret = ENOMEM;
@@ -935,7 +947,7 @@ ad_resolve_callback(void *private_data, struct fo_server *server)
}
DEBUG(SSSDBG_CONF_SETTINGS, "Constructed uri '%s'\n", new_uri);
- sockaddr = resolv_get_sockaddr_address(tmp_ctx, srvaddr, LDAP_PORT);
+ sockaddr = resolv_get_sockaddr_address(tmp_ctx, srvaddr, service->port);
if (sockaddr == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_sockaddr_address failed.\n");
ret = EIO;
@@ -951,8 +963,12 @@ ad_resolve_callback(void *private_data, struct fo_server *server)
talloc_zfree(service->gc->uri);
talloc_zfree(service->gc->sockaddr);
if (sdata && sdata->gc) {
- new_port = fo_get_server_port(server);
- new_port = (new_port == 0) ? AD_GC_PORT : new_port;
+ if (service->gc_port == AD_GC_LDAPS_PORT) {
+ new_port = service->gc_port;
+ } else {
+ new_port = fo_get_server_port(server);
+ new_port = (new_port == 0) ? service->gc_port : new_port;
+ }
service->gc->uri = talloc_asprintf(service->gc, "%s:%d",
new_uri, new_port);
diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
index 75f11de2e..820e06124 100644
--- a/src/providers/ad/ad_common.h
+++ b/src/providers/ad/ad_common.h
@@ -29,7 +29,8 @@
#define AD_SERVICE_NAME "AD"
#define AD_GC_SERVICE_NAME "AD_GC"
/* The port the Global Catalog runs on */
-#define AD_GC_PORT 3268
+#define AD_GC_PORT 3268
+#define AD_GC_LDAPS_PORT 3269
#define AD_AT_OBJECT_SID "objectSID"
#define AD_AT_DNS_DOMAIN "DnsDomain"
@@ -67,6 +68,7 @@ enum ad_basic_opt {
AD_KRB5_CONFD_PATH,
AD_MAXIMUM_MACHINE_ACCOUNT_PASSWORD_AGE,
AD_MACHINE_ACCOUNT_PASSWORD_RENEWAL_OPTS,
+ AD_USE_LDAPS,
AD_OPTS_BASIC /* opts counter */
};
@@ -82,6 +84,9 @@ struct ad_service {
struct sdap_service *sdap;
struct sdap_service *gc;
struct krb5_service *krb5_service;
+ const char *ldap_scheme;
+ int port;
+ int gc_port;
};
struct ad_options {
@@ -147,6 +152,7 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *ctx,
const char *ad_gc_service,
const char *ad_domain,
bool use_kdcinfo,
+ bool ad_use_ldaps,
size_t n_lookahead_primary,
size_t n_lookahead_backup,
struct ad_service **_service);
diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c
index 290d5b5c1..2b4b9e2e7 100644
--- a/src/providers/ad/ad_init.c
+++ b/src/providers/ad/ad_init.c
@@ -138,6 +138,7 @@ static errno_t ad_init_options(TALLOC_CTX *mem_ctx,
char *ad_servers = NULL;
char *ad_backup_servers = NULL;
char *ad_realm;
+ bool ad_use_ldaps = false;
errno_t ret;
ad_sasl_initialize();
@@ -154,12 +155,14 @@ static errno_t ad_init_options(TALLOC_CTX *mem_ctx,
ad_servers = dp_opt_get_string(ad_options->basic, AD_SERVER);
ad_backup_servers = dp_opt_get_string(ad_options->basic, AD_BACKUP_SERVER);
ad_realm = dp_opt_get_string(ad_options->basic, AD_KRB5_REALM);
+ ad_use_ldaps = dp_opt_get_bool(ad_options->basic, AD_USE_LDAPS);
/* Set up the failover service */
ret = ad_failover_init(ad_options, be_ctx, ad_servers, ad_backup_servers,
ad_realm, AD_SERVICE_NAME, AD_GC_SERVICE_NAME,
dp_opt_get_string(ad_options->basic, AD_DOMAIN),
false, /* will be set in ad_get_auth_options() */
+ ad_use_ldaps,
(size_t) -1,
(size_t) -1,
&ad_options->service);
@@ -184,11 +187,13 @@ static errno_t ad_init_srv_plugin(struct be_ctx *be_ctx,
const char *ad_site_override;
bool sites_enabled;
errno_t ret;
+ bool ad_use_ldaps;
hostname = dp_opt_get_string(ad_options->basic, AD_HOSTNAME);
ad_domain = dp_opt_get_string(ad_options->basic, AD_DOMAIN);
ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE);
sites_enabled = dp_opt_get_bool(ad_options->basic, AD_ENABLE_DNS_SITES);
+ ad_use_ldaps = dp_opt_get_bool(ad_options->basic, AD_USE_LDAPS);
if (!sites_enabled) {
@@ -205,7 +210,8 @@ static errno_t ad_init_srv_plugin(struct be_ctx *be_ctx,
srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx, be_ctx->be_res,
default_host_dbs, ad_options->id,
hostname, ad_domain,
- ad_site_override);
+ ad_site_override,
+ ad_use_ldaps);
if (srv_ctx == NULL) {
DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
return ENOMEM;
diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c
index 1293219ee..30f9b62fd 100644
--- a/src/providers/ad/ad_opts.c
+++ b/src/providers/ad/ad_opts.c
@@ -54,6 +54,7 @@ struct dp_option ad_basic_opts[] = {
{ "krb5_confd_path", DP_OPT_STRING, { KRB5_MAPPING_DIR }, NULL_STRING },
{ "ad_maximum_machine_account_password_age", DP_OPT_NUMBER, { .number = 30 }, NULL_NUMBER },
{ "ad_machine_account_password_renewal_opts", DP_OPT_STRING, { "86400:750" }, NULL_STRING },
+ { "ad_use_ldaps", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
DP_OPTION_TERMINATOR
};
diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c
index 5fd25f60e..ca15d3715 100644
--- a/src/providers/ad/ad_srv.c
+++ b/src/providers/ad/ad_srv.c
@@ -244,6 +244,7 @@ struct ad_get_client_site_state {
enum host_database *host_db;
struct sdap_options *opts;
const char *ad_domain;
+ bool ad_use_ldaps;
struct fo_server_info *dcs;
size_t num_dcs;
size_t dc_index;
@@ -264,6 +265,7 @@ struct tevent_req *ad_get_client_site_send(TALLOC_CTX *mem_ctx,
enum host_database *host_db,
struct sdap_options *opts,
const char *ad_domain,
+ bool ad_use_ldaps,
struct fo_server_info *dcs,
size_t num_dcs)
{
@@ -288,6 +290,7 @@ struct tevent_req *ad_get_client_site_send(TALLOC_CTX *mem_ctx,
state->host_db = host_db;
state->opts = opts;
state->ad_domain = ad_domain;
+ state->ad_use_ldaps = ad_use_ldaps;
state->dcs = dcs;
state->num_dcs = num_dcs;
@@ -331,8 +334,11 @@ static errno_t ad_get_client_site_next_dc(struct tevent_req *req)
subreq = sdap_connect_host_send(state, state->ev, state->opts,
state->be_res->resolv,
state->be_res->family_order,
- state->host_db, "ldap", state->dc.host,
- state->dc.port, false);
+ state->host_db,
+ state->ad_use_ldaps ? "ldaps" : "ldap",
+ state->dc.host,
+ state->ad_use_ldaps ? 636 : state->dc.port,
+ false);
if (subreq == NULL) {
ret = ENOMEM;
goto done;
@@ -491,6 +497,7 @@ struct ad_srv_plugin_ctx {
const char *ad_domain;
const char *ad_site_override;
const char *current_site;
+ bool ad_use_ldaps;
};
struct ad_srv_plugin_ctx *
@@ -501,7 +508,8 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
struct sdap_options *opts,
const char *hostname,
const char *ad_domain,
- const char *ad_site_override)
+ const char *ad_site_override,
+ bool ad_use_ldaps)
{
struct ad_srv_plugin_ctx *ctx = NULL;
errno_t ret;
@@ -515,6 +523,7 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
ctx->be_res = be_res;
ctx->host_dbs = host_dbs;
ctx->opts = opts;
+ ctx->ad_use_ldaps = ad_use_ldaps;
ctx->hostname = talloc_strdup(ctx, hostname);
if (ctx->hostname == NULL) {
@@ -714,6 +723,7 @@ static void ad_srv_plugin_dcs_done(struct tevent_req *subreq)
state->ctx->host_dbs,
state->ctx->opts,
state->discovery_domain,
+ state->ctx->ad_use_ldaps,
dcs, num_dcs);
if (subreq == NULL) {
ret = ENOMEM;
diff --git a/src/providers/ad/ad_srv.h b/src/providers/ad/ad_srv.h
index e553d594d..8e410ec26 100644
--- a/src/providers/ad/ad_srv.h
+++ b/src/providers/ad/ad_srv.h
@@ -31,7 +31,8 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
struct sdap_options *opts,
const char *hostname,
const char *ad_domain,
- const char *ad_site_override);
+ const char *ad_site_override,
+ bool ad_use_ldaps);
struct tevent_req *ad_srv_plugin_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index 2ce34489f..d8c201437 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -282,6 +282,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
bool use_kdcinfo = false;
size_t n_lookahead_primary = SSS_KRB5_LOOKAHEAD_PRIMARY_DEFAULT;
size_t n_lookahead_backup = SSS_KRB5_LOOKAHEAD_BACKUP_DEFAULT;
+ bool ad_use_ldaps = false;
realm = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_KRB5_REALM);
hostname = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_HOSTNAME);
@@ -312,6 +313,21 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
return ENOMEM;
}
+ ret = ad_inherit_opts_if_needed(id_ctx->ad_options->basic,
+ ad_options->basic,
+ be_ctx->cdb, subdom_conf_path,
+ AD_USE_LDAPS);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to inherit option [%s] to sub-domain [%s]. "
+ "This error is ignored but might cause issues or unexpected "
+ "behavior later on.\n",
+ id_ctx->ad_options->basic[AD_USE_LDAPS].opt_name,
+ subdom->name);
+
+ return ret;
+ }
+
ret = ad_inherit_opts_if_needed(id_ctx->sdap_id_ctx->opts->basic,
ad_options->id->basic,
be_ctx->cdb, subdom_conf_path,
@@ -344,6 +360,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
servers = dp_opt_get_string(ad_options->basic, AD_SERVER);
backup_servers = dp_opt_get_string(ad_options->basic, AD_BACKUP_SERVER);
+ ad_use_ldaps = dp_opt_get_bool(ad_options->basic, AD_USE_LDAPS);
if (id_ctx->ad_options->auth_ctx != NULL
&& id_ctx->ad_options->auth_ctx->opts != NULL) {
@@ -362,7 +379,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
ret = ad_failover_init(ad_options, be_ctx, servers, backup_servers,
subdom->realm, service_name, gc_service_name,
- subdom->name, use_kdcinfo,
+ subdom->name, use_kdcinfo, ad_use_ldaps,
n_lookahead_primary,
n_lookahead_backup,
&ad_options->service);
@@ -386,7 +403,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
ad_id_ctx->ad_options->id,
hostname,
ad_domain,
- ad_site_override);
+ ad_site_override, ad_use_ldaps);
if (srv_ctx == NULL) {
DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
return ENOMEM;
diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
index fd998877b..9aebf72a5 100644
--- a/src/providers/ipa/ipa_subdomains_server.c
+++ b/src/providers/ipa/ipa_subdomains_server.c
@@ -319,7 +319,7 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
ret = ad_failover_init(ad_options, be_ctx, ad_servers, ad_backup_servers,
subdom->realm,
service_name, gc_service_name,
- subdom->name, use_kdcinfo,
+ subdom->name, use_kdcinfo, false,
n_lookahead_primary, n_lookahead_backup,
&ad_options->service);
if (ret != EOK) {
@@ -344,7 +344,7 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
ad_id_ctx->ad_options->id,
id_ctx->server_mode->hostname,
ad_domain,
- ad_site_override);
+ ad_site_override, false);
if (srv_ctx == NULL) {
DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
return ENOMEM;
--
2.20.1

View File

@ -0,0 +1,43 @@
From df632eec450791559a4a7644f241964397c10ff9 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 5 Jun 2020 13:59:25 +0200
Subject: [PATCH] ipa: add failover to subdomain override lookups
In the ipa_subdomain_account request failover handling was missing.
Related to https://github.com/SSSD/sssd/issues/5075
(was https://pagure.io/SSSD/sssd/issue/4114)
Reviewed-by: Pawel Polawski <ppolawsk@redhat.com>
---
src/providers/ipa/ipa_subdomains_id.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index 1224c7b73..36f32fae8 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -208,6 +208,20 @@ static void ipa_subdomain_account_got_override(struct tevent_req *subreq)
&state->override_attrs);
talloc_zfree(subreq);
if (ret != EOK) {
+ ret = sdap_id_op_done(state->op, ret, &dp_error);
+
+ if (dp_error == DP_ERR_OK && ret != EOK) {
+ /* retry */
+ subreq = sdap_id_op_connect_send(state->op, state, &ret);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed.\n");
+ goto fail;
+ }
+ tevent_req_set_callback(subreq, ipa_subdomain_account_connected,
+ req);
+ return;
+ }
+
DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret);
goto fail;
}
--
2.21.3

View File

@ -0,0 +1,132 @@
From dce025b882db7247571b135e928afb47f069a60f Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 27 Feb 2020 06:54:21 +0100
Subject: [PATCH] GPO: fix link order in a SOM
GPOs of the same OU were applied in the wrong order. Details about how
GPOs should be processed can be found e.g. at
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/dn581922(v%3Dws.11)
Resolves: https://github.com/SSSD/sssd/issues/5103
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
---
src/providers/ad/ad_gpo.c | 59 +++++++++++++++++++++++++++++----------
1 file changed, 45 insertions(+), 14 deletions(-)
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index bbe8d8a1e..1524c4bfc 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -3511,14 +3511,19 @@ ad_gpo_process_som_recv(struct tevent_req *req,
* - GPOs linked to an OU will be applied after GPOs linked to a Domain,
* which will be applied after GPOs linked to a Site.
* - multiple GPOs linked to a single SOM are applied in their link order
- * (i.e. 1st GPO linked to SOM is applied after 2nd GPO linked to SOM, etc).
+ * (i.e. 1st GPO linked to SOM is applied before 2nd GPO linked to SOM, etc).
* - enforced GPOs are applied after unenforced GPOs.
*
* As such, the _candidate_gpos output's dn fields looks like (in link order):
- * [unenforced {Site, Domain, OU}; enforced {Site, Domain, OU}]
+ * [unenforced {Site, Domain, OU}; enforced {OU, Domain, Site}]
*
* Note that in the case of conflicting policy settings, GPOs appearing later
- * in the list will trump GPOs appearing earlier in the list.
+ * in the list will trump GPOs appearing earlier in the list. Therefore the
+ * enforced GPOs are applied in revers order after the unenforced GPOs to
+ * make sure the enforced setting form the highest level will be applied.
+ *
+ * GPO processing details can be found e.g. at
+ * https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/dn581922(v%3Dws.11)
*/
static errno_t
ad_gpo_populate_candidate_gpos(TALLOC_CTX *mem_ctx,
@@ -3542,6 +3547,7 @@ ad_gpo_populate_candidate_gpos(TALLOC_CTX *mem_ctx,
int i = 0;
int j = 0;
int ret;
+ size_t som_count = 0;
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
@@ -3568,6 +3574,7 @@ ad_gpo_populate_candidate_gpos(TALLOC_CTX *mem_ctx,
}
i++;
}
+ som_count = i;
num_candidate_gpos = num_enforced + num_unenforced;
@@ -3590,9 +3597,43 @@ ad_gpo_populate_candidate_gpos(TALLOC_CTX *mem_ctx,
goto done;
}
+ i = som_count -1 ;
+ while (i >= 0) {
+ gp_som = som_list[i];
+
+ /* For unenforced_gpo_dns the most specific GPOs with the highest
+ * priority should be the last. We start with the top-level SOM and go
+ * down to the most specific one and add the unenforced following the
+ * gplink_list where the GPO with the highest priority comes last. */
+ j = 0;
+ while (gp_som && gp_som->gplink_list && gp_som->gplink_list[j]) {
+ gp_gplink = gp_som->gplink_list[j];
+
+ if (!gp_gplink->enforced) {
+ unenforced_gpo_dns[unenforced_idx] =
+ talloc_steal(unenforced_gpo_dns, gp_gplink->gpo_dn);
+
+ if (unenforced_gpo_dns[unenforced_idx] == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ unenforced_idx++;
+ }
+ j++;
+ }
+ i--;
+ }
+
i = 0;
while (som_list[i]) {
gp_som = som_list[i];
+
+ /* For enforced GPOs we start processing with the most specific SOM to
+ * make sur enforced GPOs from higher levels override to lower level
+ * ones. According to the 'Group Policy Inheritance' tab in the
+ * Windows 'Goup Policy Management' utility in the same SOM the link
+ * order is still observed and an enforced GPO with a lower link order
+ * value still overrides an enforced GPO with a higher link order. */
j = 0;
while (gp_som && gp_som->gplink_list && gp_som->gplink_list[j]) {
gp_gplink = gp_som->gplink_list[j];
@@ -3610,16 +3651,6 @@ ad_gpo_populate_candidate_gpos(TALLOC_CTX *mem_ctx,
goto done;
}
enforced_idx++;
- } else {
-
- unenforced_gpo_dns[unenforced_idx] =
- talloc_steal(unenforced_gpo_dns, gp_gplink->gpo_dn);
-
- if (unenforced_gpo_dns[unenforced_idx] == NULL) {
- ret = ENOMEM;
- goto done;
- }
- unenforced_idx++;
}
j++;
}
@@ -3638,7 +3669,7 @@ ad_gpo_populate_candidate_gpos(TALLOC_CTX *mem_ctx,
}
gpo_dn_idx = 0;
- for (i = num_unenforced - 1; i >= 0; i--) {
+ for (i = 0; i < num_unenforced; i++) {
candidate_gpos[gpo_dn_idx] = talloc_zero(candidate_gpos, struct gp_gpo);
if (candidate_gpos[gpo_dn_idx] == NULL) {
ret = ENOMEM;
--
2.21.3

View File

@ -1,199 +0,0 @@
From 4c855d55944087cb2317c681f1dc78953ec95c4e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 27 Sep 2019 11:49:59 +0200
Subject: [PATCH 12/13] ldap: add new option ldap_sasl_maxssf
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There is already the ldap_sasl_minssf option. To be able to control the
maximal security strength factor (ssf) e.g. when using SASL together
with TLS the option ldap_sasl_maxssf is added as well.
Related to https://pagure.io/SSSD/sssd/issue/4131
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/config/SSSDConfig/__init__.py.in | 1 +
src/config/cfg_rules.ini | 1 +
src/config/etc/sssd.api.d/sssd-ad.conf | 1 +
src/config/etc/sssd.api.d/sssd-ipa.conf | 1 +
src/config/etc/sssd.api.d/sssd-ldap.conf | 1 +
src/man/sssd-ldap.5.xml | 16 ++++++++++++++++
src/providers/ad/ad_opts.c | 1 +
src/providers/ipa/ipa_opts.c | 1 +
src/providers/ldap/ldap_opts.c | 1 +
src/providers/ldap/sdap.h | 1 +
src/providers/ldap/sdap_async_connection.c | 14 ++++++++++++++
11 files changed, 39 insertions(+)
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 84631862a..a1b088bc4 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -305,6 +305,7 @@ option_strings = {
'ldap_sasl_authid' : _('Specify the sasl authorization id to use'),
'ldap_sasl_realm' : _('Specify the sasl authorization realm to use'),
'ldap_sasl_minssf' : _('Specify the minimal SSF for LDAP sasl authorization'),
+ 'ldap_sasl_maxssf' : _('Specify the maximal SSF for LDAP sasl authorization'),
'ldap_krb5_keytab' : _('Kerberos service keytab'),
'ldap_krb5_init_creds' : _('Use Kerberos auth for LDAP connection'),
'ldap_referrals' : _('Follow LDAP referrals'),
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index 1034a1fd6..fd5336db7 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -664,6 +664,7 @@ option = ldap_sasl_authid
option = ldap_sasl_canonicalize
option = ldap_sasl_mech
option = ldap_sasl_minssf
+option = ldap_sasl_maxssf
option = ldap_schema
option = ldap_pwmodify_mode
option = ldap_search_base
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index a2af72603..d6443e200 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -41,6 +41,7 @@ ldap_tls_reqcert = str, None, false
ldap_sasl_mech = str, None, false
ldap_sasl_authid = str, None, false
ldap_sasl_minssf = int, None, false
+ldap_sasl_maxssf = int, None, false
krb5_kdcip = str, None, false
krb5_server = str, None, false
krb5_backup_server = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 7ed153d36..839f9f471 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -32,6 +32,7 @@ ldap_tls_reqcert = str, None, false
ldap_sasl_mech = str, None, false
ldap_sasl_authid = str, None, false
ldap_sasl_minssf = int, None, false
+ldap_sasl_maxssf = int, None, false
krb5_kdcip = str, None, false
krb5_server = str, None, false
krb5_backup_server = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index 4f73e901e..6db9828b9 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -35,6 +35,7 @@ ldap_page_size = int, None, false
ldap_deref_threshold = int, None, false
ldap_sasl_canonicalize = bool, None, false
ldap_sasl_minssf = int, None, false
+ldap_sasl_maxssf = int, None, false
ldap_connection_expire_timeout = int, None, false
ldap_connection_expire_offset = int, None, false
ldap_disable_paging = bool, None, false
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index f8bb973c7..0dc675410 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -612,6 +612,22 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>ldap_sasl_maxssf (integer)</term>
+ <listitem>
+ <para>
+ When communicating with an LDAP server using SASL,
+ specify the maximal security level necessary to
+ establish the connection. The values of this
+ option are defined by OpenLDAP.
+ </para>
+ <para>
+ Default: Use the system default (usually specified
+ by ldap.conf)
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>ldap_deref_threshold (integer)</term>
<listitem>
diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c
index 30f9b62fd..905a15cd0 100644
--- a/src/providers/ad/ad_opts.c
+++ b/src/providers/ad/ad_opts.c
@@ -105,6 +105,7 @@ struct dp_option ad_def_ldap_opts[] = {
{ "ldap_sasl_authid", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_sasl_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_sasl_minssf", DP_OPT_NUMBER, { .number = -1 }, NULL_NUMBER },
+ { "ldap_sasl_maxssf", DP_OPT_NUMBER, { .number = -1 }, NULL_NUMBER },
{ "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
/* use the same parm name as the krb5 module so we set it only once */
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
index 4fafa073d..55de6e600 100644
--- a/src/providers/ipa/ipa_opts.c
+++ b/src/providers/ipa/ipa_opts.c
@@ -114,6 +114,7 @@ struct dp_option ipa_def_ldap_opts[] = {
{ "ldap_sasl_authid", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_sasl_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_sasl_minssf", DP_OPT_NUMBER, { .number = 56 }, NULL_NUMBER },
+ { "ldap_sasl_maxssf", DP_OPT_NUMBER, { .number = -1 }, NULL_NUMBER },
{ "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
/* use the same parm name as the krb5 module so we set it only once */
diff --git a/src/providers/ldap/ldap_opts.c b/src/providers/ldap/ldap_opts.c
index ffd0c6baa..d1b4e98ad 100644
--- a/src/providers/ldap/ldap_opts.c
+++ b/src/providers/ldap/ldap_opts.c
@@ -74,6 +74,7 @@ struct dp_option default_basic_opts[] = {
{ "ldap_sasl_authid", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_sasl_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_sasl_minssf", DP_OPT_NUMBER, { .number = -1 }, NULL_NUMBER },
+ { "ldap_sasl_maxssf", DP_OPT_NUMBER, { .number = -1 }, NULL_NUMBER },
{ "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
/* use the same parm name as the krb5 module so we set it only once */
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index f27b3c480..808a2c400 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -192,6 +192,7 @@ enum sdap_basic_opt {
SDAP_SASL_AUTHID,
SDAP_SASL_REALM,
SDAP_SASL_MINSSF,
+ SDAP_SASL_MAXSSF,
SDAP_KRB5_KEYTAB,
SDAP_KRB5_KINIT,
SDAP_KRB5_KDC,
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index 7438d14a7..5f69cedcc 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -148,6 +148,8 @@ static void sdap_sys_connect_done(struct tevent_req *subreq)
const char *sasl_mech;
int sasl_minssf;
ber_len_t ber_sasl_minssf;
+ int sasl_maxssf;
+ ber_len_t ber_sasl_maxssf;
ret = sss_ldap_init_recv(subreq, &state->sh->ldap, &sd);
talloc_zfree(subreq);
@@ -291,6 +293,18 @@ static void sdap_sys_connect_done(struct tevent_req *subreq)
goto fail;
}
}
+
+ sasl_maxssf = dp_opt_get_int(state->opts->basic, SDAP_SASL_MAXSSF);
+ if (sasl_maxssf >= 0) {
+ ber_sasl_maxssf = (ber_len_t)sasl_maxssf;
+ lret = ldap_set_option(state->sh->ldap, LDAP_OPT_X_SASL_SSF_MAX,
+ &ber_sasl_maxssf);
+ if (lret != LDAP_OPT_SUCCESS) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set LDAP MAX SSF option "
+ "to %d\n", sasl_maxssf);
+ goto fail;
+ }
+ }
}
/* if we do not use start_tls the connection is not really connected yet
--
2.20.1

View File

@ -1,91 +0,0 @@
From d702d594e380a1d0f0e937524bdd8a3eabc9bdf1 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 27 Sep 2019 13:45:13 +0200
Subject: [PATCH 13/13] ad: set min and max ssf for ldaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
AD does not allow to use encryption in the TLS and SASL layer at the
same time. To be able to use ldaps this patch sets min and max ssf to 0
if ldaps should be used.
Related to https://pagure.io/SSSD/sssd/issue/4131
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/providers/ad/ad_common.c | 21 +++++++++++++++++++++
src/providers/ad/ad_common.h | 2 ++
src/providers/ad/ad_subdomains.c | 4 ++++
3 files changed, 27 insertions(+)
diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index a2369166a..51300f5b2 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -1021,6 +1021,23 @@ done:
return;
}
+void ad_set_ssf_for_ldaps(struct sdap_options *id_opts)
+{
+ int ret;
+
+ DEBUG(SSSDBG_TRACE_ALL, "Setting ssf for ldaps usage.\n");
+ ret = dp_opt_set_int(id_opts->basic, SDAP_SASL_MINSSF, 0);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to set SASL minssf for ldaps usage, ignored.\n");
+ }
+ ret = dp_opt_set_int(id_opts->basic, SDAP_SASL_MAXSSF, 0);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to set SASL maxssf for ldaps usage, ignored.\n");
+ }
+}
+
static errno_t
ad_set_sdap_options(struct ad_options *ad_opts,
struct sdap_options *id_opts)
@@ -1079,6 +1096,10 @@ ad_set_sdap_options(struct ad_options *ad_opts,
goto done;
}
+ if (dp_opt_get_bool(ad_opts->basic, AD_USE_LDAPS)) {
+ ad_set_ssf_for_ldaps(id_opts);
+ }
+
/* Warn if the user is doing something silly like overriding the schema
* with the AD provider
*/
diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
index 820e06124..d23aee616 100644
--- a/src/providers/ad/ad_common.h
+++ b/src/providers/ad/ad_common.h
@@ -181,6 +181,8 @@ errno_t
ad_get_dyndns_options(struct be_ctx *be_ctx,
struct ad_options *ad_opts);
+void ad_set_ssf_for_ldaps(struct sdap_options *id_opts);
+
struct ad_id_ctx *
ad_id_ctx_init(struct ad_options *ad_opts, struct be_ctx *bectx);
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index d8c201437..a9c6b9f28 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -328,6 +328,10 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
return ret;
}
+ if (dp_opt_get_bool(ad_options->basic, AD_USE_LDAPS)) {
+ ad_set_ssf_for_ldaps(ad_options->id);
+ }
+
ret = ad_inherit_opts_if_needed(id_ctx->sdap_id_ctx->opts->basic,
ad_options->id->basic,
be_ctx->cdb, subdom_conf_path,
--
2.20.1

View File

@ -0,0 +1,58 @@
From 8ca799ea968e548337acb0300642a0d88f1bba9b Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 7 May 2020 15:47:35 +0200
Subject: [PATCH 13/19] sysdb: make sysdb_update_subdomains() more robust
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some NULL checks are added basically to allow that missing values can be
set later.
Resolves: https://github.com/SSSD/sssd/issues/5151
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/db/sysdb_subdomains.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index b170d1978..d256817a6 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -421,7 +421,9 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain,
}
/* in theory these may change, but it should never happen */
- if (strcasecmp(dom->realm, realm) != 0) {
+ if ((dom->realm == NULL && realm != NULL)
+ || (dom->realm != NULL && realm != NULL
+ && strcasecmp(dom->realm, realm) != 0)) {
DEBUG(SSSDBG_TRACE_INTERNAL,
"Realm name changed from [%s] to [%s]!\n",
dom->realm, realm);
@@ -432,7 +434,9 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain,
goto done;
}
}
- if (strcasecmp(dom->flat_name, flat) != 0) {
+ if ((dom->flat_name == NULL && flat != NULL)
+ || (dom->flat_name != NULL && flat != NULL
+ && strcasecmp(dom->flat_name, flat) != 0)) {
DEBUG(SSSDBG_TRACE_INTERNAL,
"Flat name changed from [%s] to [%s]!\n",
dom->flat_name, flat);
@@ -443,7 +447,9 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain,
goto done;
}
}
- if (strcasecmp(dom->domain_id, id) != 0) {
+ if ((dom->domain_id == NULL && id != NULL)
+ || (dom->domain_id != NULL && id != NULL
+ && strcasecmp(dom->domain_id, id) != 0)) {
DEBUG(SSSDBG_TRACE_INTERNAL,
"Domain changed from [%s] to [%s]!\n",
dom->domain_id, id);
--
2.21.3

View File

@ -1,36 +0,0 @@
From 007d5b79b7aef67dd843ed9a3b65095faaeb580f Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 22 Jan 2020 09:43:21 +0000
Subject: [PATCH] BE_REFRESH: Do not try to refresh domains from other backends
We cannot refresh domains from different sssd_be processes.
We can refresh just subdomains
Resolves:
https://pagure.io/SSSD/sssd/issue/4142
Merges: https://pagure.io/SSSD/sssd/pull-request/4139
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/providers/be_refresh.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c
index 6cce38390..5e43571ce 100644
--- a/src/providers/be_refresh.c
+++ b/src/providers/be_refresh.c
@@ -385,6 +385,10 @@ static errno_t be_refresh_step(struct tevent_req *req)
if (state->index == BE_REFRESH_TYPE_SENTINEL) {
state->domain = get_next_domain(state->domain,
SSS_GND_DESCEND);
+ /* we can update just subdomains */
+ if (state->domain != NULL && !IS_SUBDOMAIN(state->domain)) {
+ break;
+ }
state->index = 0;
continue;
}
--
2.20.1

View File

@ -0,0 +1,334 @@
From d3089173dd8be85a83cf0236e116ba8e11326a6d Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 7 May 2020 16:51:02 +0200
Subject: [PATCH 14/19] ad: rename ad_master_domain_* to ad_domain_info_*
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The ad_master_domain_{send|recv} are not specific to the master domain
so a more generic name seems to be suitable.
Resolves: https://github.com/SSSD/sssd/issues/5151
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/providers/ad/ad_domain_info.c | 64 +++++++++++++++----------------
src/providers/ad/ad_domain_info.h | 10 ++---
src/providers/ad/ad_gpo.c | 8 ++--
src/providers/ad/ad_id.c | 14 +++----
src/providers/ad/ad_resolver.c | 8 ++--
src/providers/ad/ad_subdomains.c | 8 ++--
6 files changed, 56 insertions(+), 56 deletions(-)
diff --git a/src/providers/ad/ad_domain_info.c b/src/providers/ad/ad_domain_info.c
index 5302c8083..52b2e2442 100644
--- a/src/providers/ad/ad_domain_info.c
+++ b/src/providers/ad/ad_domain_info.c
@@ -175,7 +175,7 @@ done:
return ret;
}
-struct ad_master_domain_state {
+struct ad_domain_info_state {
struct tevent_context *ev;
struct sdap_id_conn_ctx *conn;
struct sdap_id_op *id_op;
@@ -191,22 +191,22 @@ struct ad_master_domain_state {
char *sid;
};
-static errno_t ad_master_domain_next(struct tevent_req *req);
-static void ad_master_domain_next_done(struct tevent_req *subreq);
-static void ad_master_domain_netlogon_done(struct tevent_req *req);
+static errno_t ad_domain_info_next(struct tevent_req *req);
+static void ad_domain_info_next_done(struct tevent_req *subreq);
+static void ad_domain_info_netlogon_done(struct tevent_req *req);
struct tevent_req *
-ad_master_domain_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sdap_id_conn_ctx *conn,
- struct sdap_id_op *op,
- const char *dom_name)
+ad_domain_info_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sdap_id_conn_ctx *conn,
+ struct sdap_id_op *op,
+ const char *dom_name)
{
errno_t ret;
struct tevent_req *req;
- struct ad_master_domain_state *state;
+ struct ad_domain_info_state *state;
- req = tevent_req_create(mem_ctx, &state, struct ad_master_domain_state);
+ req = tevent_req_create(mem_ctx, &state, struct ad_domain_info_state);
if (!req) return NULL;
state->ev = ev;
@@ -216,7 +216,7 @@ ad_master_domain_send(TALLOC_CTX *mem_ctx,
state->opts = conn->id_ctx->opts;
state->dom_name = dom_name;
- ret = ad_master_domain_next(req);
+ ret = ad_domain_info_next(req);
if (ret != EOK && ret != EAGAIN) {
goto immediate;
}
@@ -234,14 +234,14 @@ immediate:
}
static errno_t
-ad_master_domain_next(struct tevent_req *req)
+ad_domain_info_next(struct tevent_req *req)
{
struct tevent_req *subreq;
struct sdap_search_base *base;
const char *master_sid_attrs[] = {AD_AT_OBJECT_SID, NULL};
- struct ad_master_domain_state *state =
- tevent_req_data(req, struct ad_master_domain_state);
+ struct ad_domain_info_state *state =
+ tevent_req_data(req, struct ad_domain_info_state);
base = state->opts->sdom->search_bases[state->base_iter];
if (base == NULL) {
@@ -261,13 +261,13 @@ ad_master_domain_next(struct tevent_req *req)
DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n");
return ENOMEM;
}
- tevent_req_set_callback(subreq, ad_master_domain_next_done, req);
+ tevent_req_set_callback(subreq, ad_domain_info_next_done, req);
return EAGAIN;
}
static void
-ad_master_domain_next_done(struct tevent_req *subreq)
+ad_domain_info_next_done(struct tevent_req *subreq)
{
errno_t ret;
size_t reply_count;
@@ -281,8 +281,8 @@ ad_master_domain_next_done(struct tevent_req *subreq)
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
- struct ad_master_domain_state *state =
- tevent_req_data(req, struct ad_master_domain_state);
+ struct ad_domain_info_state *state =
+ tevent_req_data(req, struct ad_domain_info_state);
ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
talloc_zfree(subreq);
@@ -293,7 +293,7 @@ ad_master_domain_next_done(struct tevent_req *subreq)
if (reply_count == 0) {
state->base_iter++;
- ret = ad_master_domain_next(req);
+ ret = ad_domain_info_next(req);
if (ret == EAGAIN) {
/* Async request will get us back here again */
return;
@@ -362,7 +362,7 @@ ad_master_domain_next_done(struct tevent_req *subreq)
goto done;
}
- tevent_req_set_callback(subreq, ad_master_domain_netlogon_done, req);
+ tevent_req_set_callback(subreq, ad_domain_info_netlogon_done, req);
return;
done:
@@ -370,7 +370,7 @@ done:
}
static void
-ad_master_domain_netlogon_done(struct tevent_req *subreq)
+ad_domain_info_netlogon_done(struct tevent_req *subreq)
{
int ret;
size_t reply_count;
@@ -378,8 +378,8 @@ ad_master_domain_netlogon_done(struct tevent_req *subreq)
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
- struct ad_master_domain_state *state =
- tevent_req_data(req, struct ad_master_domain_state);
+ struct ad_domain_info_state *state =
+ tevent_req_data(req, struct ad_domain_info_state);
ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
talloc_zfree(subreq);
@@ -422,15 +422,15 @@ done:
}
errno_t
-ad_master_domain_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx,
- char **_flat,
- char **_id,
- char **_site,
- char **_forest)
+ad_domain_info_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ char **_flat,
+ char **_id,
+ char **_site,
+ char **_forest)
{
- struct ad_master_domain_state *state = tevent_req_data(req,
- struct ad_master_domain_state);
+ struct ad_domain_info_state *state = tevent_req_data(req,
+ struct ad_domain_info_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
diff --git a/src/providers/ad/ad_domain_info.h b/src/providers/ad/ad_domain_info.h
index b96e8a3c3..631e543f5 100644
--- a/src/providers/ad/ad_domain_info.h
+++ b/src/providers/ad/ad_domain_info.h
@@ -22,22 +22,22 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _AD_MASTER_DOMAIN_H_
-#define _AD_MASTER_DOMAIN_H_
+#ifndef _AD_DOMAIN_INFO_H_
+#define _AD_DOMAIN_INFO_H_
struct tevent_req *
-ad_master_domain_send(TALLOC_CTX *mem_ctx,
+ad_domain_info_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct sdap_id_conn_ctx *conn,
struct sdap_id_op *op,
const char *dom_name);
errno_t
-ad_master_domain_recv(struct tevent_req *req,
+ad_domain_info_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
char **_flat,
char **_id,
char **_site,
char **_forest);
-#endif /* _AD_MASTER_DOMAIN_H_ */
+#endif /* _AD_DOMAIN_INFO_H_ */
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index 1524c4bfc..53560a754 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -3151,11 +3151,11 @@ ad_gpo_process_som_send(TALLOC_CTX *mem_ctx,
goto immediately;
}
- subreq = ad_master_domain_send(state, state->ev, conn,
- state->sdap_op, domain_name);
+ subreq = ad_domain_info_send(state, state->ev, conn,
+ state->sdap_op, domain_name);
if (subreq == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "ad_master_domain_send failed.\n");
+ DEBUG(SSSDBG_OP_FAILURE, "ad_domain_info_send failed.\n");
ret = ENOMEM;
goto immediately;
}
@@ -3188,7 +3188,7 @@ ad_gpo_site_name_retrieval_done(struct tevent_req *subreq)
state = tevent_req_data(req, struct ad_gpo_process_som_state);
/* gpo code only cares about the site name */
- ret = ad_master_domain_recv(subreq, state, NULL, NULL, &site, NULL);
+ ret = ad_domain_info_recv(subreq, state, NULL, NULL, &site, NULL);
talloc_zfree(subreq);
if (ret != EOK || site == NULL) {
diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
index 84e5c42ac..ca6486e03 100644
--- a/src/providers/ad/ad_id.c
+++ b/src/providers/ad/ad_id.c
@@ -663,12 +663,12 @@ ad_enumeration_conn_done(struct tevent_req *subreq)
return;
}
- subreq = ad_master_domain_send(state, state->ev,
- state->id_ctx->ldap_ctx,
- state->sdap_op,
- state->sdom->dom->name);
+ subreq = ad_domain_info_send(state, state->ev,
+ state->id_ctx->ldap_ctx,
+ state->sdap_op,
+ state->sdom->dom->name);
if (subreq == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "ad_master_domain_send failed.\n");
+ DEBUG(SSSDBG_OP_FAILURE, "ad_domain_info_send failed.\n");
tevent_req_error(req, ret);
return;
}
@@ -687,8 +687,8 @@ ad_enumeration_master_done(struct tevent_req *subreq)
char *master_sid;
char *forest;
- ret = ad_master_domain_recv(subreq, state,
- &flat_name, &master_sid, NULL, &forest);
+ ret = ad_domain_info_recv(subreq, state,
+ &flat_name, &master_sid, NULL, &forest);
talloc_zfree(subreq);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot retrieve master domain info\n");
diff --git a/src/providers/ad/ad_resolver.c b/src/providers/ad/ad_resolver.c
index b58f08ecf..c87706094 100644
--- a/src/providers/ad/ad_resolver.c
+++ b/src/providers/ad/ad_resolver.c
@@ -317,10 +317,10 @@ ad_resolver_enumeration_conn_done(struct tevent_req *subreq)
return;
}
- subreq = ad_master_domain_send(state, state->ev, id_ctx->conn,
- state->sdap_op, state->sdom->dom->name);
+ subreq = ad_domain_info_send(state, state->ev, id_ctx->conn,
+ state->sdap_op, state->sdom->dom->name);
if (subreq == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "ad_master_domain_send failed.\n");
+ DEBUG(SSSDBG_OP_FAILURE, "ad_domain_info_send failed.\n");
tevent_req_error(req, ret);
return;
}
@@ -346,7 +346,7 @@ ad_resolver_enumeration_master_done(struct tevent_req *subreq)
char *forest;
struct ad_id_ctx *ad_id_ctx;
- ret = ad_master_domain_recv(subreq, state,
+ ret = ad_domain_info_recv(subreq, state,
&flat_name, &master_sid, NULL, &forest);
talloc_zfree(subreq);
if (ret != EOK) {
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index 06fbdb0ef..c53962283 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -1756,8 +1756,8 @@ static void ad_subdomains_refresh_connect_done(struct tevent_req *subreq)
}
/* connect to the DC we are a member of */
- subreq = ad_master_domain_send(state, state->ev, state->id_ctx->conn,
- state->sdap_op, state->sd_ctx->domain_name);
+ subreq = ad_domain_info_send(state, state->ev, state->id_ctx->conn,
+ state->sdap_op, state->sd_ctx->domain_name);
if (subreq == NULL) {
tevent_req_error(req, ENOMEM);
return;
@@ -1779,8 +1779,8 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq)
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct ad_subdomains_refresh_state);
- ret = ad_master_domain_recv(subreq, state, &flat_name, &master_sid,
- NULL, &state->forest);
+ ret = ad_domain_info_recv(subreq, state, &flat_name, &master_sid,
+ NULL, &state->forest);
talloc_zfree(subreq);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get master domain information "
--
2.21.3

View File

@ -0,0 +1,117 @@
From 9aa26f6514220bae3b3314f830e3e3f95fab2cf9 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 7 May 2020 21:18:13 +0200
Subject: [PATCH 15/19] sysdb: make new_subdomain() public
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves: https://github.com/SSSD/sssd/issues/5151
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/db/sysdb.h | 18 ++++++++++++++++++
src/db/sysdb_private.h | 19 -------------------
src/tests/cmocka/test_negcache.c | 1 -
src/tests/cmocka/test_nss_srv.c | 1 -
src/tests/cmocka/test_responder_cache_req.c | 1 -
5 files changed, 18 insertions(+), 22 deletions(-)
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 64e546f5b..e4ed10b54 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -562,6 +562,24 @@ errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name);
errno_t sysdb_subdomain_content_delete(struct sysdb_ctx *sysdb,
const char *name);
+/* The utility function to create a subdomain sss_domain_info object is handy
+ * for unit tests, so it should be available in a headerr.
+ */
+struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *parent,
+ const char *name,
+ const char *realm,
+ const char *flat_name,
+ const char *id,
+ enum sss_domain_mpg_mode mpg_mode,
+ bool enumerate,
+ const char *forest,
+ const char **upn_suffixes,
+ uint32_t trust_direction,
+ struct confdb_ctx *confdb,
+ bool enabled);
+
+
errno_t sysdb_get_ranges(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
size_t *range_count,
struct range_info ***range_list);
diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h
index 3302919a6..70fe3fa18 100644
--- a/src/db/sysdb_private.h
+++ b/src/db/sysdb_private.h
@@ -196,25 +196,6 @@ int sysdb_replace_ulong(struct ldb_message *msg,
int sysdb_delete_ulong(struct ldb_message *msg,
const char *attr, unsigned long value);
-/* The utility function to create a subdomain sss_domain_info object is handy
- * for unit tests, so it should be available in a header, but not a public util
- * one, because the only interface for the daemon itself should be adding
- * the sysdb domain object and calling sysdb_update_subdomains()
- */
-struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *parent,
- const char *name,
- const char *realm,
- const char *flat_name,
- const char *id,
- enum sss_domain_mpg_mode mpg_mode,
- bool enumerate,
- const char *forest,
- const char **upn_suffixes,
- uint32_t trust_direction,
- struct confdb_ctx *confdb,
- bool enabled);
-
/* Helper functions to deal with the timestamp cache should not be used
* outside the sysdb itself. The timestamp cache should be completely
* opaque to the sysdb consumers
diff --git a/src/tests/cmocka/test_negcache.c b/src/tests/cmocka/test_negcache.c
index 3ed1cb14a..b3a379227 100644
--- a/src/tests/cmocka/test_negcache.c
+++ b/src/tests/cmocka/test_negcache.c
@@ -38,7 +38,6 @@
#include "util/util_sss_idmap.h"
#include "lib/idmap/sss_idmap.h"
#include "util/util.h"
-#include "db/sysdb_private.h"
#include "responder/common/responder.h"
#include "responder/common/negcache.h"
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
index 3cd7809cf..99ba02a80 100644
--- a/src/tests/cmocka/test_nss_srv.c
+++ b/src/tests/cmocka/test_nss_srv.c
@@ -36,7 +36,6 @@
#include "util/crypto/sss_crypto.h"
#include "util/crypto/nss/nss_util.h"
#include "util/sss_endian.h"
-#include "db/sysdb_private.h" /* new_subdomain() */
#include "db/sysdb_iphosts.h"
#include "db/sysdb_ipnetworks.h"
diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c
index 2611c589b..68a651240 100644
--- a/src/tests/cmocka/test_responder_cache_req.c
+++ b/src/tests/cmocka/test_responder_cache_req.c
@@ -27,7 +27,6 @@
#include "tests/cmocka/common_mock_resp.h"
#include "db/sysdb.h"
#include "responder/common/cache_req/cache_req.h"
-#include "db/sysdb_private.h" /* new_subdomain() */
#define TESTS_PATH "tp_" BASE_FILE_STEM
#define TEST_CONF_DB "test_responder_cache_req_conf.ldb"
--
2.21.3

View File

@ -1,52 +0,0 @@
From 9ba6f33ee78e1c15847f11b8f75f8a8413034875 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Po=C5=82awski?= <ppolawsk@redhat.com>
Date: Tue, 3 Dec 2019 04:13:53 +0100
Subject: [PATCH] sysdb_sudo: Enable LDAP time format compatibility
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
LDAP specification allows to ommit seconds and minutes
in time border definition. In that case they defaults to zeros.
Current sssd.sudo implementation requires precision up to
seconds in time definition. This commit allows to lower
the precision up to hours.
Resolves:
https://pagure.io/SSSD/sssd/issue/4118
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/db/sysdb_sudo.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c
index 59d6824c0..18088b017 100644
--- a/src/db/sysdb_sudo.c
+++ b/src/db/sysdb_sudo.c
@@ -55,6 +55,22 @@ static errno_t sysdb_sudo_convert_time(const char *str, time_t *unix_time)
"%Y%m%d%H%M%S.0%z",
"%Y%m%d%H%M%S,0Z",
"%Y%m%d%H%M%S,0%z",
+ /* LDAP specification says that minutes and seconds
+ might be omitted and in that case these are meant
+ to be treated as zeros [1].
+ */
+ "%Y%m%d%H%MZ", /* Discard seconds */
+ "%Y%m%d%H%M%z",
+ "%Y%m%d%H%M.0Z",
+ "%Y%m%d%H%M.0%z",
+ "%Y%m%d%H%M,0Z",
+ "%Y%m%d%H%M,0%z",
+ "%Y%m%d%HZ", /* Discard minutes and seconds*/
+ "%Y%m%d%H%z",
+ "%Y%m%d%H.0Z",
+ "%Y%m%d%H.0%z",
+ "%Y%m%d%H,0Z",
+ "%Y%m%d%H,0%z",
NULL};
for (format = formats; *format != NULL; format++) {
--
2.20.1

View File

@ -0,0 +1,89 @@
From 2bad4d4b299440d33919a9fdb8c4d75814583e12 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 7 May 2020 21:24:42 +0200
Subject: [PATCH 16/19] ad: rename ads_get_root_id_ctx() to ads_get_dom_id_ctx
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since the function can be used to get the id ctx of any domain the
'root' is removed from the name.
Resolves: https://github.com/SSSD/sssd/issues/5151
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/providers/ad/ad_subdomains.c | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index c53962283..a9a552ff7 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -1231,37 +1231,37 @@ static errno_t ad_get_slave_domain_recv(struct tevent_req *req)
}
static struct ad_id_ctx *
-ads_get_root_id_ctx(struct be_ctx *be_ctx,
- struct ad_id_ctx *ad_id_ctx,
- struct sss_domain_info *root_domain,
- struct sdap_options *opts)
+ads_get_dom_id_ctx(struct be_ctx *be_ctx,
+ struct ad_id_ctx *ad_id_ctx,
+ struct sss_domain_info *domain,
+ struct sdap_options *opts)
{
errno_t ret;
struct sdap_domain *sdom;
- struct ad_id_ctx *root_id_ctx;
+ struct ad_id_ctx *dom_id_ctx;
- sdom = sdap_domain_get(opts, root_domain);
+ sdom = sdap_domain_get(opts, domain);
if (sdom == NULL) {
DEBUG(SSSDBG_OP_FAILURE,
- "Cannot get the sdom for %s!\n", root_domain->name);
+ "Cannot get the sdom for %s!\n", domain->name);
return NULL;
}
if (sdom->pvt == NULL) {
- ret = ad_subdom_ad_ctx_new(be_ctx, ad_id_ctx, root_domain,
- &root_id_ctx);
+ ret = ad_subdom_ad_ctx_new(be_ctx, ad_id_ctx, domain,
+ &dom_id_ctx);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "ad_subdom_ad_ctx_new failed.\n");
return NULL;
}
- sdom->pvt = root_id_ctx;
+ sdom->pvt = dom_id_ctx;
} else {
- root_id_ctx = sdom->pvt;
+ dom_id_ctx = sdom->pvt;
}
- root_id_ctx->ldap_ctx->ignore_mark_offline = true;
- return root_id_ctx;
+ dom_id_ctx->ldap_ctx->ignore_mark_offline = true;
+ return dom_id_ctx;
}
struct ad_get_root_domain_state {
@@ -1403,9 +1403,9 @@ static void ad_get_root_domain_done(struct tevent_req *subreq)
goto done;
}
- state->root_id_ctx = ads_get_root_id_ctx(state->be_ctx,
- state->sd_ctx->ad_id_ctx,
- root_domain, state->opts);
+ state->root_id_ctx = ads_get_dom_id_ctx(state->be_ctx,
+ state->sd_ctx->ad_id_ctx,
+ root_domain, state->opts);
if (state->root_id_ctx == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot create id ctx for the root domain\n");
ret = EFAULT;
--
2.21.3

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
From 8c642a542245a9f9fde5c2de9c96082b4c0d0963 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 11 May 2020 21:26:13 +0200
Subject: [PATCH 17/19] ad: remove unused trust_type from ad_subdom_store()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves: https://github.com/SSSD/sssd/issues/5151
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/providers/ad/ad_subdomains.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index a9a552ff7..198f5c916 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -576,7 +576,6 @@ ad_subdom_store(struct confdb_ctx *cdb,
enum idmap_error_code err;
struct ldb_message_element *el;
char *sid_str = NULL;
- uint32_t trust_type;
enum sss_domain_mpg_mode mpg_mode;
enum sss_domain_mpg_mode default_mpg_mode;
@@ -586,13 +585,6 @@ ad_subdom_store(struct confdb_ctx *cdb,
goto done;
}
- ret = sysdb_attrs_get_uint32_t(subdom_attrs, AD_AT_TRUST_TYPE,
- &trust_type);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_uint32_t failed.\n");
- goto done;
- }
-
ret = sysdb_attrs_get_string(subdom_attrs, AD_AT_TRUST_PARTNER, &name);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "failed to get subdomain name\n");
--
2.21.3

View File

@ -1,43 +0,0 @@
From faa5dbf6f716bd4ac0a3020a28a1ee6fbf74654a Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Thu, 23 Jan 2020 17:22:28 +0100
Subject: [PATCH 17/23] sbus_server: stylistic rename
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Renamed sbus_server_name_remove_from_table() to
sbus_server_name_remove_from_table_cb() to keep naming consistent
with other functions used as `hash_delete_callback` argument of
sss_ptr_hash_create()
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/sbus/server/sbus_server.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/sbus/server/sbus_server.c b/src/sbus/server/sbus_server.c
index 5405dae56..2b9327051 100644
--- a/src/sbus/server/sbus_server.c
+++ b/src/sbus/server/sbus_server.c
@@ -584,7 +584,7 @@ sbus_server_name_lost(struct sbus_server *server,
}
static void
-sbus_server_name_remove_from_table(hash_entry_t *item,
+sbus_server_name_remove_from_table_cb(hash_entry_t *item,
hash_destroy_enum type,
void *pvt)
{
@@ -676,7 +676,7 @@ sbus_server_create(TALLOC_CTX *mem_ctx,
}
sbus_server->names = sss_ptr_hash_create(sbus_server,
- sbus_server_name_remove_from_table, sbus_server);
+ sbus_server_name_remove_from_table_cb, sbus_server);
if (sbus_server->names == NULL) {
ret = ENOMEM;
goto done;
--
2.20.1

View File

@ -0,0 +1,283 @@
From 3ae3286d61ed796f0be7a1d72157af3687bc04a5 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 7 May 2020 21:26:16 +0200
Subject: [PATCH 18/19] ad: add ad_check_domain_{send|recv}
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This new request tries to get the basic domain information like domain
SID and NetBIOS domain name for a domain given by the name. To achieve
this the needed data is added to general domain structure and the SDAP
domain structure. If the domain data cannot be looked up the data is
removed again.
Resolves: https://github.com/SSSD/sssd/issues/5151
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/providers/ad/ad_subdomains.c | 251 +++++++++++++++++++++++++++++++
1 file changed, 251 insertions(+)
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index 198f5c916..299aa7391 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -2143,3 +2143,254 @@ errno_t ad_subdomains_init(TALLOC_CTX *mem_ctx,
return EOK;
}
+
+struct ad_check_domain_state {
+ struct tevent_context *ev;
+ struct be_ctx *be_ctx;
+ struct sdap_id_op *sdap_op;
+ struct ad_id_ctx *dom_id_ctx;
+ struct sdap_options *opts;
+
+ const char *dom_name;
+ struct sss_domain_info *dom;
+ struct sss_domain_info *parent;
+ struct sdap_domain *sdom;
+
+ char *flat;
+ char *site;
+ char *forest;
+ char *sid;
+};
+
+static void ad_check_domain_connect_done(struct tevent_req *subreq);
+static void ad_check_domain_done(struct tevent_req *subreq);
+
+static int ad_check_domain_destructor(void *mem)
+{
+ struct ad_check_domain_state *state = talloc_get_type(mem,
+ struct ad_check_domain_state);
+
+ if (state->sdom != NULL) {
+ DEBUG(SSSDBG_TRACE_ALL, "Removing sdap domain [%s].\n",
+ state->dom->name);
+ sdap_domain_remove(state->opts, state->dom);
+ /* terminate all requests for this subdomain so we can free it */
+ dp_terminate_domain_requests(state->be_ctx->provider, state->dom->name);
+ talloc_zfree(state->sdom);
+ }
+
+ if (state->dom != NULL) {
+ DEBUG(SSSDBG_TRACE_ALL, "Removing domain [%s].\n", state->dom->name);
+ sss_domain_set_state(state->dom, DOM_DISABLED);
+ DLIST_REMOVE(state->be_ctx->domain->subdomains, state->dom);
+ talloc_zfree(state->dom);
+ }
+
+ return 0;
+}
+
+struct tevent_req *
+ad_check_domain_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct be_ctx *be_ctx,
+ struct ad_id_ctx *ad_id_ctx,
+ const char *dom_name,
+ const char *parent_dom_name)
+{
+ errno_t ret;
+ struct tevent_req *req;
+ struct tevent_req *subreq;
+ struct ad_check_domain_state *state;
+
+ req = tevent_req_create(mem_ctx, &state, struct ad_check_domain_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n");
+ return NULL;
+ }
+
+ state->ev = ev;
+ state->be_ctx = be_ctx;
+ state->opts = ad_id_ctx->sdap_id_ctx->opts;
+ state->dom_name = dom_name;
+ state->parent = NULL;
+ state->sdom = NULL;
+
+ state->dom = find_domain_by_name(be_ctx->domain, dom_name, true);
+ if (state->dom == NULL) {
+ state->parent = find_domain_by_name(be_ctx->domain, parent_dom_name,
+ true);
+ if (state->parent == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to find domain object for domain [%s].\n",
+ parent_dom_name);
+ ret = ENOENT;
+ goto immediately;
+ }
+
+ state->dom = new_subdomain(state->parent, state->parent, dom_name,
+ dom_name, NULL, NULL, MPG_DISABLED, false,
+ state->parent->forest,
+ NULL, 0, be_ctx->cdb, true);
+ if (state->dom == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "new_subdomain() failed.\n");
+ ret = EINVAL;
+ goto immediately;
+ }
+
+ talloc_set_destructor((TALLOC_CTX *) state, ad_check_domain_destructor);
+
+ DLIST_ADD_END(state->parent->subdomains, state->dom,
+ struct sss_domain_info *);
+
+ ret = sdap_domain_add(state->opts, state->dom, &state->sdom);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sdap_domain_subdom_add failed.\n");
+ goto immediately;
+ }
+
+ ret = ad_set_search_bases(ad_id_ctx->ad_options->id, state->sdom);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "failed to set ldap search bases for "
+ "domain '%s'. Will try to use automatically detected search "
+ "bases.", state->sdom->dom->name);
+ }
+
+ }
+
+ state->dom_id_ctx = ads_get_dom_id_ctx(be_ctx, ad_id_ctx, state->dom,
+ state->opts);
+ if (state->dom_id_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ads_get_dom_id_ctx() failed.\n");
+ ret = EINVAL;
+ goto immediately;
+ }
+
+ state->sdap_op = sdap_id_op_create(state,
+ state->dom_id_ctx->sdap_id_ctx->conn->conn_cache);
+ if (state->sdap_op == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create() failed\n");
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "sdap_id_op_connect_send() failed "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto immediately;
+ }
+
+ tevent_req_set_callback(subreq, ad_check_domain_connect_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 ad_check_domain_connect_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req;
+ struct ad_check_domain_state *state;
+ int ret;
+ int dp_error;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct ad_check_domain_state);
+
+ ret = sdap_id_op_connect_recv(subreq, &dp_error);
+ talloc_zfree(subreq);
+
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to connect to LDAP "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ if (dp_error == DP_ERR_OFFLINE) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "No AD server is available, "
+ "cannot get the subdomain list while offline\n");
+ ret = ERR_OFFLINE;
+ }
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ subreq = ad_domain_info_send(state, state->ev,
+ state->dom_id_ctx->sdap_id_ctx->conn,
+ state->sdap_op, state->dom_name);
+
+ tevent_req_set_callback(subreq, ad_check_domain_done, req);
+
+ return;
+}
+
+static void ad_check_domain_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req;
+ struct ad_check_domain_state *state;
+ errno_t ret;
+
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct ad_check_domain_state);
+
+ ret = ad_domain_info_recv(subreq, state, &state->flat, &state->sid,
+ &state->site, &state->forest);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to lookup domain information "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
+ DEBUG(SSSDBG_TRACE_ALL, "%s %s %s %s.\n", state->flat, state->sid,
+ state->site, state->forest);
+
+ /* New domain was successfully checked, remove destructor. */
+ talloc_set_destructor(state, NULL);
+
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
+errno_t ad_check_domain_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ char **_flat,
+ char **_id,
+ char **_site,
+ char **_forest)
+{
+ struct ad_check_domain_state *state = tevent_req_data(req,
+ struct ad_check_domain_state);
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ if (_flat) {
+ *_flat = talloc_steal(mem_ctx, state->flat);
+ }
+
+ if (_site) {
+ *_site = talloc_steal(mem_ctx, state->site);
+ }
+
+ if (_forest) {
+ *_forest = talloc_steal(mem_ctx, state->forest);
+ }
+
+ if (_id) {
+ *_id = talloc_steal(mem_ctx, state->sid);
+ }
+
+ return EOK;
+}
--
2.21.3

View File

@ -1,91 +0,0 @@
From adc7730a4e1b9721c93863a1b283457e9c02a3c5 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Thu, 23 Jan 2020 17:55:24 +0100
Subject: [PATCH 18/23] sss_ptr_hash: don't keep empty sss_ptr_hash_delete_data
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There is no need to allocate memory for `sss_ptr_hash_delete_data`
if table user doesn't provide custom delete callback.
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/util/sss_ptr_hash.c | 36 ++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/src/util/sss_ptr_hash.c b/src/util/sss_ptr_hash.c
index 8f9762cb9..f8addec1e 100644
--- a/src/util/sss_ptr_hash.c
+++ b/src/util/sss_ptr_hash.c
@@ -138,12 +138,6 @@ sss_ptr_hash_delete_cb(hash_entry_t *item,
struct sss_ptr_hash_value *value;
struct hash_entry_t callback_entry;
- data = talloc_get_type(pvt, struct sss_ptr_hash_delete_data);
- if (data == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Invalid data!\n");
- return;
- }
-
value = talloc_get_type(item->value.ptr, struct sss_ptr_hash_value);
if (value == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Invalid value!\n");
@@ -157,8 +151,14 @@ sss_ptr_hash_delete_cb(hash_entry_t *item,
/* Free value, this also will disable spy */
talloc_free(value);
- /* Switch to the input value and call custom callback. */
- if (data->callback != NULL) {
+ if (pvt != NULL) {
+ /* Switch to the input value and call custom callback. */
+ data = talloc_get_type(pvt, struct sss_ptr_hash_delete_data);
+ if (data == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid data!\n");
+ return;
+ }
+
data->callback(&callback_entry, deltype, data->pvt);
}
}
@@ -167,17 +167,19 @@ hash_table_t *sss_ptr_hash_create(TALLOC_CTX *mem_ctx,
hash_delete_callback *del_cb,
void *del_cb_pvt)
{
- struct sss_ptr_hash_delete_data *data;
+ struct sss_ptr_hash_delete_data *data = NULL;
hash_table_t *table;
errno_t ret;
- data = talloc_zero(NULL, struct sss_ptr_hash_delete_data);
- if (data == NULL) {
- return NULL;
- }
+ if (del_cb != NULL) {
+ data = talloc_zero(NULL, struct sss_ptr_hash_delete_data);
+ if (data == NULL) {
+ return NULL;
+ }
- data->callback = del_cb;
- data->pvt = del_cb_pvt;
+ data->callback = del_cb;
+ data->pvt = del_cb_pvt;
+ }
ret = sss_hash_create_ex(mem_ctx, 10, &table, 0, 0, 0, 0,
sss_ptr_hash_delete_cb, data);
@@ -188,7 +190,9 @@ hash_table_t *sss_ptr_hash_create(TALLOC_CTX *mem_ctx,
return NULL;
}
- talloc_steal(table, data);
+ if (data != NULL) {
+ talloc_steal(table, data);
+ }
return table;
}
--
2.20.1

View File

@ -0,0 +1,281 @@
From e25e1e9228a6108d8e94f2e99f3004e6cbfc3349 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 12 May 2020 16:55:32 +0200
Subject: [PATCH 19/19] ad: check forest root directly if not present on local
DC
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the information about the forest root domain cannot be read from the
local domain-controller it is tried to read it from a DC of the forest
root directly.
Resolves: https://github.com/SSSD/sssd/issues/5151
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/providers/ad/ad_subdomains.c | 184 +++++++++++++++++++++++++++----
1 file changed, 164 insertions(+), 20 deletions(-)
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index 299aa7391..7c6f51db7 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -35,6 +35,10 @@
#include <ndr.h>
#include <ndr/ndr_nbt.h>
+/* Avoid that ldb_val is overwritten by data_blob.h */
+#undef ldb_val
+#include <ldb.h>
+
/* Attributes of AD trusted domains */
#define AD_AT_FLATNAME "flatName"
#define AD_AT_SID "securityIdentifier"
@@ -1258,15 +1262,37 @@ ads_get_dom_id_ctx(struct be_ctx *be_ctx,
struct ad_get_root_domain_state {
struct ad_subdomains_ctx *sd_ctx;
+ struct tevent_context *ev;
struct be_ctx *be_ctx;
struct sdap_idmap_ctx *idmap_ctx;
struct sdap_options *opts;
+ const char *domain;
+ const char *forest;
+ struct sysdb_attrs **reply;
+ size_t reply_count;
struct ad_id_ctx *root_id_ctx;
struct sysdb_attrs *root_domain_attrs;
};
static void ad_get_root_domain_done(struct tevent_req *subreq);
+static void ad_check_root_domain_done(struct tevent_req *subreq);
+static errno_t
+ad_get_root_domain_refresh(struct ad_get_root_domain_state *state);
+
+struct tevent_req *
+ad_check_domain_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct be_ctx *be_ctx,
+ struct ad_id_ctx *ad_id_ctx,
+ const char *dom_name,
+ const char *parent_dom_name);
+errno_t ad_check_domain_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ char **_flat,
+ char **_id,
+ char **_site,
+ char **_forest);
static struct tevent_req *
ad_get_root_domain_send(TALLOC_CTX *mem_ctx,
@@ -1305,6 +1331,9 @@ ad_get_root_domain_send(TALLOC_CTX *mem_ctx,
state->opts = opts = sd_ctx->sdap_id_ctx->opts;
state->be_ctx = sd_ctx->be_ctx;
state->idmap_ctx = opts->idmap_ctx;
+ state->ev = ev;
+ state->domain = domain;
+ state->forest = forest;
filter = talloc_asprintf(state, FOREST_ROOT_FILTER_FMT, forest);
if (filter == NULL) {
@@ -1340,17 +1369,14 @@ static void ad_get_root_domain_done(struct tevent_req *subreq)
{
struct tevent_req *req;
struct ad_get_root_domain_state *state;
- struct sysdb_attrs **reply;
- struct sss_domain_info *root_domain;
- size_t reply_count;
- bool has_changes;
errno_t ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct ad_get_root_domain_state);
- ret = sdap_search_bases_return_first_recv(subreq, state, &reply_count,
- &reply);
+ ret = sdap_search_bases_return_first_recv(subreq, state,
+ &state->reply_count,
+ &state->reply);
talloc_zfree(subreq);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Unable to lookup forest root information "
@@ -1358,19 +1384,142 @@ static void ad_get_root_domain_done(struct tevent_req *subreq)
goto done;
}
- if (reply_count == 0) {
- DEBUG(SSSDBG_OP_FAILURE, "No information provided for root domain\n");
- ret = ENOENT;
- goto done;
- } else if (reply_count > 1) {
+ if (state->reply_count == 0) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "No information provided for root domain, trying directly.\n");
+ subreq = ad_check_domain_send(state, state->ev, state->be_ctx,
+ state->sd_ctx->ad_id_ctx, state->forest,
+ state->domain);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ad_check_domain_send() failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ tevent_req_set_callback(subreq, ad_check_root_domain_done, req);
+ return;
+ } else if (state->reply_count > 1) {
DEBUG(SSSDBG_CRIT_FAILURE, "Multiple results for root domain search, "
"domain list might be incomplete!\n");
ret = ERR_MALFORMED_ENTRY;
goto done;
}
+ ret = ad_get_root_domain_refresh(state);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "ad_get_root_domain_refresh() failed.\n");
+ }
+
+done:
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
+static void ad_check_root_domain_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req;
+ struct ad_get_root_domain_state *state;
+ errno_t ret;
+ char *flat = NULL;
+ char *id = NULL;
+ enum idmap_error_code err;
+ struct ldb_val id_val;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct ad_get_root_domain_state);
+
+ ret = ad_check_domain_recv(state, subreq, &flat, &id, NULL, NULL);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to check forest root information "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+ if (flat == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "NetBIOS name of forest root not available.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ if (id == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Domain SID of forest root not available.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ state->reply = talloc_array(state, struct sysdb_attrs *, 1);
+ if (state->reply == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_array() failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ state->reply[0] = sysdb_new_attrs(state->reply);
+ if (state->reply[0] == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs() failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_attrs_add_string(state->reply[0], AD_AT_FLATNAME, flat);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string() failed.\n");
+ goto done;
+ }
+
+ ret = sysdb_attrs_add_string(state->reply[0], AD_AT_TRUST_PARTNER,
+ state->forest);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string() failed.\n");
+ goto done;
+ }
+
+ err = sss_idmap_sid_to_bin_sid(state->idmap_ctx->map, id,
+ &id_val.data, &id_val.length);
+ if (err != IDMAP_SUCCESS) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Could not convert SID: [%s].\n", idmap_error_string(err));
+ ret = EFAULT;
+ goto done;
+ }
+
+ ret = sysdb_attrs_add_val(state->reply[0], AD_AT_SID, &id_val);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string() failed.\n");
+ goto done;
+ }
+
+ state->reply_count = 1;
+
+ ret = ad_get_root_domain_refresh(state);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "ad_get_root_domain_refresh() failed.\n");
+ }
+
+done:
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
+static errno_t
+ad_get_root_domain_refresh(struct ad_get_root_domain_state *state)
+{
+ struct sss_domain_info *root_domain;
+ bool has_changes;
+ errno_t ret;
+
ret = ad_subdomains_refresh(state->be_ctx, state->idmap_ctx, state->opts,
- reply, reply_count, true,
+ state->reply, state->reply_count, true,
&state->sd_ctx->last_refreshed,
&has_changes);
if (ret != EOK) {
@@ -1387,8 +1536,8 @@ static void ad_get_root_domain_done(struct tevent_req *subreq)
}
}
- state->root_domain_attrs = reply[0];
- root_domain = ads_get_root_domain(state->be_ctx, reply[0]);
+ state->root_domain_attrs = state->reply[0];
+ root_domain = ads_get_root_domain(state->be_ctx, state->reply[0]);
if (root_domain == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "Could not find the root domain\n");
ret = EFAULT;
@@ -1407,12 +1556,7 @@ static void ad_get_root_domain_done(struct tevent_req *subreq)
ret = EOK;
done:
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
+ return ret;
}
static errno_t ad_get_root_domain_recv(TALLOC_CTX *mem_ctx,
--
2.21.3

View File

@ -1,62 +0,0 @@
From d0eb88089b059bfe2da3bd1a3797b89d69119c29 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Thu, 23 Jan 2020 19:00:27 +0100
Subject: [PATCH 19/23] sss_ptr_hash: sss_ptr_hash_delete fix/optimization
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- no reason to skip hash_delete() just because sss_ptr_hash_lookup_internal()
failed
- avoid excessive lookup if it is not required to free payload
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/util/sss_ptr_hash.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/src/util/sss_ptr_hash.c b/src/util/sss_ptr_hash.c
index f8addec1e..7326244e6 100644
--- a/src/util/sss_ptr_hash.c
+++ b/src/util/sss_ptr_hash.c
@@ -331,20 +331,21 @@ void sss_ptr_hash_delete(hash_table_t *table,
struct sss_ptr_hash_value *value;
hash_key_t table_key;
int hret;
- void *ptr;
+ void *payload;
if (table == NULL || key == NULL) {
return;
}
- value = sss_ptr_hash_lookup_internal(table, key);
- if (value == NULL) {
- /* Value not found. */
- return;
+ if (free_value) {
+ value = sss_ptr_hash_lookup_internal(table, key);
+ if (value == NULL) {
+ free_value = false;
+ } else {
+ payload = value->ptr;
+ }
}
- ptr = value->ptr;
-
table_key.type = HASH_KEY_STRING;
table_key.str = discard_const_p(char, key);
@@ -357,7 +358,7 @@ void sss_ptr_hash_delete(hash_table_t *table,
/* Also free the original value if requested. */
if (free_value) {
- talloc_free(ptr);
+ talloc_free(payload);
}
return;
--
2.20.1

View File

@ -0,0 +1,44 @@
From d8d743870c459b5ff283c89d78b70d1684bd19a9 Mon Sep 17 00:00:00 2001
From: Tomas Halman <thalman@redhat.com>
Date: Wed, 13 May 2020 09:45:56 +0200
Subject: [PATCH] man: Document invalid selinux context for homedirs
The default value of fallback_homedir expands into path, that is not
expected by selinux. Generally not only selinux might be affected by
this default value. This PR documents the issue and recommends
further steps.
Resolves:
https://github.com/SSSD/sssd/issues/5155
Reviewed-by: Alexey Tikhonov <atikhonov@redhat.com>
---
src/man/include/ad_modified_defaults.xml | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/man/include/ad_modified_defaults.xml b/src/man/include/ad_modified_defaults.xml
index 91623d57a..65c9a0140 100644
--- a/src/man/include/ad_modified_defaults.xml
+++ b/src/man/include/ad_modified_defaults.xml
@@ -92,6 +92,18 @@
this fallback behavior, you can explicitly
set "fallback_homedir = %o".
</para>
+ <para>
+ Note that the system typically expects a home directory
+ in /home/%u folder. If you decide to use a different
+ directory structure, some other parts of your system may
+ need adjustments.
+ </para>
+ <para>
+ For example automated creation of home directories in
+ combination with selinux requires selinux adjustment,
+ otherwise the home directory will be created with wrong
+ selinux context.
+ </para>
</listitem>
</itemizedlist>
</refsect2>
--
2.21.3

View File

@ -1,35 +0,0 @@
From 8cc2ce4e9060a71d441a377008fb2f567baa5d92 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Thu, 23 Jan 2020 20:07:41 +0100
Subject: [PATCH 20/23] sss_ptr_hash: removed redundant check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
`sss_ptr_hash_check_type()` call would take care of this case.
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/util/sss_ptr_hash.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/util/sss_ptr_hash.c b/src/util/sss_ptr_hash.c
index 7326244e6..bf111a613 100644
--- a/src/util/sss_ptr_hash.c
+++ b/src/util/sss_ptr_hash.c
@@ -268,12 +268,6 @@ sss_ptr_hash_lookup_internal(hash_table_t *table,
return NULL;
}
- /* This may happen if we are in delete callback
- * and we try to search the hash table. */
- if (table_value.ptr == NULL) {
- return NULL;
- }
-
if (!sss_ptr_hash_check_type(table_value.ptr, "struct sss_ptr_hash_value")) {
return NULL;
}
--
2.20.1

View File

@ -0,0 +1,37 @@
From 26c794da31c215fef3e41429f6f13afdaf349bee Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 3 Jun 2020 20:35:04 +0200
Subject: [PATCH 21/22] pam_sss: add SERVICE_IS_GDM_SMARTCARD
Resolves: https://github.com/SSSD/sssd/issues/5190
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
---
src/sss_client/pam_sss.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index 69b440774..7e59f0487 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -71,6 +71,8 @@
#define DEBUG_MGS_LEN 1024
#define MAX_AUTHTOK_SIZE (1024*1024)
#define CHECK_AND_RETURN_PI_STRING(s) ((s != NULL && *s != '\0')? s : "(not available)")
+#define SERVICE_IS_GDM_SMARTCARD(pitem) (strcmp((pitem)->pam_service, \
+ "gdm-smartcard") == 0)
static void logger(pam_handle_t *pamh, int level, const char *fmt, ...) {
va_list ap;
@@ -2580,7 +2582,7 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh,
return PAM_AUTHINFO_UNAVAIL;
}
- if (strcmp(pi.pam_service, "gdm-smartcard") == 0
+ if (SERVICE_IS_GDM_SMARTCARD(&pi)
|| (flags & PAM_CLI_FLAGS_REQUIRE_CERT_AUTH)) {
ret = check_login_token_name(pamh, &pi, retries,
quiet_mode);
--
2.21.3

View File

@ -1,53 +0,0 @@
From 4bc0c2c7833dd643fc1137daf6519670c05c3736 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Thu, 23 Jan 2020 21:11:16 +0100
Subject: [PATCH 21/23] sss_ptr_hash: fixed memory leak
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In case `override` check was failed in _sss_ptr_hash_add()
`value` was leaking.
Fixed to do `override` check before value allocation.
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/util/sss_ptr_hash.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/util/sss_ptr_hash.c b/src/util/sss_ptr_hash.c
index bf111a613..114b6edeb 100644
--- a/src/util/sss_ptr_hash.c
+++ b/src/util/sss_ptr_hash.c
@@ -217,21 +217,21 @@ errno_t _sss_ptr_hash_add(hash_table_t *table,
return ERR_INVALID_DATA_TYPE;
}
+ table_key.type = HASH_KEY_STRING;
+ table_key.str = discard_const_p(char, key);
+
+ if (override == false && hash_has_key(table, &table_key)) {
+ return EEXIST;
+ }
+
value = sss_ptr_hash_value_create(table, key, talloc_ptr);
if (value == NULL) {
return ENOMEM;
}
- table_key.type = HASH_KEY_STRING;
- table_key.str = discard_const_p(char, key);
-
table_value.type = HASH_VALUE_PTR;
table_value.ptr = value;
- if (override == false && hash_has_key(table, &table_key)) {
- return EEXIST;
- }
-
hret = hash_enter(table, &table_key, &table_value);
if (hret != HASH_SUCCESS) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add key %s!\n", key);
--
2.20.1

View File

@ -0,0 +1,80 @@
From 3ed254765fc92e9cc9e4c35335818eaf1256e0d6 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 3 Jun 2020 20:36:54 +0200
Subject: [PATCH 22/22] pam_sss: special handling for gdm-smartcard
The gdm-smartcard service is special since it is triggered by the
presence of a Smartcard and even in the case of an error it will
immediately try again. To break this loop we should ask for an user
input and asking for a PIN is most straight forward and would show the
same behavior as pam_pkcs11.
Additionally it does not make sense to fall back the a password prompt
for gdm-smartcard so also here a PIN prompt should be shown.
Resolves: https://github.com/SSSD/sssd/issues/5190
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
---
src/sss_client/pam_sss.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index 7e59f0487..093e53af5 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -1835,8 +1835,13 @@ static int prompt_sc_pin(pam_handle_t *pamh, struct pam_items *pi)
struct pam_message m[2] = { { 0 }, { 0 } };
struct pam_response *resp = NULL;
struct cert_auth_info *cai = pi->selected_cert;
+ struct cert_auth_info empty_cai = { NULL, NULL, discard_const("Smartcard"),
+ NULL, NULL, NULL, NULL, NULL };
- if (cai == NULL || cai->token_name == NULL || *cai->token_name == '\0') {
+ if (cai == NULL && SERVICE_IS_GDM_SMARTCARD(pi)) {
+ cai = &empty_cai;
+ } else if (cai == NULL || cai->token_name == NULL
+ || *cai->token_name == '\0') {
return PAM_SYSTEM_ERR;
}
@@ -2188,6 +2193,9 @@ static int get_authtok_for_authentication(pam_handle_t *pamh,
}
}
ret = prompt_sc_pin(pamh, pi);
+ } else if (SERVICE_IS_GDM_SMARTCARD(pi)) {
+ /* Use pin prompt as fallback for gdm-smartcard */
+ ret = prompt_sc_pin(pamh, pi);
} else {
ret = prompt_password(pamh, pi, _("Password: "));
}
@@ -2496,7 +2504,7 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh,
{
int ret;
int pam_status;
- struct pam_items pi;
+ struct pam_items pi = { 0 };
uint32_t flags = 0;
const int *exp_data;
int *pw_exp_data;
@@ -2570,7 +2578,8 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh,
/*
* Since we are only interested in the result message
* and will always use password authentication
- * as a fallback, errors can be ignored here.
+ * as a fallback (except for gdm-smartcard),
+ * errors can be ignored here.
*/
}
}
@@ -2588,7 +2597,6 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh,
quiet_mode);
if (ret != PAM_SUCCESS) {
D(("check_login_token_name failed.\n"));
- return ret;
}
}
--
2.21.3

View File

@ -1,366 +0,0 @@
From 0bb1289252eec972ea26721a92adc7db47383f76 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Fri, 24 Jan 2020 23:57:39 +0100
Subject: [PATCH 22/23] sss_ptr_hash: internal refactoring
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
sss_ptr_hash code was refactored:
- got rid of a "spy" to make logic cleaner
- table got destructor to wipe its content
- described some usage limitation in the documentation
And resolves: https://pagure.io/SSSD/sssd/issue/4135
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/util/sss_ptr_hash.c | 183 +++++++++++++++++-----------------------
src/util/sss_ptr_hash.h | 17 +++-
2 files changed, 91 insertions(+), 109 deletions(-)
diff --git a/src/util/sss_ptr_hash.c b/src/util/sss_ptr_hash.c
index 114b6edeb..6409236c7 100644
--- a/src/util/sss_ptr_hash.c
+++ b/src/util/sss_ptr_hash.c
@@ -39,67 +39,35 @@ static bool sss_ptr_hash_check_type(void *ptr, const char *type)
return true;
}
+static int sss_ptr_hash_table_destructor(hash_table_t *table)
+{
+ sss_ptr_hash_delete_all(table, false);
+ return 0;
+}
+
struct sss_ptr_hash_delete_data {
hash_delete_callback *callback;
void *pvt;
};
struct sss_ptr_hash_value {
- struct sss_ptr_hash_spy *spy;
- void *ptr;
-};
-
-struct sss_ptr_hash_spy {
- struct sss_ptr_hash_value *value;
hash_table_t *table;
const char *key;
+ void *payload;
};
-static int
-sss_ptr_hash_spy_destructor(struct sss_ptr_hash_spy *spy)
-{
- spy->value->spy = NULL;
-
- /* This results in removing entry from hash table and freeing the value. */
- sss_ptr_hash_delete(spy->table, spy->key, false);
-
- return 0;
-}
-
-static struct sss_ptr_hash_spy *
-sss_ptr_hash_spy_create(TALLOC_CTX *mem_ctx,
- hash_table_t *table,
- const char *key,
- struct sss_ptr_hash_value *value)
-{
- struct sss_ptr_hash_spy *spy;
-
- spy = talloc_zero(mem_ctx, struct sss_ptr_hash_spy);
- if (spy == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory!\n");
- return NULL;
- }
-
- spy->key = talloc_strdup(spy, key);
- if (spy->key == NULL) {
- talloc_free(spy);
- return NULL;
- }
-
- spy->table = table;
- spy->value = value;
- talloc_set_destructor(spy, sss_ptr_hash_spy_destructor);
-
- return spy;
-}
-
static int
sss_ptr_hash_value_destructor(struct sss_ptr_hash_value *value)
{
- if (value->spy != NULL) {
- /* Disable spy destructor and free it. */
- talloc_set_destructor(value->spy, NULL);
- talloc_zfree(value->spy);
+ hash_key_t table_key;
+
+ if (value->table && value->key) {
+ table_key.type = HASH_KEY_STRING;
+ table_key.str = discard_const_p(char, value->key);
+ if (hash_delete(value->table, &table_key) != HASH_SUCCESS) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "failed to delete entry with key '%s'\n", value->key);
+ }
}
return 0;
@@ -112,18 +80,19 @@ sss_ptr_hash_value_create(hash_table_t *table,
{
struct sss_ptr_hash_value *value;
- value = talloc_zero(table, struct sss_ptr_hash_value);
+ value = talloc_zero(talloc_ptr, struct sss_ptr_hash_value);
if (value == NULL) {
return NULL;
}
- value->spy = sss_ptr_hash_spy_create(talloc_ptr, table, key, value);
- if (value->spy == NULL) {
+ value->key = talloc_strdup(value, key);
+ if (value->key == NULL) {
talloc_free(value);
return NULL;
}
- value->ptr = talloc_ptr;
+ value->table = table;
+ value->payload = talloc_ptr;
talloc_set_destructor(value, sss_ptr_hash_value_destructor);
return value;
@@ -138,29 +107,31 @@ sss_ptr_hash_delete_cb(hash_entry_t *item,
struct sss_ptr_hash_value *value;
struct hash_entry_t callback_entry;
+ if (pvt == NULL) {
+ return;
+ }
+
value = talloc_get_type(item->value.ptr, struct sss_ptr_hash_value);
if (value == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Invalid value!\n");
return;
}
+ /* Switch to the input value and call custom callback. */
+ data = talloc_get_type(pvt, struct sss_ptr_hash_delete_data);
+ if (data == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid data!\n");
+ return;
+ }
+
callback_entry.key = item->key;
callback_entry.value.type = HASH_VALUE_PTR;
- callback_entry.value.ptr = value->ptr;
-
- /* Free value, this also will disable spy */
- talloc_free(value);
-
- if (pvt != NULL) {
- /* Switch to the input value and call custom callback. */
- data = talloc_get_type(pvt, struct sss_ptr_hash_delete_data);
- if (data == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Invalid data!\n");
- return;
- }
-
- data->callback(&callback_entry, deltype, data->pvt);
- }
+ callback_entry.value.ptr = value->payload;
+ /* Even if execution is already in the context of
+ * talloc_free(payload) -> talloc_free(value) -> ...
+ * there still might be legitimate reasons to execute callback.
+ */
+ data->callback(&callback_entry, deltype, data->pvt);
}
hash_table_t *sss_ptr_hash_create(TALLOC_CTX *mem_ctx,
@@ -194,6 +165,8 @@ hash_table_t *sss_ptr_hash_create(TALLOC_CTX *mem_ctx,
talloc_steal(table, data);
}
+ talloc_set_destructor(table, sss_ptr_hash_table_destructor);
+
return table;
}
@@ -282,15 +255,15 @@ void *_sss_ptr_hash_lookup(hash_table_t *table,
struct sss_ptr_hash_value *value;
value = sss_ptr_hash_lookup_internal(table, key);
- if (value == NULL || value->ptr == NULL) {
+ if (value == NULL || value->payload == NULL) {
return NULL;
}
- if (!sss_ptr_hash_check_type(value->ptr, type)) {
+ if (!sss_ptr_hash_check_type(value->payload, type)) {
return NULL;
}
- return value->ptr;
+ return value->payload;
}
void *_sss_ptr_get_value(hash_value_t *table_value,
@@ -311,11 +284,11 @@ void *_sss_ptr_get_value(hash_value_t *table_value,
value = table_value->ptr;
- if (!sss_ptr_hash_check_type(value->ptr, type)) {
+ if (!sss_ptr_hash_check_type(value->payload, type)) {
return NULL;
}
- return value->ptr;
+ return value->payload;
}
void sss_ptr_hash_delete(hash_table_t *table,
@@ -323,74 +296,70 @@ void sss_ptr_hash_delete(hash_table_t *table,
bool free_value)
{
struct sss_ptr_hash_value *value;
- hash_key_t table_key;
- int hret;
- void *payload;
+ void *payload = NULL;
if (table == NULL || key == NULL) {
return;
}
- if (free_value) {
- value = sss_ptr_hash_lookup_internal(table, key);
- if (value == NULL) {
- free_value = false;
- } else {
- payload = value->ptr;
- }
- }
-
- table_key.type = HASH_KEY_STRING;
- table_key.str = discard_const_p(char, key);
-
- /* Delete table entry. This will free value and spy in delete callback. */
- hret = hash_delete(table, &table_key);
- if (hret != HASH_SUCCESS && hret != HASH_ERROR_KEY_NOT_FOUND) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to remove key from table [%d]\n",
- hret);
+ value = sss_ptr_hash_lookup_internal(table, key);
+ if (value == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Unable to remove key '%s' from table\n", key);
+ return;
}
- /* Also free the original value if requested. */
if (free_value) {
- talloc_free(payload);
+ payload = value->payload;
}
+ talloc_free(value); /* this will call hash_delete() in value d-tor */
+
+ talloc_free(payload); /* it is safe to call talloc_free(NULL) */
+
return;
}
void sss_ptr_hash_delete_all(hash_table_t *table,
bool free_values)
{
+ hash_value_t *content;
struct sss_ptr_hash_value *value;
- hash_value_t *values;
+ void *payload = NULL;
unsigned long count;
unsigned long i;
int hret;
- void *ptr;
if (table == NULL) {
return;
}
- hret = hash_values(table, &count, &values);
+ hret = hash_values(table, &count, &content);
if (hret != HASH_SUCCESS) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get values [%d]\n", hret);
return;
}
- for (i = 0; i < count; i++) {
- value = values[i].ptr;
- ptr = value->ptr;
-
- /* This will remove the entry from hash table and free value. */
- talloc_free(value->spy);
-
- if (free_values) {
- /* Also free the original value. */
- talloc_free(ptr);
+ for (i = 0; i < count; ++i) {
+ if ((content[i].type == HASH_VALUE_PTR) &&
+ sss_ptr_hash_check_type(content[i].ptr,
+ "struct sss_ptr_hash_value")) {
+ value = content[i].ptr;
+ if (free_values) {
+ payload = value->payload;
+ }
+ talloc_free(value);
+ if (free_values) {
+ talloc_free(payload); /* it's safe to call talloc_free(NULL) */
+ }
+ } else {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Unexpected type of table content, skipping");
}
}
+ talloc_free(content);
+
return;
}
diff --git a/src/util/sss_ptr_hash.h b/src/util/sss_ptr_hash.h
index 56bb19a65..0889b171a 100644
--- a/src/util/sss_ptr_hash.h
+++ b/src/util/sss_ptr_hash.h
@@ -28,7 +28,19 @@
/**
* Create a new hash table with string key and talloc pointer value with
- * possible delete callback.
+ * possible custom delete callback @del_cb.
+ * Table will have destructor setup to wipe content.
+ * Never call hash_destroy(table) and hash_delete() explicitly but rather
+ * use talloc_free(table) and sss_ptr_hash_delete().
+ *
+ * A notes about @del_cb:
+ * - this callback must never modify hash table (i.e. add/del entries);
+ * - this callback is triggered when value is either explicitly removed
+ * from the table or simply freed (latter leads to removal of an entry
+ * from the table);
+ * - this callback is also triggered for every entry when table is freed
+ * entirely. In this case (deltype == HASH_TABLE_DESTROY) any table
+ * lookups / iteration are forbidden as table might be already invalidated.
*/
hash_table_t *sss_ptr_hash_create(TALLOC_CTX *mem_ctx,
hash_delete_callback *del_cb,
@@ -41,7 +53,8 @@ hash_table_t *sss_ptr_hash_create(TALLOC_CTX *mem_ctx,
* the value is overridden. Otherwise EEXIST error is returned.
*
* If talloc_ptr is freed the key and value are automatically
- * removed from the hash table.
+ * removed from the hash table (del_cb that was set up during
+ * table creation is executed as a first step of this removal).
*
* @return EOK If the <@key, @talloc_ptr> pair was inserted.
* @return EEXIST If @key already exists and @override is false.
--
2.20.1

View File

@ -1,266 +0,0 @@
From 88b23bf50dd1c12413f3314639de2c3909bd9098 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Tue, 28 Jan 2020 19:26:08 +0100
Subject: [PATCH 23/23] TESTS: added sss_ptr_hash unit test
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
Makefile.am | 1 +
src/tests/cmocka/test_sss_ptr_hash.c | 193 +++++++++++++++++++++++++++
src/tests/cmocka/test_utils.c | 9 ++
src/tests/cmocka/test_utils.h | 6 +
4 files changed, 209 insertions(+)
create mode 100644 src/tests/cmocka/test_sss_ptr_hash.c
diff --git a/Makefile.am b/Makefile.am
index 57ba51356..c991f2aa0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3054,6 +3054,7 @@ test_ipa_idmap_LDADD = \
test_utils_SOURCES = \
src/tests/cmocka/test_utils.c \
src/tests/cmocka/test_string_utils.c \
+ src/tests/cmocka/test_sss_ptr_hash.c \
src/p11_child/p11_child_common_utils.c \
$(NULL)
if BUILD_SSH
diff --git a/src/tests/cmocka/test_sss_ptr_hash.c b/src/tests/cmocka/test_sss_ptr_hash.c
new file mode 100644
index 000000000..1458238f5
--- /dev/null
+++ b/src/tests/cmocka/test_sss_ptr_hash.c
@@ -0,0 +1,193 @@
+/*
+ Copyright (C) 2020 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 "tests/cmocka/common_mock.h"
+#include "util/sss_ptr_hash.h"
+
+static const int MAX_ENTRIES_AMOUNT = 5;
+
+static void populate_table(hash_table_t *table, int **payloads)
+{
+ char key[2] = {'z', 0};
+
+ for (int i = 0; i < MAX_ENTRIES_AMOUNT; ++i) {
+ payloads[i] = talloc_zero(global_talloc_context, int);
+ assert_non_null(payloads[i]);
+ *payloads[i] = i;
+ key[0] = '0'+(char)i;
+ assert_int_equal(sss_ptr_hash_add(table, key, payloads[i], int), 0);
+ }
+
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT);
+}
+
+static void free_payload_cb(hash_entry_t *item, hash_destroy_enum type, void *pvt)
+{
+ int *counter;
+
+ assert_non_null(item);
+ assert_non_null(item->value.ptr);
+ talloc_zfree(item->value.ptr);
+
+ assert_non_null(pvt);
+ counter = (int *)pvt;
+ (*counter)++;
+}
+
+void test_sss_ptr_hash_with_free_cb(void **state)
+{
+ hash_table_t *table;
+ int free_counter = 0;
+ int *payloads[MAX_ENTRIES_AMOUNT];
+
+ table = sss_ptr_hash_create(global_talloc_context,
+ free_payload_cb,
+ &free_counter);
+ assert_non_null(table);
+
+ populate_table(table, payloads);
+
+ /* check explicit removal from the hash */
+ sss_ptr_hash_delete(table, "1", false);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-1);
+ assert_int_equal(free_counter, 1);
+
+ /* check implicit removal triggered by payload deletion */
+ talloc_free(payloads[3]);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-2);
+ assert_int_equal(free_counter, 2);
+
+ /* try to remove non existent entry */
+ sss_ptr_hash_delete(table, "q", false);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-2);
+ assert_int_equal(free_counter, 2);
+
+ /* clear all */
+ sss_ptr_hash_delete_all(table, false);
+ assert_int_equal((int)hash_count(table), 0);
+ assert_int_equal(free_counter, MAX_ENTRIES_AMOUNT);
+
+ /* check that table is still operable */
+ populate_table(table, payloads);
+ sss_ptr_hash_delete(table, "2", false);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-1);
+ assert_int_equal(free_counter, MAX_ENTRIES_AMOUNT+1);
+
+ talloc_free(table);
+ assert_int_equal(free_counter, MAX_ENTRIES_AMOUNT*2);
+}
+
+struct table_wrapper
+{
+ hash_table_t **table;
+};
+
+static void lookup_cb(hash_entry_t *item, hash_destroy_enum type, void *pvt)
+{
+ hash_table_t *table;
+ hash_key_t *keys;
+ unsigned long count;
+ int *value = NULL;
+ int sum = 0;
+
+ assert_non_null(pvt);
+ table = *((struct table_wrapper *)pvt)->table;
+ assert_non_null(table);
+
+ if (type == HASH_TABLE_DESTROY) {
+ /* table is being destroyed */
+ return;
+ }
+
+ assert_int_equal(hash_keys(table, &count, &keys), HASH_SUCCESS);
+ for (unsigned int i = 0; i < count; ++i) {
+ assert_int_equal(keys[i].type, HASH_KEY_STRING);
+ value = sss_ptr_hash_lookup(table, keys[i].c_str, int);
+ assert_non_null(value);
+ sum += *value;
+ }
+ DEBUG(SSSDBG_TRACE_ALL, "sum of all values = %d\n", sum);
+ talloc_free(keys);
+}
+
+/* main difference with `test_sss_ptr_hash_with_free_cb()`
+ * is that table cb here doesn't delete payload so
+ * this is requested via `free_value(s)` arg
+ */
+void test_sss_ptr_hash_with_lookup_cb(void **state)
+{
+ hash_table_t *table;
+ struct table_wrapper wrapper;
+ int *payloads[MAX_ENTRIES_AMOUNT];
+
+ wrapper.table = &table;
+ table = sss_ptr_hash_create(global_talloc_context,
+ lookup_cb,
+ &wrapper);
+ assert_non_null(table);
+
+ populate_table(table, payloads);
+
+ /* check explicit removal from the hash */
+ sss_ptr_hash_delete(table, "2", true);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-1);
+
+ /* check implicit removal triggered by payload deletion */
+ talloc_free(payloads[0]);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-2);
+
+ /* clear all */
+ sss_ptr_hash_delete_all(table, true);
+ assert_int_equal((int)hash_count(table), 0);
+ /* teardown function shall verify there are no leaks
+ * on global_talloc_context and so that payloads[] were freed
+ */
+
+ /* check that table is still operable */
+ populate_table(table, payloads);
+
+ talloc_free(table);
+ /* d-tor triggers hash_destroy() but since cb here doesn free payload
+ * this should be done manually
+ */
+ for (int i = 0; i < MAX_ENTRIES_AMOUNT; ++i) {
+ talloc_free(payloads[i]);
+ }
+}
+
+/* Just smoke test to verify that absence of cb doesn't break anything */
+void test_sss_ptr_hash_without_cb(void **state)
+{
+ hash_table_t *table;
+ int *payloads[MAX_ENTRIES_AMOUNT];
+
+ table = sss_ptr_hash_create(global_talloc_context, NULL, NULL);
+ assert_non_null(table);
+
+ populate_table(table, payloads);
+
+ sss_ptr_hash_delete(table, "4", true);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-1);
+
+ talloc_free(payloads[1]);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-2);
+
+ sss_ptr_hash_delete_all(table, true);
+ assert_int_equal((int)hash_count(table), 0);
+
+ talloc_free(table);
+}
diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c
index 666f32903..c5eda4dd2 100644
--- a/src/tests/cmocka/test_utils.c
+++ b/src/tests/cmocka/test_utils.c
@@ -2055,6 +2055,15 @@ int main(int argc, const char *argv[])
cmocka_unit_test_setup_teardown(test_sss_get_domain_mappings_content,
setup_dom_list_with_subdomains,
teardown_dom_list),
+ cmocka_unit_test_setup_teardown(test_sss_ptr_hash_with_free_cb,
+ setup_leak_tests,
+ teardown_leak_tests),
+ cmocka_unit_test_setup_teardown(test_sss_ptr_hash_with_lookup_cb,
+ setup_leak_tests,
+ teardown_leak_tests),
+ cmocka_unit_test_setup_teardown(test_sss_ptr_hash_without_cb,
+ setup_leak_tests,
+ teardown_leak_tests),
};
/* Set debug level to invalid value so we can decide if -d 0 was used. */
diff --git a/src/tests/cmocka/test_utils.h b/src/tests/cmocka/test_utils.h
index e93e0da25..44b9479f9 100644
--- a/src/tests/cmocka/test_utils.h
+++ b/src/tests/cmocka/test_utils.h
@@ -33,4 +33,10 @@ void test_guid_blob_to_string_buf(void **state);
void test_get_last_x_chars(void **state);
void test_concatenate_string_array(void **state);
+/* from src/tests/cmocka/test_sss_ptr_hash.c */
+void test_sss_ptr_hash_with_free_cb(void **state);
+void test_sss_ptr_hash_with_lookup_cb(void **state);
+void test_sss_ptr_hash_without_cb(void **state);
+
+
#endif /* __TESTS__CMOCKA__TEST_UTILS_H__ */
--
2.20.1

View File

@ -0,0 +1,36 @@
From 31e57432537b9d248839159d83cfa9049faf192b Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 19 Jun 2020 13:32:30 +0200
Subject: [PATCH] pam_sss: make sure old certificate data is removed before
retry
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
To avoid that certificates will be shown in the certificate selection
which are not available anymore they must be remove before a new request
to look up the certificates is send to SSSD's PAM responder.
Resolves: https://github.com/SSSD/sssd/issues/5190
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/sss_client/pam_sss.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index e3ad2c9b2..6a3ba2f50 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -2467,6 +2467,8 @@ static int check_login_token_name(pam_handle_t *pamh, struct pam_items *pi,
&& strcmp(login_token_name,
pi->cert_list->token_name) != 0)) {
+ free_cert_list(pi->cert_list);
+ pi->cert_list = NULL;
if (retries < 0) {
ret = PAM_AUTHINFO_UNAVAIL;
goto done;
--
2.21.3

View File

@ -1,86 +0,0 @@
From 7b647338a40d701c6a5bb51c48c10a31a6b72699 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 30 Jan 2020 13:14:14 +0100
Subject: [PATCH 24/25] p11_child: check if card is present in wait_for_card()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some implementations of C_WaitForSlotEvent() might return even if no
card was inserted. So it has to be checked if a card is really present.
Resolves: https://pagure.io/SSSD/sssd/issue/4159
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/p11_child/p11_child_openssl.c | 47 ++++++++++++++++---------------
1 file changed, 25 insertions(+), 22 deletions(-)
diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c
index 56601b117..295715612 100644
--- a/src/p11_child/p11_child_openssl.c
+++ b/src/p11_child/p11_child_openssl.c
@@ -1546,35 +1546,38 @@ static errno_t wait_for_card(CK_FUNCTION_LIST *module, CK_SLOT_ID *slot_id)
CK_RV rv;
CK_SLOT_INFO info;
- rv = module->C_WaitForSlotEvent(wait_flags, slot_id, NULL);
- if (rv != CKR_OK) {
- if (rv != CKR_FUNCTION_NOT_SUPPORTED) {
+ do {
+ rv = module->C_WaitForSlotEvent(wait_flags, slot_id, NULL);
+ if (rv != CKR_OK && rv != CKR_FUNCTION_NOT_SUPPORTED) {
DEBUG(SSSDBG_OP_FAILURE,
"C_WaitForSlotEvent failed [%lu][%s].\n",
rv, p11_kit_strerror(rv));
return EIO;
}
- /* Poor man's wait */
- do {
+ if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
+ /* Poor man's wait */
sleep(10);
- rv = module->C_GetSlotInfo(*slot_id, &info);
- if (rv != CKR_OK) {
- DEBUG(SSSDBG_OP_FAILURE, "C_GetSlotInfo failed\n");
- return EIO;
- }
- DEBUG(SSSDBG_TRACE_ALL,
- "Description [%s] Manufacturer [%s] flags [%lu] "
- "removable [%s] token present [%s].\n",
- info.slotDescription, info.manufacturerID, info.flags,
- (info.flags & CKF_REMOVABLE_DEVICE) ? "true": "false",
- (info.flags & CKF_TOKEN_PRESENT) ? "true": "false");
- if ((info.flags & CKF_REMOVABLE_DEVICE)
- && (info.flags & CKF_TOKEN_PRESENT)) {
- break;
- }
- } while (true);
- }
+ }
+
+ rv = module->C_GetSlotInfo(*slot_id, &info);
+ if (rv != CKR_OK) {
+ DEBUG(SSSDBG_OP_FAILURE, "C_GetSlotInfo failed\n");
+ return EIO;
+ }
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Description [%s] Manufacturer [%s] flags [%lu] "
+ "removable [%s] token present [%s].\n",
+ info.slotDescription, info.manufacturerID, info.flags,
+ (info.flags & CKF_REMOVABLE_DEVICE) ? "true": "false",
+ (info.flags & CKF_TOKEN_PRESENT) ? "true": "false");
+
+ /* Check if really a token is present */
+ if ((info.flags & CKF_REMOVABLE_DEVICE)
+ && (info.flags & CKF_TOKEN_PRESENT)) {
+ break;
+ }
+ } while (true);
return EOK;
}
--
2.20.1

View File

@ -0,0 +1,34 @@
From 66029529fa0f0e2d16999f22294822deeec5f60b Mon Sep 17 00:00:00 2001
From: Alejandro Visiedo <avisiedo@redhat.com>
Date: Thu, 11 Jun 2020 00:36:04 +0200
Subject: [PATCH] systemtap: Missing a comma
sssd_functions.stp was missing a comma.
Thanks to William Cohen for reporting the issue and the patch to fix it.
https://bugzilla.redhat.com/show_bug.cgi?id=1840194
Resolves: https://github.com/SSSD/sssd/issues/5201
Reviewed-by: Pawel Polawski <ppolawsk@redhat.com>
---
src/systemtap/sssd_functions.stp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/systemtap/sssd_functions.stp b/src/systemtap/sssd_functions.stp
index 1eb140ccf..01f553177 100644
--- a/src/systemtap/sssd_functions.stp
+++ b/src/systemtap/sssd_functions.stp
@@ -7,7 +7,7 @@ global TARGET_ID=0, TARGET_AUTH=1, TARGET_ACCESS=2, TARGET_CHPASS=3,
global METHOD_CHECK_ONLINE=0, METHOD_ACCOUNT_HANDLER=1, METHOD_AUTH_HANDLER=2,
METHOD_ACCESS_HANDLER=3, METHOD_SELINUX_HANDLER=4, METHOD_SUDO_HANDLER=5,
METHOD_AUTOFS_HANDLER=6, METHOD_HOSTID_HANDLER=7, METHOD_DOMAINS_HANDLER=8,
- METHOD_RESOLVER_HANDLER=9 METHOD_SENTINEL=10
+ METHOD_RESOLVER_HANDLER=9, METHOD_SENTINEL=10
function acct_req_desc(entry_type)
{
--
2.21.3

View File

@ -1,37 +0,0 @@
From 37780b895199bab991edae6b1eeb91b7b3966bcf Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 6 Feb 2020 14:50:23 +0100
Subject: [PATCH 25/25] PAM client: only require UID 0 for private socket
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some privileged services like e.g. gdm might only call with UID 0 but
with a different GID. This patch removes the GID 0 requirement to access
to private PAM socket so that e.g. gdm can use the wait-for-card option.
Resolves: https://pagure.io/SSSD/sssd/issue/4159
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/sss_client/common.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/sss_client/common.c b/src/sss_client/common.c
index 270ca8b54..902438c86 100644
--- a/src/sss_client/common.c
+++ b/src/sss_client/common.c
@@ -910,8 +910,8 @@ int sss_pam_make_request(enum sss_cli_command cmd,
goto out;
}
- /* only root shall use the privileged pipe */
- if (getuid() == 0 && getgid() == 0) {
+ /* only UID 0 shall use the privileged pipe */
+ if (getuid() == 0) {
socket_name = SSS_PAM_PRIV_SOCKET_NAME;
errno = 0;
statret = stat(socket_name, &stat_buf);
--
2.20.1

View File

@ -0,0 +1,94 @@
From ffb9ad1331ac5f5d9bf237666aff19f1def77871 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 26 Jun 2020 12:07:48 +0200
Subject: [PATCH] proxy: use 'x' as default pwfield only for sssd-shadowutils
target
To avoid regression for case where files is used for proxy but authentication
is handled by other module then pam_unix. E.g. auth_provider = krb
This provides different solution to the ticket and improves the documentation.
Resolves:
https://github.com/SSSD/sssd/issues/5129
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/confdb/confdb.c | 25 ++++++++++++++++++++-----
src/man/sssd.conf.5.xml | 12 +++++++++---
2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index 65ad18dcf..c2daa9a2c 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -872,7 +872,7 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
struct sss_domain_info *domain;
struct ldb_result *res;
TALLOC_CTX *tmp_ctx;
- const char *tmp;
+ const char *tmp, *tmp_pam_target, *tmp_auth;
int ret, val;
uint32_t entry_cache_timeout;
char *default_domain;
@@ -1030,13 +1030,28 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
}
if (domain->provider != NULL && strcasecmp(domain->provider, "proxy") == 0) {
- /* The password field must be reported as 'x' for proxy provider
- * using files library, else pam_unix won't
- * authenticate this entry. */
+ /* The password field must be reported as 'x' for proxy provider
+ * using files library, else pam_unix won't authenticate this entry.
+ * We set this only for sssd-shadowutils target which can be used
+ * to authenticate with pam_unix only. Otherwise we let administrator
+ * to overwrite default * value with pwfield option to avoid regression
+ * on more common use case where remote authentication is required. */
tmp = ldb_msg_find_attr_as_string(res->msgs[0],
CONFDB_PROXY_LIBNAME,
NULL);
- if (tmp != NULL && strcasecmp(tmp, "files") == 0) {
+
+ tmp_auth = ldb_msg_find_attr_as_string(res->msgs[0],
+ CONFDB_DOMAIN_AUTH_PROVIDER,
+ NULL);
+
+ tmp_pam_target = ldb_msg_find_attr_as_string(res->msgs[0],
+ CONFDB_PROXY_PAM_TARGET,
+ NULL);
+
+ if (tmp != NULL && tmp_pam_target != NULL
+ && strcasecmp(tmp, "files") == 0
+ && (tmp_auth == NULL || strcasecmp(tmp_auth, "proxy") == 0)
+ && strcmp(tmp_pam_target, "sssd-shadowutils") == 0) {
domain->pwfield = "x";
}
}
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index cae24bb63..44b3b8f20 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1135,11 +1135,17 @@ fallback_homedir = /home/%u
<quote>password</quote> field.
</para>
<para>
- This option can also be set per-domain.
+ Default: <quote>*</quote>
</para>
<para>
- Default: <quote>*</quote> (remote domains)
- or <quote>x</quote> (the files domain)
+ Note: This option can also be set per-domain which
+ overwrites the value in [nss] section.
+ </para>
+ <para>
+ Default: <quote>not set</quote> (remote domains),
+ <quote>x</quote> (the files domain),
+ <quote>x</quote> (proxy domain with nss_files
+ and sssd-shadowutils target)
</para>
</listitem>
</varlistentry>
--
2.21.3

View File

@ -0,0 +1,291 @@
From 8969c43dc2d8d0800c2f0b509d078378db855622 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 23 Jun 2020 12:05:08 +0200
Subject: [PATCH] files: allow root membership
There are two use cases that do not work with files provider:
1. User has primary GID 0:
This is fine by itself since SSSD does not store this user in cache and it is
handled only by `nss_files` so the user (`tuser`) is returned correctly. The
problem is when you try to resolve group that the user is member of. In this
case that the membership is missing the group (but only if the user was
previously resolved and thus stored in negative cache).
```
tuser:x:1001:0::/home/tuser:/bin/bash
tuser:x:1001:tuser
// tuser@files is ghost member of the group so it is returned because it is not in negative cache
$ getent group tuser
tuser:x:1001:tuser
// expire memcache
// tuser@files is ghost member but not returned because it is in negative cache
$ id tuser // returned from nss_files
uid=1001(tuser) gid=0(root) groups=0(root),1001(tuser)
[pbrezina /dev/shm/sssd]$ getent group tuser
tuser:x:1001:
```
**2. root is member of other group**
The root member is missing from the membership since it was filtered out by
negative cache.
```
tuser:x:1001:root
$ id root
uid=0(root) gid=0(root) groups=0(root),1001(tuser)
[pbrezina /dev/shm/sssd]$ getent group tuser
tuser:x:1001:
```
In files provider, only the users that we do not want to managed are stored
as ghost member, therefore we can let nss_files handle group that has ghost
members.
Tests are changed as well to work with this behavior. Users are added when
required and ghost are expected to return ENOENT.
Resolves:
https://github.com/SSSD/sssd/issues/5170
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/responder/nss/nss_protocol_grent.c | 18 +++++++
src/tests/intg/files_ops.py | 13 +++++
src/tests/intg/test_files_provider.py | 73 ++++++++++++++++----------
3 files changed, 77 insertions(+), 27 deletions(-)
diff --git a/src/responder/nss/nss_protocol_grent.c b/src/responder/nss/nss_protocol_grent.c
index 9c443d0e7..6d8e71083 100644
--- a/src/responder/nss/nss_protocol_grent.c
+++ b/src/responder/nss/nss_protocol_grent.c
@@ -141,6 +141,24 @@ nss_protocol_fill_members(struct sss_packet *packet,
members[0] = nss_get_group_members(domain, msg);
members[1] = nss_get_group_ghosts(domain, msg, group_name);
+ if (is_files_provider(domain) && members[1] != NULL) {
+ /* If there is a ghost member in files provider it means that we
+ * did not store the user on purpose (e.g. it has uid or gid 0).
+ * Therefore nss_files does handle the user and therefore we
+ * must let nss_files to also handle this group in order to
+ * provide correct membership. */
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "Unknown members found. nss_files will handle it.\n");
+
+ ret = sss_ncache_set_group(rctx->ncache, false, domain, group_name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_ncache_set_group failed.\n");
+ }
+
+ ret = ENOENT;
+ goto done;
+ }
+
sss_packet_get_body(packet, &body, &body_len);
num_members = 0;
diff --git a/src/tests/intg/files_ops.py b/src/tests/intg/files_ops.py
index c1c4465e7..57959f501 100644
--- a/src/tests/intg/files_ops.py
+++ b/src/tests/intg/files_ops.py
@@ -103,6 +103,13 @@ class FilesOps(object):
contents = self._read_contents()
+ def _has_line(self, key):
+ try:
+ self._get_named_line(key, self._read_contents())
+ return True
+ except KeyError:
+ return False
+
class PasswdOps(FilesOps):
"""
@@ -132,6 +139,9 @@ class PasswdOps(FilesOps):
def userdel(self, name):
self._del_line(name)
+ def userexist(self, name):
+ return self._has_line(name)
+
class GroupOps(FilesOps):
"""
@@ -158,3 +168,6 @@ class GroupOps(FilesOps):
def groupdel(self, name):
self._del_line(name)
+
+ def groupexist(self, name):
+ return self._has_line(name)
diff --git a/src/tests/intg/test_files_provider.py b/src/tests/intg/test_files_provider.py
index 023333020..90be198c3 100644
--- a/src/tests/intg/test_files_provider.py
+++ b/src/tests/intg/test_files_provider.py
@@ -60,11 +60,13 @@ OV_USER1 = dict(name='ov_user1', passwd='x', uid=10010, gid=20010,
dir='/home/ov/user1',
shell='/bin/ov_user1_shell')
-ALT_USER1 = dict(name='altuser1', passwd='x', uid=60001, gid=70001,
+ALT_USER1 = dict(name='alt_user1', passwd='x', uid=60001, gid=70001,
gecos='User for tests from alt files',
dir='/home/altuser1',
shell='/bin/bash')
+ALL_USERS = [CANARY, USER1, USER2, OV_USER1, ALT_USER1]
+
CANARY_GR = dict(name='canary',
gid=300001,
mem=[])
@@ -365,21 +367,34 @@ def setup_pw_with_canary(passwd_ops_setup):
return setup_pw_with_list(passwd_ops_setup, [CANARY])
-def setup_gr_with_list(grp_ops, group_list):
+def add_group_members(pwd_ops, group):
+ members = {x['name']: x for x in ALL_USERS}
+ for member in group['mem']:
+ if pwd_ops.userexist(member):
+ continue
+
+ pwd_ops.useradd(**members[member])
+
+
+def setup_gr_with_list(pwd_ops, grp_ops, group_list):
for group in group_list:
+ add_group_members(pwd_ops, group)
grp_ops.groupadd(**group)
+
ent.assert_group_by_name(CANARY_GR['name'], CANARY_GR)
return grp_ops
@pytest.fixture
-def add_group_with_canary(group_ops_setup):
- return setup_gr_with_list(group_ops_setup, [GROUP1, CANARY_GR])
+def add_group_with_canary(passwd_ops_setup, group_ops_setup):
+ return setup_gr_with_list(
+ passwd_ops_setup, group_ops_setup, [GROUP1, CANARY_GR]
+ )
@pytest.fixture
-def setup_gr_with_canary(group_ops_setup):
- return setup_gr_with_list(group_ops_setup, [CANARY_GR])
+def setup_gr_with_canary(passwd_ops_setup, group_ops_setup):
+ return setup_gr_with_list(passwd_ops_setup, group_ops_setup, [CANARY_GR])
def poll_canary(fn, name, threshold=20):
@@ -766,7 +781,9 @@ def test_gid_zero_does_not_resolve(files_domain_only):
assert res == NssReturnCode.NOTFOUND
-def test_add_remove_add_file_group(setup_gr_with_canary, files_domain_only):
+def test_add_remove_add_file_group(
+ setup_pw_with_canary, setup_gr_with_canary, files_domain_only
+):
"""
Test that removing a group is detected and the group
is removed from the sssd database. Similarly, an add
@@ -776,6 +793,7 @@ def test_add_remove_add_file_group(setup_gr_with_canary, files_domain_only):
res, group = call_sssd_getgrnam(GROUP1["name"])
assert res == NssReturnCode.NOTFOUND
+ add_group_members(setup_pw_with_canary, GROUP1)
setup_gr_with_canary.groupadd(**GROUP1)
check_group(GROUP1)
@@ -817,8 +835,10 @@ def test_mod_group_gid(add_group_with_canary, files_domain_only):
@pytest.fixture
-def add_group_nomem_with_canary(group_ops_setup):
- return setup_gr_with_list(group_ops_setup, [GROUP_NOMEM, CANARY_GR])
+def add_group_nomem_with_canary(passwd_ops_setup, group_ops_setup):
+ return setup_gr_with_list(
+ passwd_ops_setup, group_ops_setup, [GROUP_NOMEM, CANARY_GR]
+ )
def test_getgrnam_no_members(add_group_nomem_with_canary, files_domain_only):
@@ -911,16 +931,19 @@ def test_getgrnam_ghost(setup_pw_with_canary,
setup_gr_with_canary,
files_domain_only):
"""
- Test that a group with members while the members are not present
- are added as ghosts. This is also what nss_files does, getgrnam would
- return group members that do not exist as well.
+ Test that group if not found (and will be handled by nss_files) if there
+ are any ghost members.
"""
user_and_group_setup(setup_pw_with_canary,
setup_gr_with_canary,
[],
[GROUP12],
False)
- check_group(GROUP12)
+
+ time.sleep(1)
+ res, group = call_sssd_getgrnam(GROUP12["name"])
+ assert res == NssReturnCode.NOTFOUND
+
for member in GROUP12['mem']:
res, _ = call_sssd_getpwnam(member)
assert res == NssReturnCode.NOTFOUND
@@ -932,7 +955,10 @@ def ghost_and_member_test(pw_ops, grp_ops, reverse):
[USER1],
[GROUP12],
reverse)
- check_group(GROUP12)
+
+ time.sleep(1)
+ res, group = call_sssd_getgrnam(GROUP12["name"])
+ assert res == NssReturnCode.NOTFOUND
# We checked that the group added has the same members as group12,
# so both user1 and user2. Now check that user1 is a member of
@@ -1027,28 +1053,21 @@ def test_getgrnam_add_remove_ghosts(setup_pw_with_canary,
modgroup = dict(GROUP_NOMEM)
modgroup['mem'] = ['user1', 'user2']
add_group_nomem_with_canary.groupmod(old_name=modgroup['name'], **modgroup)
- check_group(modgroup)
+ time.sleep(1)
+ res, group = call_sssd_getgrnam(modgroup['name'])
+ assert res == sssd_id.NssReturnCode.NOTFOUND
modgroup['mem'] = ['user2']
add_group_nomem_with_canary.groupmod(old_name=modgroup['name'], **modgroup)
- check_group(modgroup)
+ time.sleep(1)
+ res, group = call_sssd_getgrnam(modgroup['name'])
+ assert res == sssd_id.NssReturnCode.NOTFOUND
res, _ = call_sssd_getpwnam('user1')
assert res == NssReturnCode.NOTFOUND
res, _ = call_sssd_getpwnam('user2')
assert res == NssReturnCode.NOTFOUND
- # Add this user and verify it's been added as a member
- pwd_ops.useradd(**USER2)
- # The negative cache might still have user2 from the previous request,
- # flushing the caches might help to prevent a failed lookup after adding
- # the user.
- subprocess.call(["sss_cache", "-E"])
- res, groups = sssd_id_sync('user2')
- assert res == sssd_id.NssReturnCode.SUCCESS
- assert len(groups) == 2
- assert 'group_nomem' in groups
-
def realloc_users(pwd_ops, num):
# Intentionally not including the last one because
--
2.21.3

View File

@ -1,209 +0,0 @@
From f9b3c0d1009da8d8dbe273c38d6725100789e57b Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 8 Jan 2020 13:46:22 +0100
Subject: [PATCH 26/27] ssh: do not mix different certificate lists
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There was a list of binary certificates and a list with base64 encoded
ones which might be different depending on the active matching rules.
Only the base64 one with the filtered results should be used.
Related to https://pagure.io/SSSD/sssd/issue/4121
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/tests/cmocka/test_cert_utils.c | 80 +++++++++++++++++++++++++++
src/util/cert.h | 3 +
src/util/cert/cert_common.c | 20 +++++++
src/util/cert/cert_common_p11_child.c | 12 ++--
4 files changed, 108 insertions(+), 7 deletions(-)
diff --git a/src/tests/cmocka/test_cert_utils.c b/src/tests/cmocka/test_cert_utils.c
index 325e49f00..c2c9ca270 100644
--- a/src/tests/cmocka/test_cert_utils.c
+++ b/src/tests/cmocka/test_cert_utils.c
@@ -711,6 +711,84 @@ void test_cert_to_ssh_2keys_with_certmap_send(void **state)
talloc_free(ev);
}
+void test_cert_to_ssh_2keys_with_certmap_2_done(struct tevent_req *req)
+{
+ int ret;
+ struct test_state *ts = tevent_req_callback_data(req, struct test_state);
+ struct ldb_val *keys;
+ uint8_t *exp_key;
+ size_t exp_key_size;
+ size_t valid_keys;
+
+ assert_non_null(ts);
+ ts->done = true;
+
+ ret = cert_to_ssh_key_recv(req, ts, &keys, &valid_keys);
+ talloc_free(req);
+ assert_int_equal(ret, 0);
+ assert_non_null(keys[0].data);
+ assert_int_equal(valid_keys, 1);
+
+ exp_key = sss_base64_decode(ts, SSSD_TEST_CERT_SSH_KEY_0002, &exp_key_size);
+ assert_non_null(exp_key);
+ assert_int_equal(keys[0].length, exp_key_size);
+ assert_memory_equal(keys[0].data, exp_key, exp_key_size);
+ talloc_free(exp_key);
+
+ talloc_free(keys);
+ sss_certmap_free_ctx(ts->sss_certmap_ctx);
+}
+
+void test_cert_to_ssh_2keys_with_certmap_2_send(void **state)
+{
+ int ret;
+ struct tevent_context *ev;
+ struct tevent_req *req;
+ struct ldb_val val[2];
+
+ struct test_state *ts = talloc_get_type_abort(*state, struct test_state);
+ assert_non_null(ts);
+ ts->done = false;
+
+ ret = sss_certmap_init(ts, NULL, NULL, &ts->sss_certmap_ctx);
+ assert_int_equal(ret, EOK);
+
+ ret = sss_certmap_add_rule(ts->sss_certmap_ctx, -1,
+ "<SUBJECT>CN=SSSD test cert 0002,.*", NULL,
+ NULL);
+ assert_int_equal(ret, EOK);
+
+ val[0].data = sss_base64_decode(ts, SSSD_TEST_CERT_0001,
+ &val[0].length);
+ assert_non_null(val[0].data);
+
+ val[1].data = sss_base64_decode(ts, SSSD_TEST_CERT_0002,
+ &val[1].length);
+ assert_non_null(val[1].data);
+
+ ev = tevent_context_init(ts);
+ assert_non_null(ev);
+
+ req = cert_to_ssh_key_send(ts, ev, -1, P11_CHILD_TIMEOUT,
+#ifdef HAVE_NSS
+ "sql:" ABS_BUILD_DIR "/src/tests/test_CA/p11_nssdb",
+#else
+ ABS_BUILD_DIR "/src/tests/test_CA/SSSD_test_CA.pem",
+#endif
+ ts->sss_certmap_ctx, 2, &val[0], NULL);
+ assert_non_null(req);
+
+ tevent_req_set_callback(req, test_cert_to_ssh_2keys_with_certmap_2_done, ts);
+
+ while (!ts->done) {
+ tevent_loop_once(ev);
+ }
+
+ talloc_free(val[0].data);
+ talloc_free(val[1].data);
+ talloc_free(ev);
+}
+
int main(int argc, const char *argv[])
{
poptContext pc;
@@ -746,6 +824,8 @@ int main(int argc, const char *argv[])
setup, teardown),
cmocka_unit_test_setup_teardown(test_cert_to_ssh_2keys_with_certmap_send,
setup, teardown),
+ cmocka_unit_test_setup_teardown(test_cert_to_ssh_2keys_with_certmap_2_send,
+ setup, teardown),
#endif
};
diff --git a/src/util/cert.h b/src/util/cert.h
index e0d44e3d6..d038a99f6 100644
--- a/src/util/cert.h
+++ b/src/util/cert.h
@@ -52,6 +52,9 @@ errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx,
uint8_t *der_blob, size_t der_size,
uint8_t **key_blob, size_t *key_size);
+errno_t get_ssh_key_from_derb64(TALLOC_CTX *mem_ctx, const char *derb64,
+ uint8_t **key_blob, size_t *key_size);
+
struct tevent_req *cert_to_ssh_key_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
int child_debug_fd, time_t timeout,
diff --git a/src/util/cert/cert_common.c b/src/util/cert/cert_common.c
index 766877089..511fddd4d 100644
--- a/src/util/cert/cert_common.c
+++ b/src/util/cert/cert_common.c
@@ -206,3 +206,23 @@ done:
return ret;
}
+
+errno_t get_ssh_key_from_derb64(TALLOC_CTX *mem_ctx, const char *derb64,
+ uint8_t **key_blob, size_t *key_size)
+{
+ int ret;
+ uint8_t *der_blob;
+ size_t der_size;
+
+ der_blob = sss_base64_decode(mem_ctx, derb64, &der_size);
+ if (der_blob == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n");
+ return EIO;
+ }
+
+ ret = get_ssh_key_from_cert(mem_ctx, der_blob, der_size,
+ key_blob, key_size);
+ talloc_free(der_blob);
+
+ return ret;
+}
diff --git a/src/util/cert/cert_common_p11_child.c b/src/util/cert/cert_common_p11_child.c
index 80c10eff1..1846ff89a 100644
--- a/src/util/cert/cert_common_p11_child.c
+++ b/src/util/cert/cert_common_p11_child.c
@@ -28,7 +28,6 @@ struct cert_to_ssh_key_state {
time_t timeout;
const char **extra_args;
const char **certs;
- struct ldb_val *bin_certs;
struct ldb_val *keys;
size_t cert_count;
size_t iter;
@@ -74,7 +73,6 @@ struct tevent_req *cert_to_ssh_key_send(TALLOC_CTX *mem_ctx,
state->child_debug_fd = (child_debug_fd == -1) ? STDERR_FILENO
: child_debug_fd;
state->timeout = timeout;
- state->bin_certs = bin_certs;
state->io = talloc(state, struct child_io_fds);
if (state->io == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "talloc failed.\n");
@@ -138,6 +136,7 @@ struct tevent_req *cert_to_ssh_key_send(TALLOC_CTX *mem_ctx,
ret = EINVAL;
goto done;
}
+
state->cert_count++;
}
@@ -289,11 +288,10 @@ static void cert_to_ssh_key_done(int child_status,
if (valid) {
DEBUG(SSSDBG_TRACE_LIBS, "Certificate [%s] is valid.\n",
state->certs[state->iter]);
- ret = get_ssh_key_from_cert(state->keys,
- state->bin_certs[state->iter].data,
- state->bin_certs[state->iter].length,
- &state->keys[state->iter].data,
- &state->keys[state->iter].length);
+ ret = get_ssh_key_from_derb64(state->keys,
+ state->certs[state->iter],
+ &state->keys[state->iter].data,
+ &state->keys[state->iter].length);
if (ret == EOK) {
state->valid_keys++;
} else {
--
2.20.1

View File

@ -0,0 +1,42 @@
From 100839b64390d7010bfa28552fd9381ef4366496 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 26 Jun 2020 09:48:17 +0200
Subject: [PATCH] PAM: do not treat error for cache-only lookups as fatal
The original fatal error came from a time where at this place in the
code the response form the backend was checked and an error was clearly
fatal.
Now we only check if the entry is in the cache and valid. An error would
mean that the backend is called to lookup or refresh the entry. So the
backend can change the state of the cache and make upcoming cache
lookups successful. So it makes sense to not only call the backend if
ENOENT is returned but for all kind of errors.
Resolves https://pagure.io/SSSD/sssd/issue/4098
Reviewed-by: Pawel Polawski <ppolawsk@redhat.com>
---
src/responder/pam/pamsrv_cmd.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 1cd901f15..666131cb7 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -1941,10 +1941,8 @@ static void pam_check_user_search_next(struct tevent_req *req)
ret = cache_req_single_domain_recv(preq, req, &result);
talloc_zfree(req);
if (ret != EOK && ret != ENOENT) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Fatal error, killing connection!\n");
- talloc_zfree(preq->cctx);
- return;
+ DEBUG(SSSDBG_OP_FAILURE, "Cache lookup failed, trying to get fresh "
+ "data from the backened.\n");
}
DEBUG(SSSDBG_TRACE_ALL, "PAM initgroups scheme [%s].\n",
--
2.21.3

View File

@ -1,314 +0,0 @@
From 849d495ea948e75ecb4ea469c9f8db4a740a2377 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 7 Feb 2020 20:32:45 +0100
Subject: [PATCH 27/27] ssh: add 'no_rules' and 'all_rules' to
ssh_use_certificate_matching_rules
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
To make ssh_use_certificate_matching_rules option more flexible and
predictable the keywords 'all_rules' and 'no_rules' are added.
'no_rules' can be used to allow all certificates.
If rules names are given but no matching rules can be found this is
considered an error and no ssh keys will be derived from the
certificates.
Related to https://pagure.io/SSSD/sssd/issue/4121
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/man/sssd.conf.5.xml | 16 +++--
src/responder/ssh/ssh_cmd.c | 33 ++++++---
src/responder/ssh/ssh_private.h | 1 +
src/responder/ssh/ssh_reply.c | 8 +++
src/tests/cmocka/test_ssh_srv.c | 122 +++++++++++++++++++++++++++++++-
5 files changed, 165 insertions(+), 15 deletions(-)
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index ef07c43d3..f71fbf4aa 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1760,12 +1760,20 @@ p11_uri = library-description=OpenSC%20smartcard%20framework;slot-id=2
will be ignored.
</para>
<para>
- If a non-existing rule name is given all rules will
- be ignored and all available certificates will be
- used to derive ssh keys.
+ There are two special key words 'all_rules' and
+ 'no_rules' which will enable all or no rules,
+ respectively. The latter means that no certificates
+ will be filtered out and ssh keys will be generated
+ from all valid certificates.
</para>
<para>
- Default: not set, all found rules are used
+ A non-existing rule name is considered an error.
+ If as a result no rule is selected all certificates
+ will be ignored.
+ </para>
+ <para>
+ Default: not set, equivalent to 'all_rules,
+ all found rules are used
</para>
</listitem>
</varlistentry>
diff --git a/src/responder/ssh/ssh_cmd.c b/src/responder/ssh/ssh_cmd.c
index 09f9b73b6..d1e7c667b 100644
--- a/src/responder/ssh/ssh_cmd.c
+++ b/src/responder/ssh/ssh_cmd.c
@@ -157,10 +157,26 @@ static errno_t ssh_cmd_refresh_certmap_ctx(struct ssh_ctx *ssh_ctx,
size_t c;
int ret;
bool rule_added;
+ bool all_rules = false;
+ bool no_rules = false;
+
+ ssh_ctx->cert_rules_error = false;
+
+ if (ssh_ctx->cert_rules == NULL || ssh_ctx->cert_rules[0] == NULL) {
+ all_rules = true;
+ } else if (ssh_ctx->cert_rules[0] != NULL
+ && ssh_ctx->cert_rules[1] == NULL) {
+ if (strcmp(ssh_ctx->cert_rules[0], "all_rules") == 0) {
+ all_rules = true;
+ } else if (strcmp(ssh_ctx->cert_rules[0], "no_rules") == 0) {
+ no_rules = true;
+ }
+ }
if (!ssh_ctx->use_cert_keys
|| ssh_ctx->certmap_last_read
- >= ssh_ctx->rctx->get_domains_last_call.tv_sec) {
+ >= ssh_ctx->rctx->get_domains_last_call.tv_sec
+ || no_rules) {
DEBUG(SSSDBG_TRACE_ALL, "No certmap update needed.\n");
return EOK;
}
@@ -180,9 +196,8 @@ static errno_t ssh_cmd_refresh_certmap_ctx(struct ssh_ctx *ssh_ctx,
for (c = 0; certmap_list[c] != NULL; c++) {
- if (ssh_ctx->cert_rules != NULL
- && !string_in_list(certmap_list[c]->name,
- ssh_ctx->cert_rules, true)) {
+ if (!all_rules && !string_in_list(certmap_list[c]->name,
+ ssh_ctx->cert_rules, true)) {
DEBUG(SSSDBG_TRACE_ALL, "Skipping matching rule [%s], it is "
"not listed in the ssh_use_certificate_matching_rules "
"option.\n", certmap_list[c]->name);
@@ -212,11 +227,12 @@ static errno_t ssh_cmd_refresh_certmap_ctx(struct ssh_ctx *ssh_ctx,
}
if (!rule_added) {
- DEBUG(SSSDBG_TRACE_ALL,
- "No matching rule added, all certificates will be used.\n");
+ DEBUG(SSSDBG_CONF_SETTINGS,
+ "No matching rule added, please check "
+ "ssh_use_certificate_matching_rules option values for typos .\n");
- sss_certmap_free_ctx(sss_certmap_ctx);
- sss_certmap_ctx = NULL;
+ ret = EINVAL;
+ goto done;
}
ret = EOK;
@@ -228,6 +244,7 @@ done:
ssh_ctx->certmap_last_read = ssh_ctx->rctx->get_domains_last_call.tv_sec;
} else {
sss_certmap_free_ctx(sss_certmap_ctx);
+ ssh_ctx->cert_rules_error = true;
}
return ret;
diff --git a/src/responder/ssh/ssh_private.h b/src/responder/ssh/ssh_private.h
index 76a1aead3..028ccd616 100644
--- a/src/responder/ssh/ssh_private.h
+++ b/src/responder/ssh/ssh_private.h
@@ -40,6 +40,7 @@ struct ssh_ctx {
time_t certmap_last_read;
struct sss_certmap_ctx *sss_certmap_ctx;
char **cert_rules;
+ bool cert_rules_error;
};
struct sss_cmd_table *get_ssh_cmds(void);
diff --git a/src/responder/ssh/ssh_reply.c b/src/responder/ssh/ssh_reply.c
index 1200a3a36..97914266d 100644
--- a/src/responder/ssh/ssh_reply.c
+++ b/src/responder/ssh/ssh_reply.c
@@ -196,6 +196,14 @@ struct tevent_req *ssh_get_output_keys_send(TALLOC_CTX *mem_ctx,
goto done;
}
+ if (state->ssh_ctx->cert_rules_error) {
+ DEBUG(SSSDBG_CONF_SETTINGS,
+ "Skipping keys from certificates because there was an error "
+ "while processing matching rules.\n");
+ ret = EOK;
+ goto done;
+ }
+
ret = confdb_get_string(cli_ctx->rctx->cdb, state,
CONFDB_MONITOR_CONF_ENTRY,
CONFDB_MONITOR_CERT_VERIFICATION, NULL,
diff --git a/src/tests/cmocka/test_ssh_srv.c b/src/tests/cmocka/test_ssh_srv.c
index 45915f681..fc43663a7 100644
--- a/src/tests/cmocka/test_ssh_srv.c
+++ b/src/tests/cmocka/test_ssh_srv.c
@@ -712,6 +712,120 @@ void test_ssh_user_pubkey_cert_with_rule(void **state)
assert_int_equal(ret, EOK);
}
+void test_ssh_user_pubkey_cert_with_all_rules(void **state)
+{
+ int ret;
+ struct sysdb_attrs *attrs;
+ /* Both rules are enabled, both certificates should be handled. */
+ const char *rule_list[] = { "all_rules", NULL };
+ struct certmap_info *certmap_list[] = { &rule_1, &rule_2, NULL};
+
+ attrs = sysdb_new_attrs(ssh_test_ctx);
+ assert_non_null(attrs);
+ ret = sysdb_attrs_add_string(attrs, SYSDB_SSH_PUBKEY, TEST_SSH_PUBKEY);
+ assert_int_equal(ret, EOK);
+ ret = sysdb_attrs_add_base64_blob(attrs, SYSDB_USER_CERT,
+ SSSD_TEST_CERT_0001);
+ assert_int_equal(ret, EOK);
+ ret = sysdb_attrs_add_base64_blob(attrs, SYSDB_USER_CERT,
+ SSSD_TEST_CERT_0002);
+ assert_int_equal(ret, EOK);
+
+ ret = sysdb_set_user_attr(ssh_test_ctx->tctx->dom,
+ ssh_test_ctx->ssh_user_fqdn,
+ attrs,
+ LDB_FLAG_MOD_ADD);
+ talloc_free(attrs);
+ assert_int_equal(ret, EOK);
+
+ mock_input_user(ssh_test_ctx, ssh_test_ctx->ssh_user_fqdn);
+ will_return(__wrap_sss_packet_get_cmd, SSS_SSH_GET_USER_PUBKEYS);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+ /* Enable certificate support */
+ ssh_test_ctx->ssh_ctx->use_cert_keys = true;
+ ssh_test_ctx->ssh_ctx->rctx->domains->certmaps = certmap_list;
+ ssh_test_ctx->ssh_ctx->certmap_last_read = 0;
+ ssh_test_ctx->ssh_ctx->rctx->get_domains_last_call.tv_sec = 1;
+ ssh_test_ctx->ssh_ctx->cert_rules = discard_const(rule_list);
+#ifdef HAVE_NSS
+ ssh_test_ctx->ssh_ctx->ca_db = discard_const("sql:" ABS_BUILD_DIR
+ "/src/tests/test_CA/p11_nssdb");
+#else
+ ssh_test_ctx->ssh_ctx->ca_db = discard_const(ABS_BUILD_DIR
+ "/src/tests/test_CA/SSSD_test_CA.pem");
+#endif
+
+ set_cmd_cb(test_ssh_user_pubkey_cert_check);
+ ret = sss_cmd_execute(ssh_test_ctx->cctx, SSS_SSH_GET_USER_PUBKEYS,
+ ssh_test_ctx->ssh_cmds);
+ assert_int_equal(ret, EOK);
+
+ /* Wait until the test finishes with EOK */
+ ret = test_ev_loop(ssh_test_ctx->tctx);
+ assert_int_equal(ret, EOK);
+}
+
+void test_ssh_user_pubkey_cert_with_no_rules(void **state)
+{
+ int ret;
+ struct sysdb_attrs *attrs;
+ /* No rules should be used, both certificates should be handled. */
+ const char *rule_list[] = { "no_rules", NULL };
+ struct certmap_info *certmap_list[] = { &rule_1, &rule_2, NULL};
+
+ attrs = sysdb_new_attrs(ssh_test_ctx);
+ assert_non_null(attrs);
+ ret = sysdb_attrs_add_string(attrs, SYSDB_SSH_PUBKEY, TEST_SSH_PUBKEY);
+ assert_int_equal(ret, EOK);
+ ret = sysdb_attrs_add_base64_blob(attrs, SYSDB_USER_CERT,
+ SSSD_TEST_CERT_0001);
+ assert_int_equal(ret, EOK);
+ ret = sysdb_attrs_add_base64_blob(attrs, SYSDB_USER_CERT,
+ SSSD_TEST_CERT_0002);
+ assert_int_equal(ret, EOK);
+
+ ret = sysdb_set_user_attr(ssh_test_ctx->tctx->dom,
+ ssh_test_ctx->ssh_user_fqdn,
+ attrs,
+ LDB_FLAG_MOD_ADD);
+ talloc_free(attrs);
+ assert_int_equal(ret, EOK);
+
+ mock_input_user(ssh_test_ctx, ssh_test_ctx->ssh_user_fqdn);
+ will_return(__wrap_sss_packet_get_cmd, SSS_SSH_GET_USER_PUBKEYS);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+ /* Enable certificate support */
+ ssh_test_ctx->ssh_ctx->use_cert_keys = true;
+ ssh_test_ctx->ssh_ctx->rctx->domains->certmaps = certmap_list;
+ ssh_test_ctx->ssh_ctx->certmap_last_read = 0;
+ ssh_test_ctx->ssh_ctx->rctx->get_domains_last_call.tv_sec = 1;
+ ssh_test_ctx->ssh_ctx->cert_rules = discard_const(rule_list);
+#ifdef HAVE_NSS
+ ssh_test_ctx->ssh_ctx->ca_db = discard_const("sql:" ABS_BUILD_DIR
+ "/src/tests/test_CA/p11_nssdb");
+#else
+ ssh_test_ctx->ssh_ctx->ca_db = discard_const(ABS_BUILD_DIR
+ "/src/tests/test_CA/SSSD_test_CA.pem");
+#endif
+
+ set_cmd_cb(test_ssh_user_pubkey_cert_check);
+ ret = sss_cmd_execute(ssh_test_ctx->cctx, SSS_SSH_GET_USER_PUBKEYS,
+ ssh_test_ctx->ssh_cmds);
+ assert_int_equal(ret, EOK);
+
+ /* Wait until the test finishes with EOK */
+ ret = test_ev_loop(ssh_test_ctx->tctx);
+ assert_int_equal(ret, EOK);
+}
+
void test_ssh_user_pubkey_cert_with_unknow_rule_name(void **state)
{
int ret;
@@ -743,8 +857,6 @@ void test_ssh_user_pubkey_cert_with_unknow_rule_name(void **state)
will_return(__wrap_sss_packet_get_cmd, SSS_SSH_GET_USER_PUBKEYS);
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
- will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
- will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
/* Enable certificate support */
ssh_test_ctx->ssh_ctx->use_cert_keys = true;
@@ -760,7 +872,7 @@ void test_ssh_user_pubkey_cert_with_unknow_rule_name(void **state)
"/src/tests/test_CA/SSSD_test_CA.pem");
#endif
- set_cmd_cb(test_ssh_user_pubkey_cert_check);
+ set_cmd_cb(test_ssh_user_one_pubkey_check);
ret = sss_cmd_execute(ssh_test_ctx->cctx, SSS_SSH_GET_USER_PUBKEYS,
ssh_test_ctx->ssh_cmds);
assert_int_equal(ret, EOK);
@@ -852,6 +964,10 @@ int main(int argc, const char *argv[])
ssh_test_setup, ssh_test_teardown),
cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_rule,
ssh_test_setup, ssh_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_all_rules,
+ ssh_test_setup, ssh_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_no_rules,
+ ssh_test_setup, ssh_test_teardown),
cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_unknow_rule_name,
ssh_test_setup, ssh_test_teardown),
cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_rule_1,
--
2.20.1

View File

@ -1,50 +0,0 @@
From 7aa96458f3bec4ef6ff7385107458e6b2b0b06ac Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Tue, 10 Sep 2019 14:33:37 +0000
Subject: [PATCH] Add TCP level timeout to LDAP services
In some cases the TCP connection may hang with data sent because
of network conditions, this may cause the socket to stall for much
longer than the timeout intended.
Set a TCP option to forcibly timeout a socket that sees its data not
ACKed within the ldap_network_timeout seconds.
Signed-off-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/util/sss_sockets.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/util/sss_sockets.c b/src/util/sss_sockets.c
index 0e4d8df8a..b6b6dbac5 100644
--- a/src/util/sss_sockets.c
+++ b/src/util/sss_sockets.c
@@ -79,6 +79,7 @@ static errno_t set_fd_common_opts(int fd, int timeout)
int dummy = 1;
int ret;
struct timeval tv;
+ unsigned int milli;
/* SO_KEEPALIVE and TCP_NODELAY are set by OpenLDAP client libraries but
* failures are ignored.*/
@@ -117,6 +118,16 @@ static errno_t set_fd_common_opts(int fd, int timeout)
"setsockopt SO_SNDTIMEO failed.[%d][%s].\n", ret,
strerror(ret));
}
+
+ milli = timeout * 1000; /* timeout in milliseconds */
+ ret = setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, milli,
+ sizeof(milli));
+ if (ret != 0) {
+ ret = errno;
+ DEBUG(SSSDBG_FUNC_DATA,
+ "setsockopt TCP_USER_TIMEOUT failed.[%d][%s].\n", ret,
+ strerror(ret));
+ }
}
return EOK;
--
2.21.1

View File

@ -0,0 +1,193 @@
From 2d90e642078c15f001b34a0a50a67fa6eac9a3b9 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Tue, 3 Mar 2020 18:44:11 +0100
Subject: [PATCH 28/35] mem-cache: sizes of free and data tables were made
consistent
Since size of "free table" didn't account for SSS_AVG_*_PAYLOAD factor
only small fraction of "data table" was actually used.
SSS_AVG_*_PAYLOAD differentiation for different payload types only
affected size of hash table and was removed as unjustified.
Resolves:
https://github.com/SSSD/sssd/issues/5115
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/responder/nss/nsssrv.c | 22 +++++++++++-------
src/responder/nss/nsssrv_mmap_cache.c | 33 +++++++--------------------
src/responder/nss/nsssrv_mmap_cache.h | 2 --
src/util/mmap_cache.h | 3 ---
4 files changed, 22 insertions(+), 38 deletions(-)
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 87300058f..21d93ae77 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -83,10 +83,9 @@ nss_clear_memcache(TALLOC_CTX *mem_ctx,
return ret;
}
- /* TODO: read cache sizes from configuration */
DEBUG(SSSDBG_TRACE_FUNC, "Clearing memory caches.\n");
ret = sss_mmap_cache_reinit(nctx, nctx->mc_uid, nctx->mc_gid,
- SSS_MC_CACHE_ELEMENTS,
+ -1, /* keep current size */
(time_t) memcache_timeout,
&nctx->pwd_mc_ctx);
if (ret != EOK) {
@@ -96,7 +95,7 @@ nss_clear_memcache(TALLOC_CTX *mem_ctx,
}
ret = sss_mmap_cache_reinit(nctx, nctx->mc_uid, nctx->mc_gid,
- SSS_MC_CACHE_ELEMENTS,
+ -1, /* keep current size */
(time_t) memcache_timeout,
&nctx->grp_mc_ctx);
if (ret != EOK) {
@@ -106,7 +105,7 @@ nss_clear_memcache(TALLOC_CTX *mem_ctx,
}
ret = sss_mmap_cache_reinit(nctx, nctx->mc_uid, nctx->mc_gid,
- SSS_MC_CACHE_ELEMENTS,
+ -1, /* keep current size */
(time_t)memcache_timeout,
&nctx->initgr_mc_ctx);
if (ret != EOK) {
@@ -210,6 +209,11 @@ done:
static int setup_memcaches(struct nss_ctx *nctx)
{
+ /* TODO: read cache sizes from configuration */
+ static const size_t SSS_MC_CACHE_PASSWD_SLOTS = 200000; /* 8mb */
+ static const size_t SSS_MC_CACHE_GROUP_SLOTS = 150000; /* 6mb */
+ static const size_t SSS_MC_CACHE_INITGROUP_SLOTS = 250000; /* 10mb */
+
int ret;
int memcache_timeout;
@@ -239,11 +243,11 @@ static int setup_memcaches(struct nss_ctx *nctx)
return EOK;
}
- /* TODO: read cache sizes from configuration */
ret = sss_mmap_cache_init(nctx, "passwd",
nctx->mc_uid, nctx->mc_gid,
SSS_MC_PASSWD,
- SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
+ SSS_MC_CACHE_PASSWD_SLOTS,
+ (time_t)memcache_timeout,
&nctx->pwd_mc_ctx);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache is DISABLED\n");
@@ -252,7 +256,8 @@ static int setup_memcaches(struct nss_ctx *nctx)
ret = sss_mmap_cache_init(nctx, "group",
nctx->mc_uid, nctx->mc_gid,
SSS_MC_GROUP,
- SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
+ SSS_MC_CACHE_GROUP_SLOTS,
+ (time_t)memcache_timeout,
&nctx->grp_mc_ctx);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n");
@@ -261,7 +266,8 @@ static int setup_memcaches(struct nss_ctx *nctx)
ret = sss_mmap_cache_init(nctx, "initgroups",
nctx->mc_uid, nctx->mc_gid,
SSS_MC_INITGROUPS,
- SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
+ SSS_MC_CACHE_INITGROUP_SLOTS,
+ (time_t)memcache_timeout,
&nctx->initgr_mc_ctx);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE, "initgroups mmap cache is DISABLED\n");
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 69e767690..5e23bbe6f 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -28,13 +28,6 @@
#include "responder/nss/nss_private.h"
#include "responder/nss/nsssrv_mmap_cache.h"
-/* arbitrary (avg of my /etc/passwd) */
-#define SSS_AVG_PASSWD_PAYLOAD (MC_SLOT_SIZE * 4)
-/* short group name and no gids (private user group */
-#define SSS_AVG_GROUP_PAYLOAD (MC_SLOT_SIZE * 3)
-/* average place for 40 supplementary groups + 2 names */
-#define SSS_AVG_INITGROUP_PAYLOAD (MC_SLOT_SIZE * 5)
-
#define MC_NEXT_BARRIER(val) ((((val) + 1) & 0x00ffffff) | 0xf0000000)
#define MC_RAISE_BARRIER(m) do { \
@@ -1251,24 +1244,14 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
enum sss_mc_type type, size_t n_elem,
time_t timeout, struct sss_mc_ctx **mcc)
{
+ /* sss_mc_header alone occupies whole slot,
+ * so each entry takes 2 slots at the very least
+ */
+ static const int PAYLOAD_FACTOR = 2;
+
struct sss_mc_ctx *mc_ctx = NULL;
- int payload;
int ret, dret;
- switch (type) {
- case SSS_MC_PASSWD:
- payload = SSS_AVG_PASSWD_PAYLOAD;
- break;
- case SSS_MC_GROUP:
- payload = SSS_AVG_GROUP_PAYLOAD;
- break;
- case SSS_MC_INITGROUPS:
- payload = SSS_AVG_INITGROUP_PAYLOAD;
- break;
- default:
- return EINVAL;
- }
-
mc_ctx = talloc_zero(mem_ctx, struct sss_mc_ctx);
if (!mc_ctx) {
return ENOMEM;
@@ -1303,9 +1286,9 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
/* hash table is double the size because it will store both forward and
* reverse keys (name/uid, name/gid, ..) */
- mc_ctx->ht_size = MC_HT_SIZE(n_elem * 2);
- mc_ctx->dt_size = MC_DT_SIZE(n_elem, payload);
- mc_ctx->ft_size = MC_FT_SIZE(n_elem);
+ mc_ctx->ht_size = MC_HT_SIZE(2 * n_elem / PAYLOAD_FACTOR);
+ mc_ctx->dt_size = n_elem * MC_SLOT_SIZE;
+ mc_ctx->ft_size = n_elem / 8; /* 1 bit per slot */
mc_ctx->mmap_size = MC_HEADER_SIZE +
MC_ALIGN64(mc_ctx->dt_size) +
MC_ALIGN64(mc_ctx->ft_size) +
diff --git a/src/responder/nss/nsssrv_mmap_cache.h b/src/responder/nss/nsssrv_mmap_cache.h
index e06257949..c40af2fb4 100644
--- a/src/responder/nss/nsssrv_mmap_cache.h
+++ b/src/responder/nss/nsssrv_mmap_cache.h
@@ -22,8 +22,6 @@
#ifndef _NSSSRV_MMAP_CACHE_H_
#define _NSSSRV_MMAP_CACHE_H_
-#define SSS_MC_CACHE_ELEMENTS 50000
-
struct sss_mc_ctx;
enum sss_mc_type {
diff --git a/src/util/mmap_cache.h b/src/util/mmap_cache.h
index 63e096027..d3d92bc98 100644
--- a/src/util/mmap_cache.h
+++ b/src/util/mmap_cache.h
@@ -40,9 +40,6 @@ typedef uint32_t rel_ptr_t;
#define MC_HT_SIZE(elems) ( (elems) * MC_32 )
#define MC_HT_ELEMS(size) ( (size) / MC_32 )
-#define MC_DT_SIZE(elems, payload) ( (elems) * (payload) )
-#define MC_FT_SIZE(elems) ( (elems) / 8 )
-/* ^^ 8 bits per byte so we need just elems/8 bytes to represent all blocks */
#define MC_PTR_ADD(ptr, bytes) (void *)((uint8_t *)(ptr) + (bytes))
#define MC_PTR_DIFF(ptr, base) ((uint8_t *)(ptr) - (uint8_t *)(base))
--
2.21.3

View File

@ -0,0 +1,543 @@
From 80e7163b7bf512a45e2fa31494f3bdff9e9e2dce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Wed, 4 Mar 2020 16:26:18 +0100
Subject: [PATCH 29/35] NSS: make memcache size configurable
Added options to configure memcache size:
memcache_size_passwd
memcache_size_group
memcache_size_initgroups
Related:
https://github.com/SSSD/sssd/issues/4578
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/confdb/confdb.h | 3 +
src/config/SSSDConfig/sssdoptions.py | 3 +
src/config/cfg_rules.ini | 3 +
src/man/sssd.conf.5.xml | 78 +++++++++
src/responder/nss/nsssrv.c | 104 ++++++++----
src/tests/intg/test_memory_cache.py | 236 +++++++++++++++++++++++++++
6 files changed, 398 insertions(+), 29 deletions(-)
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index a5d35fd70..c96896da5 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -115,6 +115,9 @@
#define CONFDB_NSS_SHELL_FALLBACK "shell_fallback"
#define CONFDB_NSS_DEFAULT_SHELL "default_shell"
#define CONFDB_MEMCACHE_TIMEOUT "memcache_timeout"
+#define CONFDB_NSS_MEMCACHE_SIZE_PASSWD "memcache_size_passwd"
+#define CONFDB_NSS_MEMCACHE_SIZE_GROUP "memcache_size_group"
+#define CONFDB_NSS_MEMCACHE_SIZE_INITGROUPS "memcache_size_initgroups"
#define CONFDB_NSS_HOMEDIR_SUBSTRING "homedir_substring"
#define CONFDB_DEFAULT_HOMEDIR_SUBSTRING "/home"
diff --git a/src/config/SSSDConfig/sssdoptions.py b/src/config/SSSDConfig/sssdoptions.py
index 9c071f70a..16d85cfa3 100644
--- a/src/config/SSSDConfig/sssdoptions.py
+++ b/src/config/SSSDConfig/sssdoptions.py
@@ -72,6 +72,9 @@ class SSSDOptions(object):
'shell_fallback': _('If a shell stored in central directory is allowed but not available, use this fallback'),
'default_shell': _('Shell to use if the provider does not list one'),
'memcache_timeout': _('How long will be in-memory cache records valid'),
+ 'memcache_size_passwd': _('Number of slots in fast in-memory cache for passwd requests'),
+ 'memcache_size_group': _('Number of slots in fast in-memory cache for group requests'),
+ 'memcache_size_initgroups': _('Number of slots in fast in-memory cache for initgroups requests'),
'homedir_substring': _('The value of this option will be used in the expansion of the override_homedir option '
'if the template contains the format string %H.'),
'get_domains_timeout': _('Specifies time in seconds for which the list of subdomains will be considered '
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index 1a7e2c5cd..2874ea048 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -92,6 +92,9 @@ option = shell_fallback
option = default_shell
option = get_domains_timeout
option = memcache_timeout
+option = memcache_size_passwd
+option = memcache_size_group
+option = memcache_size_initgroups
[rule/allowed_pam_options]
validator = ini_allowed_options
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 9a9679a4b..9bc2e26e5 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1100,6 +1100,84 @@ fallback_homedir = /home/%u
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>memcache_size_passwd (integer)</term>
+ <listitem>
+ <para>
+ Number of slots allocated inside fast in-memory
+ cache for passwd requests. Note that one entry
+ in fast in-memory cache can occupy more than one slot.
+ Setting the size to 0 will disable the passwd in-memory
+ cache.
+ </para>
+ <para>
+ Default: 200000
+ </para>
+ <para>
+ WARNING: Disabled or too small in-memory cache can
+ have significant negative impact on SSSD's
+ performance.
+ </para>
+ <para>
+ NOTE: If the environment variable
+ SSS_NSS_USE_MEMCACHE is set to "NO", client
+ applications will not use the fast in-memory
+ cache.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>memcache_size_group (integer)</term>
+ <listitem>
+ <para>
+ Number of slots allocated inside fast in-memory
+ cache for group requests. Note that one entry
+ in fast in-memory cache can occupy more than one
+ slot. Setting the size to 0 will disable the group
+ in-memory cache.
+ </para>
+ <para>
+ Default: 150000
+ </para>
+ <para>
+ WARNING: Disabled or too small in-memory cache can
+ have significant negative impact on SSSD's
+ performance.
+ </para>
+ <para>
+ NOTE: If the environment variable
+ SSS_NSS_USE_MEMCACHE is set to "NO", client
+ applications will not use the fast in-memory
+ cache.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>memcache_size_initgroups (integer)</term>
+ <listitem>
+ <para>
+ Number of slots allocated inside fast in-memory
+ cache for initgroups requests. Note that one entry
+ in fast in-memory cache can occupy more than one
+ slot. Setting the size to 0 will disable the
+ initgroups in-memory cache.
+ </para>
+ <para>
+ Default: 250000
+ </para>
+ <para>
+ WARNING: Disabled or too small in-memory cache can
+ have significant negative impact on SSSD's
+ performance.
+ </para>
+ <para>
+ NOTE: If the environment variable
+ SSS_NSS_USE_MEMCACHE is set to "NO", client
+ applications will not use the fast in-memory
+ cache.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>user_attributes (string)</term>
<listitem>
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 21d93ae77..0a201d3ae 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -209,13 +209,16 @@ done:
static int setup_memcaches(struct nss_ctx *nctx)
{
- /* TODO: read cache sizes from configuration */
+ /* Default memcache sizes */
static const size_t SSS_MC_CACHE_PASSWD_SLOTS = 200000; /* 8mb */
static const size_t SSS_MC_CACHE_GROUP_SLOTS = 150000; /* 6mb */
static const size_t SSS_MC_CACHE_INITGROUP_SLOTS = 250000; /* 10mb */
int ret;
int memcache_timeout;
+ int mc_size_passwd;
+ int mc_size_group;
+ int mc_size_initgroups;
/* Remove the CLEAR_MC_FLAG file if exists. */
ret = unlink(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG);
@@ -243,34 +246,77 @@ static int setup_memcaches(struct nss_ctx *nctx)
return EOK;
}
- ret = sss_mmap_cache_init(nctx, "passwd",
- nctx->mc_uid, nctx->mc_gid,
- SSS_MC_PASSWD,
- SSS_MC_CACHE_PASSWD_SLOTS,
- (time_t)memcache_timeout,
- &nctx->pwd_mc_ctx);
- if (ret) {
- DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache is DISABLED\n");
- }
-
- ret = sss_mmap_cache_init(nctx, "group",
- nctx->mc_uid, nctx->mc_gid,
- SSS_MC_GROUP,
- SSS_MC_CACHE_GROUP_SLOTS,
- (time_t)memcache_timeout,
- &nctx->grp_mc_ctx);
- if (ret) {
- DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n");
- }
-
- ret = sss_mmap_cache_init(nctx, "initgroups",
- nctx->mc_uid, nctx->mc_gid,
- SSS_MC_INITGROUPS,
- SSS_MC_CACHE_INITGROUP_SLOTS,
- (time_t)memcache_timeout,
- &nctx->initgr_mc_ctx);
- if (ret) {
- DEBUG(SSSDBG_CRIT_FAILURE, "initgroups mmap cache is DISABLED\n");
+ /* Get all memcache sizes from confdb (pwd, grp, initgr) */
+
+ ret = confdb_get_int(nctx->rctx->cdb,
+ CONFDB_NSS_CONF_ENTRY,
+ CONFDB_NSS_MEMCACHE_SIZE_PASSWD,
+ SSS_MC_CACHE_PASSWD_SLOTS,
+ &mc_size_passwd);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Failed to get 'memcache_size_passwd' option from confdb.\n");
+ return ret;
+ }
+
+ ret = confdb_get_int(nctx->rctx->cdb,
+ CONFDB_NSS_CONF_ENTRY,
+ CONFDB_NSS_MEMCACHE_SIZE_GROUP,
+ SSS_MC_CACHE_GROUP_SLOTS,
+ &mc_size_group);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Failed to get 'memcache_size_group' option from confdb.\n");
+ return ret;
+ }
+
+ ret = confdb_get_int(nctx->rctx->cdb,
+ CONFDB_NSS_CONF_ENTRY,
+ CONFDB_NSS_MEMCACHE_SIZE_INITGROUPS,
+ SSS_MC_CACHE_INITGROUP_SLOTS,
+ &mc_size_initgroups);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Failed to get 'memcache_size_nitgroups' option from confdb.\n");
+ return ret;
+ }
+
+ /* Initialize the fast in-memory caches if they were not disabled */
+
+ if (mc_size_passwd != 0) {
+ ret = sss_mmap_cache_init(nctx, "passwd",
+ nctx->mc_uid, nctx->mc_gid,
+ SSS_MC_PASSWD,
+ mc_size_passwd,
+ (time_t)memcache_timeout,
+ &nctx->pwd_mc_ctx);
+ if (ret) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache is DISABLED\n");
+ }
+ }
+
+ if (mc_size_group != 0) {
+ ret = sss_mmap_cache_init(nctx, "group",
+ nctx->mc_uid, nctx->mc_gid,
+ SSS_MC_GROUP,
+ mc_size_group,
+ (time_t)memcache_timeout,
+ &nctx->grp_mc_ctx);
+ if (ret) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n");
+ }
+ }
+
+ if (mc_size_initgroups != 0) {
+ ret = sss_mmap_cache_init(nctx, "initgroups",
+ nctx->mc_uid, nctx->mc_gid,
+ SSS_MC_INITGROUPS,
+ mc_size_initgroups,
+ (time_t)memcache_timeout,
+ &nctx->initgr_mc_ctx);
+ if (ret) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "initgroups mmap cache is DISABLED\n");
+ }
}
return EOK;
diff --git a/src/tests/intg/test_memory_cache.py b/src/tests/intg/test_memory_cache.py
index 322f76fe0..6ed696e00 100644
--- a/src/tests/intg/test_memory_cache.py
+++ b/src/tests/intg/test_memory_cache.py
@@ -135,6 +135,112 @@ def load_data_to_ldap(request, ldap_conn):
create_ldap_fixture(request, ldap_conn, ent_list)
+@pytest.fixture
+def disable_memcache_rfc2307(request, ldap_conn):
+ load_data_to_ldap(request, ldap_conn)
+
+ conf = unindent("""\
+ [sssd]
+ domains = LDAP
+ services = nss
+
+ [nss]
+ memcache_size_group = 0
+ memcache_size_passwd = 0
+ memcache_size_initgroups = 0
+
+ [domain/LDAP]
+ ldap_auth_disable_tls_never_use_in_production = true
+ ldap_schema = rfc2307
+ id_provider = ldap
+ auth_provider = ldap
+ sudo_provider = ldap
+ ldap_uri = {ldap_conn.ds_inst.ldap_url}
+ ldap_search_base = {ldap_conn.ds_inst.base_dn}
+ """).format(**locals())
+ create_conf_fixture(request, conf)
+ create_sssd_fixture(request)
+ return None
+
+
+@pytest.fixture
+def disable_pwd_mc_rfc2307(request, ldap_conn):
+ load_data_to_ldap(request, ldap_conn)
+
+ conf = unindent("""\
+ [sssd]
+ domains = LDAP
+ services = nss
+
+ [nss]
+ memcache_size_passwd = 0
+
+ [domain/LDAP]
+ ldap_auth_disable_tls_never_use_in_production = true
+ ldap_schema = rfc2307
+ id_provider = ldap
+ auth_provider = ldap
+ sudo_provider = ldap
+ ldap_uri = {ldap_conn.ds_inst.ldap_url}
+ ldap_search_base = {ldap_conn.ds_inst.base_dn}
+ """).format(**locals())
+ create_conf_fixture(request, conf)
+ create_sssd_fixture(request)
+ return None
+
+
+@pytest.fixture
+def disable_grp_mc_rfc2307(request, ldap_conn):
+ load_data_to_ldap(request, ldap_conn)
+
+ conf = unindent("""\
+ [sssd]
+ domains = LDAP
+ services = nss
+
+ [nss]
+ memcache_size_group = 0
+
+ [domain/LDAP]
+ ldap_auth_disable_tls_never_use_in_production = true
+ ldap_schema = rfc2307
+ id_provider = ldap
+ auth_provider = ldap
+ sudo_provider = ldap
+ ldap_uri = {ldap_conn.ds_inst.ldap_url}
+ ldap_search_base = {ldap_conn.ds_inst.base_dn}
+ """).format(**locals())
+ create_conf_fixture(request, conf)
+ create_sssd_fixture(request)
+ return None
+
+
+@pytest.fixture
+def disable_initgr_mc_rfc2307(request, ldap_conn):
+ load_data_to_ldap(request, ldap_conn)
+
+ conf = unindent("""\
+ [sssd]
+ domains = LDAP
+ services = nss
+
+ [nss]
+ memcache_size_initgroups = 0
+
+ [domain/LDAP]
+ ldap_auth_disable_tls_never_use_in_production = true
+ ldap_schema = rfc2307
+ id_provider = ldap
+ auth_provider = ldap
+ sudo_provider = ldap
+ ldap_uri = {ldap_conn.ds_inst.ldap_url}
+ ldap_search_base = {ldap_conn.ds_inst.base_dn}
+ """).format(**locals())
+ create_conf_fixture(request, conf)
+ create_sssd_fixture(request)
+ return None
+
+
@pytest.fixture
def sanity_rfc2307(request, ldap_conn):
load_data_to_ldap(request, ldap_conn)
@@ -354,6 +460,19 @@ def test_getgrnam_simple_with_mc(ldap_conn, sanity_rfc2307):
test_getgrnam_simple(ldap_conn, sanity_rfc2307)
+def test_getgrnam_simple_disabled_pwd_mc(ldap_conn, disable_pwd_mc_rfc2307):
+ test_getgrnam_simple(ldap_conn, disable_pwd_mc_rfc2307)
+ stop_sssd()
+ test_getgrnam_simple(ldap_conn, disable_pwd_mc_rfc2307)
+
+
+def test_getgrnam_simple_disabled_intitgr_mc(ldap_conn,
+ disable_initgr_mc_rfc2307):
+ test_getgrnam_simple(ldap_conn, disable_initgr_mc_rfc2307)
+ stop_sssd()
+ test_getgrnam_simple(ldap_conn, disable_initgr_mc_rfc2307)
+
+
def test_getgrnam_membership(ldap_conn, sanity_rfc2307):
ent.assert_group_by_name(
"group1",
@@ -919,3 +1038,120 @@ def test_mc_zero_timeout(ldap_conn, zero_timeout_rfc2307):
grp.getgrnam('group1')
with pytest.raises(KeyError):
grp.getgrgid(2001)
+
+
+def test_disabled_mc(ldap_conn, disable_memcache_rfc2307):
+ ent.assert_passwd_by_name(
+ 'user1',
+ dict(name='user1', passwd='*', uid=1001, gid=2001,
+ gecos='1001', shell='/bin/bash'))
+ ent.assert_passwd_by_uid(
+ 1001,
+ dict(name='user1', passwd='*', uid=1001, gid=2001,
+ gecos='1001', shell='/bin/bash'))
+
+ ent.assert_group_by_name("group1", dict(name="group1", gid=2001))
+ ent.assert_group_by_gid(2001, dict(name="group1", gid=2001))
+
+ assert_user_gids_equal('user1', [2000, 2001])
+
+ stop_sssd()
+
+ # sssd is stopped and the memory cache is disabled;
+ # so pytest should not be able to find anything
+ with pytest.raises(KeyError):
+ pwd.getpwnam('user1')
+ with pytest.raises(KeyError):
+ pwd.getpwuid(1001)
+
+ with pytest.raises(KeyError):
+ grp.getgrnam('group1')
+ with pytest.raises(KeyError):
+ grp.getgrgid(2001)
+
+ with pytest.raises(KeyError):
+ (res, errno, gids) = sssd_id.get_user_gids('user1')
+
+
+def test_disabled_passwd_mc(ldap_conn, disable_pwd_mc_rfc2307):
+ ent.assert_passwd_by_name(
+ 'user1',
+ dict(name='user1', passwd='*', uid=1001, gid=2001,
+ gecos='1001', shell='/bin/bash'))
+ ent.assert_passwd_by_uid(
+ 1001,
+ dict(name='user1', passwd='*', uid=1001, gid=2001,
+ gecos='1001', shell='/bin/bash'))
+
+ assert_user_gids_equal('user1', [2000, 2001])
+
+ stop_sssd()
+
+ # passwd cache is disabled
+ with pytest.raises(KeyError):
+ pwd.getpwnam('user1')
+ with pytest.raises(KeyError):
+ pwd.getpwuid(1001)
+
+ # Initgroups looks up the user first, hence KeyError from the
+ # passwd database even if the initgroups cache is active.
+ with pytest.raises(KeyError):
+ (res, errno, gids) = sssd_id.get_user_gids('user1')
+
+
+def test_disabled_group_mc(ldap_conn, disable_grp_mc_rfc2307):
+ ent.assert_passwd_by_name(
+ 'user1',
+ dict(name='user1', passwd='*', uid=1001, gid=2001,
+ gecos='1001', shell='/bin/bash'))
+ ent.assert_passwd_by_uid(
+ 1001,
+ dict(name='user1', passwd='*', uid=1001, gid=2001,
+ gecos='1001', shell='/bin/bash'))
+
+ ent.assert_group_by_name("group1", dict(name="group1", gid=2001))
+ ent.assert_group_by_gid(2001, dict(name="group1", gid=2001))
+
+ assert_user_gids_equal('user1', [2000, 2001])
+
+ stop_sssd()
+
+ # group cache is disabled, other caches should work
+ ent.assert_passwd_by_name(
+ 'user1',
+ dict(name='user1', passwd='*', uid=1001, gid=2001,
+ gecos='1001', shell='/bin/bash'))
+ ent.assert_passwd_by_uid(
+ 1001,
+ dict(name='user1', passwd='*', uid=1001, gid=2001,
+ gecos='1001', shell='/bin/bash'))
+
+ with pytest.raises(KeyError):
+ grp.getgrnam('group1')
+ with pytest.raises(KeyError):
+ grp.getgrgid(2001)
+
+ assert_user_gids_equal('user1', [2000, 2001])
+
+
+def test_disabled_initgr_mc(ldap_conn, disable_initgr_mc_rfc2307):
+ # Even if initgroups is disabled, passwd should work
+ ent.assert_passwd_by_name(
+ 'user1',
+ dict(name='user1', passwd='*', uid=1001, gid=2001,
+ gecos='1001', shell='/bin/bash'))
+ ent.assert_passwd_by_uid(
+ 1001,
+ dict(name='user1', passwd='*', uid=1001, gid=2001,
+ gecos='1001', shell='/bin/bash'))
+
+ stop_sssd()
+
+ ent.assert_passwd_by_name(
+ 'user1',
+ dict(name='user1', passwd='*', uid=1001, gid=2001,
+ gecos='1001', shell='/bin/bash'))
+ ent.assert_passwd_by_uid(
+ 1001,
+ dict(name='user1', passwd='*', uid=1001, gid=2001,
+ gecos='1001', shell='/bin/bash'))
--
2.21.3

View File

@ -1,46 +0,0 @@
From 5b87af6f5b50c464ee7ea4558f73431e398e1423 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Mon, 10 Feb 2020 11:52:35 +0100
Subject: [PATCH] sss_sockets: pass pointer instead of integer
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
```
/home/pbrezina/workspace/sssd/src/util/sss_sockets.c: In function set_fd_common_opts:
/home/pbrezina/workspace/sssd/src/util/sss_sockets.c:123:61: error: passing argument 4 of setsockopt makes pointer from integer without a cast [-Werror=int-conversion]
123 | ret = setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, milli,
| ^~~~~
| |
| unsigned int
In file included from /home/pbrezina/workspace/sssd/src/util/sss_sockets.c:28:
/usr/include/sys/socket.h:216:22: note: expected const void * but argument is of type unsigned int
216 | const void *__optval, socklen_t __optlen) __THROW;
| ~~~~~~~~~~~~^~~~~~~~
CC src/util/sssd_kcm-sss_iobuf.o
cc1: all warnings being treated as errors
```
Introduced by 7aa96458f3bec4ef6ff7385107458e6b2b0b06ac
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/util/sss_sockets.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/util/sss_sockets.c b/src/util/sss_sockets.c
index b6b6dbac5..6f2b71bc8 100644
--- a/src/util/sss_sockets.c
+++ b/src/util/sss_sockets.c
@@ -120,7 +120,7 @@ static errno_t set_fd_common_opts(int fd, int timeout)
}
milli = timeout * 1000; /* timeout in milliseconds */
- ret = setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, milli,
+ ret = setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &milli,
sizeof(milli));
if (ret != 0) {
ret = errno;
--
2.21.1

View File

@ -0,0 +1,83 @@
From e12340e7d9efe5f272e58d69333c1c09c3bcc44d Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Wed, 4 Mar 2020 21:09:33 +0100
Subject: [PATCH 30/35] NSS: avoid excessive log messages
- do not log error message if mem-cache was disabled explicitly
- increase message severity in case of fail to store entry in mem-cache
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/responder/nss/nss_protocol_grent.c | 12 +++++++-----
src/responder/nss/nss_protocol_pwent.c | 7 ++++---
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/src/responder/nss/nss_protocol_grent.c b/src/responder/nss/nss_protocol_grent.c
index 2f6d869ef..8f1d3fe81 100644
--- a/src/responder/nss/nss_protocol_grent.c
+++ b/src/responder/nss/nss_protocol_grent.c
@@ -292,16 +292,17 @@ nss_protocol_fill_grent(struct nss_ctx *nss_ctx,
num_results++;
/* Do not store entry in memory cache during enumeration or when
- * requested. */
+ * requested or if cache explicitly disabled. */
if (!cmd_ctx->enumeration
- && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) {
+ && ((cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0)
+ && (nss_ctx->grp_mc_ctx != NULL)) {
members = (char *)&body[rp_members];
members_size = body_len - rp_members;
ret = sss_mmap_cache_gr_store(&nss_ctx->grp_mc_ctx, name, &pwfield,
gid, num_members, members,
members_size);
if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
+ DEBUG(SSSDBG_OP_FAILURE,
"Failed to store group %s (%s) in mem-cache [%d]: %s!\n",
name->str, result->domain->name, ret, sss_strerror(ret));
}
@@ -423,7 +424,8 @@ nss_protocol_fill_initgr(struct nss_ctx *nss_ctx,
}
if (nss_ctx->initgr_mc_ctx
- && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) {
+ && ((cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0)
+ && (nss_ctx->initgr_mc_ctx != NULL)) {
to_sized_string(&rawname, cmd_ctx->rawname);
to_sized_string(&unique_name, result->lookup_name);
@@ -431,7 +433,7 @@ nss_protocol_fill_initgr(struct nss_ctx *nss_ctx,
&unique_name, num_results,
body + 2 * sizeof(uint32_t));
if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
+ DEBUG(SSSDBG_OP_FAILURE,
"Failed to store initgroups %s (%s) in mem-cache [%d]: %s!\n",
rawname.str, domain->name, ret, sss_strerror(ret));
sss_packet_set_size(packet, 0);
diff --git a/src/responder/nss/nss_protocol_pwent.c b/src/responder/nss/nss_protocol_pwent.c
index 31fd01698..f9f3f0cf0 100644
--- a/src/responder/nss/nss_protocol_pwent.c
+++ b/src/responder/nss/nss_protocol_pwent.c
@@ -301,13 +301,14 @@ nss_protocol_fill_pwent(struct nss_ctx *nss_ctx,
num_results++;
/* Do not store entry in memory cache during enumeration or when
- * requested. */
+ * requested or if cache explicitly disabled. */
if (!cmd_ctx->enumeration
- && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) {
+ && ((cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0)
+ && (nss_ctx->pwd_mc_ctx != NULL)) {
ret = sss_mmap_cache_pw_store(&nss_ctx->pwd_mc_ctx, name, &pwfield,
uid, gid, &gecos, &homedir, &shell);
if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
+ DEBUG(SSSDBG_OP_FAILURE,
"Failed to store user %s (%s) in mmap cache [%d]: %s!\n",
name->str, result->domain->name, ret, sss_strerror(ret));
}
--
2.21.3

View File

@ -1,235 +0,0 @@
From 6f7f15691b071cefd4e04a9fee44af580b6c502b Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 9 Mar 2020 13:39:47 +0100
Subject: [PATCH] ssh: fix matching rules default
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Before the ssh_use_certificate_matching_rules option was added the ssh
responder returned ssh keys derived from all valid certificates. Since
the default of the ssh_use_certificate_matching_rules option is
'all_rules' in a case where no matching rules are defined all
certificated will be filtered out and no ssh keys are returned.
The intention of the default was to allow the same same certificates
which are allowed in the PAM responder for authentication. The missing
default matching rule which is currently use by the PAM responder if no
other rules are available is added by this patch.
There might still be a small regression in case certificates without the
extended key usage (EKU) clientAuth were used for ssh. In this case
'ssh_use_certificate_matching_rules = no_rules' or a suitable matching
rule must be added to the configuration.
Related to https://pagure.io/SSSD/sssd/issue/4121
Reviewed-by: Tomáš Halman <thalman@redhat.com>
---
src/man/sssd.conf.5.xml | 9 ++++-
src/responder/pam/pam_helpers.h | 2 ++
src/responder/pam/pamsrv_p11.c | 3 +-
src/responder/ssh/ssh_cmd.c | 30 +++++++++++++----
src/tests/cmocka/test_ssh_srv.c | 58 +++++++++++++++++++++++++++++++++
5 files changed, 93 insertions(+), 9 deletions(-)
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 58383579c..a2567f5ac 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1766,6 +1766,13 @@ p11_uri = library-description=OpenSC%20smartcard%20framework;slot-id=2
will be filtered out and ssh keys will be generated
from all valid certificates.
</para>
+ <para>
+ If no rules are configured using 'all_rules' will
+ enable a default rule which enables all
+ certificates suitable for client authentication.
+ This is the same behavior as for the PAM responder
+ if certificate authentication is enabled.
+ </para>
<para>
A non-existing rule name is considered an error.
If as a result no rule is selected all certificates
@@ -1773,7 +1780,7 @@ p11_uri = library-description=OpenSC%20smartcard%20framework;slot-id=2
</para>
<para>
Default: not set, equivalent to 'all_rules,
- all found rules are used
+ all found rules or the default rule are used
</para>
</listitem>
</varlistentry>
diff --git a/src/responder/pam/pam_helpers.h b/src/responder/pam/pam_helpers.h
index 614389706..23fd308bb 100644
--- a/src/responder/pam/pam_helpers.h
+++ b/src/responder/pam/pam_helpers.h
@@ -25,6 +25,8 @@
#include "util/util.h"
+#define CERT_AUTH_DEFAULT_MATCHING_RULE "KRB5:<EKU>clientAuth"
+
errno_t pam_initgr_cache_set(struct tevent_context *ev,
hash_table_t *id_table,
char *name,
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index 0dc53a826..8e276b200 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -26,13 +26,12 @@
#include "util/child_common.h"
#include "util/strtonum.h"
#include "responder/pam/pamsrv.h"
+#include "responder/pam/pam_helpers.h"
#include "lib/certmap/sss_certmap.h"
#include "util/crypto/sss_crypto.h"
#include "db/sysdb.h"
-#define CERT_AUTH_DEFAULT_MATCHING_RULE "KRB5:<EKU>clientAuth"
-
struct cert_auth_info {
char *cert;
char *token_name;
diff --git a/src/responder/ssh/ssh_cmd.c b/src/responder/ssh/ssh_cmd.c
index e42e29bfd..a593c904f 100644
--- a/src/responder/ssh/ssh_cmd.c
+++ b/src/responder/ssh/ssh_cmd.c
@@ -29,6 +29,7 @@
#include "responder/common/responder.h"
#include "responder/common/cache_req/cache_req.h"
#include "responder/ssh/ssh_private.h"
+#include "responder/pam/pam_helpers.h"
#include "lib/certmap/sss_certmap.h"
struct ssh_cmd_ctx {
@@ -159,6 +160,7 @@ static errno_t ssh_cmd_refresh_certmap_ctx(struct ssh_ctx *ssh_ctx,
bool rule_added;
bool all_rules = false;
bool no_rules = false;
+ bool rules_present = false;
ssh_ctx->cert_rules_error = false;
@@ -195,6 +197,7 @@ static errno_t ssh_cmd_refresh_certmap_ctx(struct ssh_ctx *ssh_ctx,
}
for (c = 0; certmap_list[c] != NULL; c++) {
+ rules_present = true;
if (!all_rules && !string_in_list(certmap_list[c]->name,
ssh_ctx->cert_rules, true)) {
@@ -227,12 +230,27 @@ static errno_t ssh_cmd_refresh_certmap_ctx(struct ssh_ctx *ssh_ctx,
}
if (!rule_added) {
- DEBUG(SSSDBG_CONF_SETTINGS,
- "No matching rule added, please check "
- "ssh_use_certificate_matching_rules option values for typos .\n");
-
- ret = EINVAL;
- goto done;
+ if (!rules_present) {
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "No rules available, trying to add default matching rule.\n");
+ ret = sss_certmap_add_rule(sss_certmap_ctx, SSS_CERTMAP_MIN_PRIO,
+ CERT_AUTH_DEFAULT_MATCHING_RULE,
+ NULL, NULL);
+ if (ret != 0) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to add default matching rule [%d][%s].\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+ } else {
+ DEBUG(SSSDBG_CONF_SETTINGS,
+ "No matching rule added, please check "
+ "ssh_use_certificate_matching_rules option values for "
+ "typos.\n");
+
+ ret = EINVAL;
+ goto done;
+ }
}
ret = EOK;
diff --git a/src/tests/cmocka/test_ssh_srv.c b/src/tests/cmocka/test_ssh_srv.c
index fc43663a7..a48013416 100644
--- a/src/tests/cmocka/test_ssh_srv.c
+++ b/src/tests/cmocka/test_ssh_srv.c
@@ -769,6 +769,62 @@ void test_ssh_user_pubkey_cert_with_all_rules(void **state)
assert_int_equal(ret, EOK);
}
+void test_ssh_user_pubkey_cert_with_all_rules_but_no_rules_present(void **state)
+{
+ int ret;
+ struct sysdb_attrs *attrs;
+ /* Both rules are enabled, both certificates should be handled. */
+ const char *rule_list[] = { "all_rules", NULL };
+
+ attrs = sysdb_new_attrs(ssh_test_ctx);
+ assert_non_null(attrs);
+ ret = sysdb_attrs_add_string(attrs, SYSDB_SSH_PUBKEY, TEST_SSH_PUBKEY);
+ assert_int_equal(ret, EOK);
+ ret = sysdb_attrs_add_base64_blob(attrs, SYSDB_USER_CERT,
+ SSSD_TEST_CERT_0001);
+ assert_int_equal(ret, EOK);
+ ret = sysdb_attrs_add_base64_blob(attrs, SYSDB_USER_CERT,
+ SSSD_TEST_CERT_0002);
+ assert_int_equal(ret, EOK);
+
+ ret = sysdb_set_user_attr(ssh_test_ctx->tctx->dom,
+ ssh_test_ctx->ssh_user_fqdn,
+ attrs,
+ LDB_FLAG_MOD_ADD);
+ talloc_free(attrs);
+ assert_int_equal(ret, EOK);
+
+ mock_input_user(ssh_test_ctx, ssh_test_ctx->ssh_user_fqdn);
+ will_return(__wrap_sss_packet_get_cmd, SSS_SSH_GET_USER_PUBKEYS);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+ /* Enable certificate support */
+ ssh_test_ctx->ssh_ctx->use_cert_keys = true;
+ ssh_test_ctx->ssh_ctx->rctx->domains->certmaps = NULL;
+ ssh_test_ctx->ssh_ctx->certmap_last_read = 0;
+ ssh_test_ctx->ssh_ctx->rctx->get_domains_last_call.tv_sec = 1;
+ ssh_test_ctx->ssh_ctx->cert_rules = discard_const(rule_list);
+#ifdef HAVE_NSS
+ ssh_test_ctx->ssh_ctx->ca_db = discard_const("sql:" ABS_BUILD_DIR
+ "/src/tests/test_CA/p11_nssdb");
+#else
+ ssh_test_ctx->ssh_ctx->ca_db = discard_const(ABS_BUILD_DIR
+ "/src/tests/test_CA/SSSD_test_CA.pem");
+#endif
+
+ set_cmd_cb(test_ssh_user_pubkey_cert_check);
+ ret = sss_cmd_execute(ssh_test_ctx->cctx, SSS_SSH_GET_USER_PUBKEYS,
+ ssh_test_ctx->ssh_cmds);
+ assert_int_equal(ret, EOK);
+
+ /* Wait until the test finishes with EOK */
+ ret = test_ev_loop(ssh_test_ctx->tctx);
+ assert_int_equal(ret, EOK);
+}
+
void test_ssh_user_pubkey_cert_with_no_rules(void **state)
{
int ret;
@@ -966,6 +1022,8 @@ int main(int argc, const char *argv[])
ssh_test_setup, ssh_test_teardown),
cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_all_rules,
ssh_test_setup, ssh_test_teardown),
+ cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_all_rules_but_no_rules_present,
+ ssh_test_setup, ssh_test_teardown),
cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_no_rules,
ssh_test_setup, ssh_test_teardown),
cmocka_unit_test_setup_teardown(test_ssh_user_pubkey_cert_with_unknow_rule_name,
--
2.21.1

View File

@ -0,0 +1,101 @@
From be8052bbb61c572702fe16e2850539f445dcc0e2 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Wed, 4 Mar 2020 22:13:52 +0100
Subject: [PATCH 31/35] NSS: enhanced debug during mem-cache initialization
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/responder/nss/nsssrv.c | 39 ++++++++++++++++++++++++++++++++------
1 file changed, 33 insertions(+), 6 deletions(-)
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 0a201d3ae..42a63d9bb 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -255,7 +255,8 @@ static int setup_memcaches(struct nss_ctx *nctx)
&mc_size_passwd);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE,
- "Failed to get 'memcache_size_passwd' option from confdb.\n");
+ "Failed to get '"CONFDB_NSS_MEMCACHE_SIZE_PASSWD
+ "' option from confdb.\n");
return ret;
}
@@ -266,7 +267,8 @@ static int setup_memcaches(struct nss_ctx *nctx)
&mc_size_group);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE,
- "Failed to get 'memcache_size_group' option from confdb.\n");
+ "Failed to get '"CONFDB_NSS_MEMCACHE_SIZE_GROUP
+ "' option from confdb.\n");
return ret;
}
@@ -277,7 +279,8 @@ static int setup_memcaches(struct nss_ctx *nctx)
&mc_size_initgroups);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE,
- "Failed to get 'memcache_size_nitgroups' option from confdb.\n");
+ "Failed to get '"CONFDB_NSS_MEMCACHE_SIZE_INITGROUPS
+ "' option from confdb.\n");
return ret;
}
@@ -291,8 +294,16 @@ static int setup_memcaches(struct nss_ctx *nctx)
(time_t)memcache_timeout,
&nctx->pwd_mc_ctx);
if (ret) {
- DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache is DISABLED\n");
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to initialize passwd mmap cache: '%s'\n",
+ sss_strerror(ret));
+ } else {
+ DEBUG(SSSDBG_CONF_SETTINGS, "Passwd mmap cache size is %d\n",
+ mc_size_passwd);
}
+ } else {
+ DEBUG(SSSDBG_IMPORTANT_INFO,
+ "Passwd mmap cache is explicitly DISABLED\n");
}
if (mc_size_group != 0) {
@@ -303,8 +314,16 @@ static int setup_memcaches(struct nss_ctx *nctx)
(time_t)memcache_timeout,
&nctx->grp_mc_ctx);
if (ret) {
- DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n");
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to initialize group mmap cache: '%s'\n",
+ sss_strerror(ret));
+ } else {
+ DEBUG(SSSDBG_CONF_SETTINGS, "Group mmap cache size is %d\n",
+ mc_size_group);
}
+ } else {
+ DEBUG(SSSDBG_IMPORTANT_INFO,
+ "Group mmap cache is explicitly DISABLED\n");
}
if (mc_size_initgroups != 0) {
@@ -315,8 +334,16 @@ static int setup_memcaches(struct nss_ctx *nctx)
(time_t)memcache_timeout,
&nctx->initgr_mc_ctx);
if (ret) {
- DEBUG(SSSDBG_CRIT_FAILURE, "initgroups mmap cache is DISABLED\n");
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to initialize initgroups mmap cache: '%s'\n",
+ sss_strerror(ret));
+ } else {
+ DEBUG(SSSDBG_CONF_SETTINGS, "Initgroups mmap cache size is %d\n",
+ mc_size_initgroups);
}
+ } else {
+ DEBUG(SSSDBG_IMPORTANT_INFO,
+ "Initgroups mmap cache is explicitly DISABLED\n");
}
return EOK;
--
2.21.3

View File

@ -0,0 +1,53 @@
From 2ad4aa8f265e02d01f77e5d29d8377d849c78d11 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Wed, 4 Mar 2020 22:33:17 +0100
Subject: [PATCH 32/35] mem-cache: added log message in case cache is full
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/responder/nss/nsssrv_mmap_cache.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 5e23bbe6f..23df164da 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -371,6 +371,20 @@ static bool sss_mc_is_valid_rec(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec)
return true;
}
+static const char *mc_type_to_str(enum sss_mc_type type)
+{
+ switch (type) {
+ case SSS_MC_PASSWD:
+ return "PASSWD";
+ case SSS_MC_GROUP:
+ return "GROUP";
+ case SSS_MC_INITGROUPS:
+ return "INITGROUPS";
+ default:
+ return "-UNKNOWN-";
+ }
+}
+
/* FIXME: This is a very simplistic, inefficient, memory allocator,
* it will just free the oldest entries regardless of expiration if it
* cycled the whole free bits map and found no empty slot */
@@ -438,6 +452,14 @@ static errno_t sss_mc_find_free_slots(struct sss_mc_ctx *mcc,
} else {
cur = mcc->next_slot;
}
+ if (cur == 0) {
+ /* inform only once per full loop to avoid excessive spam */
+ DEBUG(SSSDBG_IMPORTANT_INFO, "mmap cache of type '%s' is full\n",
+ mc_type_to_str(mcc->type));
+ sss_log(SSS_LOG_NOTICE, "mmap cache of type '%s' is full, if you see "
+ "this message often then please consider increase of cache size",
+ mc_type_to_str(mcc->type));
+ }
for (i = 0; i < num_slots; i++) {
MC_PROBE_BIT(mcc->free_table, cur + i, used);
if (used) {
--
2.21.3

View File

@ -0,0 +1,189 @@
From b7f31936e21b109b5446c48513619cd87974be54 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Tue, 31 Mar 2020 22:57:25 +0200
Subject: [PATCH 33/35] NSS: make memcache size configurable in megabytes
Memcache size was made configurable in megabytes and not in slots
to hide internal implementation from users.
Relates: https://github.com/SSSD/sssd/issues/5115
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/config/SSSDConfig/sssdoptions.py | 6 ++---
src/man/sssd.conf.5.xml | 33 +++++++++++++---------------
src/responder/nss/nsssrv.c | 20 +++++++++--------
3 files changed, 29 insertions(+), 30 deletions(-)
diff --git a/src/config/SSSDConfig/sssdoptions.py b/src/config/SSSDConfig/sssdoptions.py
index 16d85cfa3..f57ad4b41 100644
--- a/src/config/SSSDConfig/sssdoptions.py
+++ b/src/config/SSSDConfig/sssdoptions.py
@@ -72,9 +72,9 @@ class SSSDOptions(object):
'shell_fallback': _('If a shell stored in central directory is allowed but not available, use this fallback'),
'default_shell': _('Shell to use if the provider does not list one'),
'memcache_timeout': _('How long will be in-memory cache records valid'),
- 'memcache_size_passwd': _('Number of slots in fast in-memory cache for passwd requests'),
- 'memcache_size_group': _('Number of slots in fast in-memory cache for group requests'),
- 'memcache_size_initgroups': _('Number of slots in fast in-memory cache for initgroups requests'),
+ 'memcache_size_passwd': _('Size (in megabytes) of the data table allocated inside fast in-memory cache for passwd requests'),
+ 'memcache_size_group': _('Size (in megabytes) of the data table allocated inside fast in-memory cache for group requests'),
+ 'memcache_size_initgroups': _('Size (in megabytes) of the data table allocated inside fast in-memory cache for initgroups requests'),
'homedir_substring': _('The value of this option will be used in the expansion of the override_homedir option '
'if the template contains the format string %H.'),
'get_domains_timeout': _('Specifies time in seconds for which the list of subdomains will be considered '
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 9bc2e26e5..874a09c49 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1076,7 +1076,7 @@ fallback_homedir = /home/%u
</listitem>
</varlistentry>
<varlistentry>
- <term>memcache_timeout (int)</term>
+ <term>memcache_timeout (integer)</term>
<listitem>
<para>
Specifies time in seconds for which records
@@ -1104,14 +1104,13 @@ fallback_homedir = /home/%u
<term>memcache_size_passwd (integer)</term>
<listitem>
<para>
- Number of slots allocated inside fast in-memory
- cache for passwd requests. Note that one entry
- in fast in-memory cache can occupy more than one slot.
- Setting the size to 0 will disable the passwd in-memory
- cache.
+ Size (in megabytes) of the data table allocated inside
+ fast in-memory cache for passwd requests.
+ Setting the size to 0 will disable the passwd
+ in-memory cache.
</para>
<para>
- Default: 200000
+ Default: 8
</para>
<para>
WARNING: Disabled or too small in-memory cache can
@@ -1130,14 +1129,13 @@ fallback_homedir = /home/%u
<term>memcache_size_group (integer)</term>
<listitem>
<para>
- Number of slots allocated inside fast in-memory
- cache for group requests. Note that one entry
- in fast in-memory cache can occupy more than one
- slot. Setting the size to 0 will disable the group
+ Size (in megabytes) of the data table allocated inside
+ fast in-memory cache for group requests.
+ Setting the size to 0 will disable the group
in-memory cache.
</para>
<para>
- Default: 150000
+ Default: 6
</para>
<para>
WARNING: Disabled or too small in-memory cache can
@@ -1156,14 +1154,13 @@ fallback_homedir = /home/%u
<term>memcache_size_initgroups (integer)</term>
<listitem>
<para>
- Number of slots allocated inside fast in-memory
- cache for initgroups requests. Note that one entry
- in fast in-memory cache can occupy more than one
- slot. Setting the size to 0 will disable the
- initgroups in-memory cache.
+ Size (in megabytes) of the data table allocated inside
+ fast in-memory cache for initgroups requests.
+ Setting the size to 0 will disable the initgroups
+ in-memory cache.
</para>
<para>
- Default: 250000
+ Default: 10
</para>
<para>
WARNING: Disabled or too small in-memory cache can
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 42a63d9bb..741e94aaa 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -34,6 +34,7 @@
#include "util/util.h"
#include "util/sss_ptr_hash.h"
+#include "util/mmap_cache.h"
#include "responder/nss/nss_private.h"
#include "responder/nss/nss_iface.h"
#include "responder/nss/nsssrv_mmap_cache.h"
@@ -210,9 +211,10 @@ done:
static int setup_memcaches(struct nss_ctx *nctx)
{
/* Default memcache sizes */
- static const size_t SSS_MC_CACHE_PASSWD_SLOTS = 200000; /* 8mb */
- static const size_t SSS_MC_CACHE_GROUP_SLOTS = 150000; /* 6mb */
- static const size_t SSS_MC_CACHE_INITGROUP_SLOTS = 250000; /* 10mb */
+ static const size_t SSS_MC_CACHE_SLOTS_PER_MB = 1024*1024/MC_SLOT_SIZE;
+ static const size_t SSS_MC_CACHE_PASSWD_SIZE = 8;
+ static const size_t SSS_MC_CACHE_GROUP_SIZE = 6;
+ static const size_t SSS_MC_CACHE_INITGROUP_SIZE = 10;
int ret;
int memcache_timeout;
@@ -251,7 +253,7 @@ static int setup_memcaches(struct nss_ctx *nctx)
ret = confdb_get_int(nctx->rctx->cdb,
CONFDB_NSS_CONF_ENTRY,
CONFDB_NSS_MEMCACHE_SIZE_PASSWD,
- SSS_MC_CACHE_PASSWD_SLOTS,
+ SSS_MC_CACHE_PASSWD_SIZE,
&mc_size_passwd);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE,
@@ -263,7 +265,7 @@ static int setup_memcaches(struct nss_ctx *nctx)
ret = confdb_get_int(nctx->rctx->cdb,
CONFDB_NSS_CONF_ENTRY,
CONFDB_NSS_MEMCACHE_SIZE_GROUP,
- SSS_MC_CACHE_GROUP_SLOTS,
+ SSS_MC_CACHE_GROUP_SIZE,
&mc_size_group);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE,
@@ -275,7 +277,7 @@ static int setup_memcaches(struct nss_ctx *nctx)
ret = confdb_get_int(nctx->rctx->cdb,
CONFDB_NSS_CONF_ENTRY,
CONFDB_NSS_MEMCACHE_SIZE_INITGROUPS,
- SSS_MC_CACHE_INITGROUP_SLOTS,
+ SSS_MC_CACHE_INITGROUP_SIZE,
&mc_size_initgroups);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE,
@@ -290,7 +292,7 @@ static int setup_memcaches(struct nss_ctx *nctx)
ret = sss_mmap_cache_init(nctx, "passwd",
nctx->mc_uid, nctx->mc_gid,
SSS_MC_PASSWD,
- mc_size_passwd,
+ mc_size_passwd * SSS_MC_CACHE_SLOTS_PER_MB,
(time_t)memcache_timeout,
&nctx->pwd_mc_ctx);
if (ret) {
@@ -310,7 +312,7 @@ static int setup_memcaches(struct nss_ctx *nctx)
ret = sss_mmap_cache_init(nctx, "group",
nctx->mc_uid, nctx->mc_gid,
SSS_MC_GROUP,
- mc_size_group,
+ mc_size_group * SSS_MC_CACHE_SLOTS_PER_MB,
(time_t)memcache_timeout,
&nctx->grp_mc_ctx);
if (ret) {
@@ -330,7 +332,7 @@ static int setup_memcaches(struct nss_ctx *nctx)
ret = sss_mmap_cache_init(nctx, "initgroups",
nctx->mc_uid, nctx->mc_gid,
SSS_MC_INITGROUPS,
- mc_size_initgroups,
+ mc_size_initgroups * SSS_MC_CACHE_SLOTS_PER_MB,
(time_t)memcache_timeout,
&nctx->initgr_mc_ctx);
if (ret) {
--
2.21.3

View File

@ -0,0 +1,38 @@
From b96b05bc40757b26f177e4093d7f4f5b96a0f7d0 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Fri, 3 Jul 2020 18:45:11 +0200
Subject: [PATCH 34/35] mem-cache: comment added
Added comment explaining usage of `mcc->next_slot`
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/responder/nss/nsssrv_mmap_cache.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 23df164da..71919e4ac 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -65,7 +65,7 @@ struct sss_mc_ctx {
uint8_t *free_table; /* free list bitmaps */
uint32_t ft_size; /* size of free table */
- uint32_t next_slot; /* the next slot after last allocation */
+ uint32_t next_slot; /* the next slot after last allocation done via erasure */
uint8_t *data_table; /* data table address (in mmap) */
uint32_t dt_size; /* size of data table */
@@ -442,6 +442,9 @@ static errno_t sss_mc_find_free_slots(struct sss_mc_ctx *mcc,
if (cur == t) {
/* ok found num_slots consecutive free bits */
*free_slot = cur - num_slots;
+ /* `mcc->next_slot` is not updated here intentionally.
+ * For details see discussion in https://github.com/SSSD/sssd/pull/999
+ */
return EOK;
}
}
--
2.21.3

View File

@ -0,0 +1,262 @@
From 484507bf20d27afd700d52c67651e6f08d1da1a3 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Wed, 8 Jul 2020 11:34:12 +0200
Subject: [PATCH 35/35] mem-cache: always cleanup old content
(Try to) cleanup old files even if currently mem-cache is disabled.
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/responder/nss/nsssrv.c | 98 ++++++++++-----------------
src/responder/nss/nsssrv_mmap_cache.c | 74 ++++++++++++--------
2 files changed, 79 insertions(+), 93 deletions(-)
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 741e94aaa..ffb1ca29d 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -242,12 +242,6 @@ static int setup_memcaches(struct nss_ctx *nctx)
return ret;
}
- if (memcache_timeout == 0) {
- DEBUG(SSSDBG_CONF_SETTINGS,
- "Fast in-memory cache will not be initialized.");
- return EOK;
- }
-
/* Get all memcache sizes from confdb (pwd, grp, initgr) */
ret = confdb_get_int(nctx->rctx->cdb,
@@ -288,64 +282,40 @@ static int setup_memcaches(struct nss_ctx *nctx)
/* Initialize the fast in-memory caches if they were not disabled */
- if (mc_size_passwd != 0) {
- ret = sss_mmap_cache_init(nctx, "passwd",
- nctx->mc_uid, nctx->mc_gid,
- SSS_MC_PASSWD,
- mc_size_passwd * SSS_MC_CACHE_SLOTS_PER_MB,
- (time_t)memcache_timeout,
- &nctx->pwd_mc_ctx);
- if (ret) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Failed to initialize passwd mmap cache: '%s'\n",
- sss_strerror(ret));
- } else {
- DEBUG(SSSDBG_CONF_SETTINGS, "Passwd mmap cache size is %d\n",
- mc_size_passwd);
- }
- } else {
- DEBUG(SSSDBG_IMPORTANT_INFO,
- "Passwd mmap cache is explicitly DISABLED\n");
- }
-
- if (mc_size_group != 0) {
- ret = sss_mmap_cache_init(nctx, "group",
- nctx->mc_uid, nctx->mc_gid,
- SSS_MC_GROUP,
- mc_size_group * SSS_MC_CACHE_SLOTS_PER_MB,
- (time_t)memcache_timeout,
- &nctx->grp_mc_ctx);
- if (ret) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Failed to initialize group mmap cache: '%s'\n",
- sss_strerror(ret));
- } else {
- DEBUG(SSSDBG_CONF_SETTINGS, "Group mmap cache size is %d\n",
- mc_size_group);
- }
- } else {
- DEBUG(SSSDBG_IMPORTANT_INFO,
- "Group mmap cache is explicitly DISABLED\n");
- }
-
- if (mc_size_initgroups != 0) {
- ret = sss_mmap_cache_init(nctx, "initgroups",
- nctx->mc_uid, nctx->mc_gid,
- SSS_MC_INITGROUPS,
- mc_size_initgroups * SSS_MC_CACHE_SLOTS_PER_MB,
- (time_t)memcache_timeout,
- &nctx->initgr_mc_ctx);
- if (ret) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Failed to initialize initgroups mmap cache: '%s'\n",
- sss_strerror(ret));
- } else {
- DEBUG(SSSDBG_CONF_SETTINGS, "Initgroups mmap cache size is %d\n",
- mc_size_initgroups);
- }
- } else {
- DEBUG(SSSDBG_IMPORTANT_INFO,
- "Initgroups mmap cache is explicitly DISABLED\n");
+ ret = sss_mmap_cache_init(nctx, "passwd",
+ nctx->mc_uid, nctx->mc_gid,
+ SSS_MC_PASSWD,
+ mc_size_passwd * SSS_MC_CACHE_SLOTS_PER_MB,
+ (time_t)memcache_timeout,
+ &nctx->pwd_mc_ctx);
+ if (ret) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to initialize passwd mmap cache: '%s'\n",
+ sss_strerror(ret));
+ }
+
+ ret = sss_mmap_cache_init(nctx, "group",
+ nctx->mc_uid, nctx->mc_gid,
+ SSS_MC_GROUP,
+ mc_size_group * SSS_MC_CACHE_SLOTS_PER_MB,
+ (time_t)memcache_timeout,
+ &nctx->grp_mc_ctx);
+ if (ret) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to initialize group mmap cache: '%s'\n",
+ sss_strerror(ret));
+ }
+
+ ret = sss_mmap_cache_init(nctx, "initgroups",
+ nctx->mc_uid, nctx->mc_gid,
+ SSS_MC_INITGROUPS,
+ mc_size_initgroups * SSS_MC_CACHE_SLOTS_PER_MB,
+ (time_t)memcache_timeout,
+ &nctx->initgr_mc_ctx);
+ if (ret) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to initialize initgroups mmap cache: '%s'\n",
+ sss_strerror(ret));
}
return EOK;
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 71919e4ac..f66e76ce4 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -1108,48 +1108,48 @@ static errno_t sss_mc_set_recycled(int fd)
return EOK;
}
-/*
- * When we (re)create a new file we must mark the current file as recycled
- * so active clients will abandon its use ASAP.
- * We unlink the current file and make a new one.
- */
-static errno_t sss_mc_create_file(struct sss_mc_ctx *mc_ctx)
+static void sss_mc_destroy_file(const char *filename)
{
- mode_t old_mask;
+ const useconds_t t = 50000;
+ const int retries = 3;
int ofd;
- int ret, uret;
- useconds_t t = 50000;
- int retries = 3;
+ int ret;
- ofd = open(mc_ctx->file, O_RDWR);
+ ofd = open(filename, O_RDWR);
if (ofd != -1) {
ret = sss_br_lock_file(ofd, 0, 1, retries, t);
if (ret != EOK) {
- DEBUG(SSSDBG_FATAL_FAILURE,
- "Failed to lock file %s.\n", mc_ctx->file);
+ DEBUG(SSSDBG_FATAL_FAILURE, "Failed to lock file %s.\n", filename);
}
ret = sss_mc_set_recycled(ofd);
if (ret) {
DEBUG(SSSDBG_FATAL_FAILURE, "Failed to mark mmap file %s as"
- " recycled: %d(%s)\n",
- mc_ctx->file, ret, strerror(ret));
+ " recycled: %d (%s)\n",
+ filename, ret, strerror(ret));
}
-
close(ofd);
} else if (errno != ENOENT) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE,
- "Failed to open old memory cache file %s: %d(%s).\n",
- mc_ctx->file, ret, strerror(ret));
+ "Failed to open old memory cache file %s: %d (%s)\n",
+ filename, ret, strerror(ret));
}
errno = 0;
- ret = unlink(mc_ctx->file);
+ ret = unlink(filename);
if (ret == -1 && errno != ENOENT) {
ret = errno;
- DEBUG(SSSDBG_TRACE_FUNC, "Failed to rm mmap file %s: %d(%s)\n",
- mc_ctx->file, ret, strerror(ret));
+ DEBUG(SSSDBG_TRACE_FUNC, "Failed to delete mmap file %s: %d (%s)\n",
+ filename, ret, strerror(ret));
}
+}
+
+static errno_t sss_mc_create_file(struct sss_mc_ctx *mc_ctx)
+{
+ const useconds_t t = 50000;
+ const int retries = 3;
+ mode_t old_mask;
+ int ret, uret;
/* temporarily relax umask as we need the file to be readable
* by everyone for now */
@@ -1276,9 +1276,32 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
struct sss_mc_ctx *mc_ctx = NULL;
int ret, dret;
+ char *filename;
+
+ filename = talloc_asprintf(mem_ctx, "%s/%s", SSS_NSS_MCACHE_DIR, name);
+ if (!filename) {
+ return ENOMEM;
+ }
+ /*
+ * First of all mark the current file as recycled
+ * and unlink so active clients will abandon its use ASAP
+ */
+ sss_mc_destroy_file(filename);
+
+ if ((timeout == 0) || (n_elem == 0)) {
+ DEBUG(SSSDBG_IMPORTANT_INFO,
+ "Fast '%s' mmap cache is explicitly DISABLED\n",
+ mc_type_to_str(type));
+ *mcc = NULL;
+ return EOK;
+ }
+ DEBUG(SSSDBG_CONF_SETTINGS,
+ "Fast '%s' mmap cache: timeout = %d, slots = %zu\n",
+ mc_type_to_str(type), (int)timeout, n_elem);
mc_ctx = talloc_zero(mem_ctx, struct sss_mc_ctx);
if (!mc_ctx) {
+ talloc_free(filename);
return ENOMEM;
}
mc_ctx->fd = -1;
@@ -1297,12 +1320,7 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
mc_ctx->valid_time_slot = timeout;
- mc_ctx->file = talloc_asprintf(mc_ctx, "%s/%s",
- SSS_NSS_MCACHE_DIR, name);
- if (!mc_ctx->file) {
- ret = ENOMEM;
- goto done;
- }
+ mc_ctx->file = talloc_steal(mc_ctx, filename);
/* elements must always be multiple of 8 to make things easier to handle,
* so we increase by the necessary amount if they are not a multiple */
@@ -1320,8 +1338,6 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
MC_ALIGN64(mc_ctx->ht_size);
- /* for now ALWAYS create a new file on restart */
-
ret = sss_mc_create_file(mc_ctx);
if (ret) {
goto done;
--
2.21.3

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,63 @@
From 72b8e02c77f0b0b7e36663fa3bd3fd6987ea1b80 Mon Sep 17 00:00:00 2001
From: Tomas Halman <thalman@redhat.com>
Date: Mon, 13 Jul 2020 18:11:40 +0200
Subject: [PATCH] sssctl: sssctl config-check alternative snippet dir
The sssctl config-check now allows to specify not only alternative
config file but also snippet dir.
sssctl config-check -c ./sssd.conf -s /etc/sssd/conf.d
Configuration snippets are still looked up in the same place under
conf.d directory by default. It would be in ./conf.d/ for the example
above.
Resolves:
https://github.com/SSSD/sssd/issues/5142
Reviewed-by: Pawel Polawski <ppolawsk@redhat.com>
---
src/tools/sssctl/sssctl_config.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/tools/sssctl/sssctl_config.c b/src/tools/sssctl/sssctl_config.c
index de9f3de6e..db4aeeae4 100644
--- a/src/tools/sssctl/sssctl_config.c
+++ b/src/tools/sssctl/sssctl_config.c
@@ -75,6 +75,11 @@ errno_t sssctl_config_check(struct sss_cmdline *cmdline,
struct poptOption long_options[] = {
{"config", 'c', POPT_ARG_STRING, &config_path,
0, _("Specify a non-default config file"), NULL},
+ {"snippet", 's', POPT_ARG_STRING, &config_snippet_path,
+ 0, _("Specify a non-default snippet dir (The default is to look in "
+ "the same place where the main config file is located. For "
+ "example if the config is set to \"/my/path/sssd.conf\", "
+ "the snippet dir \"/my/path/conf.d\" is used)"), NULL},
POPT_TABLEEND
};
@@ -92,16 +97,17 @@ errno_t sssctl_config_check(struct sss_cmdline *cmdline,
goto done;
}
- if (config_path != NULL) {
+ if (config_path == NULL) {
+ config_path = SSSD_CONFIG_FILE;
+ }
+
+ if (config_snippet_path == NULL) {
config_snippet_path = sssctl_config_snippet_path(tmp_ctx, config_path);
if (config_snippet_path == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create snippet path\n");
ret = ENOMEM;
goto done;
}
- } else {
- config_path = SSSD_CONFIG_FILE;
- config_snippet_path = CONFDB_DEFAULT_CONFIG_DIR;
}
ret = sss_ini_read_sssd_conf(init_data,
--
2.21.3

View File

@ -0,0 +1,651 @@
From a2b9a84460429181f2a4fa7e2bb5ab49fd561274 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 9 Dec 2019 11:31:14 +0100
Subject: [PATCH] certmap: sanitize LDAP search filter
The sss_certmap_get_search_filter() will now sanitize the values read
from the certificates before adding them to a search filter. To be able
to get the plain values as well sss_certmap_expand_mapping_rule() is
added.
Resolves:
https://github.com/SSSD/sssd/issues/5135
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
---
Makefile.am | 2 +-
src/lib/certmap/sss_certmap.c | 42 ++++++++++--
src/lib/certmap/sss_certmap.exports | 5 ++
src/lib/certmap/sss_certmap.h | 35 ++++++++--
src/responder/pam/pamsrv_p11.c | 5 +-
src/tests/cmocka/test_certmap.c | 98 +++++++++++++++++++++++++++-
src/util/util.c | 94 ---------------------------
src/util/util_ext.c | 99 +++++++++++++++++++++++++++++
8 files changed, 272 insertions(+), 108 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 059e1eaf6..4bacabdda 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2163,7 +2163,7 @@ libsss_certmap_la_LIBADD = \
$(NULL)
libsss_certmap_la_LDFLAGS = \
-Wl,--version-script,$(srcdir)/src/lib/certmap/sss_certmap.exports \
- -version-info 1:0:1
+ -version-info 2:0:2
if HAVE_NSS
libsss_certmap_la_SOURCES += \
diff --git a/src/lib/certmap/sss_certmap.c b/src/lib/certmap/sss_certmap.c
index 703782b53..f19e57732 100644
--- a/src/lib/certmap/sss_certmap.c
+++ b/src/lib/certmap/sss_certmap.c
@@ -441,10 +441,12 @@ static int expand_san(struct sss_certmap_ctx *ctx,
static int expand_template(struct sss_certmap_ctx *ctx,
struct parsed_template *parsed_template,
struct sss_cert_content *cert_content,
+ bool sanitize,
char **expanded)
{
int ret;
char *exp = NULL;
+ char *exp_sanitized = NULL;
if (strcmp("issuer_dn", parsed_template->name) == 0) {
ret = rdn_list_2_dn_str(ctx, parsed_template->conversion,
@@ -455,6 +457,8 @@ static int expand_template(struct sss_certmap_ctx *ctx,
} else if (strncmp("subject_", parsed_template->name, 8) == 0) {
ret = expand_san(ctx, parsed_template, cert_content->san_list, &exp);
} else if (strcmp("cert", parsed_template->name) == 0) {
+ /* cert blob is already sanitized */
+ sanitize = false;
ret = expand_cert(ctx, parsed_template, cert_content, &exp);
} else {
CM_DEBUG(ctx, "Unsupported template name.");
@@ -471,6 +475,16 @@ static int expand_template(struct sss_certmap_ctx *ctx,
goto done;
}
+ if (sanitize) {
+ ret = sss_filter_sanitize(ctx, exp, &exp_sanitized);
+ if (ret != EOK) {
+ CM_DEBUG(ctx, "Failed to sanitize expanded template.");
+ goto done;
+ }
+ talloc_free(exp);
+ exp = exp_sanitized;
+ }
+
ret = 0;
done:
@@ -485,7 +499,7 @@ done:
static int get_filter(struct sss_certmap_ctx *ctx,
struct ldap_mapping_rule *parsed_mapping_rule,
- struct sss_cert_content *cert_content,
+ struct sss_cert_content *cert_content, bool sanitize,
char **filter)
{
struct ldap_mapping_rule_comp *comp;
@@ -503,7 +517,7 @@ static int get_filter(struct sss_certmap_ctx *ctx,
result = talloc_strdup_append(result, comp->val);
} else if (comp->type == comp_template) {
ret = expand_template(ctx, comp->parsed_template, cert_content,
- &expanded);
+ sanitize, &expanded);
if (ret != 0) {
CM_DEBUG(ctx, "Failed to expanded template.");
goto done;
@@ -791,8 +805,9 @@ done:
return ret;
}
-int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx,
+static int expand_mapping_rule_ex(struct sss_certmap_ctx *ctx,
const uint8_t *der_cert, size_t der_size,
+ bool sanitize,
char **_filter, char ***_domains)
{
int ret;
@@ -819,7 +834,8 @@ int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx,
return EINVAL;
}
- ret = get_filter(ctx, ctx->default_mapping_rule, cert_content, &filter);
+ ret = get_filter(ctx, ctx->default_mapping_rule, cert_content, sanitize,
+ &filter);
goto done;
}
@@ -829,7 +845,7 @@ int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx,
if (ret == 0) {
/* match */
ret = get_filter(ctx, r->parsed_mapping_rule, cert_content,
- &filter);
+ sanitize, &filter);
if (ret != 0) {
CM_DEBUG(ctx, "Failed to get filter");
goto done;
@@ -873,6 +889,22 @@ done:
return ret;
}
+int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx,
+ const uint8_t *der_cert, size_t der_size,
+ char **_filter, char ***_domains)
+{
+ return expand_mapping_rule_ex(ctx, der_cert, der_size, true,
+ _filter, _domains);
+}
+
+int sss_certmap_expand_mapping_rule(struct sss_certmap_ctx *ctx,
+ const uint8_t *der_cert, size_t der_size,
+ char **_expanded, char ***_domains)
+{
+ return expand_mapping_rule_ex(ctx, der_cert, der_size, false,
+ _expanded, _domains);
+}
+
int sss_certmap_init(TALLOC_CTX *mem_ctx,
sss_certmap_ext_debug *debug, void *debug_priv,
struct sss_certmap_ctx **ctx)
diff --git a/src/lib/certmap/sss_certmap.exports b/src/lib/certmap/sss_certmap.exports
index a9e48d6d0..7d7667738 100644
--- a/src/lib/certmap/sss_certmap.exports
+++ b/src/lib/certmap/sss_certmap.exports
@@ -16,3 +16,8 @@ SSS_CERTMAP_0.1 {
global:
sss_certmap_display_cert_content;
} SSS_CERTMAP_0.0;
+
+SSS_CERTMAP_0.2 {
+ global:
+ sss_certmap_expand_mapping_rule;
+} SSS_CERTMAP_0.1;
diff --git a/src/lib/certmap/sss_certmap.h b/src/lib/certmap/sss_certmap.h
index 7da2d1c58..058d4f9e4 100644
--- a/src/lib/certmap/sss_certmap.h
+++ b/src/lib/certmap/sss_certmap.h
@@ -103,7 +103,7 @@ int sss_certmap_add_rule(struct sss_certmap_ctx *ctx,
*
* @param[in] ctx certmap context previously initialized with
* @ref sss_certmap_init
- * @param[in] der_cert binary blog with the DER encoded certificate
+ * @param[in] der_cert binary blob with the DER encoded certificate
* @param[in] der_size size of the certificate blob
*
* @return
@@ -119,10 +119,11 @@ int sss_certmap_match_cert(struct sss_certmap_ctx *ctx,
*
* @param[in] ctx certmap context previously initialized with
* @ref sss_certmap_init
- * @param[in] der_cert binary blog with the DER encoded certificate
+ * @param[in] der_cert binary blob with the DER encoded certificate
* @param[in] der_size size of the certificate blob
- * @param[out] filter LDAP filter string, caller should free the data by
- * calling sss_certmap_free_filter_and_domains
+ * @param[out] filter LDAP filter string, expanded templates are sanitized,
+ * caller should free the data by calling
+ * sss_certmap_free_filter_and_domains
* @param[out] domains NULL-terminated array of strings with the domains the
* rule applies, caller should free the data by calling
* sss_certmap_free_filter_and_domains
@@ -136,8 +137,32 @@ int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx,
const uint8_t *der_cert, size_t der_size,
char **filter, char ***domains);
+/**
+ * @brief Expand the mapping rule by replacing the templates
+ *
+ * @param[in] ctx certmap context previously initialized with
+ * @ref sss_certmap_init
+ * @param[in] der_cert binary blob with the DER encoded certificate
+ * @param[in] der_size size of the certificate blob
+ * @param[out] expanded expanded mapping rule, templates are filled in
+ * verbatim in contrast to sss_certmap_get_search_filter,
+ * caller should free the data by
+ * calling sss_certmap_free_filter_and_domains
+ * @param[out] domains NULL-terminated array of strings with the domains the
+ * rule applies, caller should free the data by calling
+ * sss_certmap_free_filter_and_domains
+ *
+ * @return
+ * - 0: certificate matches a rule
+ * - ENOENT: certificate does not match
+ * - EINVAL: internal error
+ */
+int sss_certmap_expand_mapping_rule(struct sss_certmap_ctx *ctx,
+ const uint8_t *der_cert, size_t der_size,
+ char **_expanded, char ***_domains);
/**
* @brief Free data returned by @ref sss_certmap_get_search_filter
+ * and @ref sss_certmap_expand_mapping_rule
*
* @param[in] filter LDAP filter strings returned by
* sss_certmap_get_search_filter
@@ -150,7 +175,7 @@ void sss_certmap_free_filter_and_domains(char *filter, char **domains);
* @brief Get a string with the content of the certificate used by the library
*
* @param[in] mem_ctx Talloc memory context, may be NULL
- * @param[in] der_cert binary blog with the DER encoded certificate
+ * @param[in] der_cert binary blob with the DER encoded certificate
* @param[in] der_size size of the certificate blob
* @param[out] desc Multiline string showing the certificate content
* which is used by libsss_certmap
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index 3f0afaeff..cdf239e07 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -1049,9 +1049,10 @@ static char *get_cert_prompt(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = sss_certmap_get_search_filter(ctx, der, der_size, &filter, &domains);
+ ret = sss_certmap_expand_mapping_rule(ctx, der, der_size,
+ &filter, &domains);
if (ret != 0) {
- DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_get_search_filter failed.\n");
+ DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_expand_mapping_rule failed.\n");
goto done;
}
diff --git a/src/tests/cmocka/test_certmap.c b/src/tests/cmocka/test_certmap.c
index c882202a0..232ff7878 100644
--- a/src/tests/cmocka/test_certmap.c
+++ b/src/tests/cmocka/test_certmap.c
@@ -1431,6 +1431,15 @@ static void test_sss_certmap_get_search_filter(void **state)
&filter, &domains);
assert_int_equal(ret, 0);
assert_non_null(filter);
+ assert_string_equal(filter, "rule100=<I>CN=Certificate\\20Authority,O=IPA.DEVEL"
+ "<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL");
+ assert_null(domains);
+
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
+ sizeof(test_cert_der),
+ &filter, &domains);
+ assert_int_equal(ret, 0);
+ assert_non_null(filter);
assert_string_equal(filter, "rule100=<I>CN=Certificate Authority,O=IPA.DEVEL"
"<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL");
assert_null(domains);
@@ -1445,6 +1454,17 @@ static void test_sss_certmap_get_search_filter(void **state)
&filter, &domains);
assert_int_equal(ret, 0);
assert_non_null(filter);
+ assert_string_equal(filter, "rule99=<I>CN=Certificate\\20Authority,O=IPA.DEVEL"
+ "<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL");
+ assert_non_null(domains);
+ assert_string_equal(domains[0], "test.dom");
+ assert_null(domains[1]);
+
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
+ sizeof(test_cert_der),
+ &filter, &domains);
+ assert_int_equal(ret, 0);
+ assert_non_null(filter);
assert_string_equal(filter, "rule99=<I>CN=Certificate Authority,O=IPA.DEVEL"
"<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL");
assert_non_null(domains);
@@ -1466,6 +1486,16 @@ static void test_sss_certmap_get_search_filter(void **state)
assert_string_equal(domains[0], "test.dom");
assert_null(domains[1]);
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
+ sizeof(test_cert_der),
+ &filter, &domains);
+ assert_int_equal(ret, 0);
+ assert_non_null(filter);
+ assert_string_equal(filter, "rule98=userCertificate;binary=" TEST_CERT_BIN);
+ assert_non_null(domains);
+ assert_string_equal(domains[0], "test.dom");
+ assert_null(domains[1]);
+
ret = sss_certmap_add_rule(ctx, 97,
"KRB5:<ISSUER>CN=Certificate Authority,O=IPA.DEVEL",
"LDAP:rule97=<I>{issuer_dn!nss_x500}<S>{subject_dn}",
@@ -1476,6 +1506,17 @@ static void test_sss_certmap_get_search_filter(void **state)
&filter, &domains);
assert_int_equal(ret, 0);
assert_non_null(filter);
+ assert_string_equal(filter, "rule97=<I>O=IPA.DEVEL,CN=Certificate\\20Authority"
+ "<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL");
+ assert_non_null(domains);
+ assert_string_equal(domains[0], "test.dom");
+ assert_null(domains[1]);
+
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
+ sizeof(test_cert_der),
+ &filter, &domains);
+ assert_int_equal(ret, 0);
+ assert_non_null(filter);
assert_string_equal(filter, "rule97=<I>O=IPA.DEVEL,CN=Certificate Authority"
"<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL");
assert_non_null(domains);
@@ -1492,6 +1533,17 @@ static void test_sss_certmap_get_search_filter(void **state)
&filter, &domains);
assert_int_equal(ret, 0);
assert_non_null(filter);
+ assert_string_equal(filter, "rule96=<I>O=IPA.DEVEL,CN=Certificate\\20Authority"
+ "<S>O=IPA.DEVEL,CN=ipa-devel.ipa.devel");
+ assert_non_null(domains);
+ assert_string_equal(domains[0], "test.dom");
+ assert_null(domains[1]);
+
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
+ sizeof(test_cert_der),
+ &filter, &domains);
+ assert_int_equal(ret, 0);
+ assert_non_null(filter);
assert_string_equal(filter, "rule96=<I>O=IPA.DEVEL,CN=Certificate Authority"
"<S>O=IPA.DEVEL,CN=ipa-devel.ipa.devel");
assert_non_null(domains);
@@ -1510,6 +1562,14 @@ static void test_sss_certmap_get_search_filter(void **state)
assert_string_equal(filter, "(userCertificate;binary=" TEST_CERT_BIN ")");
assert_null(domains);
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
+ sizeof(test_cert_der),
+ &filter, &domains);
+ assert_int_equal(ret, 0);
+ assert_non_null(filter);
+ assert_string_equal(filter, "(userCertificate;binary=" TEST_CERT_BIN ")");
+ assert_null(domains);
+
ret = sss_certmap_add_rule(ctx, 94,
"KRB5:<ISSUER>CN=Certificate Authority,O=IPA.DEVEL",
"LDAP:rule94=<I>{issuer_dn!ad_x500}<S>{subject_dn!ad_x500}",
@@ -1520,12 +1580,22 @@ static void test_sss_certmap_get_search_filter(void **state)
&filter, &domains);
assert_int_equal(ret, 0);
assert_non_null(filter);
- assert_string_equal(filter, "rule94=<I>O=IPA.DEVEL,CN=Certificate Authority"
+ assert_string_equal(filter, "rule94=<I>O=IPA.DEVEL,CN=Certificate\\20Authority"
"<S>O=IPA.DEVEL,CN=ipa-devel.ipa.devel");
assert_non_null(domains);
assert_string_equal(domains[0], "test.dom");
assert_null(domains[1]);
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
+ sizeof(test_cert_der),
+ &filter, &domains);
+ assert_int_equal(ret, 0);
+ assert_non_null(filter);
+ assert_string_equal(filter, "rule94=<I>O=IPA.DEVEL,CN=Certificate Authority"
+ "<S>O=IPA.DEVEL,CN=ipa-devel.ipa.devel");
+ assert_non_null(domains);
+ assert_string_equal(domains[0], "test.dom");
+ assert_null(domains[1]);
ret = sss_certmap_add_rule(ctx, 89, NULL,
"(rule89={subject_nt_principal})",
@@ -1539,6 +1609,14 @@ static void test_sss_certmap_get_search_filter(void **state)
assert_string_equal(filter, "(rule89=tu1@ad.devel)");
assert_null(domains);
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert2_der),
+ sizeof(test_cert2_der),
+ &filter, &domains);
+ assert_int_equal(ret, 0);
+ assert_non_null(filter);
+ assert_string_equal(filter, "(rule89=tu1@ad.devel)");
+ assert_null(domains);
+
ret = sss_certmap_add_rule(ctx, 88, NULL,
"(rule88={subject_nt_principal.short_name})",
NULL);
@@ -1560,6 +1638,15 @@ static void test_sss_certmap_get_search_filter(void **state)
&filter, &domains);
assert_int_equal(ret, 0);
assert_non_null(filter);
+ assert_string_equal(filter, "rule87=<I>DC=devel,DC=ad,CN=ad-AD-SERVER-CA"
+ "<S>DC=devel,DC=ad,CN=Users,CN=t\\20u,E=test.user@email.domain");
+ assert_null(domains);
+
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert2_der),
+ sizeof(test_cert2_der),
+ &filter, &domains);
+ assert_int_equal(ret, 0);
+ assert_non_null(filter);
assert_string_equal(filter, "rule87=<I>DC=devel,DC=ad,CN=ad-AD-SERVER-CA"
"<S>DC=devel,DC=ad,CN=Users,CN=t u,E=test.user@email.domain");
assert_null(domains);
@@ -1573,6 +1660,15 @@ static void test_sss_certmap_get_search_filter(void **state)
&filter, &domains);
assert_int_equal(ret, 0);
assert_non_null(filter);
+ assert_string_equal(filter, "rule86=<I>DC=devel,DC=ad,CN=ad-AD-SERVER-CA"
+ "<S>DC=devel,DC=ad,CN=Users,CN=t\\20u,E=test.user@email.domain");
+ assert_null(domains);
+
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert2_der),
+ sizeof(test_cert2_der),
+ &filter, &domains);
+ assert_int_equal(ret, 0);
+ assert_non_null(filter);
assert_string_equal(filter, "rule86=<I>DC=devel,DC=ad,CN=ad-AD-SERVER-CA"
"<S>DC=devel,DC=ad,CN=Users,CN=t u,E=test.user@email.domain");
assert_null(domains);
diff --git a/src/util/util.c b/src/util/util.c
index d9bd3cb59..19d447328 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -436,100 +436,6 @@ errno_t sss_hash_create(TALLOC_CTX *mem_ctx, unsigned long count,
return sss_hash_create_ex(mem_ctx, count, tbl, 0, 0, 0, 0, NULL, NULL);
}
-errno_t sss_filter_sanitize_ex(TALLOC_CTX *mem_ctx,
- const char *input,
- char **sanitized,
- const char *ignore)
-{
- char *output;
- size_t i = 0;
- size_t j = 0;
- char *allowed;
-
- /* Assume the worst-case. We'll resize it later, once */
- output = talloc_array(mem_ctx, char, strlen(input) * 3 + 1);
- if (!output) {
- return ENOMEM;
- }
-
- while (input[i]) {
- /* Even though this character might have a special meaning, if it's
- * explicitly allowed, just copy it and move on
- */
- if (ignore == NULL) {
- allowed = NULL;
- } else {
- allowed = strchr(ignore, input[i]);
- }
- if (allowed) {
- output[j++] = input[i++];
- continue;
- }
-
- switch(input[i]) {
- case '\t':
- output[j++] = '\\';
- output[j++] = '0';
- output[j++] = '9';
- break;
- case ' ':
- output[j++] = '\\';
- output[j++] = '2';
- output[j++] = '0';
- break;
- case '*':
- output[j++] = '\\';
- output[j++] = '2';
- output[j++] = 'a';
- break;
- case '(':
- output[j++] = '\\';
- output[j++] = '2';
- output[j++] = '8';
- break;
- case ')':
- output[j++] = '\\';
- output[j++] = '2';
- output[j++] = '9';
- break;
- case '\\':
- output[j++] = '\\';
- output[j++] = '5';
- output[j++] = 'c';
- break;
- case '\r':
- output[j++] = '\\';
- output[j++] = '0';
- output[j++] = 'd';
- break;
- case '\n':
- output[j++] = '\\';
- output[j++] = '0';
- output[j++] = 'a';
- break;
- default:
- output[j++] = input[i];
- }
-
- i++;
- }
- output[j] = '\0';
- *sanitized = talloc_realloc(mem_ctx, output, char, j+1);
- if (!*sanitized) {
- talloc_free(output);
- return ENOMEM;
- }
-
- return EOK;
-}
-
-errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx,
- const char *input,
- char **sanitized)
-{
- return sss_filter_sanitize_ex(mem_ctx, input, sanitized, NULL);
-}
-
char *
sss_escape_ip_address(TALLOC_CTX *mem_ctx, int family, const char *addr)
{
diff --git a/src/util/util_ext.c b/src/util/util_ext.c
index 04dc02a8a..a89b60f76 100644
--- a/src/util/util_ext.c
+++ b/src/util/util_ext.c
@@ -29,6 +29,11 @@
#define EOK 0
+#ifndef HAVE_ERRNO_T
+#define HAVE_ERRNO_T
+typedef int errno_t;
+#endif
+
int split_on_separator(TALLOC_CTX *mem_ctx, const char *str,
const char sep, bool trim, bool skip_empty,
char ***_list, int *size)
@@ -141,3 +146,97 @@ bool string_in_list(const char *string, char **list, bool case_sensitive)
return false;
}
+
+errno_t sss_filter_sanitize_ex(TALLOC_CTX *mem_ctx,
+ const char *input,
+ char **sanitized,
+ const char *ignore)
+{
+ char *output;
+ size_t i = 0;
+ size_t j = 0;
+ char *allowed;
+
+ /* Assume the worst-case. We'll resize it later, once */
+ output = talloc_array(mem_ctx, char, strlen(input) * 3 + 1);
+ if (!output) {
+ return ENOMEM;
+ }
+
+ while (input[i]) {
+ /* Even though this character might have a special meaning, if it's
+ * explicitly allowed, just copy it and move on
+ */
+ if (ignore == NULL) {
+ allowed = NULL;
+ } else {
+ allowed = strchr(ignore, input[i]);
+ }
+ if (allowed) {
+ output[j++] = input[i++];
+ continue;
+ }
+
+ switch(input[i]) {
+ case '\t':
+ output[j++] = '\\';
+ output[j++] = '0';
+ output[j++] = '9';
+ break;
+ case ' ':
+ output[j++] = '\\';
+ output[j++] = '2';
+ output[j++] = '0';
+ break;
+ case '*':
+ output[j++] = '\\';
+ output[j++] = '2';
+ output[j++] = 'a';
+ break;
+ case '(':
+ output[j++] = '\\';
+ output[j++] = '2';
+ output[j++] = '8';
+ break;
+ case ')':
+ output[j++] = '\\';
+ output[j++] = '2';
+ output[j++] = '9';
+ break;
+ case '\\':
+ output[j++] = '\\';
+ output[j++] = '5';
+ output[j++] = 'c';
+ break;
+ case '\r':
+ output[j++] = '\\';
+ output[j++] = '0';
+ output[j++] = 'd';
+ break;
+ case '\n':
+ output[j++] = '\\';
+ output[j++] = '0';
+ output[j++] = 'a';
+ break;
+ default:
+ output[j++] = input[i];
+ }
+
+ i++;
+ }
+ output[j] = '\0';
+ *sanitized = talloc_realloc(mem_ctx, output, char, j+1);
+ if (!*sanitized) {
+ talloc_free(output);
+ return ENOMEM;
+ }
+
+ return EOK;
+}
+
+errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx,
+ const char *input,
+ char **sanitized)
+{
+ return sss_filter_sanitize_ex(mem_ctx, input, sanitized, NULL);
+}
--
2.21.3

View File

@ -0,0 +1,42 @@
From a06bf788585f5fc14ba16d132665401a7ce7eb35 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Po=C5=82awski?= <ppolawsk@redhat.com>
Date: Thu, 28 May 2020 12:12:58 +0200
Subject: [PATCH] AD: Enforcing GPO rule restriction on user
This fixes bug related to ad_gpo_implicit_deny option set to True.
gpo_implict_denay was checked only for dacl_filtered_gpos,
but not for cse_filtered_gpos.
Resolves:
https://github.com/SSSD/sssd/issues/5181
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/providers/ad/ad_gpo.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index 53560a754..2c6aa7fa6 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -2541,7 +2541,16 @@ ad_gpo_process_gpo_done(struct tevent_req *subreq)
/* no gpos contain "SecuritySettings" cse_guid, nothing to enforce */
DEBUG(SSSDBG_TRACE_FUNC,
"no applicable gpos found after cse_guid filtering\n");
- ret = EOK;
+
+ if (state->gpo_implicit_deny == true) {
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "No applicable GPOs have been found and ad_gpo_implicit_deny"
+ " is set to 'true'. The user will be denied access.\n");
+ ret = ERR_ACCESS_DENIED;
+ } else {
+ ret = EOK;
+ }
+
goto done;
}
--
2.21.3

View File

@ -0,0 +1,33 @@
From 3bb910503bb7cbc20105f0a302db400f04436d2a Mon Sep 17 00:00:00 2001
From: ikerexxe <ipedrosa@redhat.com>
Date: Tue, 18 Aug 2020 11:45:18 +0200
Subject: [PATCH] man: clarify AD certificate rule
Clarify AD specific certificate rule example by changing userPrincipal to
userPrincipalName. Moreover, match the subject principal name in the
example with the rule name.
Resolves:
https://github.com/SSSD/sssd/issues/5278
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/man/sss-certmap.5.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/man/sss-certmap.5.xml b/src/man/sss-certmap.5.xml
index 10343625e..09aec997c 100644
--- a/src/man/sss-certmap.5.xml
+++ b/src/man/sss-certmap.5.xml
@@ -487,7 +487,7 @@
sign.
</para>
<para>
- Example: (|(userPrincipal={subject_principal})(samAccountName={subject_principal.short_name}))
+ Example: (|(userPrincipalName={subject_nt_principal})(samAccountName={subject_nt_principal.short_name}))
</para>
</listitem>
</varlistentry>
--
2.21.3

View File

@ -0,0 +1,72 @@
From 4526858adb58736066a0b2cf2dc793ddfe671b2b Mon Sep 17 00:00:00 2001
From: ikerexxe <ipedrosa@redhat.com>
Date: Tue, 4 Aug 2020 15:39:51 +0200
Subject: [PATCH] config: allow prompting options in configuration
False warnings were logged after enabling prompting options in
configuration file. This change modifies the configuration rules to
allow prompting options.
Resolves:
https://github.com/SSSD/sssd/issues/5259
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/config/cfg_rules.ini | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index 2874ea048..2d4e7b51d 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -14,6 +14,10 @@ section = session_recording
section_re = ^secrets/users/[0-9]\+$
section_re = ^secrets/secrets$
section_re = ^secrets/kcm$
+section_re = ^prompting/password$
+section_re = ^prompting/password/[^/\@]\+$
+section_re = ^prompting/2fa$
+section_re = ^prompting/2fa/[^/\@]\+$
section_re = ^domain/[^/\@]\+$
section_re = ^domain/[^/\@]\+/[^/\@]\+$
section_re = ^application/[^/\@]\+$
@@ -332,6 +336,36 @@ option = scope
option = users
option = groups
+# Prompting during authentication
+[rule/allowed_prompting_password_options]
+validator = ini_allowed_options
+section_re = ^prompting/password$
+
+option = password_prompt
+
+[rule/allowed_prompting_2fa_options]
+validator = ini_allowed_options
+section_re = ^prompting/2fa$
+
+option = single_prompt
+option = first_prompt
+option = second_prompt
+
+[rule/allowed_prompting_password_subsec_options]
+validator = ini_allowed_options
+section_re = ^prompting/password/[^/\@]\+$
+
+option = password_prompt
+
+[rule/allowed_prompting_2fa_subsec_options]
+validator = ini_allowed_options
+section_re = ^prompting/2fa/[^/\@]\+$
+
+option = single_prompt
+option = first_prompt
+option = second_prompt
+
+
[rule/allowed_domain_options]
validator = ini_allowed_options
section_re = ^\(domain\|application\)/[^/]\+$
--
2.21.3

View File

@ -0,0 +1,77 @@
From 10366b4ee8c01ea20d908102e92d52fdeda168c3 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <atikhono@redhat.com>
Date: Tue, 18 Aug 2020 14:37:04 +0200
Subject: [PATCH] p11_child: switch default ocsp_dgst to sha1
For details please see discussion at
https://github.com/SSSD/sssd/pull/837#issuecomment-672831519
:newdefault: sssd:certificate_verification:ocsp_dgst, sha256, sha1
Resolves:
https://github.com/SSSD/sssd/issues/5002
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/man/sssd.conf.5.xml | 3 ++-
src/p11_child/p11_child_common_utils.c | 6 +++---
src/p11_child/p11_child_openssl.c | 4 ++--
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 874a09c49..50692dfdd 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -507,7 +507,8 @@
<listitem><para>sha512</para></listitem>
</itemizedlist></para>
<para>
- Default: sha256
+ Default: sha1 (to allow compatibility with
+ RFC5019-compliant responder)
</para>
<para>(NSS Version) This option is
ignored, because NSS uses sha1
diff --git a/src/p11_child/p11_child_common_utils.c b/src/p11_child/p11_child_common_utils.c
index 6798752c7..95791b1f0 100644
--- a/src/p11_child/p11_child_common_utils.c
+++ b/src/p11_child/p11_child_common_utils.c
@@ -43,7 +43,7 @@ static struct cert_verify_opts *init_cert_verify_opts(TALLOC_CTX *mem_ctx)
cert_verify_opts->ocsp_default_responder = NULL;
cert_verify_opts->ocsp_default_responder_signing_cert = NULL;
cert_verify_opts->crl_file = NULL;
- cert_verify_opts->ocsp_dgst = CKM_SHA256;
+ cert_verify_opts->ocsp_dgst = CKM_SHA_1;
cert_verify_opts->soft_ocsp = false;
cert_verify_opts->soft_crl = false;
@@ -174,8 +174,8 @@ errno_t parse_cert_verify_opts(TALLOC_CTX *mem_ctx, const char *verify_opts,
} else {
DEBUG(SSSDBG_CRIT_FAILURE,
"Unsupported digest for OCSP [%s], "
- "using default sha256.\n", &opts[c][OCSP_DGST_LEN]);
- cert_verify_opts->ocsp_dgst = CKM_SHA256;
+ "using default sha1.\n", &opts[c][OCSP_DGST_LEN]);
+ cert_verify_opts->ocsp_dgst = CKM_SHA_1;
}
#endif
} else if (strcasecmp(opts[c], "soft_ocsp") == 0) {
diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c
index 321cf162e..04b3e1467 100644
--- a/src/p11_child/p11_child_openssl.c
+++ b/src/p11_child/p11_child_openssl.c
@@ -372,8 +372,8 @@ static errno_t do_ocsp(struct p11_ctx *p11_ctx, X509 *cert)
ocsp_dgst = get_dgst(p11_ctx->cert_verify_opts->ocsp_dgst);
if (ocsp_dgst == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot determine configured digest function "
- "for OCSP, using default sha256.\n");
- ocsp_dgst = EVP_sha256();
+ "for OCSP, using default sha1.\n");
+ ocsp_dgst = EVP_sha1();
}
cid = OCSP_cert_to_id(ocsp_dgst, cert, issuer);
if (cid == NULL) {
--
2.21.3

View File

@ -0,0 +1,181 @@
From 69e1f5fe79806a530e90c8af09bedd3b9e6b4dac Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 10 Jul 2020 15:30:29 +0200
Subject: [PATCH] GPO: respect ad_gpo_implicit_deny when evaluation rules
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Currently if setting ad_gpo_implicit_deny to 'True' is rejected access
if no GPOs applied to the host since in this case there are obvious not
allow rules available.
But according to the man page we have to be more strict "When this
option is set to True users will be allowed access only when explicitly
allowed by a GPO rule". So if GPOs apply and no allow rules are present
we have to reject access as well.
Resolves: https://github.com/SSSD/sssd/issues/5061
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/man/sssd-ad.5.xml | 59 +++++++++++++++++++++++++++++++++++++++
src/providers/ad/ad_gpo.c | 13 +++++++--
2 files changed, 69 insertions(+), 3 deletions(-)
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index 5c2f46546..fbd4985d7 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -477,9 +477,68 @@ DOM:dom1:(memberOf:1.2.840.113556.1.4.1941:=cn=nestedgroup,ou=groups,dc=example,
built-in Administrators group if no GPO rules
apply to them.
</para>
+
<para>
Default: False
</para>
+
+ <para>
+ The following 2 tables should illustrate when a user
+ is allowed or rejected based on the allow and deny
+ login rights defined on the server-side and the
+ setting of ad_gpo_implicit_deny.
+ </para>
+ <informaltable frame='all'>
+ <tgroup cols='3'>
+ <colspec colname='c1' align='center'/>
+ <colspec colname='c2' align='center'/>
+ <colspec colname='c3' align='center'/>
+ <thead>
+ <row><entry namest='c1' nameend='c3' align='center'>
+ ad_gpo_implicit_deny = False (default)</entry></row>
+ <row><entry>allow-rules</entry><entry>deny-rules</entry>
+ <entry>results</entry></row>
+ </thead>
+ <tbody>
+ <row><entry>missing</entry><entry>missing</entry>
+ <entry><para>all users are allowed</para>
+ </entry></row>
+ <row><entry>missing</entry><entry>present</entry>
+ <entry><para>only users not in deny-rules are
+ allowed</para></entry></row>
+ <row><entry>present</entry><entry>missing</entry>
+ <entry><para>only users in allow-rules are
+ allowed</para></entry></row>
+ <row><entry>present</entry><entry>present</entry>
+ <entry><para>only users in allow-rules and not in
+ deny-rules are allowed</para></entry></row>
+ </tbody></tgroup></informaltable>
+
+ <informaltable frame='all'>
+ <tgroup cols='3'>
+ <colspec colname='c1' align='center'/>
+ <colspec colname='c2' align='center'/>
+ <colspec colname='c3' align='center'/>
+ <thead>
+ <row><entry namest='c1' nameend='c3' align='center'>
+ ad_gpo_implicit_deny = True</entry></row>
+ <row><entry>allow-rules</entry><entry>deny-rules</entry>
+ <entry>results</entry></row>
+ </thead>
+ <tbody>
+ <row><entry>missing</entry><entry>missing</entry>
+ <entry><para>no users are allowed</para>
+ </entry></row>
+ <row><entry>missing</entry><entry>present</entry>
+ <entry><para>no users are allowed</para>
+ </entry></row>
+ <row><entry>present</entry><entry>missing</entry>
+ <entry><para>only users in allow-rules are
+ allowed</para></entry></row>
+ <row><entry>present</entry><entry>present</entry>
+ <entry><para>only users in allow-rules and not in
+ deny-rules are allowed</para></entry></row>
+ </tbody></tgroup></informaltable>
</listitem>
</varlistentry>
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index 2c6aa7fa6..0cf5da2a1 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -1531,6 +1531,7 @@ ad_gpo_access_check(TALLOC_CTX *mem_ctx,
enum gpo_access_control_mode gpo_mode,
enum gpo_map_type gpo_map_type,
const char *user,
+ bool gpo_implicit_deny,
struct sss_domain_info *domain,
char **allowed_sids,
int allowed_size,
@@ -1575,7 +1576,7 @@ ad_gpo_access_check(TALLOC_CTX *mem_ctx,
group_sids[j]);
}
- if (allowed_size == 0) {
+ if (allowed_size == 0 && !gpo_implicit_deny) {
access_granted = true;
} else {
access_granted = check_rights(allowed_sids, allowed_size, user_sid,
@@ -1694,6 +1695,7 @@ ad_gpo_perform_hbac_processing(TALLOC_CTX *mem_ctx,
enum gpo_access_control_mode gpo_mode,
enum gpo_map_type gpo_map_type,
const char *user,
+ bool gpo_implicit_deny,
struct sss_domain_info *user_domain,
struct sss_domain_info *host_domain)
{
@@ -1732,8 +1734,8 @@ ad_gpo_perform_hbac_processing(TALLOC_CTX *mem_ctx,
/* perform access check with the final resultant allow_sids and deny_sids */
ret = ad_gpo_access_check(mem_ctx, gpo_mode, gpo_map_type, user,
- user_domain, allow_sids, allow_size, deny_sids,
- deny_size);
+ gpo_implicit_deny, user_domain,
+ allow_sids, allow_size, deny_sids, deny_size);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
@@ -1918,6 +1920,7 @@ immediately:
static errno_t
process_offline_gpos(TALLOC_CTX *mem_ctx,
const char *user,
+ bool gpo_implicit_deny,
enum gpo_access_control_mode gpo_mode,
struct sss_domain_info *user_domain,
struct sss_domain_info *host_domain,
@@ -1930,6 +1933,7 @@ process_offline_gpos(TALLOC_CTX *mem_ctx,
gpo_mode,
gpo_map_type,
user,
+ gpo_implicit_deny,
user_domain,
host_domain);
if (ret != EOK) {
@@ -1976,6 +1980,7 @@ ad_gpo_connect_done(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_FUNC, "Preparing for offline operation.\n");
ret = process_offline_gpos(state,
state->user,
+ state->gpo_implicit_deny,
state->gpo_mode,
state->user_domain,
state->host_domain,
@@ -2102,6 +2107,7 @@ ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_FUNC, "Preparing for offline operation.\n");
ret = process_offline_gpos(state,
state->user,
+ state->gpo_implicit_deny,
state->gpo_mode,
state->user_domain,
state->host_domain,
@@ -2766,6 +2772,7 @@ ad_gpo_cse_done(struct tevent_req *subreq)
state->gpo_mode,
state->gpo_map_type,
state->user,
+ state->gpo_implicit_deny,
state->user_domain,
state->host_domain);
if (ret != EOK) {
--
2.21.3

View File

@ -8,12 +8,14 @@
%global install_pcscd_polkit_rule 1
%global samba_package_version %(rpm -q samba-devel --queryformat %{version}-%{release})
# Determine the location of the LDB modules directory
%global ldb_modulesdir %(pkg-config --variable=modulesdir ldb)
%global ldb_version 1.2.0
%global enable_systemtap 1
%global enable_systemtap_opt --enable-systemtap
%global enable_systemtap_opt --enable-systemtap
%global libwbc_alternatives_version 0.14
%global libwbc_lib_version %{libwbc_alternatives_version}.0
@ -23,8 +25,8 @@
%endif
Name: sssd
Version: 2.2.3
Release: 20%{?dist}
Version: 2.3.0
Release: 9%{?dist}
Group: Applications/System
Summary: System Security Services Daemon
License: GPLv3+
@ -32,36 +34,50 @@ URL: https://pagure.io/SSSD/sssd/
Source0: https://releases.pagure.org/SSSD/sssd/%{name}-%{version}.tar.gz
### Patches ###
Patch0001: 0001-INI-sssctl-config-check-command-error-messages.patch
Patch0002: 0002-certmap-mention-special-regex-characters-in-man-page.patch
Patch0003: 0003-ldap_child-do-not-try-PKINIT.patch
Patch0004: 0004-util-watchdog-fixed-watchdog-implementation.patch
Patch0005: 0005-providers-krb5-got-rid-of-unused-code.patch
Patch0006: 0006-data_provider_be-got-rid-of-duplicating-SIGTERM-hand.patch
Patch0007: 0007-util-server-improved-debug-at-shutdown.patch
Patch0008: 0008-util-sss_ptr_hash-fixed-double-free-in-sss_ptr_hash_.patch
Patch0009: 0009-sdap-Add-randomness-to-ldap-connection-timeout.patch
Patch0010: 0010-ad-allow-booleans-for-ad_inherit_opts_if_needed.patch
Patch0011: 0011-ad-add-ad_use_ldaps.patch
Patch0012: 0012-ldap-add-new-option-ldap_sasl_maxssf.patch
Patch0013: 0013-ad-set-min-and-max-ssf-for-ldaps.patch
Patch0014: 0014-BE_REFRESH-Do-not-try-to-refresh-domains-from-other-.patch
Patch0015: 0015-sysdb_sudo-Enable-LDAP-time-format-compatibility.patch
Patch0016: 0016-zanata-Pulled-new-translations.patch
Patch0017: 0017-sbus_server-stylistic-rename.patch
Patch0018: 0018-sss_ptr_hash-don-t-keep-empty-sss_ptr_hash_delete_da.patch
Patch0019: 0019-sss_ptr_hash-sss_ptr_hash_delete-fix-optimization.patch
Patch0020: 0020-sss_ptr_hash-removed-redundant-check.patch
Patch0021: 0021-sss_ptr_hash-fixed-memory-leak.patch
Patch0022: 0022-sss_ptr_hash-internal-refactoring.patch
Patch0023: 0023-TESTS-added-sss_ptr_hash-unit-test.patch
Patch0024: 0024-p11_child-check-if-card-is-present-in-wait_for_card.patch
Patch0025: 0025-PAM-client-only-require-UID-0-for-private-socket.patch
Patch0026: 0026-ssh-do-not-mix-different-certificate-lists.patch
Patch0027: 0027-ssh-add-no_rules-and-all_rules-to-ssh_use_certificat.patch
Patch0028: 0028-Add-TCP-level-timeout-to-LDAP-services.patch
Patch0029: 0029-sss_sockets-pass-pointer-instead-of-integer.patch
Patch0030: 0030-ssh-fix-matching-rules-default.patch
Patch0001: 0001-ad_gpo_ndr.c-more-ndr-updates.patch
Patch0002: 0002-test-avoid-endian-issues-in-network-tests.patch
Patch0003: 0003-sssctl-sssctl-config-check-alternative-config-file.patch
Patch0004: 0004-DEBUG-only-open-child-process-log-files-when-require.patch
Patch0005: 0005-DEBUG-use-new-exec_child-_ex-interface-in-tests.patch
Patch0006: 0006-NEGCACHE-skip-permanent-entries-in-users-groups-rese.patch
Patch0007: 0007-util-inotify-fixed-CLANG_WARNING.patch
Patch0008: 0008-util-inotify-fixed-bug-in-inotify-event-processing.patch
Patch0009: 0009-Replaced-enter-with-insert.patch
Patch0010: 0010-NSS-client-preserve-errno-during-_nss_sss_end-calls.patch
Patch0011: 0011-ipa-add-failover-to-subdomain-override-lookups.patch
Patch0012: 0012-GPO-fix-link-order-in-a-SOM.patch
Patch0013: 0013-sysdb-make-sysdb_update_subdomains-more-robust.patch
Patch0014: 0014-ad-rename-ad_master_domain_-to-ad_domain_info_.patch
Patch0015: 0015-sysdb-make-new_subdomain-public.patch
Patch0016: 0016-ad-rename-ads_get_root_id_ctx-to-ads_get_dom_id_ctx.patch
Patch0017: 0017-ad-remove-unused-trust_type-from-ad_subdom_store.patch
Patch0018: 0018-ad-add-ad_check_domain_-send-recv.patch
Patch0019: 0019-ad-check-forest-root-directly-if-not-present-on-loca.patch
Patch0020: 0020-man-Document-invalid-selinux-context-for-homedirs.patch
Patch0021: 0021-pam_sss-add-SERVICE_IS_GDM_SMARTCARD.patch
Patch0022: 0022-pam_sss-special-handling-for-gdm-smartcard.patch
Patch0023: 0023-pam_sss-make-sure-old-certificate-data-is-removed-be.patch
Patch0024: 0024-systemtap-Missing-a-comma.patch
Patch0025: 0025-proxy-use-x-as-default-pwfield-only-for-sssd-shadowu.patch
Patch0026: 0026-files-allow-root-membership.patch
Patch0027: 0027-PAM-do-not-treat-error-for-cache-only-lookups-as-fat.patch
Patch0028: 0028-mem-cache-sizes-of-free-and-data-tables-were-made-co.patch
Patch0029: 0029-NSS-make-memcache-size-configurable.patch
Patch0030: 0030-NSS-avoid-excessive-log-messages.patch
Patch0031: 0031-NSS-enhanced-debug-during-mem-cache-initialization.patch
Patch0032: 0032-mem-cache-added-log-message-in-case-cache-is-full.patch
Patch0033: 0033-NSS-make-memcache-size-configurable-in-megabytes.patch
Patch0034: 0034-mem-cache-comment-added.patch
Patch0035: 0035-mem-cache-always-cleanup-old-content.patch
Patch0036: 0036-TRANSLATIONS-updated-translations-to-include-new-sou.patch
Patch0037: 0037-Updated-translation-files-Japanese-Chinese-China-Fre.patch
Patch0038: 0038-sssctl-sssctl-config-check-alternative-snippet-dir.patch
Patch0039: 0039-certmap-sanitize-LDAP-search-filter.patch
Patch0040: 0040-AD-Enforcing-GPO-rule-restriction-on-user.patch
Patch0041: 0041-man-clarify-AD-certificate-rule.patch
Patch0042: 0042-config-allow-prompting-options-in-configuration.patch
Patch0043: 0043-p11_child-switch-default-ocsp_dgst-to-sha1.patch
Patch0044: 0044-GPO-respect-ad_gpo_implicit_deny-when-evaluation-rul.patch
### Downstream Patches ###
@ -146,7 +162,7 @@ BuildRequires: systemd-devel
BuildRequires: systemd
BuildRequires: cifs-utils-devel
BuildRequires: libnfsidmap-devel
BuildRequires: samba4-devel
BuildRequires: samba-devel
BuildRequires: libsmbclient-devel
BuildRequires: samba-winbind
BuildRequires: systemtap-sdt-devel
@ -202,6 +218,8 @@ sub-packages such as sssd-ldap.
Summary: SSSD Client libraries for NSS and PAM
Group: Applications/System
License: LGPLv3+
Requires: libsss_nss_idmap = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
Requires(post): /usr/sbin/alternatives
@ -236,6 +254,7 @@ Summary: Userspace tools for use with the SSSD
Group: Applications/System
License: GPLv3+
Requires: sssd-common = %{version}-%{release}
Requires: libsss_simpleifp = %{version}-%{release}
# required by sss_obfuscate
Requires: python3-sss = %{version}-%{release}
Requires: python3-sssdconfig = %{version}-%{release}
@ -292,6 +311,7 @@ License: GPLv3+
Conflicts: sssd < 1.10.0-8.beta2
Requires: sssd-common = %{version}-%{release}
Requires: sssd-krb5-common = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
%description ldap
Provides the LDAP back end that the SSSD can utilize to fetch identity data
@ -327,6 +347,7 @@ Summary: Common files needed for supporting PAC processing
Group: Applications/System
License: GPLv3+
Requires: sssd-common = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
%description common-pac
Provides common files needed by SSSD providers such as IPA and Active Directory
@ -337,11 +358,13 @@ Summary: The IPA back end of the SSSD
Group: Applications/System
License: GPLv3+
Conflicts: sssd < 1.10.0-8.beta2
Requires: samba-client-libs >= %{samba_package_version}
Requires: sssd-common = %{version}-%{release}
Requires: sssd-krb5-common = %{version}-%{release}
Requires: libipa_hbac%{?_isa} = %{version}-%{release}
Recommends: bind-utils
Requires: sssd-common-pac = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
Requires(pre): shadow-utils
%description ipa
@ -353,9 +376,11 @@ Summary: The AD back end of the SSSD
Group: Applications/System
License: GPLv3+
Conflicts: sssd < 1.10.0-8.beta2
Requires: samba-client-libs >= %{samba_package_version}
Requires: sssd-common = %{version}-%{release}
Requires: sssd-krb5-common = %{version}-%{release}
Requires: sssd-common-pac = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
Recommends: bind-utils
Recommends: adcli
Suggests: sssd-libwbclient = %{version}-%{release}
@ -505,6 +530,7 @@ Provides library that simplifies D-Bus API for the SSSD InfoPipe responder.
Summary: The SSSD libwbclient implementation
Group: Applications/System
License: GPLv3+ and LGPLv3+
Requires: libsss_nss_idmap = %{version}-%{release}
Conflicts: libwbclient < 4.2.0-0.2.rc2
Conflicts: sssd-common < %{version}-%{release}
@ -526,6 +552,8 @@ Summary: SSSD's idmap_sss Backend for Winbind
Group: Applications/System
License: GPLv3+ and LGPLv3+
Conflicts: sssd-common < %{version}-%{release}
Requires: libsss_nss_idmap = %{version}-%{release}
Requires: libsss_idmap = %{version}-%{release}
%description winbind-idmap
The idmap_sss module provides a way for Winbind to call SSSD to map UIDs/GIDs
@ -627,6 +655,7 @@ autoreconf -ivf
make %{?_smp_mflags} all docs
make -C po ja.gmo
make -C po fr.gmo
make -C po zh_CN.po
%check
export CK_TIMEOUT_MULTIPLIER=10
@ -848,8 +877,6 @@ done
%{_libdir}/%{name}/conf/sssd.conf
%{_datadir}/sssd/cfg_rules.ini
%{_datadir}/sssd/sssd.api.conf
%{_datadir}/sssd/sssd.api.d
%{_mandir}/man1/sss_ssh_authorizedkeys.1*
%{_mandir}/man1/sss_ssh_knownhostsproxy.1*
%{_mandir}/man5/sssd.conf.5*
@ -991,6 +1018,9 @@ done
%{python3_sitelib}/SSSDConfig/*.py*
%dir %{python3_sitelib}/SSSDConfig/__pycache__
%{python3_sitelib}/SSSDConfig/__pycache__/*.py*
%dir %{_datadir}/sssd
%{_datadir}/sssd/sssd.api.conf
%{_datadir}/sssd/sssd.api.d
%files -n python3-sss
%defattr(-,root,root,-)
@ -1220,6 +1250,58 @@ fi
%{_libdir}/%{name}/modules/libwbclient.so
%changelog
* Mon Sep 14 2020 Alexey Tikhonov <atikhono@redhat.com> - 2.3.0-9
- Resolves: rhbz#1855323 - When ad_gpo_implicit_deny is True, it is permitting users to login when no gpo is applied
* Fri Aug 21 2020 Alexey Tikhonov <atikhono@redhat.com> - 2.3.0-8
- Resolves: rhbz#1868387 - system not enforcing GPO rule restriction. ad_gpo_implicit_deny = True is not working
- Resolves: rhbz#1854951 - sss-certmap man page change to add clarification for userPrincipalName attribute from AD schema
- Resolves: rhbz#1856861 - False errors/warnings are logged in sssd.log file after enabling 2FA prompting settings in sssd.conf
- Resolves: rhbz#1869683 - p11_child: default value of ocsp_dgst == sha256 doesn't conform RFC5019 and has to be changed to sha1
* Fri Aug 07 2020 Alexey Tikhonov <atikhono@redhat.com> - 2.3.0-7
- Resolves: rhbz#1723273 - RFE: Add option to specify alternate sssd config file location with "sssctl config-check" command.
- Resolves: rhbz#1780404 - smartcards: special characters must be escaped when building search filter
* Fri Jul 24 2020 Alexey Tikhonov <atikhono@redhat.com> - 2.3.0-6
- Resolves: rhbz#1820574 - [sssd] RHEL 8.3 Tier 0 Localization
* Mon Jul 20 2020 Alexey Tikhonov <atikhono@redhat.com> - 2.3.0-5
- Resolves: rhbz#1821719 - sssd (sssd_be) is consuming 100% CPU, partially due to failing mem-cache
- Fixed "requires/provides" rpmdiff warning
* Thu Jul 02 2020 Alexey Tikhonov <atikhono@redhat.com> - 2.3.0-4
- Resolves: rhbz#1815584 - id_provider = proxy proxy_lib_name = files returns * in password field, breaking PAM authentication
- Resolves: rhbz#1794607 - SSSD must be able to resolve membership involving root with files provider
- Resolves: rhbz#1803134 - Improve "unlock" time when user session already active
* Fri Jun 26 2020 Alexey Tikhonov <atikhono@redhat.com> - 2.3.0-3
- Resolves: rhbz#1829470 - `sssd.api.conf` and `sssd.api.d` should belong to `python-sssdconfig` package
- Resolves: rhbz#1544457 - sssd fails to release file descriptor on child logs after receiving HUP
- Resolves: rhbz#1824323 - SSSD user filtering is failing on RHEL 8 after "files" provider rebuilds cache
- Resolves: rhbz#1827432 - When the passwd or group files are replaced, sssd stops monitoring the file for
inotify events, and no updates are triggered
- Resolves: rhbz#1835710 - Change the message "Please enter smart card" to "Please insert smart card"
on GDM login with smart-card
- Resolves: rhbz#1838037 - Oddjob-mkhomedir fails when using NSS compat
- Resolves: rhbz#1845904 - gdm smart card authentication does not work shortly after disconnecting from network.
- Resolves: rhbz#1845975 - sssd doesn't follow the link order of AD Group Policy Management
- Resolves: rhbz#1845980 - sssd is failing to discover other subdomains in the forest
if LDAP entries do not contain AD forest root information
- Resolves: rhbz#1845987 - Document how to prevent invalid selinux context for default home directories
in SSSD-AD direct integration.
- Resolves: rhbz#1845994 - GDM failure loop when no user mapped for smart card
- Resolves: rhbz#1846003 - GDM password prompt when cert mapped to multiple users and promptusername is False
- Resolves: rhbz#1850961 - /usr/share/systemtap/tapset/sssd_functions.stp missing a comma
* Thu Jun 11 2020 Alexey Tikhonov <atikhono@redhat.com> - 2.3.0-2
- Resolves: rhbz#Bug 1723273 - RFE: Add option to specify alternate sssd config file location with "sssctl config-check" command.
* Mon Jun 08 2020 Alexey Tikhonov <atikhono@redhat.com> - 2.3.0-1
- Resolves: rhbz#1839037 - Rebase SSSD for RHEL 8.3
- Resolves: rhbz#1843872 - sssd 2.3.0 breaks AD auth due to GPO parsing failure
- Resolves: rhbz#1834156 - sssd or sssd-ad not updating their dependencies on "yum update" which breaks working
* Mon Mar 16 2020 Alexey Tikhonov <atikhono@redhat.com> - 2.2.3-19
- Resolves: rhbz#1580506 - [RFE]: sssd to be able to read smartcard
certificate EKU and perform an action based