import sssd-2.2.3-20.el8

This commit is contained in:
CentOS Sources 2020-04-28 05:34:45 -04:00 committed by Andrew Lukoshko
commit 20a068d984
34 changed files with 71915 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/sssd-2.2.3.tar.gz

1
.sssd.metadata Normal file
View File

@ -0,0 +1 @@
c2b457f85586750f5b22bfedd4cbca5b6f8fdb88 SOURCES/sssd-2.2.3.tar.gz

View File

@ -0,0 +1,35 @@
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,42 @@
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,98 @@
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,52 @@
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,56 @@
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,84 @@
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,32 @@
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,52 @@
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,195 @@
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,55 @@
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

@ -0,0 +1,438 @@
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,199 @@
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

@ -0,0 +1,91 @@
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,36 @@
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,52 @@
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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
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,91 @@
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,62 @@
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,35 @@
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,53 @@
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,366 @@
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

@ -0,0 +1,266 @@
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,86 @@
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,37 @@
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,209 @@
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,314 @@
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

@ -0,0 +1,50 @@
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,46 @@
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,235 @@
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,26 @@
From 8d38a4b28ab7af15406b244910f369ba1aff02db Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Thu, 30 Oct 2014 15:59:17 +0100
Subject: [PATCH 93/93] NOUPSTREAM: Default to root if sssd user is not
specified
---
src/monitor/monitor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 0dea327213a1ad04b6f69c0ffb0fb87254420796..20b4aef4ee94fd42de1585d7d7c2e01ea01845ac 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -925,7 +925,7 @@ static int get_service_user(struct mt_ctx *ctx)
ret = confdb_get_string(ctx->cdb, ctx, CONFDB_MONITOR_CONF_ENTRY,
CONFDB_MONITOR_USER_RUNAS,
- SSSD_USER, &user_str);
+ "root", &user_str);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get the user to run as\n");
return ret;
--
1.9.3

3026
SPECS/sssd.spec Normal file

File diff suppressed because it is too large Load Diff