Resolves: upstream#3523 - ABRT crash - /usr/libexec/sssd/sssd_nss in setnetgrent_result_timeout

Resolves: upstream#3588 - sssd_nss consumes more memory until restarted
                          or machine swaps
Resolves: failure in glibc tests
          https://sourceware.org/bugzilla/show_bug.cgi?id=22530
Resolves: upstream#3451 - When sssd is configured with id_provider proxy and
                          auth_provider ldap, login fails if the LDAP server
                          is not allowing anonymous binds
Resolves: upstream#3285 - SSSD needs restart after incorrect clock is
                          corrected with AD
Resolves: upstream#3586 - Give a more detailed debug and system-log message
                          if krb5_init_context() failed
Resolves: rhbz#1431153 - SSSD ships a drop-in configuration snippet
                         in /etc/systemd/system
Backport few upstream features from 1.16.1
This commit is contained in:
Lukas Slebodnik 2017-12-04 21:33:29 +01:00
parent ce65f7d9ee
commit 1dedfbb334
80 changed files with 12250 additions and 60 deletions

View File

@ -0,0 +1,38 @@
From fd7226ff51eb9af70d0fcb63727cd1a48ab0534b Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 23 Oct 2017 07:35:52 +0200
Subject: [PATCH 01/79] KCM: Fix typo in comments
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/responder/kcm/kcmsrv_ccache_json.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/responder/kcm/kcmsrv_ccache_json.c b/src/responder/kcm/kcmsrv_ccache_json.c
index 8199bc613e4204859438e1cd820f3f4b2123dd7e..f1cca9880d128d05ad1edfc5c3b2f709d1a67d48 100644
--- a/src/responder/kcm/kcmsrv_ccache_json.c
+++ b/src/responder/kcm/kcmsrv_ccache_json.c
@@ -265,7 +265,7 @@ static json_t *princ_data_to_json(TALLOC_CTX *mem_ctx,
* {
* "type": "number",
* "realm": "string",
- * "componenents": [ "elem1", "elem2", ...]
+ * "components": [ "elem1", "elem2", ...]
* }
*/
static json_t *princ_to_json(TALLOC_CTX *mem_ctx,
@@ -400,7 +400,7 @@ static json_t *creds_to_json_array(struct kcm_cred *creds)
* principal : {
* "type": "number",
* "realm": "string",
- * "componenents": [ "elem1", "elem2", ...]
+ * "components": [ "elem1", "elem2", ...]
* }
* creds : [
* {
--
2.15.1

View File

@ -0,0 +1,556 @@
From aeb34cfcb9ded4cd7d272220a3d3802be89b7dd8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ren=C3=A9=20Genz?= <liebundartig@freenet.de>
Date: Sun, 22 Oct 2017 22:24:27 +0200
Subject: [PATCH 02/79] Fix minor spelling mistakes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Merges: https://pagure.io/SSSD/sssd/pull-request/3556
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
---
contrib/sssd.spec.in | 6 +++---
src/db/sysdb_private.h | 2 +-
src/db/sysdb_views.c | 4 ++--
src/examples/sssd-example.conf | 2 +-
src/lib/idmap/sss_idmap.doxy.in | 2 +-
src/man/sssd-secrets.5.xml | 2 +-
src/providers/ad/ad_gpo.c | 4 ++--
src/providers/be_dyndns.c | 2 +-
src/providers/data_provider/dp_request.c | 2 +-
src/providers/krb5/krb5_child.c | 2 +-
src/providers/ldap/sdap_async_sudo.c | 2 +-
src/responder/kcm/kcmsrv_ccache_json.c | 2 +-
src/responder/kcm/kcmsrv_op_queue.c | 4 ++--
src/sbus/sssd_dbus_connection.c | 4 ++--
src/shared/safealign.h | 4 ++--
src/sss_client/autofs/sss_autofs.c | 4 ++--
src/sss_client/idmap/sss_nss_idmap.doxy.in | 2 +-
src/sss_client/libwbclient/wbc_pwd_sssd.c | 2 +-
src/sss_client/sudo/sss_sudo.h | 10 +++++-----
src/tests/cmocka/common_mock_resp_dp.c | 2 +-
src/tests/cmocka/test_sbus_opath.c | 2 +-
src/tools/common/sss_process.c | 2 +-
src/tools/common/sss_process.h | 2 +-
src/tools/sssctl/sssctl.c | 4 ++--
src/tools/sssctl/sssctl_data.c | 2 +-
src/util/crypto/libcrypto/crypto_sha512crypt.c | 2 +-
src/util/crypto/nss/nss_sha512crypt.c | 2 +-
src/util/server.c | 6 +++---
src/util/sss_ini.h | 2 +-
src/util/tev_curl.c | 2 +-
src/util/util_lock.c | 2 +-
31 files changed, 46 insertions(+), 46 deletions(-)
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index e76b51833d5dfa3207d28add4af1016c00f25e1f..d6ab73e60863316cbf239d34242959fdfe8d4b1b 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -241,7 +241,7 @@ the system and a pluggable backend system to connect to multiple different
account sources. It is also the basis to provide client auditing and policy
services for projects like FreeIPA.
-The sssd subpackage is a meta-package that contains the deamon as well as all
+The sssd subpackage is a meta-package that contains the daemon as well as all
the existing back ends.
%package common
@@ -496,7 +496,7 @@ Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
%description -n libsss_idmap
-Utility library to convert SIDs to Unix uids and gids
+Utility library to convert SIDs to UNIX UIDs and GIDs
%package -n libsss_idmap-devel
Summary: FreeIPA Idmap library
@@ -505,7 +505,7 @@ License: LGPLv3+
Requires: libsss_idmap = %{version}-%{release}
%description -n libsss_idmap-devel
-Utility library to SIDs to Unix uids and gids
+Utility library to SIDs to UNIX UIDs and GIDs
%package -n libipa_hbac
Summary: FreeIPA HBAC Evaluator library
diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h
index dbd75615bc212e73c4338a76dceaa68a5889ed1d..7c3347fec99f60160804a6eed178baedafb81d33 100644
--- a/src/db/sysdb_private.h
+++ b/src/db/sysdb_private.h
@@ -185,7 +185,7 @@ int sysdb_delete_ulong(struct ldb_message *msg,
/* The utility function to create a subdomain sss_domain_info object is handy
* for unit tests, so it should be available in a header, but not a public util
- * one, because the only interface for the deamon itself should be adding
+ * one, because the only interface for the daemon itself should be adding
* the sysdb domain object and calling sysdb_update_subdomains()
*/
struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
index afc7852ecf402ef144beca9c1b94fbe3cc4bbb6a..f640c813acf4deafe98eb15708d3a94790502dcb 100644
--- a/src/db/sysdb_views.c
+++ b/src/db/sysdb_views.c
@@ -722,7 +722,7 @@ static errno_t safe_original_attributes(struct sss_domain_info *domain,
goto done;
}
- /* Safe orginal values in attributes prefixed by OriginalAD. */
+ /* Safe original values in attributes prefixed by OriginalAD. */
for (c = 0; allowed_attrs[c] != NULL; c++) {
el = ldb_msg_find_element(orig_obj->msgs[0], allowed_attrs[c]);
if (el != NULL) {
@@ -753,7 +753,7 @@ static errno_t safe_original_attributes(struct sss_domain_info *domain,
el = ldb_msg_find_element(orig_obj->msgs[0], SYSDB_NAME_ALIAS);
if (el != NULL) {
for (c = 0; c < el->num_values; c++) {
- /* To avoid issue with ldb_modify if e.g. the orginal and the
+ /* To avoid issue with ldb_modify if e.g. the original and the
* override name are the same, we use the *_safe version here. */
ret = sysdb_attrs_add_val_safe(attrs, SYSDB_NAME_ALIAS,
&el->values[c]);
diff --git a/src/examples/sssd-example.conf b/src/examples/sssd-example.conf
index 59df41673586d5c7d2602cc5290c40ec5bd64986..34b2b22c5f619f49bb9aa1edf04849df5e40c787 100644
--- a/src/examples/sssd-example.conf
+++ b/src/examples/sssd-example.conf
@@ -32,7 +32,7 @@ services = nss, pam
# An example Active Directory domain. Please note that this configuration
# works for AD 2003R2 and AD 2008, because they use pretty much RFC2307bis
# compliant attribute names. To support UNIX clients with AD 2003 or older,
-# you must install Microsoft Services For Unix and map LDAP attributes onto
+# you must install Microsoft Services For UNIX and map LDAP attributes onto
# msSFU30* attribute names.
; [domain/AD]
; id_provider = ldap
diff --git a/src/lib/idmap/sss_idmap.doxy.in b/src/lib/idmap/sss_idmap.doxy.in
index 991028f65c251e2bc0086487817271b527fa439b..833498b189a038a06414ff623179ef69d24affb7 100644
--- a/src/lib/idmap/sss_idmap.doxy.in
+++ b/src/lib/idmap/sss_idmap.doxy.in
@@ -719,7 +719,7 @@ RECURSIVE = NO
EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
+# directories that are symbolic links (a UNIX file system feature) are excluded
# from the input.
EXCLUDE_SYMLINKS = NO
diff --git a/src/man/sssd-secrets.5.xml b/src/man/sssd-secrets.5.xml
index 08ab371c64eb49e4f153bb2183c07681b1050bb0..a738fbfffa1bdb7038e70a4a49651eb6a9286b1c 100644
--- a/src/man/sssd-secrets.5.xml
+++ b/src/man/sssd-secrets.5.xml
@@ -46,7 +46,7 @@
project was born to deal with this problem in cloud like
environments, but we found the idea compelling even at a
single system level. As a security service, SSSD is ideal to
- host this capability while offering the same API via a Unix
+ host this capability while offering the same API via a UNIX
Socket. This will make it possible to use local calls and have
them transparently routed to a local or a remote key management
store like IPA Vault for storage, escrow and recovery.
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index a5237f6fad7fc79fbcbafc8aac28cff15677009f..d9ea311417fc5d57850aa9a6c3736964844675bd 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -680,7 +680,7 @@ ad_gpo_ace_includes_client_sid(const char *user_sid,
* named "ApplyGroupPolicy" (AGP) is allowed, by comparing the specified
* user_sid and group_sids against the specified access control entry (ACE).
* This function returns ALLOWED, DENIED, or NEUTRAL depending on whether
- * the ACE explictly allows, explicitly denies, or does neither.
+ * the ACE explicitly allows, explicitly denies, or does neither.
*
* Note that the 'M' abbreviation used in the evaluation algorithm stands for
* "access_mask", which represents the set of access rights associated with an
@@ -3860,7 +3860,7 @@ ad_gpo_sd_process_attrs(struct tevent_req *req,
ret = sysdb_attrs_get_int32_t(result, AD_AT_FUNC_VERSION,
&gp_gpo->gpo_func_version);
if (ret == ENOENT) {
- /* If this attrbute is missing we can skip the GPO. It will
+ /* If this attribute is missing we can skip the GPO. It will
* be filtered out according to MS-GPOL:
* https://msdn.microsoft.com/en-us/library/cc232538.aspx */
DEBUG(SSSDBG_TRACE_ALL, "GPO with GUID %s is missing attribute "
diff --git a/src/providers/be_dyndns.c b/src/providers/be_dyndns.c
index ee264156824d7c5ab27c919ae0c56bbd6c0bc54f..b968e67b3e3e6a4f2937dce502c2c9b4ad136a4b 100644
--- a/src/providers/be_dyndns.c
+++ b/src/providers/be_dyndns.c
@@ -706,7 +706,7 @@ nsupdate_get_addrs_done(struct tevent_req *subreq)
return;
}
- /* The second address matched either immediatelly or after a retry.
+ /* The second address matched either immediately or after a retry.
* No need to retry again. */
ret = EOK;
diff --git a/src/providers/data_provider/dp_request.c b/src/providers/data_provider/dp_request.c
index a6bc020e0649760c46637d6f90569248792f7f04..295758a765bfdedd539d44f86a37efae0846763f 100644
--- a/src/providers/data_provider/dp_request.c
+++ b/src/providers/data_provider/dp_request.c
@@ -412,7 +412,7 @@ static void dp_terminate_request(struct dp_req *dp_req)
{
if (dp_req->handler_req == NULL) {
/* This may occur when the handler already finished but the caller
- * of dp request did not yet recieved data/free dp_req. We just
+ * of dp request did not yet received data/free dp_req. We just
* return here. */
return;
}
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 888cc5d6f5c554901cc46d4315844d7bbbe582b8..b8ee497728b4b70fae89e528172e9d5bd42239c0 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -1612,7 +1612,7 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
goto done;
}
- /* Successfull authentication! Check if ccache contains the
+ /* Successful authentication! Check if ccache contains the
* right principal...
*/
kerr = sss_krb5_check_ccache_princ(kr->ctx, kr->ccname, kr->creds->client);
diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index 3c69837fda313b2645c3a8497252670312f600ea..f33d5b5fa86dc1806695482d627bd71a2b040d6e 100644
--- a/src/providers/ldap/sdap_async_sudo.c
+++ b/src/providers/ldap/sdap_async_sudo.c
@@ -616,7 +616,7 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq)
}
in_transaction = false;
- DEBUG(SSSDBG_TRACE_FUNC, "Sudoers is successfuly stored in cache\n");
+ DEBUG(SSSDBG_TRACE_FUNC, "Sudoers is successfully stored in cache\n");
/* remember new usn */
ret = sysdb_get_highest_usn(state, rules, rules_count, &usn);
diff --git a/src/responder/kcm/kcmsrv_ccache_json.c b/src/responder/kcm/kcmsrv_ccache_json.c
index f1cca9880d128d05ad1edfc5c3b2f709d1a67d48..33cb51621f26a11051e2fac4c5d7c959b30d9f00 100644
--- a/src/responder/kcm/kcmsrv_ccache_json.c
+++ b/src/responder/kcm/kcmsrv_ccache_json.c
@@ -210,7 +210,7 @@ bool sec_key_match_uuid(const char *sec_key,
/*
* Creates an array of principal elements that will be used later
* in the form of:
- * "componenets": [ "elem1", "elem2", ...]
+ * "components": [ "elem1", "elem2", ...]
*/
static json_t *princ_data_to_json(TALLOC_CTX *mem_ctx,
krb5_principal princ)
diff --git a/src/responder/kcm/kcmsrv_op_queue.c b/src/responder/kcm/kcmsrv_op_queue.c
index 55c8b65d94f70979fe56fcc4d8747547a9cc9d33..ee1aa47ab629022bb726c4d5deb1eb1456124df1 100644
--- a/src/responder/kcm/kcmsrv_op_queue.c
+++ b/src/responder/kcm/kcmsrv_op_queue.c
@@ -179,7 +179,7 @@ static struct kcm_ops_queue *kcm_op_queue_get(struct kcm_ops_queue_ctx *qctx,
case HASH_ERROR_KEY_NOT_FOUND:
/* No request for this UID yet. Enqueue this request in case
* another one comes in and return EOK to run the current request
- * immediatelly
+ * immediately
*/
DEBUG(SSSDBG_TRACE_LIBS, "No existing queue for this ID\n");
@@ -220,7 +220,7 @@ static errno_t kcm_op_queue_add_req(struct kcm_ops_queue *kq,
* Enqueue a request.
*
* If the request queue /for the given ID/ is empty, that is, if this
- * request is the first one in the queue, run the request immediatelly.
+ * request is the first one in the queue, run the request immediately.
*
* Otherwise just add it to the queue and wait until the previous request
* finishes and only at that point mark the current request as done, which
diff --git a/src/sbus/sssd_dbus_connection.c b/src/sbus/sssd_dbus_connection.c
index de134f2f21bfb9697fcc8a42622817bc50b54f2a..bdd4a247a670f1928573a1bd18dc8e585b997b7d 100644
--- a/src/sbus/sssd_dbus_connection.c
+++ b/src/sbus/sssd_dbus_connection.c
@@ -179,7 +179,7 @@ int sbus_init_connection(TALLOC_CTX *ctx,
conn->incoming_signals = sbus_incoming_signal_hash_init(conn);
if (conn->incoming_signals == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create incoming singals "
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create incoming signals "
"hash table\n");
talloc_free(conn);
return EIO;
@@ -327,7 +327,7 @@ static int connection_destructor(void *ctx)
/*
* sbus_get_connection
- * Utility function to retreive the DBusConnection object
+ * Utility function to retrieve the DBusConnection object
* from a sbus_connection
*/
DBusConnection *sbus_get_connection(struct sbus_connection *conn)
diff --git a/src/shared/safealign.h b/src/shared/safealign.h
index 2316ed14245c4469171f9eb4a42e70fc6b3fd8a8..b00c37f5b98bd4bf7ff6cea8e1208d80c77f0228 100644
--- a/src/shared/safealign.h
+++ b/src/shared/safealign.h
@@ -98,8 +98,8 @@ safealign_memcpy(void *dest, const void *src, size_t n, size_t *counter)
SAFEALIGN_SETMEM_VALUE(dest, value, uint16_t, pctr)
/* These macros are the same as their equivalents without _CHECK suffix,
- * but additionally make the caller return EINVAL immediatelly if *pctr
- * would excceed len. */
+ * but additionally make the caller return EINVAL immediately if *pctr
+ * would exceed len. */
#define SAFEALIGN_COPY_UINT32_CHECK(dest, src, len, pctr) do { \
if ((*(pctr) + sizeof(uint32_t)) > (len) || \
SIZE_T_OVERFLOW(*(pctr), sizeof(uint32_t))) { return EINVAL; } \
diff --git a/src/sss_client/autofs/sss_autofs.c b/src/sss_client/autofs/sss_autofs.c
index 02f91ab2b3d29a189e949f6a8d645ea4ccd7f6e3..482ff2c400b10829ccb6d6a921c8c2e15c7fcdd2 100644
--- a/src/sss_client/autofs/sss_autofs.c
+++ b/src/sss_client/autofs/sss_autofs.c
@@ -30,7 +30,7 @@
#define MAX_AUTOMNTMAPNAME_LEN NAME_MAX
#define MAX_AUTOMNTKEYNAME_LEN PATH_MAX
-/* How many entries shall _sss_getautomntent_r retreive at once */
+/* How many entries shall _sss_getautomntent_r retrieve at once */
#define GETAUTOMNTENT_MAX_ENTRIES 512
struct automtent {
@@ -287,7 +287,7 @@ _sss_getautomntent_r(char **key, char **value, void *context)
data_len = sizeof(uint32_t) + /* mapname len */
name_len + 1 + /* mapname\0 */
sizeof(uint32_t) + /* index into the map */
- sizeof(uint32_t); /* num entries to retreive */
+ sizeof(uint32_t); /* num entries to retrieve */
data = malloc(data_len);
if (!data) {
diff --git a/src/sss_client/idmap/sss_nss_idmap.doxy.in b/src/sss_client/idmap/sss_nss_idmap.doxy.in
index d75237622507d2a43ef382815544b8339054f474..f6c18ba1f0d368e989ce0d18a500b6523622b9c1 100644
--- a/src/sss_client/idmap/sss_nss_idmap.doxy.in
+++ b/src/sss_client/idmap/sss_nss_idmap.doxy.in
@@ -616,7 +616,7 @@ RECURSIVE = NO
EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem feature) are excluded
+# directories that are symbolic links (a UNIX filesystem feature) are excluded
# from the input.
EXCLUDE_SYMLINKS = NO
diff --git a/src/sss_client/libwbclient/wbc_pwd_sssd.c b/src/sss_client/libwbclient/wbc_pwd_sssd.c
index 08c3b86372c86f228aeeb584068f82bd97cfe0fe..cacad9d3230c341ae478a4e4e41864ecdc4209b3 100644
--- a/src/sss_client/libwbclient/wbc_pwd_sssd.c
+++ b/src/sss_client/libwbclient/wbc_pwd_sssd.c
@@ -606,7 +606,7 @@ wbcErr wbcGetgrlist(struct group **grp)
WBC_SSSD_NOT_IMPLEMENTED;
}
-/* Return the unix group array belonging to the given user */
+/* Return the Unix group array belonging to the given user */
wbcErr wbcGetGroups(const char *account,
uint32_t *num_groups,
gid_t **_groups)
diff --git a/src/sss_client/sudo/sss_sudo.h b/src/sss_client/sudo/sss_sudo.h
index 1a275cfafbb0476b163599854cbbc1f91101f360..1dcd569a59cde2eec88476aef2bc3ab35a089c86 100644
--- a/src/sss_client/sudo/sss_sudo.h
+++ b/src/sss_client/sudo/sss_sudo.h
@@ -87,11 +87,11 @@ struct sss_sudo_result {
};
/**
- * @brief Send a request to SSSD to retreive all SUDO rules for a given
+ * @brief Send a request to SSSD to retrieve all SUDO rules for a given
* user.
*
- * @param[in] uid The uid of the user to retreive the rules for.
- * @param[in] username The username to retreive the rules for
+ * @param[in] uid The uid of the user to retrieve the rules for.
+ * @param[in] username The username to retrieve the rules for
* @param[in] domainname The domain name the user is a member of.
* @param[out] _error The result of the search in SSSD's domains. If the
* user was present in the domain, the _error code is
@@ -122,9 +122,9 @@ int sss_sudo_send_recv(uid_t uid,
* @brief Send a request to SSSD to retrieve the default options, commonly
* stored in the "cn=defaults" record,
*
- * @param[in] uid The uid of the user to retreive the rules for.
+ * @param[in] uid The uid of the user to retrieve the rules for.
*
- * @param[in] username The username to retreive the rules for.
+ * @param[in] username The username to retrieve the rules for.
*
* @param[out] _error The result of the search in SSSD's domains. If the
* options were present in the domain, the _error code
diff --git a/src/tests/cmocka/common_mock_resp_dp.c b/src/tests/cmocka/common_mock_resp_dp.c
index 4b38a38e6f53499132f9fe14a0ec0af157cf85ca..ece887b12d472c3fb01477d213f4308a535f8fe7 100644
--- a/src/tests/cmocka/common_mock_resp_dp.c
+++ b/src/tests/cmocka/common_mock_resp_dp.c
@@ -24,7 +24,7 @@
#include "responder/common/responder.h"
#include "tests/cmocka/common_mock_resp.h"
-/* Mock DP requests that finish immediatelly and return
+/* Mock DP requests that finish immediately and return
* mocked values as per previous set by mock_account_recv
*/
struct tevent_req *
diff --git a/src/tests/cmocka/test_sbus_opath.c b/src/tests/cmocka/test_sbus_opath.c
index e38eaf1972b55f01d712584b67c731ac0031736d..b469fa8da90b6f54e15a590014be650e32221136 100644
--- a/src/tests/cmocka/test_sbus_opath.c
+++ b/src/tests/cmocka/test_sbus_opath.c
@@ -72,7 +72,7 @@ void test_sbus_opath_escape_unescape(void **state)
escaped = sbus_opath_escape_part(mem_ctx, "path_with_underscore");
assert_non_null(escaped);
- /* underscore is 0x5F in ascii */
+ /* underscore is 0x5F in ASCII */
assert_string_equal(escaped, "path_5fwith_5funderscore");
raw = sbus_opath_unescape_part(mem_ctx, escaped);
talloc_free(escaped);
diff --git a/src/tools/common/sss_process.c b/src/tools/common/sss_process.c
index 574ccab24d0ff20784f6223e743bf9561ea2281e..fc710a553dbf6a27e23693be79bb333dcbcd3a3e 100644
--- a/src/tools/common/sss_process.c
+++ b/src/tools/common/sss_process.c
@@ -97,7 +97,7 @@ done:
return ret;
}
-bool sss_deamon_running(void)
+bool sss_daemon_running(void)
{
return sss_signal(0) == EOK;
}
diff --git a/src/tools/common/sss_process.h b/src/tools/common/sss_process.h
index 43408afc7fab3caed3febd1a159dbfc6acbbb3f9..6bbb0947570a5fc9e77b479c7386db1cead05aaf 100644
--- a/src/tools/common/sss_process.h
+++ b/src/tools/common/sss_process.h
@@ -23,7 +23,7 @@
#include "util/util.h"
-bool sss_deamon_running(void);
+bool sss_daemon_running(void);
errno_t sss_signal(int signum);
#endif /* _SSS_PROCESS_H_ */
diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c
index 1e061c00d2238bf34adff4183e560dc127dd62c7..d9bc897c1a32954bbdd2d4ae2b0a9fb6d2c34752 100644
--- a/src/tools/sssctl/sssctl.c
+++ b/src/tools/sssctl/sssctl.c
@@ -148,7 +148,7 @@ bool sssctl_start_sssd(bool force)
enum sssctl_prompt_result prompt;
errno_t ret;
- if (sss_deamon_running()) {
+ if (sss_daemon_running()) {
return true;
}
@@ -187,7 +187,7 @@ bool sssctl_stop_sssd(bool force)
enum sssctl_prompt_result prompt;
errno_t ret;
- if (!sss_deamon_running()) {
+ if (!sss_daemon_running()) {
return true;
}
diff --git a/src/tools/sssctl/sssctl_data.c b/src/tools/sssctl/sssctl_data.c
index 4b7f1dfff666743f9c47bc34515bbe63ee85eff1..b16fede1e2f3f743f65f8f86b0a5bdcfdca71f0b 100644
--- a/src/tools/sssctl/sssctl_data.c
+++ b/src/tools/sssctl/sssctl_data.c
@@ -270,7 +270,7 @@ errno_t sssctl_cache_upgrade(struct sss_cmdline *cmdline,
return ret;
}
- if (sss_deamon_running()) {
+ if (sss_daemon_running()) {
return ERR_SSSD_RUNNING;
}
diff --git a/src/util/crypto/libcrypto/crypto_sha512crypt.c b/src/util/crypto/libcrypto/crypto_sha512crypt.c
index 1023566624f0e7b8fc08e30d4ea7ad031fbffff9..b074eee555fafac6e486bfdf9efb9ddf4964a990 100644
--- a/src/util/crypto/libcrypto/crypto_sha512crypt.c
+++ b/src/util/crypto/libcrypto/crypto_sha512crypt.c
@@ -7,7 +7,7 @@
* Sumit Bose <sbose@redhat.com>
* George McCollister <georgem@novatech-llc.com>
*/
-/* SHA512-based Unix crypt implementation.
+/* SHA512-based UNIX crypt implementation.
Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>. */
#include "config.h"
diff --git a/src/util/crypto/nss/nss_sha512crypt.c b/src/util/crypto/nss/nss_sha512crypt.c
index 9fedd5ec6c62855d9cc0c9c2869d8c9be7fb5ade..2f1624e6396c40f539a4e2034ab545cad8f05434 100644
--- a/src/util/crypto/nss/nss_sha512crypt.c
+++ b/src/util/crypto/nss/nss_sha512crypt.c
@@ -5,7 +5,7 @@
*
* Sumit Bose <sbose@redhat.com>
*/
-/* SHA512-based Unix crypt implementation.
+/* SHA512-based UNIX crypt implementation.
Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>. */
#include "config.h"
diff --git a/src/util/server.c b/src/util/server.c
index 0046c9737bc0d9aea7be59b4fed5e0f8930ff66e..4e65cc66c01ba020b13a88df8e017765ac97f76e 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -69,7 +69,7 @@ static void close_low_fds(void)
#endif
}
-static void deamon_parent_sigterm(int sig)
+static void daemon_parent_sigterm(int sig)
{
_exit(0);
}
@@ -88,10 +88,10 @@ void become_daemon(bool Fork)
pid = fork();
if (pid != 0) {
/* Terminate parent process on demand so we can hold systemd
- * or initd from starting next service until sssd in initialized.
+ * or initd from starting next service until sssd is initialized.
* We use signals directly here because we don't have a tevent
* context yet. */
- CatchSignal(SIGTERM, deamon_parent_sigterm);
+ CatchSignal(SIGTERM, daemon_parent_sigterm);
/* or exit when sssd monitor is terminated */
do {
diff --git a/src/util/sss_ini.h b/src/util/sss_ini.h
index 77fbddc3ab073d930eecd68dacb00dae52847744..0b173831d4fd7c283fa939a2f3bfda2a3bb97515 100644
--- a/src/util/sss_ini.h
+++ b/src/util/sss_ini.h
@@ -94,7 +94,7 @@ int sss_ini_call_validators_strs(TALLOC_CTX *mem_ctx,
struct ref_array *
sss_ini_get_ra_error_list(struct sss_ini_initdata *init_data);
-/* Get pointer to list of successfuly merged snippet files */
+/* Get pointer to list of successfully merged snippet files */
struct ref_array *
sss_ini_get_ra_success_list(struct sss_ini_initdata *init_data);
diff --git a/src/util/tev_curl.c b/src/util/tev_curl.c
index 52c86adde65c173a874534a7001d7859789581cd..4c2f1ec9ff0127ccfd72010460ed75dad43e9ce3 100644
--- a/src/util/tev_curl.c
+++ b/src/util/tev_curl.c
@@ -67,7 +67,7 @@ struct tcurl_ctx {
struct tcurl_sock {
struct tcurl_ctx *tctx; /* Backchannel to the main context */
- curl_socket_t sockfd; /* curl socket is an int typedef on Unix */
+ curl_socket_t sockfd; /* curl socket is an int typedef on UNIX */
struct tevent_fd *fde; /* tevent tracker of the fd events */
};
diff --git a/src/util/util_lock.c b/src/util/util_lock.c
index b8e41cc29fbdcf3b5b75bf1507a4d33f5ba07be0..58d3b1bdf60f411fb7116055a5de775355d1839e 100644
--- a/src/util/util_lock.c
+++ b/src/util/util_lock.c
@@ -74,7 +74,7 @@ errno_t sss_br_lock_file(int fd, size_t start, size_t len,
return ret;
}
} else if (ret == 0) {
- /* File successfuly locked */
+ /* File successfully locked */
break;
}
}
--
2.15.1

View File

@ -0,0 +1,158 @@
From 04fc0d758ae1e5c4ab71ab3bf8b8f50b99a6c63a Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Tue, 3 Oct 2017 12:34:33 +0200
Subject: [PATCH 03/79] CONFIG: Add a new option auto_private_groups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The auto_private_groups option is used to configure the domain->mpg flag
which was already set automatically for subdomains, but for some time was
not settable by the admin via the configuration file.
The new option name, instead of the old magic_private_groups, was chosen
purely because this name would hopefully be better understood by admins.
The option doesn't do anything yet, it is just added to all the places a
new option should be added to.
Related:
https://pagure.io/SSSD/sssd/issue/1872
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/confdb/confdb.c | 8 ++++++++
src/confdb/confdb.h | 1 +
src/config/SSSDConfig/__init__.py.in | 1 +
src/config/SSSDConfigTest.py | 6 ++++--
src/config/cfg_rules.ini | 1 +
src/config/etc/sssd.api.conf | 1 +
src/man/sssd.conf.5.xml | 20 ++++++++++++++++++++
7 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index fefecc03d554f6eca12efe07990bfae17033bd02..a028224817f12ace2a0c4165d7b9cb0bb80ce5a1 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -936,6 +936,14 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
goto done;
}
+ ret = get_entry_as_bool(res->msgs[0], &domain->mpg,
+ CONFDB_DOMAIN_AUTO_UPG, 0);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Invalid value for %s\n", CONFDB_DOMAIN_AUTO_UPG);
+ goto done;
+ }
+
if (strcasecmp(domain->provider, "local") == 0) {
/* If this is the local provider, we need to ensure that
* no other provider was specified for other types, since
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index bcea99ae49a3fa5f0393ce6b2c215b5b2d4bc3fc..2539b906993edbceb38aac9265e04deed69cf2e4 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -198,6 +198,7 @@
#define CONFDB_DEFAULT_CACHE_CREDS_MIN_FF_LENGTH 8
#define CONFDB_DOMAIN_LEGACY_PASS "store_legacy_passwords"
#define CONFDB_DOMAIN_MPG "magic_private_groups"
+#define CONFDB_DOMAIN_AUTO_UPG "auto_private_groups"
#define CONFDB_DOMAIN_FQ "use_fully_qualified_names"
#define CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT "entry_cache_timeout"
#define CONFDB_DOMAIN_ACCOUNT_CACHE_EXPIRATION "account_cache_expiration"
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index d99b718e09283d113f73639e0f94e7f1cec55f68..d2bb709d69c8790558b5c06a7e405463b508c189 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -195,6 +195,7 @@ option_strings = {
'cached_auth_timeout' : _('How long can cached credentials be used for cached authentication'),
'full_name_format' : _('Printf-compatible format for displaying fully-qualified names'),
're_expression' : _('Regex to parse username and domain'),
+ 'auto_private_groups' : _('Whether to automatically create private groups for users'),
# [provider/ipa]
'ipa_domain' : _('IPA domain'),
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index 4a583bdd3124dc05a116d2e6bd48afb92aa0b54d..87d1f6e6410dfeafc77d578cf0b950dc71a1f0a2 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -624,7 +624,8 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
'subdomain_homedir',
'full_name_format',
're_expression',
- 'cached_auth_timeout']
+ 'cached_auth_timeout',
+ 'auto_private_groups']
self.assertTrue(type(options) == dict,
"Options should be a dictionary")
@@ -994,7 +995,8 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase):
'subdomain_homedir',
'full_name_format',
're_expression',
- 'cached_auth_timeout']
+ 'cached_auth_timeout',
+ 'auto_private_groups']
self.assertTrue(type(options) == dict,
"Options should be a dictionary")
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index e49e8d43f4aead14d833866110784fd62382cc2b..4e70bf7b6f0fa7421a0c35bd4279830265bf3470 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -382,6 +382,7 @@ option = cached_auth_timeout
option = wildcard_limit
option = full_name_format
option = re_expression
+option = auto_private_groups
#Entry cache timeouts
option = entry_cache_user_timeout
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index 7f2b8977b7e67fcfc20df49056cda8ebe6da0be8..2be2e3e685ba3abd9a4a419f93332a89ff774262 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -185,6 +185,7 @@ subdomain_homedir = str, None, false
cached_auth_timeout = int, None, false
full_name_format = str, None, false
re_expression = str, None, false
+auto_private_groups = str, None, false
#Entry cache timeouts
entry_cache_user_timeout = int, None, false
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 7752e450835b5beba50ddc4c635ff985d38ca421..1e8d9537517c85c3021b9c2c4185ea272c5bfffa 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -2816,6 +2816,26 @@ subdomain_inherit = ldap_purge_cache_timeout
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>auto_private_groups (string)</term>
+ <listitem>
+ <para>
+ If this option is enabled, SSSD will automatically
+ create user private groups based on user's
+ UID number. The GID number is ignored in this case.
+ </para>
+ <para>
+ NOTE: Because the GID number and the user private group
+ are inferred frm the UID number, it is not supported
+ to have multiple entries with the same UID or GID number
+ with this option. In other words, enabling this option
+ enforces uniqueness across the ID space.
+ </para>
+ <para>
+ Default: False
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
--
2.15.1

View File

@ -0,0 +1,32 @@
From bd4e962128c7ea95fa0bdc5aa8f360ab11cda178 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Tue, 3 Oct 2017 12:36:02 +0200
Subject: [PATCH 04/79] CONFDB: Remove the obsolete option magic_private_groups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since this confdb definition was completely unused across the codebase,
this patch just removes the definition.
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/confdb/confdb.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 2539b906993edbceb38aac9265e04deed69cf2e4..1471949623e9dd7a8536e3ac3048a10227a5d857 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -197,7 +197,6 @@
"cache_credentials_minimal_first_factor_length"
#define CONFDB_DEFAULT_CACHE_CREDS_MIN_FF_LENGTH 8
#define CONFDB_DOMAIN_LEGACY_PASS "store_legacy_passwords"
-#define CONFDB_DOMAIN_MPG "magic_private_groups"
#define CONFDB_DOMAIN_AUTO_UPG "auto_private_groups"
#define CONFDB_DOMAIN_FQ "use_fully_qualified_names"
#define CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT "entry_cache_timeout"
--
2.15.1

View File

@ -0,0 +1,166 @@
From f7c559955ab380d097f8e98786ba710c7bff812c Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Tue, 3 Oct 2017 12:34:49 +0200
Subject: [PATCH 05/79] SDAP: Allow the mpg flag for the main domain
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit allows saving the users in the MPG domain in the SDAP
layer.
The commit contains the following changes:
- abstracts the change where if the primary GID exists in the original
object, it is saved instead as the SYSDB_PRIMARY_GROUP_GIDNUM attribute,
which will allow the original primary GID to be exposed as a
secondary group
- if the primary GID does not exist, no SYSDB_PRIMARY_GROUP_GIDNUM
is added. This will allow to handle LDAP objects that only contain
the UID but no GID. Since this is a new use-case, a test is added
later
- a branch that handles the above is added to sdap_save_user() also
for joined domains that set the MPG flag. Previously, only
subdomains were handled.
- to allow passing GID=0 to the sysdb layer, the range check is
relaxed.
Related:
https://pagure.io/SSSD/sssd/issue/1872
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/providers/ldap/sdap_async_users.c | 83 +++++++++++++++++++++++++++++++----
1 file changed, 75 insertions(+), 8 deletions(-)
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index 09d096e84cac6c9d52bcde0e1587c47dbd88b504..7338b4a15694b1d0a16723990130a23a7280af5f 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -136,6 +136,38 @@ static errno_t sdap_set_non_posix_flag(struct sysdb_attrs *attrs,
return EOK;
}
+static int sdap_user_set_mpg(struct sysdb_attrs *user_attrs,
+ gid_t *_gid)
+{
+ errno_t ret;
+
+ if (_gid == NULL) {
+ return EINVAL;
+ }
+
+ if (*_gid == 0) {
+ /* The original entry had no GID number. This is OK, we just won't add
+ * the SYSDB_PRIMARY_GROUP_GIDNUM attribute
+ */
+ return EOK;
+ }
+
+ ret = sysdb_attrs_add_uint32(user_attrs,
+ SYSDB_PRIMARY_GROUP_GIDNUM,
+ (uint32_t) *_gid);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_uint32 failed.\n");
+ return ret;
+ }
+
+ /* We won't really store gidNumber=0, but the zero value tells
+ * the sysdb layer that no GID is set, which sysdb requires for
+ * MPG-enabled domains
+ */
+ *_gid = 0;
+ return EOK;
+}
+
/* FIXME: support storing additional attributes */
int sdap_save_user(TALLOC_CTX *memctx,
struct sdap_options *opts,
@@ -357,7 +389,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
goto done;
}
- if (IS_SUBDOMAIN(dom)) {
+ if (IS_SUBDOMAIN(dom) || dom->mpg == true) {
/* For subdomain users, only create the private group as
* the subdomain is an MPG domain.
* But we have to save the GID of the original primary group
@@ -365,14 +397,13 @@ int sdap_save_user(TALLOC_CTX *memctx,
* typically (Unix and AD) the user is not listed in his primary
* group as a member.
*/
- ret = sysdb_attrs_add_uint32(user_attrs, SYSDB_PRIMARY_GROUP_GIDNUM,
- (uint32_t) gid);
+ ret = sdap_user_set_mpg(user_attrs, &gid);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_uint32 failed.\n");
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sdap_user_set_mpg failed [%d]: %s\n", ret,
+ sss_strerror(ret));
goto done;
}
-
- gid = 0;
}
/* Store the GID in the ldap_attrs so it doesn't get
@@ -380,6 +411,41 @@ int sdap_save_user(TALLOC_CTX *memctx,
*/
ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid);
if (ret != EOK) goto done;
+ } else if (dom->mpg) {
+ /* Likewise, if a domain is set to contain 'magic private groups', do
+ * not process the real GID, but save it in the cache as originalGID
+ * (if available)
+ */
+ ret = sysdb_attrs_get_uint32_t(attrs,
+ opts->user_map[SDAP_AT_USER_GID].sys_name,
+ &gid);
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_TRACE_LIBS,
+ "Missing GID, won't save the %s attribute\n",
+ SYSDB_PRIMARY_GROUP_GIDNUM);
+
+ /* Store the UID as GID (since we're in a MPG domain so that it doesn't
+ * get treated as a missing attribute and removed
+ */
+ ret = sdap_replace_id(attrs, SYSDB_GIDNUM, uid);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot set the id-mapped UID\n");
+ goto done;
+ }
+ gid = 0;
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Cannot retrieve GID, won't save the %s attribute\n",
+ SYSDB_PRIMARY_GROUP_GIDNUM);
+ gid = 0;
+ }
+
+ ret = sdap_user_set_mpg(user_attrs, &gid);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sdap_user_set_mpg failed [%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
} else {
ret = sysdb_attrs_get_uint32_t(attrs,
opts->user_map[SDAP_AT_USER_GID].sys_name,
@@ -403,8 +469,9 @@ int sdap_save_user(TALLOC_CTX *memctx,
}
/* check that the gid is valid for this domain */
- if (is_posix == true && IS_SUBDOMAIN(dom) == false &&
- OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
+ if (is_posix == true && IS_SUBDOMAIN(dom) == false
+ && dom->mpg == false
+ && OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) {
DEBUG(SSSDBG_CRIT_FAILURE,
"User [%s] filtered out! (primary gid out of range)\n",
user_name);
--
2.15.1

View File

@ -0,0 +1,221 @@
From 80ea108ab4263c1a1ac67ce6eac41dc6040b21dd Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Tue, 3 Oct 2017 14:31:18 +0200
Subject: [PATCH 06/79] LDAP: Turn group request into user request for MPG
domains if needed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the primary group GID or the group name is requested before the user
is, we need to also search the user space to save the user in the back
end which then allows the responder to generate the group from the
user entry.
Related:
https://pagure.io/SSSD/sssd/issue/1872
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/providers/ldap/ldap_id.c | 162 +++++++++++++++++++++++++++++++------------
1 file changed, 118 insertions(+), 44 deletions(-)
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 93204d35ea3782c9aa5d622a962c295869472631..e89fc6133316f684810afe4c1a0731b8a04f2931 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -694,6 +694,8 @@ struct groups_get_state {
static int groups_get_retry(struct tevent_req *req);
static void groups_get_connect_done(struct tevent_req *subreq);
static void groups_get_posix_check_done(struct tevent_req *subreq);
+static void groups_get_mpg_done(struct tevent_req *subreq);
+static errno_t groups_get_handle_no_group(struct tevent_req *req);
static void groups_get_search(struct tevent_req *req);
static void groups_get_done(struct tevent_req *subreq);
@@ -1051,8 +1053,6 @@ static void groups_get_done(struct tevent_req *subreq)
struct tevent_req);
struct groups_get_state *state = tevent_req_data(req,
struct groups_get_state);
- char *endptr;
- gid_t gid;
int dp_error = DP_ERR_FATAL;
int ret;
@@ -1078,49 +1078,33 @@ static void groups_get_done(struct tevent_req *subreq)
return;
}
- if (ret == ENOENT && state->noexist_delete == true) {
- switch (state->filter_type) {
- case BE_FILTER_ENUM:
- tevent_req_error(req, ret);
+ if (ret == ENOENT
+ && state->domain->mpg == true) {
+ /* The requested filter did not find a group. Before giving up, we must
+ * also check if the GID can be resolved through a primary group of a
+ * user
+ */
+ subreq = users_get_send(state,
+ state->ev,
+ state->ctx,
+ state->sdom,
+ state->conn,
+ state->filter_value,
+ state->filter_type,
+ NULL,
+ state->noexist_delete);
+ if (subreq == NULL) {
+ tevent_req_error(req, ENOMEM);
return;
- case BE_FILTER_NAME:
- ret = sysdb_delete_group(state->domain, state->filter_value, 0);
- if (ret != EOK && ret != ENOENT) {
- tevent_req_error(req, ret);
- return;
- }
- break;
-
- case BE_FILTER_IDNUM:
- gid = (gid_t) strtouint32(state->filter_value, &endptr, 10);
- if (errno || *endptr || (state->filter_value == endptr)) {
- tevent_req_error(req, errno ? errno : EINVAL);
- return;
- }
-
- ret = sysdb_delete_group(state->domain, NULL, gid);
- if (ret != EOK && ret != ENOENT) {
- tevent_req_error(req, ret);
- return;
- }
- break;
-
- case BE_FILTER_SECID:
- case BE_FILTER_UUID:
- /* Since it is not clear if the SID/UUID belongs to a user or a
- * group we have nothing to do here. */
- break;
-
- case BE_FILTER_WILDCARD:
- /* We can't know if all groups are up-to-date, especially in
- * a large environment. Do not delete any records, let the
- * responder fetch the entries they are requested in.
- */
- break;
-
-
- default:
- tevent_req_error(req, EINVAL);
+ }
+ tevent_req_set_callback(subreq, groups_get_mpg_done, req);
+ return;
+ } else if (ret == ENOENT && state->noexist_delete == true) {
+ ret = groups_get_handle_no_group(req);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Could not delete group [%d]: %s\n", ret, sss_strerror(ret));
+ tevent_req_error(req, ret);
return;
}
}
@@ -1129,6 +1113,96 @@ static void groups_get_done(struct tevent_req *subreq)
tevent_req_done(req);
}
+static void groups_get_mpg_done(struct tevent_req *subreq)
+{
+ errno_t ret;
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct groups_get_state *state = tevent_req_data(req,
+ struct groups_get_state);
+
+ ret = users_get_recv(subreq, &state->dp_error, &state->sdap_ret);
+ talloc_zfree(subreq);
+
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ if (state->sdap_ret == ENOENT && state->noexist_delete == true) {
+ ret = groups_get_handle_no_group(req);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Could not delete group [%d]: %s\n", ret, sss_strerror(ret));
+ tevent_req_error(req, ret);
+ return;
+ }
+ }
+
+ /* GID resolved to a user private group, done */
+ tevent_req_done(req);
+ return;
+}
+
+static errno_t groups_get_handle_no_group(struct tevent_req *req)
+{
+ struct groups_get_state *state = tevent_req_data(req,
+ struct groups_get_state);
+ errno_t ret;
+ char *endptr;
+ gid_t gid;
+
+ switch (state->filter_type) {
+ case BE_FILTER_ENUM:
+ ret = ENOENT;
+ break;
+ case BE_FILTER_NAME:
+ ret = sysdb_delete_group(state->domain, state->filter_value, 0);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Cannot delete group %s [%d]: %s\n",
+ state->filter_value, ret, sss_strerror(ret));
+ return ret;
+ }
+ ret = EOK;
+ break;
+ case BE_FILTER_IDNUM:
+ gid = (gid_t) strtouint32(state->filter_value, &endptr, 10);
+ if (errno || *endptr || (state->filter_value == endptr)) {
+ ret = errno ? errno : EINVAL;
+ break;
+ }
+
+ ret = sysdb_delete_group(state->domain, NULL, gid);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Cannot delete group %"SPRIgid" [%d]: %s\n",
+ gid, ret, sss_strerror(ret));
+ return ret;
+ }
+ ret = EOK;
+ break;
+ case BE_FILTER_SECID:
+ case BE_FILTER_UUID:
+ /* Since it is not clear if the SID/UUID belongs to a user or a
+ * group we have nothing to do here. */
+ ret = EOK;
+ break;
+ case BE_FILTER_WILDCARD:
+ /* We can't know if all groups are up-to-date, especially in
+ * a large environment. Do not delete any records, let the
+ * responder fetch the entries they are requested in.
+ */
+ ret = EOK;
+ break;
+ default:
+ ret = EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
int groups_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret)
{
struct groups_get_state *state = tevent_req_data(req,
--
2.15.1

View File

@ -0,0 +1,96 @@
From 561b887c08c6199a50f1295071626b3e9040a7d1 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Thu, 19 Oct 2017 17:18:15 +0200
Subject: [PATCH 07/79] SYSDB: Prevent users and groups ID collision in MPG
domains except for id_provider=local
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit makes the check when adding an object in a MPG domain
stricter in the sense that not only same names are allowed in a MPG
domain, but also the same groups are not allowed either.
This commit is a backwards-incompatible change, but one that is needed,
otherwise requesting the duplicate group first and then requesting the
user entry would yield two object when searching by GID.
In order to keep backwards-compatibility, this uniqueness is NOT
enforced with id_provider=local. This constraint can be removed in
the future (or the local provider can be dropped altogether)
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/db/sysdb_ops.c | 41 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 0e39a629a5823ff49ed02ec4c08a21b66119f06f..2f8e36c6c9a2c2cefe4af5fb78957763304d989a 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -1960,16 +1960,34 @@ int sysdb_add_user(struct sss_domain_info *domain,
}
if (domain->mpg) {
- /* In MPG domains you can't have groups with the same name as users,
- * search if a group with the same name exists.
+ /* In MPG domains you can't have groups with the same name or GID
+ * as users, search if a group with the same name exists.
* Don't worry about users, if we try to add a user with the same
* name the operation will fail */
ret = sysdb_search_group_by_name(tmp_ctx, domain, name, NULL, &msg);
if (ret != ENOENT) {
- if (ret == EOK) ret = EEXIST;
+ if (ret == EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Group named %s already exists in an MPG domain\n",
+ name);
+ ret = EEXIST;
+ }
goto done;
}
+
+ if (strcasecmp(domain->provider, "local") != 0) {
+ ret = sysdb_search_group_by_gid(tmp_ctx, domain, uid, NULL, &msg);
+ if (ret != ENOENT) {
+ if (ret == EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Group with GID [%"SPRIgid"] already exists in an "
+ "MPG domain\n", gid);
+ ret = EEXIST;
+ }
+ goto done;
+ }
+ }
}
/* check no other user with the same uid exist */
@@ -2177,6 +2195,23 @@ int sysdb_add_group(struct sss_domain_info *domain,
}
goto done;
}
+
+ if (strcasecmp(domain->provider, "local") != 0) {
+ ret = sysdb_search_user_by_uid(tmp_ctx, domain, gid, NULL, &msg);
+ if (ret != ENOENT) {
+ if (ret == EOK) {
+ DEBUG(SSSDBG_TRACE_LIBS,
+ "User with the same UID exists in MPG domain: "
+ "[%"SPRIgid"].\n", gid);
+ ret = EEXIST;
+ } else {
+ DEBUG(SSSDBG_TRACE_LIBS,
+ "sysdb_search_user_by_uid failed for gid: "
+ "[%"SPRIgid"].\n", gid);
+ }
+ goto done;
+ }
+ }
}
/* check no other groups with the same gid exist */
--
2.15.1

View File

@ -0,0 +1,345 @@
From dc8e3fcdd6807974122e47ff97e9bbd3be16557f Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Tue, 3 Oct 2017 16:55:40 +0200
Subject: [PATCH 08/79] TESTS: Add integration tests for the
auto_private_groups option
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Related:
https://pagure.io/SSSD/sssd/issue/1872
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/tests/intg/test_enumeration.py | 79 +++++++++++++-
src/tests/intg/test_ldap.py | 214 +++++++++++++++++++++++++++++++++++++
2 files changed, 290 insertions(+), 3 deletions(-)
diff --git a/src/tests/intg/test_enumeration.py b/src/tests/intg/test_enumeration.py
index fdb8d376879f756957f8f25fd28b37d7178aeff5..c7d78155c64dc6c85cb4dc070b205bdcfceff6af 100644
--- a/src/tests/intg/test_enumeration.py
+++ b/src/tests/intg/test_enumeration.py
@@ -237,9 +237,7 @@ def sanity_rfc2307(request, ldap_conn):
create_sssd_fixture(request)
return None
-
-@pytest.fixture
-def sanity_rfc2307_bis(request, ldap_conn):
+def populate_rfc2307bis(request, ldap_conn):
ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn)
ent_list.add_user("user1", 1001, 2001)
ent_list.add_user("user2", 1002, 2002)
@@ -266,6 +264,11 @@ def sanity_rfc2307_bis(request, ldap_conn):
[], ["one_user_group1", "one_user_group2"])
create_ldap_fixture(request, ldap_conn, ent_list)
+
+
+@pytest.fixture
+def sanity_rfc2307_bis(request, ldap_conn):
+ populate_rfc2307bis(request, ldap_conn)
conf = format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS)
create_conf_fixture(request, conf)
create_sssd_fixture(request)
@@ -695,3 +698,73 @@ def test_vetoed_shells(vetoed_shells):
shell="/bin/default")
)
)
+
+
+@pytest.fixture
+def sanity_rfc2307_bis_mpg(request, ldap_conn):
+ populate_rfc2307bis(request, ldap_conn)
+
+ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn)
+ ent_list.add_group_bis("conflict1", 1001)
+ ent_list.add_group_bis("conflict2", 1002)
+ create_ldap_fixture(request, ldap_conn, ent_list)
+
+ conf = \
+ format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) + \
+ unindent("""
+ [domain/LDAP]
+ auto_private_groups = True
+ """).format(**locals())
+ create_conf_fixture(request, conf)
+ create_sssd_fixture(request)
+ return None
+
+
+def test_ldap_auto_private_groups_enumerate(ldap_conn,
+ sanity_rfc2307_bis_mpg):
+ """
+ Test the auto_private_groups together with enumeration
+ """
+ passwd_pattern = ent.contains_only(
+ dict(name='user1', passwd='*', uid=1001, gid=1001, gecos='1001',
+ dir='/home/user1', shell='/bin/bash'),
+ dict(name='user2', passwd='*', uid=1002, gid=1002, gecos='1002',
+ dir='/home/user2', shell='/bin/bash'),
+ dict(name='user3', passwd='*', uid=1003, gid=1003, gecos='1003',
+ dir='/home/user3', shell='/bin/bash')
+ )
+ ent.assert_passwd(passwd_pattern)
+
+ group_pattern = ent.contains_only(
+ dict(name='user1', passwd='*', gid=1001, mem=ent.contains_only()),
+ dict(name='user2', passwd='*', gid=1002, mem=ent.contains_only()),
+ dict(name='user3', passwd='*', gid=1003, mem=ent.contains_only()),
+ dict(name='group1', passwd='*', gid=2001, mem=ent.contains_only()),
+ dict(name='group2', passwd='*', gid=2002, mem=ent.contains_only()),
+ dict(name='group3', passwd='*', gid=2003, mem=ent.contains_only()),
+ dict(name='empty_group1', passwd='*', gid=2010,
+ mem=ent.contains_only()),
+ dict(name='empty_group2', passwd='*', gid=2011,
+ mem=ent.contains_only()),
+ dict(name='two_user_group', passwd='*', gid=2012,
+ mem=ent.contains_only("user1", "user2")),
+ dict(name='group_empty_group', passwd='*', gid=2013,
+ mem=ent.contains_only()),
+ dict(name='group_two_empty_groups', passwd='*', gid=2014,
+ mem=ent.contains_only()),
+ dict(name='one_user_group1', passwd='*', gid=2015,
+ mem=ent.contains_only("user1")),
+ dict(name='one_user_group2', passwd='*', gid=2016,
+ mem=ent.contains_only("user2")),
+ dict(name='group_one_user_group', passwd='*', gid=2017,
+ mem=ent.contains_only("user1")),
+ dict(name='group_two_user_group', passwd='*', gid=2018,
+ mem=ent.contains_only("user1", "user2")),
+ dict(name='group_two_one_user_groups', passwd='*', gid=2019,
+ mem=ent.contains_only("user1", "user2"))
+ )
+ ent.assert_group(group_pattern)
+
+ with pytest.raises(KeyError):
+ grp.getgrnam("conflict1")
+ ent.assert_group_by_gid(1002, dict(name="user2", mem=ent.contains_only()))
diff --git a/src/tests/intg/test_ldap.py b/src/tests/intg/test_ldap.py
index f2467f1ffe9890049ad73bba6432102d029510e8..a6659b1b78df4d72eb98c208d67ee5d10c9c88ea 100644
--- a/src/tests/intg/test_ldap.py
+++ b/src/tests/intg/test_ldap.py
@@ -1169,3 +1169,217 @@ def test_nss_filters_cached(ldap_conn, sanity_nss_filter_cached):
res, _ = call_sssd_getgrgid(0)
assert res == NssReturnCode.NOTFOUND
+
+
+@pytest.fixture
+def mpg_setup(request, ldap_conn):
+ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn)
+ ent_list.add_user("user1", 1001, 2001)
+ ent_list.add_user("user2", 1002, 2002)
+ ent_list.add_user("user3", 1003, 2003)
+
+ ent_list.add_group_bis("group1", 2001)
+ ent_list.add_group_bis("group2", 2002)
+ ent_list.add_group_bis("group3", 2003)
+
+ ent_list.add_group_bis("two_user_group", 2012, ["user1", "user2"])
+ ent_list.add_group_bis("one_user_group1", 2015, ["user1"])
+ ent_list.add_group_bis("one_user_group2", 2016, ["user2"])
+
+ create_ldap_entries(ldap_conn, ent_list)
+ create_ldap_cleanup(request, ldap_conn, None)
+
+ conf = \
+ format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) + \
+ unindent("""
+ [domain/LDAP]
+ auto_private_groups = True
+ """).format(**locals())
+ create_conf_fixture(request, conf)
+ create_sssd_fixture(request)
+ return None
+
+
+def test_ldap_auto_private_groups_direct(ldap_conn, mpg_setup):
+ """
+ Integration test for auto_private_groups
+
+ See also ticket https://pagure.io/SSSD/sssd/issue/1872
+ """
+ # Make sure the user's GID is taken from their uidNumber
+ ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=1001))
+ # Make sure the private group is resolvable by name and by GID
+ ent.assert_group_by_name("user1", dict(gid=1001, mem=ent.contains_only()))
+ ent.assert_group_by_gid(1001, dict(name="user1", mem=ent.contains_only()))
+
+ # The group referenced in user's gidNumber attribute should be still
+ # visible, but it's fine that it doesn't contain the user as a member
+ # as the group is currently added during the initgroups operation only
+ ent.assert_group_by_name("group1", dict(gid=2001, mem=ent.contains_only()))
+ ent.assert_group_by_gid(2001, dict(name="group1", mem=ent.contains_only()))
+
+ # The user's secondary groups list must be correct as well
+ # Note that the original GID is listed as well -- this is correct and expected
+ # because we save the original GID in the SYSDB_PRIMARY_GROUP_GIDNUM attribute
+ user1_expected_gids = [1001, 2001, 2012, 2015]
+ (res, errno, gids) = sssd_id.call_sssd_initgroups("user1", 1001)
+ assert res == sssd_id.NssReturnCode.SUCCESS
+
+ assert sorted(gids) == sorted(user1_expected_gids), \
+ "result: %s\n expected %s" % (
+ ", ".join(["%s" % s for s in sorted(gids)]),
+ ", ".join(["%s" % s for s in sorted(user1_expected_gids)])
+ )
+
+ # Request user2's private group by GID without resolving the user first.
+ # This must trigger user resolution through by-GID resolution, since the GID
+ # doesn't exist on its own in LDAP
+ ent.assert_group_by_gid(1002, dict(name="user2", mem=ent.contains_only()))
+
+ # Test supplementary groups for user2 as well
+ user1_expected_gids = [1002, 2002, 2012, 2016]
+ (res, errno, gids) = sssd_id.call_sssd_initgroups("user2", 1002)
+ assert res == sssd_id.NssReturnCode.SUCCESS
+
+ assert sorted(gids) == sorted(user1_expected_gids), \
+ "result: %s\n expected %s" % (
+ ", ".join(["%s" % s for s in sorted(gids)]),
+ ", ".join(["%s" % s for s in sorted(user1_expected_gids)])
+ )
+
+ # Request user3's private group by name without resolving the user first
+ # This must trigger user resolution through by-name resolution, since the
+ # name doesn't exist on its own in LDAP
+ ent.assert_group_by_name("user3", dict(gid=1003, mem=ent.contains_only()))
+
+ # Remove entries and request them again to make sure they are not
+ # resolvable anymore
+ cleanup_ldap_entries(ldap_conn, None)
+
+ if subprocess.call(["sss_cache", "-GU"]) != 0:
+ raise Exception("sssd_cache failed")
+
+ with pytest.raises(KeyError):
+ pwd.getpwnam("user1")
+ with pytest.raises(KeyError):
+ grp.getgrnam("user1")
+ with pytest.raises(KeyError):
+ grp.getgrgid(1002)
+ with pytest.raises(KeyError):
+ grp.getgrnam("user3")
+
+
+@pytest.fixture
+def mpg_setup_conflict(request, ldap_conn):
+ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn)
+ ent_list.add_user("user1", 1001, 2001)
+ ent_list.add_user("user2", 1002, 2002)
+ ent_list.add_user("user3", 1003, 1003)
+ ent_list.add_group_bis("group1", 1001)
+ ent_list.add_group_bis("group2", 1002)
+ ent_list.add_group_bis("group3", 1003)
+ ent_list.add_group_bis("supp_group", 2015, ["user3"])
+ create_ldap_fixture(request, ldap_conn, ent_list)
+
+ conf = \
+ format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) + \
+ unindent("""
+ [domain/LDAP]
+ auto_private_groups = True
+ """).format(**locals())
+ create_conf_fixture(request, conf)
+ create_sssd_fixture(request)
+ return None
+
+
+def test_ldap_auto_private_groups_conflict(ldap_conn, mpg_setup_conflict):
+ """
+ Make sure that conflicts between groups that are auto-created with the
+ help of the auto_private_groups option and between 'real' LDAP groups
+ are handled in a predictable manner.
+ """
+ # Make sure the user's GID is taken from their uidNumber
+ ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=1001))
+ # Make sure the private group is resolvable by name and by GID
+ ent.assert_group_by_name("user1", dict(gid=1001, mem=ent.contains_only()))
+ ent.assert_group_by_gid(1001, dict(name="user1", mem=ent.contains_only()))
+
+ # Let's request the group with the same ID as user2's private group
+ # The request should match the 'real' group
+ ent.assert_group_by_gid(1002, dict(name="group2", mem=ent.contains_only()))
+ # But because of the GID conflict, the user cannot be resolved
+ with pytest.raises(KeyError):
+ pwd.getpwnam("user2")
+
+ # This user's GID is the same as the UID in this entry. The most important
+ # thing here is that the supplementary groups are correct and the GID
+ # resolves to the private group (as long as the user was requested first)
+ user3_expected_gids = [1003, 2015]
+ ent.assert_passwd_by_name("user3", dict(name="user3", uid=1003, gid=1003))
+ (res, errno, gids) = sssd_id.call_sssd_initgroups("user3", 1003)
+ assert res == sssd_id.NssReturnCode.SUCCESS
+
+ assert sorted(gids) == sorted(user3_expected_gids), \
+ "result: %s\n expected %s" % (
+ ", ".join(["%s" % s for s in sorted(gids)]),
+ ", ".join(["%s" % s for s in sorted(user3_expected_gids)])
+ )
+ # Make sure the private group is resolvable by name and by GID
+ ent.assert_group_by_gid(1003, dict(name="user3", mem=ent.contains_only()))
+ ent.assert_group_by_name("user3", dict(gid=1003, mem=ent.contains_only()))
+
+
+@pytest.fixture
+def mpg_setup_no_gid(request, ldap_conn):
+ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn)
+ ent_list.add_user("user1", 1001, 2001)
+
+ ent_list.add_group_bis("group1", 2001)
+ ent_list.add_group_bis("one_user_group1", 2015, ["user1"])
+
+ create_ldap_entries(ldap_conn, ent_list)
+ create_ldap_cleanup(request, ldap_conn, None)
+
+ conf = \
+ format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) + \
+ unindent("""
+ [domain/LDAP]
+ auto_private_groups = True
+ ldap_user_gid_number = no_such_attribute
+ """).format(**locals())
+ create_conf_fixture(request, conf)
+ create_sssd_fixture(request)
+ return None
+
+
+def test_ldap_auto_private_groups_direct_no_gid(ldap_conn, mpg_setup_no_gid):
+ """
+ Integration test for auto_private_groups - test that even a user with
+ no GID assigned at all can be resolved including their autogenerated
+ primary group.
+
+ See also ticket https://pagure.io/SSSD/sssd/issue/1872
+ """
+ # Make sure the user's GID is taken from their uidNumber
+ ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=1001))
+ # Make sure the private group is resolvable by name and by GID
+ ent.assert_group_by_name("user1", dict(gid=1001, mem=ent.contains_only()))
+ ent.assert_group_by_gid(1001, dict(name="user1", mem=ent.contains_only()))
+
+ # The group referenced in user's gidNumber attribute should be still
+ # visible, but shouldn't have any relation to the user
+ ent.assert_group_by_name("group1", dict(gid=2001, mem=ent.contains_only()))
+ ent.assert_group_by_gid(2001, dict(name="group1", mem=ent.contains_only()))
+
+ # The user's secondary groups list must be correct as well. This time only
+ # the generated group and the explicit secondary group are added, since
+ # there is no original GID
+ user1_expected_gids = [1001, 2015]
+ (res, errno, gids) = sssd_id.call_sssd_initgroups("user1", 1001)
+ assert res == sssd_id.NssReturnCode.SUCCESS
+
+ assert sorted(gids) == sorted(user1_expected_gids), \
+ "result: %s\n expected %s" % (
+ ", ".join(["%s" % s for s in sorted(gids)]),
+ ", ".join(["%s" % s for s in sorted(user1_expected_gids)])
+ )
--
2.15.1

View File

@ -1,7 +1,7 @@
From 0f44eefe2ce75a0814c8688495477f6c57f3d39a Mon Sep 17 00:00:00 2001
From ec2489ab1ba7075e69f1f3747d96656ac2b0aab5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Fri, 20 Oct 2017 09:26:43 +0200
Subject: [PATCH] CACHE_REQ: Copy the cr_domain list for each request
Subject: [PATCH 09/79] CACHE_REQ: Copy the cr_domain list for each request
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
@ -137,5 +137,5 @@ index 3780a5d8d88d76e100738d28d1dd0e697edf5eae..ebdc71dd635d5d8a5d06e30e96c5d410
--
2.15.0
2.15.1

View File

@ -0,0 +1,41 @@
From a0f79dd38cffc5ad382aae9baba76863678c26ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 20 Oct 2017 11:49:26 +0200
Subject: [PATCH 10/79] sudo: document background activity
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When we introduced socket activation, we changed the internall behaviour.
Previously we disabled sudo if it was not listed in services, with
socket activation we removed this feature. Some users were confused
so this change documents current behaviour.
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/man/sssd.conf.5.xml | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 1e8d9537517c85c3021b9c2c4185ea272c5bfffa..b247b5ac75a82d45f29023f5f9ca24a3a7a5ce0c 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -2348,6 +2348,14 @@ pam_account_locked_message = Account locked, please contact help desk.
<manvolnum>5</manvolnum>
</citerefentry>.
</para>
+ <para>
+ <emphasis>NOTE:</emphasis> Sudo rules are
+ periodically downloaded in the background unless
+ the sudo provider is explicitly disabled. Set
+ <emphasis>sudo_provider = None</emphasis> to
+ disable all sudo-related activity in SSSD if you do
+ not want to use sudo with SSSD at all.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
--
2.15.1

View File

@ -0,0 +1,40 @@
From bb20c565417a2c2ab274b254e6238657c5d8c73a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Thu, 26 Oct 2017 17:12:17 +0200
Subject: [PATCH 11/79] MAN: GPO Security Filtering limitation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Note in the man pages that current version of SSSD does not support
host entries in the 'Security filtering' list.
Resolves:
https://pagure.io/SSSD/sssd/issue/3444
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/man/sssd-ad.5.xml | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index 08c1dd09fb829c6cffb416250b9b518668ec5790..649042d587de3d3600fff59866681e302c721af8 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -345,6 +345,13 @@ DOM:dom1:(memberOf:1.2.840.113556.1.4.1941:=cn=nestedgroup,ou=groups,dc=example,
particular user is allowed to logon to a particular
host.
</para>
+ <para>
+ NOTE: The current version of SSSD does not support
+ host (computer) entries in the GPO 'Security
+ Filtering' list. Only user and group entries are
+ supported. Host entries in the list have no
+ effect.
+ </para>
<para>
NOTE: If the operation mode is set to enforcing, it
is possible that users that were previously allowed
--
2.15.1

View File

@ -0,0 +1,55 @@
From 5b34c650b387192282f3c2cd6211db0fd4944870 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 30 Oct 2017 14:54:07 +0100
Subject: [PATCH 12/79] CI: Ignore source file generated by systemtap
There are some changes in systemtap 3.2 which generate temporary
source files and remove them later. We are not interested in code
coverage in this area. Lets ignore them.
...
genhtml: failure 00:00:01 ci-build-coverage/ci-genhtml.log
FAILURE
sh$ cat ci-build-coverage/ci-genhtml.log
Start: Mon Oct 30 13:43:52 UTC 2017
+ eval 'genhtml --output-directory \
"$coverage_report_dir" \
--title "sssd" --show-details \
--legend --prefix "$BASE_DIR" \
ci.info |& tee ci-genhtml.out'
++ genhtml --output-directory ci-report-coverage --title sssd \
--show-details --legend --prefix /home/build/sssd ci.info
++ tee ci-genhtml.out
Reading data file ci.info
Found 447 entries.
Using user-specified filename prefix "/home/build/sssd"
Writing .css and .png files.
Generating output.
genhtml: ERROR: cannot read /home/build/sssd/stap_generated_probes.o.dtrace-temp.c
Processing file stap_generated_probes.o.dtrace-temp.c
End: Mon Oct 30 13:43:53 UTC 2017
sh$ ls -l /home/build/sssd/stap_generated_probes.o.dtrace-temp.c
ls: cannot access '/home/build/sssd/stap_generated_probes.o.dtrace-temp.c': No such file or directory
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
contrib/ci/run | 1 +
1 file changed, 1 insertion(+)
diff --git a/contrib/ci/run b/contrib/ci/run
index aa6d35abedbd24fce49651e43f4a704b2b1b9880..26cd32b3316eb9fdfd9fd07e26dd862fec7b669d 100755
--- a/contrib/ci/run
+++ b/contrib/ci/run
@@ -300,6 +300,7 @@ function build_coverage()
--output-file ci-dirty.info
stage lcov-clean lcov --remove ci-dirty.info \
"/usr/*" "src/tests/*" "/tmp/*" \
+ "*dtrace-temp.c" \
--output-file ci.info
stage genhtml eval 'genhtml --output-directory \
"$coverage_report_dir" \
--
2.15.1

View File

@ -0,0 +1,63 @@
From 25bc436bccacb7f995314465b2923c6e08f654d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 19 Oct 2017 10:39:21 +0200
Subject: [PATCH 13/79] sudo: always use srv_opts from id context
Prior this patch, we remember id_ctx->srv_opts in sudo request to switch
the latest usn values. This works fine most of the time but it may cause
a crash.
If we have two concurrent sudo refresh and one of these fails, it causes
failover to try the next server and possibly replacing the old srv_opts
with new one and it causes an access after free in the other refresh.
Resolves:
https://pagure.io/SSSD/sssd/issue/3562
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
src/providers/ldap/sdap_async_sudo.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index f33d5b5fa86dc1806695482d627bd71a2b040d6e..5dc58012845b7109f0fa138e2e291b8ec3267799 100644
--- a/src/providers/ldap/sdap_async_sudo.c
+++ b/src/providers/ldap/sdap_async_sudo.c
@@ -279,7 +279,6 @@ done:
struct sdap_sudo_refresh_state {
struct sdap_sudo_ctx *sudo_ctx;
struct tevent_context *ev;
- struct sdap_server_opts *srv_opts;
struct sdap_options *opts;
struct sdap_id_op *sdap_op;
struct sysdb_ctx *sysdb;
@@ -405,9 +404,6 @@ static void sdap_sudo_refresh_connect_done(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_FUNC, "SUDO LDAP connection successful\n");
- /* Obtain srv_opts here in case of first connection. */
- state->srv_opts = state->sudo_ctx->id_ctx->srv_opts;
-
/* Renew host information if needed. */
if (state->sudo_ctx->run_hostinfo) {
subreq = sdap_sudo_get_hostinfo_send(state, state->opts,
@@ -586,7 +582,6 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq)
goto done;
}
-
/* start transaction */
ret = sysdb_transaction_start(state->sysdb);
if (ret != EOK) {
@@ -621,7 +616,7 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq)
/* remember new usn */
ret = sysdb_get_highest_usn(state, rules, rules_count, &usn);
if (ret == EOK) {
- sdap_sudo_set_usn(state->srv_opts, usn);
+ sdap_sudo_set_usn(state->sudo_ctx->id_ctx->srv_opts, usn);
} else {
DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get highest USN [%d]: %s\n",
ret, sss_strerror(ret));
--
2.15.1

View File

@ -0,0 +1,108 @@
From ceb9cc228793551eb0fc42234ee3f9b3c9d6cb9b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 18 Oct 2017 15:20:34 +0200
Subject: [PATCH 14/79] AD: Remember last site discovered
To discover Active Directory site for a client we must first contact any
directory controller for an LDAP ping. This is done by searching
domain-wide DNS tree which may however contain servers that are not
reachable from current site and than we face long timeouts or failure.
This patch makes sssd remember the last successfuly discovered site
and use this for DNS search to lookup a site and forest again similar
to what we do when ad_site option is set.
Resolves:
https://pagure.io/SSSD/sssd/issue/3265
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
src/providers/ad/ad_srv.c | 44 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)
diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c
index ff01ee95c4d2c6875a989394489f1a0495cc3003..be1ba0f237add894566ae713ce5e29fd202d414c 100644
--- a/src/providers/ad/ad_srv.c
+++ b/src/providers/ad/ad_srv.c
@@ -481,6 +481,7 @@ struct ad_srv_plugin_ctx {
const char *hostname;
const char *ad_domain;
const char *ad_site_override;
+ const char *current_site;
};
struct ad_srv_plugin_ctx *
@@ -518,6 +519,11 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
if (ctx->ad_site_override == NULL) {
goto fail;
}
+
+ ctx->current_site = talloc_strdup(ctx, ad_site_override);
+ if (ctx->current_site == NULL) {
+ goto fail;
+ }
}
return ctx;
@@ -527,6 +533,32 @@ fail:
return NULL;
}
+static errno_t
+ad_srv_plugin_ctx_switch_site(struct ad_srv_plugin_ctx *ctx,
+ const char *new_site)
+{
+ const char *site;
+ errno_t ret;
+
+ if (new_site == NULL) {
+ return EOK;
+ }
+
+ if (ctx->current_site != NULL && strcmp(ctx->current_site, new_site) == 0) {
+ return EOK;
+ }
+
+ site = talloc_strdup(ctx, new_site);
+ if (site == NULL) {
+ return ENOMEM;
+ }
+
+ talloc_zfree(ctx->current_site);
+ ctx->current_site = site;
+
+ return EOK;
+}
+
struct ad_srv_plugin_state {
struct tevent_context *ev;
struct ad_srv_plugin_ctx *ctx;
@@ -613,7 +645,7 @@ struct tevent_req *ad_srv_plugin_send(TALLOC_CTX *mem_ctx,
subreq = ad_get_dc_servers_send(state, ev, ctx->be_res->resolv,
state->discovery_domain,
- state->ctx->ad_site_override);
+ state->ctx->current_site);
if (subreq == NULL) {
ret = ENOMEM;
goto immediately;
@@ -709,6 +741,16 @@ static void ad_srv_plugin_site_done(struct tevent_req *subreq)
backup_domain = NULL;
if (ret == EOK) {
+ /* Remember current site so it can be used during next lookup so
+ * we can contact directory controllers within a known reachable
+ * site first. */
+ ret = ad_srv_plugin_ctx_switch_site(state->ctx, state->site);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set site [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
if (strcmp(state->service, "gc") == 0) {
if (state->forest != NULL) {
if (state->site != NULL) {
--
2.15.1

View File

@ -0,0 +1,205 @@
From 8687782eb971d0fa6f8f4420a8616ba943d7252b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 24 Oct 2017 12:09:39 +0200
Subject: [PATCH 15/79] sysdb: add functions to get/set client site
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
src/db/sysdb.h | 10 +++
src/db/sysdb_subdomains.c | 108 +++++++++++++++++++++++++++++++
src/tests/cmocka/test_sysdb_subdomains.c | 28 ++++++++
3 files changed, 146 insertions(+)
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index fbbe321072385bd43353ef2f7d0e30667887d128..4192f9085d941814eccd2ac60ce8fb6d4e1bfa67 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -154,6 +154,7 @@
#define SYSDB_SUBDOMAIN_FOREST "memberOfForest"
#define SYSDB_SUBDOMAIN_TRUST_DIRECTION "trustDirection"
#define SYSDB_UPN_SUFFIXES "upnSuffixes"
+#define SYSDB_SITE "site"
#define SYSDB_BASE_ID "baseID"
#define SYSDB_ID_RANGE_SIZE "idRangeSize"
@@ -509,6 +510,15 @@ errno_t sysdb_domain_update_domain_resolution_order(
const char *domain_name,
const char *domain_resolution_order);
+errno_t
+sysdb_get_site(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *dom,
+ const char **_site);
+
+errno_t
+sysdb_set_site(struct sss_domain_info *dom,
+ const char *site);
+
errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb,
const char *name, const char *realm,
const char *flat_name, const char *domain_id,
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index 2789cc4949fb7be9ad272d7613ed18a64fa8a20a..cb5de1afe3e8c9692789c5d2679eb3a4e6e1cdb2 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -1284,3 +1284,111 @@ done:
talloc_free(tmp_ctx);
return ret;
}
+
+errno_t
+sysdb_get_site(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *dom,
+ const char **_site)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_res *res;
+ struct ldb_dn *dn;
+ const char *attrs[] = { SYSDB_SITE, NULL };
+ errno_t ret;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ dn = ldb_dn_new_fmt(tmp_ctx, dom->sysdb->ldb, SYSDB_DOM_BASE, dom->name);
+ if (dn == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ldb_search(dom->sysdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
+ attrs, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ if (res->count == 0) {
+ *_site = NULL;
+ ret = EOK;
+ goto done;
+ } else if (res->count != 1) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Got more than one reply for base search!\n");
+ ret = EIO;
+ goto done;
+ }
+
+ *_site = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SITE, NULL);
+ talloc_steal(mem_ctx, *_site);
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+errno_t
+sysdb_set_site(struct sss_domain_info *dom,
+ const char *site)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_message *msg;
+ struct ldb_dn *dn;
+ errno_t ret;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ dn = ldb_dn_new_fmt(tmp_ctx, dom->sysdb->ldb, SYSDB_DOM_BASE, dom->name);
+ if (dn == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ msg = ldb_msg_new(tmp_ctx);
+ if (msg == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ msg->dn = dn;
+
+ ret = ldb_msg_add_empty(msg, SYSDB_SITE, LDB_FLAG_MOD_REPLACE, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ if (site != NULL) {
+ ret = ldb_msg_add_string(msg, SYSDB_SITE, site);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+ }
+
+ ret = ldb_modify(dom->sysdb->ldb, msg);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "ldb_modify()_failed: [%s][%d][%s]\n",
+ ldb_strerror(ret), ret, ldb_errstring(dom->sysdb->ldb));
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c
index 84bcdc17b39dbc8822097c2006f157a09ea5e466..f8e3e1d915dba0f3a79adbf5af733980bf23a265 100644
--- a/src/tests/cmocka/test_sysdb_subdomains.c
+++ b/src/tests/cmocka/test_sysdb_subdomains.c
@@ -513,6 +513,31 @@ static void test_sysdb_link_ad_multidom(void **state)
}
+static void test_sysdb_set_and_get_site(void **state)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct subdom_test_ctx *test_ctx =
+ talloc_get_type(*state, struct subdom_test_ctx);
+ const char *site;
+ errno_t ret;
+
+ tmp_ctx = talloc_new(NULL);
+ assert_non_null(test_ctx);
+
+ ret = sysdb_get_site(test_ctx, test_ctx->tctx->dom, &site);
+ assert_int_equal(ret, EOK);
+ assert_null(site);
+
+ ret = sysdb_set_site(test_ctx->tctx->dom, "TestSite");
+ assert_int_equal(ret, EOK);
+
+ ret = sysdb_get_site(tmp_ctx, test_ctx->tctx->dom, &site);
+ assert_int_equal(ret, EOK);
+ assert_string_equal(site, "TestSite");
+
+ talloc_free(tmp_ctx);
+}
+
int main(int argc, const char *argv[])
{
int rv;
@@ -546,6 +571,9 @@ int main(int argc, const char *argv[])
cmocka_unit_test_setup_teardown(test_sysdb_link_ad_multidom,
test_sysdb_subdom_setup,
test_sysdb_subdom_teardown),
+ cmocka_unit_test_setup_teardown(test_sysdb_set_and_get_site,
+ test_sysdb_subdom_setup,
+ test_sysdb_subdom_teardown),
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */
--
2.15.1

View File

@ -0,0 +1,160 @@
From 48f58549e2b687ba405162bd5db23f1c323732f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 1 Nov 2017 14:57:17 +0100
Subject: [PATCH 16/79] AD: Remember last site discovered in sysdb
This can speed up sssd startup.
Resolves:
https://pagure.io/SSSD/sssd/issue/3265
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
src/db/sysdb_subdomains.c | 2 +-
src/providers/ad/ad_init.c | 2 +-
src/providers/ad/ad_srv.c | 21 +++++++++++++++++++++
src/providers/ad/ad_srv.h | 1 +
src/providers/ad/ad_subdomains.c | 2 +-
src/providers/ipa/ipa_subdomains_server.c | 2 +-
6 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index cb5de1afe3e8c9692789c5d2679eb3a4e6e1cdb2..353561765904efe4bd698c38949a1b290ecf0b80 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -1291,7 +1291,7 @@ sysdb_get_site(TALLOC_CTX *mem_ctx,
const char **_site)
{
TALLOC_CTX *tmp_ctx;
- struct ldb_res *res;
+ struct ldb_result *res;
struct ldb_dn *dn;
const char *attrs[] = { SYSDB_SITE, NULL };
errno_t ret;
diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c
index 131e960d4c623398506f834742400df9c786b86b..e62025d4acd24844a5c7082d00c597516f35de16 100644
--- a/src/providers/ad/ad_init.c
+++ b/src/providers/ad/ad_init.c
@@ -199,7 +199,7 @@ static errno_t ad_init_srv_plugin(struct be_ctx *be_ctx,
return EOK;
}
- srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res,
+ 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);
diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c
index be1ba0f237add894566ae713ce5e29fd202d414c..4fa1668605e131b2e31802b1401f49fc6e00a23b 100644
--- a/src/providers/ad/ad_srv.c
+++ b/src/providers/ad/ad_srv.c
@@ -34,6 +34,7 @@
#include "providers/fail_over_srv.h"
#include "providers/ldap/sdap.h"
#include "providers/ldap/sdap_async.h"
+#include "db/sysdb.h"
#define AD_SITE_DOMAIN_FMT "%s._sites.%s"
@@ -475,6 +476,7 @@ int ad_get_client_site_recv(TALLOC_CTX *mem_ctx,
}
struct ad_srv_plugin_ctx {
+ struct be_ctx *be_ctx;
struct be_resolv_ctx *be_res;
enum host_database *host_dbs;
struct sdap_options *opts;
@@ -486,6 +488,7 @@ struct ad_srv_plugin_ctx {
struct ad_srv_plugin_ctx *
ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
+ struct be_ctx *be_ctx,
struct be_resolv_ctx *be_res,
enum host_database *host_dbs,
struct sdap_options *opts,
@@ -494,12 +497,14 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
const char *ad_site_override)
{
struct ad_srv_plugin_ctx *ctx = NULL;
+ errno_t ret;
ctx = talloc_zero(mem_ctx, struct ad_srv_plugin_ctx);
if (ctx == NULL) {
return NULL;
}
+ ctx->be_ctx = be_ctx;
ctx->be_res = be_res;
ctx->host_dbs = host_dbs;
ctx->opts = opts;
@@ -524,6 +529,15 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
if (ctx->current_site == NULL) {
goto fail;
}
+ } else {
+ ret = sysdb_get_site(ctx, be_ctx->domain, &ctx->current_site);
+ if (ret != EOK) {
+ /* Not fatal. */
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Unable to get current site from cache [%d]: %s\n",
+ ret, sss_strerror(ret));
+ ctx->current_site = NULL;
+ }
}
return ctx;
@@ -556,6 +570,13 @@ ad_srv_plugin_ctx_switch_site(struct ad_srv_plugin_ctx *ctx,
talloc_zfree(ctx->current_site);
ctx->current_site = site;
+ ret = sysdb_set_site(ctx->be_ctx->domain, ctx->current_site);
+ if (ret != EOK) {
+ /* Not fatal. */
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to store site information "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ }
+
return EOK;
}
diff --git a/src/providers/ad/ad_srv.h b/src/providers/ad/ad_srv.h
index ae5efe44755fa09f74064014cce749e35b1831da..fddef686762e57bb95d648247131d39a797aa516 100644
--- a/src/providers/ad/ad_srv.h
+++ b/src/providers/ad/ad_srv.h
@@ -25,6 +25,7 @@ struct ad_srv_plugin_ctx;
struct ad_srv_plugin_ctx *
ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx,
+ struct be_ctx *be_ctx,
struct be_resolv_ctx *be_res,
enum host_database *host_dbs,
struct sdap_options *opts,
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index 280aa54c23bf61e60d23ea91bd44a39f9f43d155..3fb9b950f171d85817cce35ac92ad7c4974ccb68 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -245,7 +245,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
ad_options->id_ctx = ad_id_ctx;
/* use AD plugin */
- srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res,
+ srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx, be_ctx->be_res,
default_host_dbs,
ad_id_ctx->ad_options->id,
hostname,
diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
index 10166d162f746fde176e6c7c2bfbe3906b1bfddc..d670a156b37608d20d49d79131138f02e4abf82b 100644
--- a/src/providers/ipa/ipa_subdomains_server.c
+++ b/src/providers/ipa/ipa_subdomains_server.c
@@ -305,7 +305,7 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE);
/* use AD plugin */
- srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res,
+ srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx, be_ctx->be_res,
default_host_dbs,
ad_id_ctx->ad_options->id,
id_ctx->server_mode->hostname,
--
2.15.1

View File

@ -0,0 +1,132 @@
From dad79765d9ccafb3ba5d31a20462d73af96fa058 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 23 Oct 2017 14:58:14 +0200
Subject: [PATCH 17/79] UTIL: Add wrapper function to configure logger
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let's use one enum for logger type instead of many integers (debug_to_file,
debug_to_stderr plus some weird combination for journald).
Old variable were also transformed to enum for backward compatibility
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/util/debug.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/util/debug.h | 18 ++++++++++++++++++
2 files changed, 72 insertions(+)
diff --git a/src/util/debug.c b/src/util/debug.c
index ca4fa4c6f5b150700a0a136d8a7ca9df30c29d73..4e469447e5ab8aa89cd57bcd6d00269875a12bc6 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -43,9 +43,63 @@ int debug_timestamps = SSSDBG_TIMESTAMP_UNRESOLVED;
int debug_microseconds = SSSDBG_MICROSECONDS_UNRESOLVED;
int debug_to_file = 0;
int debug_to_stderr = 0;
+enum sss_logger_t sss_logger;
const char *debug_log_file = "sssd";
FILE *debug_file = NULL;
+const char *sss_logger_str[] = {
+ [STDERR_LOGGER] = "stderr",
+ [FILES_LOGGER] = "files",
+#ifdef WITH_JOURNALD
+ [JOURNALD_LOGGER] = "journald",
+#endif
+ NULL,
+};
+
+#ifdef WITH_JOURNALD
+#define JOURNALD_STR " journald,"
+#else
+#define JOURNALD_STR ""
+#endif
+
+void sss_set_logger(const char *logger)
+{
+ /* use old flags */
+ if (logger == NULL) {
+ if (debug_to_stderr != 0) {
+ sss_logger = STDERR_LOGGER;
+ }
+ /* It is never described what should be used in case of
+ * debug_to_stderr == 1 && debug_to_file == 1. Because neither
+ * of binaries provide both command line arguments.
+ * Let files have higher priority.
+ */
+ if (debug_to_file != 0) {
+ sss_logger = FILES_LOGGER;
+ }
+#ifdef WITH_JOURNALD
+ if (debug_to_file == 0 && debug_to_stderr == 0) {
+ sss_logger = JOURNALD_LOGGER;
+ }
+#endif
+ } else {
+ if (strcmp(logger, "stderr") == 0) {
+ sss_logger = STDERR_LOGGER;
+ } else if (strcmp(logger, "files") == 0) {
+ sss_logger = FILES_LOGGER;
+#ifdef WITH_JOURNALD
+ } else if (strcmp(logger, "journald") == 0) {
+ sss_logger = JOURNALD_LOGGER;
+#endif
+ } else {
+ /* unexpected value */
+ fprintf(stderr, "Unexpected logger: %s\nExpected:%s stderr, "
+ "files\n", logger, JOURNALD_STR);
+ sss_logger = STDERR_LOGGER;
+ }
+ }
+}
+
errno_t set_debug_file_from_fd(const int fd)
{
FILE *dummy;
diff --git a/src/util/debug.h b/src/util/debug.h
index 2a1bd4ffd30817d7128805996c21105fe40982a2..4adafb7cfc03f7381c4d03071eb44edad04bee00 100644
--- a/src/util/debug.h
+++ b/src/util/debug.h
@@ -31,13 +31,26 @@
#define APPEND_LINE_FEED 0x1
+enum sss_logger_t {
+ STDERR_LOGGER = 0,
+ FILES_LOGGER,
+#ifdef WITH_JOURNALD
+ JOURNALD_LOGGER,
+#endif
+};
+
+extern const char *sss_logger_str[];
extern const char *debug_prg_name;
extern int debug_level;
extern int debug_timestamps;
extern int debug_microseconds;
extern int debug_to_file;
extern int debug_to_stderr;
+extern enum sss_logger_t sss_logger;
extern const char *debug_log_file;
+
+void sss_set_logger(const char *logger);
+
void sss_vdebug_fn(const char *file,
long line,
const char *function,
@@ -80,6 +93,11 @@ int get_fd_from_debug_file(void);
#define SSSDBG_MICROSECONDS_UNRESOLVED -1
#define SSSDBG_MICROSECONDS_DEFAULT 0
+#define SSSD_LOGGER_OPTS \
+ {"logger", '\0', POPT_ARG_STRING, &opt_logger, 0, \
+ _("Set logger"), "stderr|files|journald"},
+
+
#define SSSD_DEBUG_OPTS \
{"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, \
_("Debug level"), NULL}, \
--
2.15.1

View File

@ -0,0 +1,829 @@
From 0256b7734738302da9752db5297a3d41fccd40ac Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 23 Oct 2017 15:18:47 +0200
Subject: [PATCH 18/79] Add parameter --logger to daemons
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Different binary handled information about logging differently
e,g, --debug-to-files --debug-to-stderr
And logging to journald was a special case of previous options
(!debug_file && !debug_to_stderr). It was also tied to the monitor option
"--daemon" and therefore loggind to stderr was used in interactive mode
+ systemd Type=notify.
Resolves:
https://pagure.io/SSSD/sssd/issue/3433
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/man/sssd.8.xml | 31 +++++++++++++++++++++++++
src/monitor/monitor.c | 48 ++++++++++++---------------------------
src/p11_child/p11_child_nss.c | 3 +++
src/providers/ad/ad_gpo_child.c | 4 ++++
src/providers/data_provider_be.c | 4 ++++
src/providers/ipa/selinux_child.c | 4 ++++
src/providers/krb5/krb5_child.c | 4 ++++
src/providers/ldap/ldap_child.c | 4 ++++
src/providers/proxy/proxy_auth.c | 4 ++--
src/providers/proxy/proxy_child.c | 4 ++++
src/responder/autofs/autofssrv.c | 4 ++++
src/responder/ifp/ifpsrv.c | 4 ++++
src/responder/kcm/kcm.c | 4 ++++
src/responder/nss/nsssrv.c | 4 ++++
src/responder/pac/pacsrv.c | 4 ++++
src/responder/pam/pamsrv.c | 4 ++++
src/responder/secrets/secsrv.c | 4 ++++
src/responder/ssh/sshsrv.c | 4 ++++
src/responder/sudo/sudosrv.c | 4 ++++
src/tests/cmocka/dummy_child.c | 4 ++++
src/tests/debug-tests.c | 10 ++++++++
src/util/child_common.c | 2 +-
src/util/debug.c | 4 ++--
src/util/server.c | 12 ++++++----
24 files changed, 135 insertions(+), 43 deletions(-)
diff --git a/src/man/sssd.8.xml b/src/man/sssd.8.xml
index 923da6824907f0d2d140d9ca83f87338e7664f83..0b725628ff93f48f832140dd5dc15b040a8b179f 100644
--- a/src/man/sssd.8.xml
+++ b/src/man/sssd.8.xml
@@ -92,6 +92,37 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>
+ <option>--logger=</option><replaceable>value</replaceable>
+ </term>
+ <listitem>
+ <para>
+ Location where SSSD will send log messages. This option
+ overrides the value of the deprecated option
+ <option>--debug-to-files</option>. The deprecated
+ option will still work if the <option>--logger</option>
+ is not used.
+ </para>
+ <para>
+ <emphasis>stderr</emphasis>: Redirect debug messages to
+ standard error output.
+ </para>
+ <para>
+ <emphasis>files</emphasis>: Redirect debug messages to
+ the log files. By default, the log files are stored in
+ <filename>/var/log/sssd</filename> and there are
+ separate log files for every SSSD service and domain.
+ </para>
+ <para>
+ <emphasis>journald</emphasis>: Redirect debug messages
+ to systemd-journald
+ </para>
+ <para>
+ Default: not set
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>
<option>-D</option>,<option>--daemon</option>
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 7726548bbb666bb189667efc1de2295f8a001105..3c0b7ab2dac10fe15a8a5b807cb68ea4b7ab8461 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -1211,22 +1211,11 @@ static int get_service_config(struct mt_ctx *ctx, const char *name,
}
}
- if (debug_to_file) {
- svc->command = talloc_strdup_append(
- svc->command, " --debug-to-files"
- );
- if (!svc->command) {
- talloc_free(svc);
- return ENOMEM;
- }
- } else if (ctx->is_daemon == false) {
- svc->command = talloc_strdup_append(
- svc->command, " --debug-to-stderr"
- );
- if (!svc->command) {
- talloc_free(svc);
- return ENOMEM;
- }
+ svc->command = talloc_asprintf_append(
+ svc->command, " --logger=%s", sss_logger_str[sss_logger]);
+ if (!svc->command) {
+ talloc_free(svc);
+ return ENOMEM;
}
}
@@ -1374,22 +1363,11 @@ static int get_provider_config(struct mt_ctx *ctx, const char *name,
}
}
- if (debug_to_file) {
- svc->command = talloc_strdup_append(
- svc->command, " --debug-to-files"
- );
- if (!svc->command) {
- talloc_free(svc);
- return ENOMEM;
- }
- } else if (ctx->is_daemon == false) {
- svc->command = talloc_strdup_append(
- svc->command, " --debug-to-stderr"
- );
- if (!svc->command) {
- talloc_free(svc);
- return ENOMEM;
- }
+ svc->command = talloc_asprintf_append(
+ svc->command, " --logger=%s", sss_logger_str[sss_logger]);
+ if (!svc->command) {
+ talloc_free(svc);
+ return ENOMEM;
}
}
@@ -2454,6 +2432,7 @@ int main(int argc, const char *argv[])
int opt_version = 0;
int opt_netlinkoff = 0;
char *opt_config_file = NULL;
+ char *opt_logger = NULL;
char *config_file = NULL;
int flags = 0;
struct main_context *main_ctx;
@@ -2465,6 +2444,7 @@ int main(int argc, const char *argv[])
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
+ SSSD_LOGGER_OPTS
{"daemon", 'D', POPT_ARG_NONE, &opt_daemon, 0, \
_("Become a daemon (default)"), NULL }, \
{"interactive", 'i', POPT_ARG_NONE, &opt_interactive, 0, \
@@ -2551,6 +2531,8 @@ int main(int argc, const char *argv[])
debug_to_stderr = 1;
}
+ sss_set_logger(opt_logger);
+
if (opt_config_file) {
config_file = talloc_strdup(tmp_ctx, opt_config_file);
} else {
@@ -2575,7 +2557,7 @@ int main(int argc, const char *argv[])
/* Open before server_setup() does to have logging
* during configuration checking */
- if (debug_to_file) {
+ if (sss_logger == FILES_LOGGER) {
ret = open_debug_file();
if (ret) {
return 7;
diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c
index f165b58e63d2b8a6f26acf8bd89e7b41713e7359..e7dbcb689220d1cd2585fbde5f26e84f8fa15cc2 100644
--- a/src/p11_child/p11_child_nss.c
+++ b/src/p11_child/p11_child_nss.c
@@ -537,6 +537,7 @@ int main(int argc, const char *argv[])
int opt;
poptContext pc;
int debug_fd = -1;
+ char *opt_logger = NULL;
errno_t ret;
TALLOC_CTX *main_ctx = NULL;
char *cert;
@@ -564,6 +565,7 @@ int main(int argc, const char *argv[])
{"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN,
&debug_to_stderr, 0,
_("Send the debug output to stderr directly."), NULL },
+ SSSD_LOGGER_OPTS
{"auth", 0, POPT_ARG_NONE, NULL, 'a', _("Run in auth mode"), NULL},
{"pre", 0, POPT_ARG_NONE, NULL, 'p', _("Run in pre-auth mode"), NULL},
{"pin", 0, POPT_ARG_NONE, NULL, 'i', _("Expect PIN on stdin"), NULL},
@@ -672,6 +674,7 @@ int main(int argc, const char *argv[])
DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n");
}
}
+ sss_set_logger(opt_logger);
DEBUG(SSSDBG_TRACE_FUNC, "p11_child started.\n");
diff --git a/src/providers/ad/ad_gpo_child.c b/src/providers/ad/ad_gpo_child.c
index 8e5e062547721567cb450f9d0f72f1ec8cb99f96..5375cc691e8649c289672b74c4bfe5266c8222c9 100644
--- a/src/providers/ad/ad_gpo_child.c
+++ b/src/providers/ad/ad_gpo_child.c
@@ -687,6 +687,7 @@ main(int argc, const char *argv[])
int opt;
poptContext pc;
int debug_fd = -1;
+ char *opt_logger = NULL;
errno_t ret;
int sysvol_gpt_version;
int result;
@@ -710,6 +711,7 @@ main(int argc, const char *argv[])
{"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN,
&debug_to_stderr, 0,
_("Send the debug output to stderr directly."), NULL },
+ SSSD_LOGGER_OPTS
POPT_TABLEEND
};
@@ -744,6 +746,8 @@ main(int argc, const char *argv[])
}
}
+ sss_set_logger(opt_logger);
+
DEBUG(SSSDBG_TRACE_FUNC, "gpo_child started.\n");
main_ctx = talloc_new(NULL);
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 2e55dc4e3fe9ba1aa8c1c51c426efee00b9ae91d..56ddac112a209b6937313d3d3c94a73d2067331f 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -537,6 +537,7 @@ int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
+ char *opt_logger = NULL;
char *be_domain = NULL;
char *srv_name = NULL;
struct main_context *main_ctx;
@@ -548,6 +549,7 @@ int main(int argc, const char *argv[])
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
+ SSSD_LOGGER_OPTS
SSSD_SERVER_OPTS(uid, gid)
{"domain", 0, POPT_ARG_STRING, &be_domain, 0,
_("Domain of the information provider (mandatory)"), NULL },
@@ -582,6 +584,8 @@ int main(int argc, const char *argv[])
debug_log_file = talloc_asprintf(NULL, "sssd_%s", be_domain);
if (!debug_log_file) return 2;
+ sss_set_logger(opt_logger);
+
srv_name = talloc_asprintf(NULL, "sssd[be[%s]]", be_domain);
if (!srv_name) return 2;
diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c
index 073475094ee491bd5453898c6ba65214fa14fe59..120492686963241b7e419413f489cc38953e32f2 100644
--- a/src/providers/ipa/selinux_child.c
+++ b/src/providers/ipa/selinux_child.c
@@ -206,6 +206,7 @@ int main(int argc, const char *argv[])
struct response *resp = NULL;
ssize_t written;
bool needs_update;
+ char *opt_logger = NULL;
struct poptOption long_options[] = {
POPT_AUTOHELP
@@ -220,6 +221,7 @@ int main(int argc, const char *argv[])
{"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN,
&debug_to_stderr, 0,
_("Send the debug output to stderr directly."), NULL },
+ SSSD_LOGGER_OPTS
POPT_TABLEEND
};
@@ -254,6 +256,8 @@ int main(int argc, const char *argv[])
}
}
+ sss_set_logger(opt_logger);
+
DEBUG(SSSDBG_TRACE_FUNC, "selinux_child started.\n");
DEBUG(SSSDBG_TRACE_INTERNAL,
"Running with effective IDs: [%"SPRIuid"][%"SPRIgid"].\n",
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index b8ee497728b4b70fae89e528172e9d5bd42239c0..b44f3a20f1c0725304a37620d36f8872cf9ca5d7 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -3020,6 +3020,7 @@ int main(int argc, const char *argv[])
int opt;
poptContext pc;
int debug_fd = -1;
+ char *opt_logger = NULL;
errno_t ret;
krb5_error_code kerr;
uid_t fast_uid;
@@ -3039,6 +3040,7 @@ int main(int argc, const char *argv[])
{"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN,
&debug_to_stderr, 0,
_("Send the debug output to stderr directly."), NULL },
+ SSSD_LOGGER_OPTS
{CHILD_OPT_FAST_CCACHE_UID, 0, POPT_ARG_INT, &fast_uid, 0,
_("The user to create FAST ccache as"), NULL},
{CHILD_OPT_FAST_CCACHE_GID, 0, POPT_ARG_INT, &fast_gid, 0,
@@ -3097,6 +3099,8 @@ int main(int argc, const char *argv[])
}
}
+ sss_set_logger(opt_logger);
+
DEBUG(SSSDBG_TRACE_FUNC, "krb5_child started.\n");
kr = talloc_zero(NULL, struct krb5_req);
diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c
index b796e5cae01517c85c2fc1605b1e5877454691dc..baeed239db5dc7ffa482edcbc155f25f718c8249 100644
--- a/src/providers/ldap/ldap_child.c
+++ b/src/providers/ldap/ldap_child.c
@@ -599,6 +599,7 @@ int main(int argc, const char *argv[])
int kerr;
int opt;
int debug_fd = -1;
+ char *opt_logger = NULL;
poptContext pc;
TALLOC_CTX *main_ctx = NULL;
uint8_t *buf = NULL;
@@ -622,6 +623,7 @@ int main(int argc, const char *argv[])
_("An open file descriptor for the debug logs"), NULL},
{"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, \
_("Send the debug output to stderr directly."), NULL }, \
+ SSSD_LOGGER_OPTS
POPT_TABLEEND
};
@@ -657,6 +659,8 @@ int main(int argc, const char *argv[])
}
}
+ sss_set_logger(opt_logger);
+
BlockSignals(false, SIGTERM);
CatchSignal(SIGTERM, sig_term_handler);
diff --git a/src/providers/proxy/proxy_auth.c b/src/providers/proxy/proxy_auth.c
index a05586e60b6ef894b0fcf1b8b3f30fdbf51a808d..665a29cf779290b8d35973245a36a1b5224bca78 100644
--- a/src/providers/proxy/proxy_auth.c
+++ b/src/providers/proxy/proxy_auth.c
@@ -178,9 +178,9 @@ static struct tevent_req *proxy_child_init_send(TALLOC_CTX *mem_ctx,
state->command = talloc_asprintf(req,
"%s/proxy_child -d %#.4x --debug-timestamps=%d "
- "--debug-microseconds=%d%s --domain %s --id %d",
+ "--debug-microseconds=%d --logger=%s --domain %s --id %d",
SSSD_LIBEXEC_PATH, debug_level, debug_timestamps,
- debug_microseconds, (debug_to_file ? " --debug-to-files" : ""),
+ debug_microseconds, sss_logger_str[sss_logger],
auth_ctx->be->domain->name,
child_ctx->id);
if (state->command == NULL) {
diff --git a/src/providers/proxy/proxy_child.c b/src/providers/proxy/proxy_child.c
index be58622eb8b26231eeb6699976d51f57dc44de98..ae4855adeb5cc68f1a19003355a5d94f5b1bb378 100644
--- a/src/providers/proxy/proxy_child.c
+++ b/src/providers/proxy/proxy_child.c
@@ -504,6 +504,7 @@ int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
+ char *opt_logger = NULL;
char *domain = NULL;
char *srv_name = NULL;
char *conf_entry = NULL;
@@ -517,6 +518,7 @@ int main(int argc, const char *argv[])
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
+ SSSD_LOGGER_OPTS
SSSD_SERVER_OPTS(uid, gid)
{"domain", 0, POPT_ARG_STRING, &domain, 0,
_("Domain of the information provider (mandatory)"), NULL },
@@ -561,6 +563,8 @@ int main(int argc, const char *argv[])
debug_log_file = talloc_asprintf(NULL, "proxy_child_%s", domain);
if (!debug_log_file) return 2;
+ sss_set_logger(opt_logger);
+
srv_name = talloc_asprintf(NULL, "sssd[proxy_child[%s]]", domain);
if (!srv_name) return 2;
diff --git a/src/responder/autofs/autofssrv.c b/src/responder/autofs/autofssrv.c
index cfb2233fdfc346bf27b128ee8c4261f4c73e3470..b0762a2b685a7c5ab3abfa281f0906ad8bfe1c88 100644
--- a/src/responder/autofs/autofssrv.c
+++ b/src/responder/autofs/autofssrv.c
@@ -185,6 +185,7 @@ int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
+ char *opt_logger = NULL;
struct main_context *main_ctx;
int ret;
uid_t uid;
@@ -193,6 +194,7 @@ int main(int argc, const char *argv[])
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
+ SSSD_LOGGER_OPTS
SSSD_SERVER_OPTS(uid, gid)
SSSD_RESPONDER_OPTS
POPT_TABLEEND
@@ -221,6 +223,8 @@ int main(int argc, const char *argv[])
/* set up things like debug, signals, daemonization, etc... */
debug_log_file = "sssd_autofs";
+ sss_set_logger(opt_logger);
+
ret = server_setup("sssd[autofs]", 0, uid, gid,
CONFDB_AUTOFS_CONF_ENTRY, &main_ctx);
if (ret != EOK) {
diff --git a/src/responder/ifp/ifpsrv.c b/src/responder/ifp/ifpsrv.c
index 0dc61a42200cc79fc6f12515a8f581ad0201a043..85dfbacc217e2870dd7517e36a1d39e7f2054a8b 100644
--- a/src/responder/ifp/ifpsrv.c
+++ b/src/responder/ifp/ifpsrv.c
@@ -355,6 +355,7 @@ int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
+ char *opt_logger = NULL;
struct main_context *main_ctx;
int ret;
uid_t uid;
@@ -363,6 +364,7 @@ int main(int argc, const char *argv[])
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
+ SSSD_LOGGER_OPTS
SSSD_SERVER_OPTS(uid, gid)
SSSD_RESPONDER_OPTS
POPT_TABLEEND
@@ -391,6 +393,8 @@ int main(int argc, const char *argv[])
/* set up things like debug, signals, daemonization, etc... */
debug_log_file = "sssd_ifp";
+ sss_set_logger(opt_logger);
+
ret = server_setup("sssd[ifp]", 0, 0, 0,
CONFDB_IFP_CONF_ENTRY, &main_ctx);
if (ret != EOK) return 2;
diff --git a/src/responder/kcm/kcm.c b/src/responder/kcm/kcm.c
index 2202f96381a2622a2c5433e281172287b325f960..358fcc18165dec7b41a7389a3ef22660ac04b4a8 100644
--- a/src/responder/kcm/kcm.c
+++ b/src/responder/kcm/kcm.c
@@ -258,6 +258,7 @@ int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
+ char *opt_logger = NULL;
struct main_context *main_ctx;
int ret;
uid_t uid;
@@ -266,6 +267,7 @@ int main(int argc, const char *argv[])
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
+ SSSD_LOGGER_OPTS
SSSD_SERVER_OPTS(uid, gid)
POPT_TABLEEND
};
@@ -293,6 +295,8 @@ int main(int argc, const char *argv[])
/* set up things like debug, signals, daemonization, etc... */
debug_log_file = "sssd_kcm";
+ sss_set_logger(opt_logger);
+
ret = server_setup("sssd[kcm]", 0, uid, gid, CONFDB_KCM_CONF_ENTRY,
&main_ctx);
if (ret != EOK) return 2;
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index d67b9fac8d770d113560e41b259e2d5edd219343..1559c314e5353d41c61c83ecc712311ac18a7202 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -405,6 +405,7 @@ int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
+ char *opt_logger = NULL;
struct main_context *main_ctx;
int ret;
uid_t uid;
@@ -413,6 +414,7 @@ int main(int argc, const char *argv[])
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
+ SSSD_LOGGER_OPTS
SSSD_SERVER_OPTS(uid, gid)
SSSD_RESPONDER_OPTS
POPT_TABLEEND
@@ -441,6 +443,8 @@ int main(int argc, const char *argv[])
/* set up things like debug, signals, daemonization, etc... */
debug_log_file = "sssd_nss";
+ sss_set_logger(opt_logger);
+
ret = server_setup("sssd[nss]", 0, uid, gid, CONFDB_NSS_CONF_ENTRY,
&main_ctx);
if (ret != EOK) return 2;
diff --git a/src/responder/pac/pacsrv.c b/src/responder/pac/pacsrv.c
index 1f820c07f5c55fe8df75cce05b403c41075d9f94..b72e5c8d2a42bc85f0974dcb81a1290d3f740986 100644
--- a/src/responder/pac/pacsrv.c
+++ b/src/responder/pac/pacsrv.c
@@ -209,6 +209,7 @@ int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
+ char *opt_logger = NULL;
struct main_context *main_ctx;
int ret;
uid_t uid;
@@ -217,6 +218,7 @@ int main(int argc, const char *argv[])
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
+ SSSD_LOGGER_OPTS
SSSD_SERVER_OPTS(uid, gid)
SSSD_RESPONDER_OPTS
POPT_TABLEEND
@@ -245,6 +247,8 @@ int main(int argc, const char *argv[])
/* set up things like debug, signals, daemonization, etc... */
debug_log_file = "sssd_pac";
+ sss_set_logger(opt_logger);
+
ret = server_setup("sssd[pac]", 0, uid, gid,
CONFDB_PAC_CONF_ENTRY, &main_ctx);
if (ret != EOK) return 2;
diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
index 79470823d18138da6ef9235e6336a3220ead1797..cc0e4bddcdbecfadabea78a6d2815d0ac6d651b6 100644
--- a/src/responder/pam/pamsrv.c
+++ b/src/responder/pam/pamsrv.c
@@ -355,6 +355,7 @@ int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
+ char *opt_logger = NULL;
struct main_context *main_ctx;
int ret;
uid_t uid;
@@ -365,6 +366,7 @@ int main(int argc, const char *argv[])
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
+ SSSD_LOGGER_OPTS
SSSD_SERVER_OPTS(uid, gid)
SSSD_RESPONDER_OPTS
POPT_TABLEEND
@@ -393,6 +395,8 @@ int main(int argc, const char *argv[])
/* set up things like debug, signals, daemonization, etc... */
debug_log_file = "sssd_pam";
+ sss_set_logger(opt_logger);
+
if (!is_socket_activated()) {
/* Crate pipe file descriptors here before privileges are dropped
* in server_setup() */
diff --git a/src/responder/secrets/secsrv.c b/src/responder/secrets/secsrv.c
index 2b661b165ef0c174557f53012b2dbaa236a6e359..59c0f3a56040a6fc0c092247fbd124a069f97153 100644
--- a/src/responder/secrets/secsrv.c
+++ b/src/responder/secrets/secsrv.c
@@ -324,6 +324,7 @@ int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
+ char *opt_logger = NULL;
struct main_context *main_ctx;
int ret;
uid_t uid;
@@ -332,6 +333,7 @@ int main(int argc, const char *argv[])
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
+ SSSD_LOGGER_OPTS
SSSD_SERVER_OPTS(uid, gid)
POPT_TABLEEND
};
@@ -359,6 +361,8 @@ int main(int argc, const char *argv[])
/* set up things like debug, signals, daemonization, etc... */
debug_log_file = "sssd_secrets";
+ sss_set_logger(opt_logger);
+
ret = server_setup("sssd[secrets]", 0, uid, gid, CONFDB_SEC_CONF_ENTRY,
&main_ctx);
if (ret != EOK) return 2;
diff --git a/src/responder/ssh/sshsrv.c b/src/responder/ssh/sshsrv.c
index 440f0e2b9dc06e3dc52ff96d7207b8a3727865c0..8b0e7cc2d71044d7ab3bd2439041f678ddedb4cd 100644
--- a/src/responder/ssh/sshsrv.c
+++ b/src/responder/ssh/sshsrv.c
@@ -177,6 +177,7 @@ int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
+ char *opt_logger = NULL;
struct main_context *main_ctx;
int ret;
uid_t uid;
@@ -185,6 +186,7 @@ int main(int argc, const char *argv[])
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
+ SSSD_LOGGER_OPTS
SSSD_SERVER_OPTS(uid, gid)
SSSD_RESPONDER_OPTS
POPT_TABLEEND
@@ -213,6 +215,8 @@ int main(int argc, const char *argv[])
/* set up things like debug, signals, daemonization, etc... */
debug_log_file = "sssd_ssh";
+ sss_set_logger(opt_logger);
+
ret = server_setup("sssd[ssh]", 0, uid, gid,
CONFDB_SSH_CONF_ENTRY, &main_ctx);
if (ret != EOK) {
diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c
index dca70ea4afc0e6df6d1b1864338c7b1091a98fee..19058321a25022d7704556ec0ef79729db3ac1f2 100644
--- a/src/responder/sudo/sudosrv.c
+++ b/src/responder/sudo/sudosrv.c
@@ -178,6 +178,7 @@ int main(int argc, const char *argv[])
{
int opt;
poptContext pc;
+ char *opt_logger = NULL;
struct main_context *main_ctx;
int ret;
uid_t uid;
@@ -186,6 +187,7 @@ int main(int argc, const char *argv[])
struct poptOption long_options[] = {
POPT_AUTOHELP
SSSD_MAIN_OPTS
+ SSSD_LOGGER_OPTS
SSSD_SERVER_OPTS(uid, gid)
SSSD_RESPONDER_OPTS
POPT_TABLEEND
@@ -214,6 +216,8 @@ int main(int argc, const char *argv[])
/* set up things like debug, signals, daemonization, etc... */
debug_log_file = "sssd_sudo";
+ sss_set_logger(opt_logger);
+
ret = server_setup("sssd[sudo]", 0, uid, gid, CONFDB_SUDO_CONF_ENTRY,
&main_ctx);
if (ret != EOK) {
diff --git a/src/tests/cmocka/dummy_child.c b/src/tests/cmocka/dummy_child.c
index bcaa9455037a0604422750bf7cc719a25cef4a99..811cb40490c89c4250401e0d8d3e9d1c277f57af 100644
--- a/src/tests/cmocka/dummy_child.c
+++ b/src/tests/cmocka/dummy_child.c
@@ -34,6 +34,7 @@ int main(int argc, const char *argv[])
{
int opt;
int debug_fd = -1;
+ char *opt_logger = NULL;
poptContext pc;
ssize_t len;
ssize_t written;
@@ -55,6 +56,7 @@ int main(int argc, const char *argv[])
_("An open file descriptor for the debug logs"), NULL},
{"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, \
_("Send the debug output to stderr directly."), NULL },
+ SSSD_LOGGER_OPTS
{"guitar", 0, POPT_ARG_STRING, &guitar, 0, _("Who plays guitar"), NULL },
{"drums", 0, POPT_ARG_STRING, &drums, 0, _("Who plays drums"), NULL },
POPT_TABLEEND
@@ -76,6 +78,8 @@ int main(int argc, const char *argv[])
}
poptFreeContext(pc);
+ sss_set_logger(opt_logger);
+
action = getenv("TEST_CHILD_ACTION");
if (action) {
if (strcasecmp(action, "check_extra_args") == 0) {
diff --git a/src/tests/debug-tests.c b/src/tests/debug-tests.c
index d904d7eb8b5418608023faca0d62067f3106d23b..1446ec0474ab4bf72e66b58831fef59defd7be76 100644
--- a/src/tests/debug-tests.c
+++ b/src/tests/debug-tests.c
@@ -343,6 +343,7 @@ START_TEST(test_debug_is_set_single_no_timestamp)
debug_microseconds = 0;
debug_to_file = 1;
debug_prg_name = "sssd";
+ sss_set_logger(sss_logger_str[FILES_LOGGER]);
for (i = 0; i <= 9; i++) {
debug_level = levels[i];
@@ -385,6 +386,8 @@ START_TEST(test_debug_is_set_single_timestamp)
debug_microseconds = 0;
debug_to_file = 1;
debug_prg_name = "sssd";
+ sss_set_logger(sss_logger_str[FILES_LOGGER]);
+
for (i = 0; i <= 9; i++) {
debug_level = levels[i];
@@ -432,6 +435,8 @@ START_TEST(test_debug_is_set_single_timestamp_microseconds)
debug_microseconds = 1;
debug_to_file = 1;
debug_prg_name = "sssd";
+ sss_set_logger(sss_logger_str[FILES_LOGGER]);
+
for (i = 0; i <= 9; i++) {
debug_level = levels[i];
@@ -480,6 +485,8 @@ START_TEST(test_debug_is_notset_no_timestamp)
debug_microseconds = 0;
debug_to_file = 1;
debug_prg_name = "sssd";
+ sss_set_logger(sss_logger_str[FILES_LOGGER]);
+
for (i = 0; i <= 9; i++) {
debug_level = all_set & ~levels[i];
@@ -525,6 +532,8 @@ START_TEST(test_debug_is_notset_timestamp)
debug_microseconds = 0;
debug_to_file = 1;
debug_prg_name = "sssd";
+ sss_set_logger(sss_logger_str[FILES_LOGGER]);
+
for (i = 0; i <= 9; i++) {
debug_level = all_set & ~levels[i];
@@ -570,6 +579,7 @@ START_TEST(test_debug_is_notset_timestamp_microseconds)
debug_microseconds = 1;
debug_to_file = 1;
debug_prg_name = "sssd";
+ sss_set_logger(sss_logger_str[FILES_LOGGER]);
for (i = 0; i <= 9; i++) {
debug_level = all_set & ~levels[i];
diff --git a/src/util/child_common.c b/src/util/child_common.c
index b300d84bf432608db96de36e04637b5fb115212e..dc070f26446305e07cbb34edd1e4d72db72aedc5 100644
--- a/src/util/child_common.c
+++ b/src/util/child_common.c
@@ -676,7 +676,7 @@ static errno_t prepare_child_argv(TALLOC_CTX *mem_ctx,
}
if (child_debug_stderr) {
- argv[--argc] = talloc_strdup(argv, "--debug-to-stderr");
+ argv[--argc] = talloc_strdup(argv, "--logger=stderr");
if (argv[argc] == NULL) {
ret = ENOMEM;
goto fail;
diff --git a/src/util/debug.c b/src/util/debug.c
index 4e469447e5ab8aa89cd57bcd6d00269875a12bc6..30801fce7c27b115d1cafd4ed826a57c7d444a72 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -277,7 +277,7 @@ void sss_vdebug_fn(const char *file,
errno_t ret;
va_list ap_fallback;
- if (!debug_file && !debug_to_stderr) {
+ if (sss_logger == JOURNALD_LOGGER) {
/* If we are not outputting logs to files, we should be sending them
* to journald.
* NOTE: on modern systems, this is where stdout/stderr will end up
@@ -470,7 +470,7 @@ int rotate_debug_files(void)
int ret;
errno_t error;
- if (!debug_to_file) return EOK;
+ if (sss_logger != FILES_LOGGER) return EOK;
do {
error = 0;
diff --git a/src/util/server.c b/src/util/server.c
index 4e65cc66c01ba020b13a88df8e017765ac97f76e..f76cb6a0838324d4fc3ed376eb425fee2412a817 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -455,7 +455,7 @@ int server_setup(const char *name, int flags,
char *conf_db;
int ret = EOK;
bool dt;
- bool dl;
+ bool dl = false;
bool dm;
struct tevent_signal *tes;
struct logrotate_ctx *lctx;
@@ -637,16 +637,18 @@ int server_setup(const char *name, int flags,
}
/* same for debug to file */
- dl = (debug_to_file != 0);
ret = confdb_get_bool(ctx->confdb_ctx, conf_entry,
CONFDB_SERVICE_DEBUG_TO_FILES,
- dl, &dl);
+ false, &dl);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n",
ret, strerror(ret));
return ret;
}
- if (dl) debug_to_file = 1;
+ if (dl) {
+ debug_to_file = 1;
+ sss_set_logger(sss_logger_str[FILES_LOGGER]);
+ }
/* before opening the log file set up log rotation */
lctx = talloc_zero(ctx, struct logrotate_ctx);
@@ -662,7 +664,7 @@ int server_setup(const char *name, int flags,
}
/* open log file if told so */
- if (debug_to_file) {
+ if (sss_logger == FILES_LOGGER) {
ret = open_debug_file();
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE, "Error setting up logging (%d) "
--
2.15.1

View File

@ -0,0 +1,258 @@
From e2c0eecb49af621de77426cb46fff9bbb9a3f220 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 23 Oct 2017 18:03:46 +0200
Subject: [PATCH 19/79] SYSTEMD: Replace parameter --debug-to-files with
${DEBUG_LOGGER}
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Users can set variable DEBUG_LOGGER in environment files
(/etc/sysconfig/sssd or /etc/default/sssd; depending on the distribution)
to override default logging to files.
e.g.
DEBUG_LOGGER=--logger=stderr
DEBUG_LOGGER=--logger=journald
Resolves:
https://pagure.io/SSSD/sssd/issue/3433
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
Makefile.am | 12 +-----------
contrib/sssd.spec.in | 4 ----
src/sysv/systemd/journal.conf.in | 7 -------
src/sysv/systemd/sssd-autofs.service.in | 3 ++-
src/sysv/systemd/sssd-ifp.service.in | 3 ++-
src/sysv/systemd/sssd-kcm.service.in | 3 ++-
src/sysv/systemd/sssd-nss.service.in | 3 ++-
src/sysv/systemd/sssd-pac.service.in | 3 ++-
src/sysv/systemd/sssd-pam.service.in | 3 ++-
src/sysv/systemd/sssd-secrets.service.in | 3 ++-
src/sysv/systemd/sssd-ssh.service.in | 3 ++-
src/sysv/systemd/sssd-sudo.service.in | 3 ++-
src/sysv/systemd/sssd.service.in | 3 ++-
13 files changed, 21 insertions(+), 32 deletions(-)
delete mode 100644 src/sysv/systemd/journal.conf.in
diff --git a/Makefile.am b/Makefile.am
index 41a8f32f4e76fdcbd09ad833161f0bdada19e389..5483375167d99568e8313c9a0488900419be6ec3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -91,7 +91,7 @@ sssdkcmdatadir = $(datadir)/sssd-kcm
deskprofilepath = $(sss_statedir)/deskprofile
if HAVE_SYSTEMD_UNIT
-ifp_exec_cmd = $(sssdlibexecdir)/sssd_ifp --uid 0 --gid 0 --debug-to-files --dbus-activated
+ifp_exec_cmd = $(sssdlibexecdir)/sssd_ifp --uid 0 --gid 0 --dbus-activated
ifp_systemdservice = SystemdService=sssd-ifp.service
ifp_restart = Restart=on-failure
else
@@ -4483,10 +4483,6 @@ if BUILD_KCM
src/sysv/systemd/sssd-kcm.service \
$(NULL)
endif
-if WITH_JOURNALD
- systemdconf_DATA += \
- src/sysv/systemd/journal.conf
-endif
else
if HAVE_SUSE
init_SCRIPTS += \
@@ -4535,7 +4531,6 @@ replace_script = \
EXTRA_DIST += \
src/sysv/systemd/sssd.service.in \
- src/sysv/systemd/journal.conf.in \
src/sysv/systemd/sssd-nss.socket.in \
src/sysv/systemd/sssd-nss.service.in \
src/sysv/systemd/sssd-pam.socket.in \
@@ -4585,10 +4580,6 @@ src/sysv/systemd/sssd.service: src/sysv/systemd/sssd.service.in Makefile
@$(MKDIR_P) src/sysv/systemd/
$(replace_script)
-src/sysv/systemd/journal.conf: src/sysv/systemd/journal.conf.in Makefile
- @$(MKDIR_P) src/sysv/systemd/
- $(replace_script)
-
src/sysv/systemd/sssd-nss.socket: src/sysv/systemd/sssd-nss.socket.in Makefile
@$(MKDIR_P) src/sysv/systemd/
$(replace_script)
@@ -4924,7 +4915,6 @@ endif
rm -f $(builddir)/src/sysv/systemd/sssd-secrets.service
rm -f $(builddir)/src/sysv/systemd/sssd-kcm.socket
rm -f $(builddir)/src/sysv/systemd/sssd-kcm.service
- rm -f $(builddir)/src/sysv/systemd/journal.conf
rm -f $(builddir)/src/tools/wrappers/sss_debuglevel
CLEANFILES += *.X */*.X */*/*.X
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index d6ab73e60863316cbf239d34242959fdfe8d4b1b..4aafd1832b67161ff1c25a4e9ad689586a227a25 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -971,10 +971,6 @@ done
%attr(711,sssd,sssd) %dir %{_sysconfdir}/sssd
%attr(711,sssd,sssd) %dir %{_sysconfdir}/sssd/conf.d
%ghost %attr(0600,sssd,sssd) %config(noreplace) %{_sysconfdir}/sssd/sssd.conf
-%if (0%{?use_systemd} == 1)
-%attr(755,root,root) %dir %{_sysconfdir}/systemd/system/sssd.service.d
-%config(noreplace) %{_sysconfdir}/systemd/system/sssd.service.d/journal.conf
-%endif
%dir %{_sysconfdir}/logrotate.d
%config(noreplace) %{_sysconfdir}/logrotate.d/sssd
%dir %{_sysconfdir}/rwtab.d
diff --git a/src/sysv/systemd/journal.conf.in b/src/sysv/systemd/journal.conf.in
deleted file mode 100644
index 9ce170b4893629792516aab41573adea1fb741f0..0000000000000000000000000000000000000000
--- a/src/sysv/systemd/journal.conf.in
+++ /dev/null
@@ -1,7 +0,0 @@
-[Service]
-# Uncomment *both* of the following lines to enable debug logging
-# to go to journald instead of /var/log/sssd. You will need to
-# run 'systemctl daemon-reload' and then restart the SSSD service
-# for this to take effect
-#ExecStart=
-#ExecStart=@sbindir@/sssd -i
diff --git a/src/sysv/systemd/sssd-autofs.service.in b/src/sysv/systemd/sssd-autofs.service.in
index 32ea6e19ca7f9aa65599c0cf296a8c5e73362271..c2dc254c8f3f56cb6ae4dc481781688aa702b102 100644
--- a/src/sysv/systemd/sssd-autofs.service.in
+++ b/src/sysv/systemd/sssd-autofs.service.in
@@ -9,8 +9,9 @@ RefuseManualStart=true
Also=sssd-autofs.socket
[Service]
+Environment=DEBUG_LOGGER=--logger=files
ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_autofs.log
-ExecStart=@libexecdir@/sssd/sssd_autofs --debug-to-files --socket-activated
+ExecStart=@libexecdir@/sssd/sssd_autofs ${DEBUG_LOGGER} --socket-activated
Restart=on-failure
User=@SSSD_USER@
Group=@SSSD_USER@
diff --git a/src/sysv/systemd/sssd-ifp.service.in b/src/sysv/systemd/sssd-ifp.service.in
index 8e7abdb0e8c5ec83f9423c688daf845a16c57e7e..05a9a602b2d27c54a4faa79c58e0ecba90267100 100644
--- a/src/sysv/systemd/sssd-ifp.service.in
+++ b/src/sysv/systemd/sssd-ifp.service.in
@@ -5,7 +5,8 @@ After=sssd.service
BindsTo=sssd.service
[Service]
+Environment=DEBUG_LOGGER=--logger=files
Type=dbus
BusName=org.freedesktop.sssd.infopipe
-ExecStart=@ifp_exec_cmd@
+ExecStart=@ifp_exec_cmd@ ${DEBUG_LOGGER}
@ifp_restart@
diff --git a/src/sysv/systemd/sssd-kcm.service.in b/src/sysv/systemd/sssd-kcm.service.in
index 1e2bee12dc3bedd17d41b86f91c9b2b52d985c40..92306f97ec73a775739bfdb4454df14956e5e133 100644
--- a/src/sysv/systemd/sssd-kcm.service.in
+++ b/src/sysv/systemd/sssd-kcm.service.in
@@ -6,4 +6,5 @@ Documentation=man:sssd-kcm(5)
Also=sssd-kcm.socket
[Service]
-ExecStart=@libexecdir@/sssd/sssd_kcm --uid 0 --gid 0 --debug-to-files
+Environment=DEBUG_LOGGER=--logger=files
+ExecStart=@libexecdir@/sssd/sssd_kcm --uid 0 --gid 0 ${DEBUG_LOGGER}
diff --git a/src/sysv/systemd/sssd-nss.service.in b/src/sysv/systemd/sssd-nss.service.in
index 6a29078d5a36dff229e47bf7ce953e46443ce023..fe771ad0fa99968bb1d42037abf2f960271589b1 100644
--- a/src/sysv/systemd/sssd-nss.service.in
+++ b/src/sysv/systemd/sssd-nss.service.in
@@ -9,5 +9,6 @@ RefuseManualStart=true
Also=sssd-nss.socket
[Service]
-ExecStart=@libexecdir@/sssd/sssd_nss --debug-to-files --socket-activated
+Environment=DEBUG_LOGGER=--logger=files
+ExecStart=@libexecdir@/sssd/sssd_nss ${DEBUG_LOGGER} --socket-activated
Restart=on-failure
diff --git a/src/sysv/systemd/sssd-pac.service.in b/src/sysv/systemd/sssd-pac.service.in
index ffbfdec030ba6d5cf75c989854c27bc46b6983a5..dbd25abc476f579c9d8cce171fdeafa06e567610 100644
--- a/src/sysv/systemd/sssd-pac.service.in
+++ b/src/sysv/systemd/sssd-pac.service.in
@@ -9,8 +9,9 @@ RefuseManualStart=true
Also=sssd-pac.socket
[Service]
+Environment=DEBUG_LOGGER=--logger=files
ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_pac.log
-ExecStart=@libexecdir@/sssd/sssd_pac --debug-to-files --socket-activated
+ExecStart=@libexecdir@/sssd/sssd_pac ${DEBUG_LOGGER} --socket-activated
Restart=on-failure
User=@SSSD_USER@
Group=@SSSD_USER@
diff --git a/src/sysv/systemd/sssd-pam.service.in b/src/sysv/systemd/sssd-pam.service.in
index 6dec46f0c5d384c500268dafcd00af894088e0b6..df722d1f3014bf62cc60114c30331424d14f411b 100644
--- a/src/sysv/systemd/sssd-pam.service.in
+++ b/src/sysv/systemd/sssd-pam.service.in
@@ -9,8 +9,9 @@ RefuseManualStart=true
Also=sssd-pam.socket sssd-pam-priv.socket
[Service]
+Environment=DEBUG_LOGGER=--logger=files
ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_pam.log
-ExecStart=@libexecdir@/sssd/sssd_pam --debug-to-files --socket-activated
+ExecStart=@libexecdir@/sssd/sssd_pam ${DEBUG_LOGGER} --socket-activated
Restart=on-failure
User=@SSSD_USER@
Group=@SSSD_USER@
diff --git a/src/sysv/systemd/sssd-secrets.service.in b/src/sysv/systemd/sssd-secrets.service.in
index f45d647677a62900c01c7eb103597f2b1387498c..a7b41e0b16a5fa882546b41047e616fd2140329f 100644
--- a/src/sysv/systemd/sssd-secrets.service.in
+++ b/src/sysv/systemd/sssd-secrets.service.in
@@ -6,4 +6,5 @@ Documentation=man:sssd-secrets(5)
Also=sssd-secrets.socket
[Service]
-ExecStart=@libexecdir@/sssd/sssd_secrets --uid 0 --gid 0 --debug-to-files
+Environment=DEBUG_LOGGER=--logger=files
+ExecStart=@libexecdir@/sssd/sssd_secrets --uid 0 --gid 0 ${DEBUG_LOGGER}
diff --git a/src/sysv/systemd/sssd-ssh.service.in b/src/sysv/systemd/sssd-ssh.service.in
index 6f233b4854018d79cc0ad9d67d53ebd67a49f7b7..f41249ea0fe19e5044d5d06ba195ab604d8e6a29 100644
--- a/src/sysv/systemd/sssd-ssh.service.in
+++ b/src/sysv/systemd/sssd-ssh.service.in
@@ -9,8 +9,9 @@ RefuseManualStart=true
Also=sssd-ssh.socket
[Service]
+Environment=DEBUG_LOGGER=--logger=files
ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_ssh.log
-ExecStart=@libexecdir@/sssd/sssd_ssh --debug-to-files --socket-activated
+ExecStart=@libexecdir@/sssd/sssd_ssh ${DEBUG_LOGGER} --socket-activated
Restart=on-failure
User=@SSSD_USER@
Group=@SSSD_USER@
diff --git a/src/sysv/systemd/sssd-sudo.service.in b/src/sysv/systemd/sssd-sudo.service.in
index b59bcbcd817c3986d7ee245b1083f90ff5a3775a..da022f768af91e360182fad0ff885fad43ecfdc0 100644
--- a/src/sysv/systemd/sssd-sudo.service.in
+++ b/src/sysv/systemd/sssd-sudo.service.in
@@ -9,8 +9,9 @@ RefuseManualStart=true
Also=sssd-sudo.socket
[Service]
+Environment=DEBUG_LOGGER=--logger=files
ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_sudo.log
-ExecStart=@libexecdir@/sssd/sssd_sudo --debug-to-files --socket-activated
+ExecStart=@libexecdir@/sssd/sssd_sudo --socket-activated
Restart=on-failure
User=@SSSD_USER@
Group=@SSSD_USER@
diff --git a/src/sysv/systemd/sssd.service.in b/src/sysv/systemd/sssd.service.in
index 05cfd3705084dbff8b46fb07e736612612c58b70..cea848fac80303d6fae12dd84316a91dbc60072d 100644
--- a/src/sysv/systemd/sssd.service.in
+++ b/src/sysv/systemd/sssd.service.in
@@ -5,8 +5,9 @@ Before=systemd-user-sessions.service nss-user-lookup.target
Wants=nss-user-lookup.target
[Service]
+Environment=DEBUG_LOGGER=--logger=files
EnvironmentFile=-@environment_file@
-ExecStart=@sbindir@/sssd -i -f
+ExecStart=@sbindir@/sssd -i ${DEBUG_LOGGER}
Type=notify
NotifyAccess=main
--
2.15.1

View File

@ -0,0 +1,106 @@
From 536c8687921a0afe072bf81fca0bbb618a4c92fc Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Tue, 24 Oct 2017 12:15:48 +0200
Subject: [PATCH 20/79] SYSTEMD: Add environment file to responder service
files
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/sysv/systemd/sssd-autofs.service.in | 1 +
src/sysv/systemd/sssd-ifp.service.in | 1 +
src/sysv/systemd/sssd-nss.service.in | 1 +
src/sysv/systemd/sssd-pac.service.in | 1 +
src/sysv/systemd/sssd-pam.service.in | 1 +
src/sysv/systemd/sssd-ssh.service.in | 1 +
src/sysv/systemd/sssd-sudo.service.in | 1 +
7 files changed, 7 insertions(+)
diff --git a/src/sysv/systemd/sssd-autofs.service.in b/src/sysv/systemd/sssd-autofs.service.in
index c2dc254c8f3f56cb6ae4dc481781688aa702b102..7f920ad66a46bb0785c3f947bc26c15d0e370259 100644
--- a/src/sysv/systemd/sssd-autofs.service.in
+++ b/src/sysv/systemd/sssd-autofs.service.in
@@ -10,6 +10,7 @@ Also=sssd-autofs.socket
[Service]
Environment=DEBUG_LOGGER=--logger=files
+EnvironmentFile=-@environment_file@
ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_autofs.log
ExecStart=@libexecdir@/sssd/sssd_autofs ${DEBUG_LOGGER} --socket-activated
Restart=on-failure
diff --git a/src/sysv/systemd/sssd-ifp.service.in b/src/sysv/systemd/sssd-ifp.service.in
index 05a9a602b2d27c54a4faa79c58e0ecba90267100..f3bf92223ce8847858f57c2bb04b97c858be0ead 100644
--- a/src/sysv/systemd/sssd-ifp.service.in
+++ b/src/sysv/systemd/sssd-ifp.service.in
@@ -6,6 +6,7 @@ BindsTo=sssd.service
[Service]
Environment=DEBUG_LOGGER=--logger=files
+EnvironmentFile=-@environment_file@
Type=dbus
BusName=org.freedesktop.sssd.infopipe
ExecStart=@ifp_exec_cmd@ ${DEBUG_LOGGER}
diff --git a/src/sysv/systemd/sssd-nss.service.in b/src/sysv/systemd/sssd-nss.service.in
index fe771ad0fa99968bb1d42037abf2f960271589b1..c671280f2c8a7f85fd09a72983a21db0c30df3b9 100644
--- a/src/sysv/systemd/sssd-nss.service.in
+++ b/src/sysv/systemd/sssd-nss.service.in
@@ -10,5 +10,6 @@ Also=sssd-nss.socket
[Service]
Environment=DEBUG_LOGGER=--logger=files
+EnvironmentFile=-@environment_file@
ExecStart=@libexecdir@/sssd/sssd_nss ${DEBUG_LOGGER} --socket-activated
Restart=on-failure
diff --git a/src/sysv/systemd/sssd-pac.service.in b/src/sysv/systemd/sssd-pac.service.in
index dbd25abc476f579c9d8cce171fdeafa06e567610..590449b01223fe799eebb12b63229dfb8f2438f9 100644
--- a/src/sysv/systemd/sssd-pac.service.in
+++ b/src/sysv/systemd/sssd-pac.service.in
@@ -10,6 +10,7 @@ Also=sssd-pac.socket
[Service]
Environment=DEBUG_LOGGER=--logger=files
+EnvironmentFile=-@environment_file@
ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_pac.log
ExecStart=@libexecdir@/sssd/sssd_pac ${DEBUG_LOGGER} --socket-activated
Restart=on-failure
diff --git a/src/sysv/systemd/sssd-pam.service.in b/src/sysv/systemd/sssd-pam.service.in
index df722d1f3014bf62cc60114c30331424d14f411b..f2e938579c7ef4254bb2e05231bfe83d7e20f395 100644
--- a/src/sysv/systemd/sssd-pam.service.in
+++ b/src/sysv/systemd/sssd-pam.service.in
@@ -10,6 +10,7 @@ Also=sssd-pam.socket sssd-pam-priv.socket
[Service]
Environment=DEBUG_LOGGER=--logger=files
+EnvironmentFile=-@environment_file@
ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_pam.log
ExecStart=@libexecdir@/sssd/sssd_pam ${DEBUG_LOGGER} --socket-activated
Restart=on-failure
diff --git a/src/sysv/systemd/sssd-ssh.service.in b/src/sysv/systemd/sssd-ssh.service.in
index f41249ea0fe19e5044d5d06ba195ab604d8e6a29..1c185466dfa8c13804cc980bbbdbc997d4ebe955 100644
--- a/src/sysv/systemd/sssd-ssh.service.in
+++ b/src/sysv/systemd/sssd-ssh.service.in
@@ -10,6 +10,7 @@ Also=sssd-ssh.socket
[Service]
Environment=DEBUG_LOGGER=--logger=files
+EnvironmentFile=-@environment_file@
ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_ssh.log
ExecStart=@libexecdir@/sssd/sssd_ssh ${DEBUG_LOGGER} --socket-activated
Restart=on-failure
diff --git a/src/sysv/systemd/sssd-sudo.service.in b/src/sysv/systemd/sssd-sudo.service.in
index da022f768af91e360182fad0ff885fad43ecfdc0..f13d88107eccd9e80447390c9c0f8940ae933106 100644
--- a/src/sysv/systemd/sssd-sudo.service.in
+++ b/src/sysv/systemd/sssd-sudo.service.in
@@ -10,6 +10,7 @@ Also=sssd-sudo.socket
[Service]
Environment=DEBUG_LOGGER=--logger=files
+EnvironmentFile=-@environment_file@
ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_sudo.log
ExecStart=@libexecdir@/sssd/sssd_sudo --socket-activated
Restart=on-failure
--
2.15.1

View File

@ -0,0 +1,46 @@
From d344095ece6000e7641a9c867c8e00335b8d1ab0 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Tue, 24 Oct 2017 12:07:46 +0200
Subject: [PATCH 21/79] UTIL: Hide and deprecate parameter --debug-to-files
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Justin Stephenson <jstephen@redhat.com>
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/man/sssd.8.xml | 4 ++++
src/util/debug.h | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/man/sssd.8.xml b/src/man/sssd.8.xml
index 0b725628ff93f48f832140dd5dc15b040a8b179f..f2cbe015b844579af98aebd864770bc651dcf4b1 100644
--- a/src/man/sssd.8.xml
+++ b/src/man/sssd.8.xml
@@ -90,6 +90,10 @@
log files are stored in <filename>/var/log/sssd</filename> and
there are separate log files for every SSSD service and domain.
</para>
+ <para>
+ This option is deprecated. It is replaced by
+ <option>--logger=files</option>.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
diff --git a/src/util/debug.h b/src/util/debug.h
index 4adafb7cfc03f7381c4d03071eb44edad04bee00..09f50cc9f3122f02d8ba2092dfb7ee633332de9b 100644
--- a/src/util/debug.h
+++ b/src/util/debug.h
@@ -101,7 +101,7 @@ int get_fd_from_debug_file(void);
#define SSSD_DEBUG_OPTS \
{"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, \
_("Debug level"), NULL}, \
- {"debug-to-files", 'f', POPT_ARG_NONE, &debug_to_file, 0, \
+ {"debug-to-files", 'f', POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_file, 0, \
_("Send the debug output to files instead of stderr"), NULL }, \
{"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, \
_("Send the debug output to stderr directly."), NULL }, \
--
2.15.1

View File

@ -0,0 +1,212 @@
From eafe5f3e981a951c0ff20807a0486cfa62dcc3ad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Wed, 25 Oct 2017 11:25:09 +0200
Subject: [PATCH 23/79] LDAP: Bind to the LDAP server also in the auth
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When dealing with id_provider not being the same as auth_provider, SSSD
has to bind the DN of the user which wants to authenticate with the
ldap_default_bind_dn and the password provided by the user.
In order to do so, the least intrusive way is just by replacing
sdap_connect*() functions by sdap_cli_connect*() functions in the LDAP's
auth module.
The simple change also allowed us to remove some code that is already
executed as part of sdap_cli_connect*() and some functions had their
names adapted to reflect better their new purpose.
Resolves:
https://pagure.io/SSSD/sssd/issue/3451
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/providers/ldap/ldap_auth.c | 114 +++++++++--------------------------------
1 file changed, 25 insertions(+), 89 deletions(-)
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index 00ddd889b6294e457c13218491547b84f1468266..a3b1480aae4272d2e10f105a1eaf3a5816c3487c 100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -619,14 +619,11 @@ struct auth_state {
char *dn;
enum pwexpire pw_expire_type;
void *pw_expire_data;
-
- struct fo_server *srv;
};
-static struct tevent_req *auth_get_server(struct tevent_req *req);
+static struct tevent_req *auth_connect_send(struct tevent_req *req);
static void auth_get_dn_done(struct tevent_req *subreq);
static void auth_do_bind(struct tevent_req *req);
-static void auth_resolve_done(struct tevent_req *subreq);
static void auth_connect_done(struct tevent_req *subreq);
static void auth_bind_user_done(struct tevent_req *subreq);
@@ -659,7 +656,6 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx,
state->ctx = ctx;
state->username = username;
state->authtok = authtok;
- state->srv = NULL;
if (try_chpass_service && ctx->chpass_service != NULL &&
ctx->chpass_service->name != NULL) {
state->sdap_service = ctx->chpass_service;
@@ -667,7 +663,7 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx,
state->sdap_service = ctx->service;
}
- if (!auth_get_server(req)) goto fail;
+ if (!auth_connect_send(req)) goto fail;
return req;
@@ -676,75 +672,37 @@ fail:
return NULL;
}
-static struct tevent_req *auth_get_server(struct tevent_req *req)
+static struct tevent_req *auth_connect_send(struct tevent_req *req)
{
- struct tevent_req *next_req;
+ struct tevent_req *subreq;
struct auth_state *state = tevent_req_data(req,
struct auth_state);
-
- /* NOTE: this call may cause service->uri to be refreshed
- * with a new valid server. Do not use service->uri before */
- next_req = be_resolve_server_send(state,
- state->ev,
- state->ctx->be,
- state->sdap_service->name,
- state->srv == NULL ? true : false);
- if (!next_req) {
- DEBUG(SSSDBG_CRIT_FAILURE, "be_resolve_server_send failed.\n");
- return NULL;
- }
-
- tevent_req_set_callback(next_req, auth_resolve_done, req);
- return next_req;
-}
-
-static void auth_resolve_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct auth_state *state = tevent_req_data(req,
- struct auth_state);
- int ret;
bool use_tls;
- ret = be_resolve_server_recv(subreq, state, &state->srv);
- talloc_zfree(subreq);
- if (ret) {
- /* all servers have been tried and none
- * was found good, go offline */
- tevent_req_error(req, ETIMEDOUT);
- return;
+ /* Check for undocumented debugging feature to disable TLS
+ * for authentication. This should never be used in production
+ * for obvious reasons.
+ */
+ use_tls = !dp_opt_get_bool(state->ctx->opts->basic, SDAP_DISABLE_AUTH_TLS);
+ if (!use_tls) {
+ sss_log(SSS_LOG_ALERT, "LDAP authentication being performed over "
+ "insecure connection. This should be done "
+ "for debugging purposes only.");
}
- /* Determine whether we need to use TLS */
- if (sdap_is_secure_uri(state->ctx->service->uri)) {
- DEBUG(SSSDBG_TRACE_INTERNAL,
- "[%s] is a secure channel. No need to run START_TLS\n",
- state->ctx->service->uri);
- use_tls = false;
- } else {
+ subreq = sdap_cli_connect_send(state, state->ev, state->ctx->opts,
+ state->ctx->be,
+ state->sdap_service, false,
+ use_tls ? CON_TLS_ON : CON_TLS_OFF, false);
- /* Check for undocumented debugging feature to disable TLS
- * for authentication. This should never be used in production
- * for obvious reasons.
- */
- use_tls = !dp_opt_get_bool(state->ctx->opts->basic, SDAP_DISABLE_AUTH_TLS);
- if (!use_tls) {
- sss_log(SSS_LOG_ALERT, "LDAP authentication being performed over "
- "insecure connection. This should be done "
- "for debugging purposes only.");
- }
- }
-
- subreq = sdap_connect_send(state, state->ev, state->ctx->opts,
- state->sdap_service->uri,
- state->sdap_service->sockaddr, use_tls);
- if (!subreq) {
+ if (subreq == NULL) {
tevent_req_error(req, ENOMEM);
- return;
+ return NULL;
}
tevent_req_set_callback(subreq, auth_connect_done, req);
+
+ return subreq;
}
static void auth_connect_done(struct tevent_req *subreq)
@@ -755,35 +713,13 @@ static void auth_connect_done(struct tevent_req *subreq)
struct auth_state);
int ret;
- ret = sdap_connect_recv(subreq, state, &state->sh);
+ ret = sdap_cli_connect_recv(subreq, state, NULL, &state->sh, NULL);
talloc_zfree(subreq);
- if (ret) {
- if (state->srv) {
- /* mark this server as bad if connection failed */
- be_fo_set_port_status(state->ctx->be,
- state->sdap_service->name,
- state->srv, PORT_NOT_WORKING);
- }
-
- if (auth_get_server(req) == NULL) {
+ if (ret != EOK) {
+ if (auth_connect_send(req) == NULL) {
tevent_req_error(req, ENOMEM);
}
return;
- } else if (state->srv) {
- be_fo_set_port_status(state->ctx->be, state->sdap_service->name,
- state->srv, PORT_WORKING);
- }
-
- /* In case the ID provider is set to proxy, this might be the first
- * LDAP operation at all, so we need to set the connection status
- */
- if (state->sh->connected == false) {
- ret = sdap_set_connected(state->sh, state->ev);
- if (ret) {
- DEBUG(SSSDBG_OP_FAILURE, "Cannot set connected status\n");
- tevent_req_error(req, ret);
- return;
- }
}
ret = get_user_dn(state, state->ctx->be->domain,
@@ -870,7 +806,7 @@ static void auth_bind_user_done(struct tevent_req *subreq)
break;
case ETIMEDOUT:
case ERR_NETWORK_IO:
- if (auth_get_server(req) == NULL) {
+ if (auth_connect_send(req) == NULL) {
tevent_req_error(req, ENOMEM);
}
return;
--
2.15.1

View File

@ -1,7 +1,7 @@
From 53d1459e9b87196b4f6e327f0f5db4d9229bf541 Mon Sep 17 00:00:00 2001
From 6010476f08fb52bfcea9c2b10461b0d53ce0860c Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Fri, 3 Nov 2017 11:43:18 +0100
Subject: [PATCH] KCM: Fix restart during/after upgrade
Subject: [PATCH 24/79] KCM: Fix restart during/after upgrade
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
@ -51,5 +51,5 @@ index a7b41e0b16a5fa882546b41047e616fd2140329f..a9756acf8a3c71e861b443259c071338
[Install]
Also=sssd-secrets.socket
--
2.14.3
2.15.1

View File

@ -1,7 +1,7 @@
From 7449b236523409cc8766fb957d6cba051fdfb483 Mon Sep 17 00:00:00 2001
From ea07e6e149ec78bd50a92fe7dd12fa35cbdf81f3 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 29 Sep 2017 21:38:54 +0200
Subject: [PATCH 02/11] sss_client: create nss_common.h
Subject: [PATCH 25/79] sss_client: create nss_common.h
This patch makes sss_nss_getpw_readrep() and sss_nss_getgr_readrep()
calls which parse SSSD's replies for user and group requests available
@ -138,5 +138,5 @@ index c43f9bc50f43599b541e97f5a5aa60de036a5cdf..61e2a567e684fbc7664b5d425e81cfa2
errno_t ret;
size_t i, slen, dlen;
--
2.14.3
2.15.1

View File

@ -1,7 +1,7 @@
From 5e6622722e84d594298a8324f3685a1bda2b5868 Mon Sep 17 00:00:00 2001
From 3207b69503afe2328a747dd00f0cdb9e859bc699 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 29 Sep 2017 16:16:01 +0200
Subject: [PATCH 03/11] nss-idmap: add nss like calls with timeout and flags
Subject: [PATCH 26/79] nss-idmap: add nss like calls with timeout and flags
This patch adds new calls to libsss_nss_idmap to get NSS like user and
group information directly from SSSD without using the system's NSS
@ -896,5 +896,5 @@ index 0000000000000000000000000000000000000000..afcd8e355981b9a2dc29a62bab143756
+
+#endif /* SSS_NSS_IDMAP_PRIVATE_H_ */
--
2.14.3
2.15.1

View File

@ -1,7 +1,7 @@
From cf93f7c2f2031078bbbff095dae01eb4f8deff85 Mon Sep 17 00:00:00 2001
From bde80e6ec191e80231b24328209342cf92bb7723 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 11 Oct 2017 14:54:54 +0200
Subject: [PATCH 04/11] NSS: add *_EX version of some requests
Subject: [PATCH 27/79] NSS: add *_EX version of some requests
To be able to send the flags to the SSSD responder new request types
with an _EX postfix are added which expect and additional 32bit flag
@ -601,5 +601,5 @@ index 5329651a9385d138b8ea7237cb5cf4e2b8e5f371..9d2cc00c9957f5680548461129e3e6b7
/* aliases */
--
2.14.3
2.15.1

View File

@ -1,7 +1,7 @@
From ac6b267ff3df6d0417062a128ec16b184ea2c1b7 Mon Sep 17 00:00:00 2001
From 32f913dd143d45aee7f3d91785a86d8e2a85bb22 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 12 Oct 2017 10:42:41 +0200
Subject: [PATCH 05/11] NSS: add support for SSS_NSS_EX_FLAG_NO_CACHE
Subject: [PATCH 28/79] NSS: add support for SSS_NSS_EX_FLAG_NO_CACHE
If SSS_NSS_EX_FLAG_NO_CACHE is set the object is refresh by directly
looking it up in the backend.
@ -144,5 +144,5 @@ index 2334b6cb3fb8ef62e4ce3a7187c7affaeaa034e7..1649830afbb80c617fd339f054aef8bc
/**
--
2.14.3
2.15.1

View File

@ -1,7 +1,7 @@
From 52e675ec4b160720515c81ae8c0e5a95feb50c57 Mon Sep 17 00:00:00 2001
From c8cba255e7ad59e151693b1fc9ceb9feff744d2b Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 23 Oct 2017 18:26:55 +0200
Subject: [PATCH 06/11] CACHE_REQ: Add cache_req_data_set_bypass_dp()
Subject: [PATCH 29/79] CACHE_REQ: Add cache_req_data_set_bypass_dp()
Similar to cache_req_data_set_bypass_cache()
cache_req_data_set_bypass_dp() can be used to control how the cache_req
@ -107,5 +107,5 @@ index 9b706ff7d678f543effb77089857a7e8a42a9c51..0f630542d38a277d1819063fa4134bd7
struct tevent_req *
--
2.14.3
2.15.1

View File

@ -1,7 +1,7 @@
From a7d6ca275d6b2e5d396cbefb18d0ee880011e271 Mon Sep 17 00:00:00 2001
From 5a09629d6d281565c3ce0d51e536bb73f4447758 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 24 Oct 2017 12:50:43 +0200
Subject: [PATCH 07/11] nss: make memcache_delete_entry() public
Subject: [PATCH 30/79] nss: make memcache_delete_entry() public
Related to https://pagure.io/SSSD/sssd/issue/2478
@ -44,5 +44,5 @@ index a0b573d6ecba2d8ba6f55db0adcd7ee29cbec991..5fc19d26be9adda4d967086e7b239e49
nss_get_object_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
--
2.14.3
2.15.1

View File

@ -1,7 +1,7 @@
From 55f7d8034d783c01789d76a2b9ffc901045e8af8 Mon Sep 17 00:00:00 2001
From 500a170781fc24ddf83cb93cdb609c24efa13f4a Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 24 Oct 2017 14:10:53 +0200
Subject: [PATCH 08/11] NSS: add support for SSS_NSS_EX_FLAG_INVALIDATE_CACHE
Subject: [PATCH 31/79] NSS: add support for SSS_NSS_EX_FLAG_INVALIDATE_CACHE
The patch adds support for the SSS_NSS_EX_FLAG_INVALIDATE_CACHE flag and
makes the existing code more flexible and handle additional flags.
@ -360,5 +360,5 @@ index 1649830afbb80c617fd339f054aef8bc8e585fb9..3755643312f05a31d1cf1aa76dfc2284
/**
--
2.14.3
2.15.1

View File

@ -1,7 +1,7 @@
From 85da8a5e90bffc8b0fef5e0ea364a8d3cb50de86 Mon Sep 17 00:00:00 2001
From 1a48574b723f05bc9a69099fee459b405c35dd36 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 25 Oct 2017 21:31:54 +0200
Subject: [PATCH 09/11] NSS/TESTS: add unit tests for *_EX requests
Subject: [PATCH 32/79] NSS/TESTS: add unit tests for *_EX requests
The patch adds unit tests for the new *_EX requests with different input
types and flags.
@ -585,5 +585,5 @@ index ccedf96beaecfaa4232bbe456d5e5a8394098483..6aa726153183b5a871a75d398727ea71
/* Set debug level to invalid value so we can deside if -d 0 was used. */
--
2.14.3
2.15.1

View File

@ -1,7 +1,7 @@
From e54db68cbb9c12d8a6867f2c7766fb2115ab0997 Mon Sep 17 00:00:00 2001
From ecb91e135ebdb2a01831853e86e0165b51fcd2f9 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 2 Nov 2017 10:32:41 +0100
Subject: [PATCH 10/11] nss-idmap: add timeout version of old sss_nss_* calls
Subject: [PATCH 33/79] nss-idmap: add timeout version of old sss_nss_* calls
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
@ -489,5 +489,5 @@ index 8807eca619d7b07d919168e5629042cf38f654ac..2e37040d2d3523bea157804706685fa0
assert_int_equal(ret, EOK);
assert_int_equal(type, SSS_ID_TYPE_UID);
--
2.14.3
2.15.1

View File

@ -1,7 +1,7 @@
From 859bddc2bf51dc426a3dc56bd9f365e9c5722b65 Mon Sep 17 00:00:00 2001
From ccde2fdcbe240f8a20524461abea10c8c5c5a79f Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 2 Nov 2017 11:09:20 +0100
Subject: [PATCH 11/11] nss-idmap: allow empty buffer with
Subject: [PATCH 34/79] nss-idmap: allow empty buffer with
SSS_NSS_EX_FLAG_INVALIDATE_CACHE
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
@ -179,5 +179,5 @@ index 148eb7b35ec236b6272dd203a0035399cfdef73d..dcd9619a8b07ced7498f61b7e809fa46
if (ret != 0) {
return ret;
--
2.14.3
2.15.1

View File

@ -0,0 +1,79 @@
From 6e4b53c819d2cbc0a4e25b9813e24c47ad12febb Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Thu, 9 Nov 2017 13:24:47 +0100
Subject: [PATCH 35/79] RESP: Add some missing NULL checks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/responder/autofs/autofssrv_dp.c | 4 ++++
src/responder/common/responder_dp.c | 4 ++++
src/responder/common/responder_dp_ssh.c | 4 ++++
src/responder/sudo/sudosrv_dp.c | 4 ++++
4 files changed, 16 insertions(+)
diff --git a/src/responder/autofs/autofssrv_dp.c b/src/responder/autofs/autofssrv_dp.c
index a323d83d9deb4e51180da9ff291044f1b9f64f76..bb8c2a42899b163b7727af778e554a5f55ca2d56 100644
--- a/src/responder/autofs/autofssrv_dp.c
+++ b/src/responder/autofs/autofssrv_dp.c
@@ -65,6 +65,10 @@ sss_dp_get_autofs_send(TALLOC_CTX *mem_ctx,
}
info = talloc_zero(state, struct sss_dp_get_autofs_info);
+ if (info == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
info->fast_reply = fast_reply;
info->type = type;
info->name = name;
diff --git a/src/responder/common/responder_dp.c b/src/responder/common/responder_dp.c
index a75a611960801f5f5bdc95f00aea9ab921e8e293..935a36d28d15d1074a0971fe9781474072578b8f 100644
--- a/src/responder/common/responder_dp.c
+++ b/src/responder/common/responder_dp.c
@@ -536,6 +536,10 @@ sss_dp_get_account_send(TALLOC_CTX *mem_ctx,
}
info = talloc_zero(state, struct sss_dp_account_info);
+ if (info == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
info->fast_reply = fast_reply;
info->type = type;
info->opt_name = opt_name;
diff --git a/src/responder/common/responder_dp_ssh.c b/src/responder/common/responder_dp_ssh.c
index 303ba1568b6230b0d4dfa718e4a7c024ae84d4e9..f78052296f07d3e21d8d4841a58c85fcf178fa1a 100644
--- a/src/responder/common/responder_dp_ssh.c
+++ b/src/responder/common/responder_dp_ssh.c
@@ -64,6 +64,10 @@ sss_dp_get_ssh_host_send(TALLOC_CTX *mem_ctx,
}
info = talloc_zero(state, struct sss_dp_get_ssh_host_info);
+ if (info == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
info->fast_reply = fast_reply;
info->name = name;
info->alias = alias;
diff --git a/src/responder/sudo/sudosrv_dp.c b/src/responder/sudo/sudosrv_dp.c
index 3a4a79473ff9915b3845643505d63411585aa262..f8ec8abc26d9710a2bccaadc4f807f963fe35f89 100644
--- a/src/responder/sudo/sudosrv_dp.c
+++ b/src/responder/sudo/sudosrv_dp.c
@@ -72,6 +72,10 @@ sss_dp_get_sudoers_send(TALLOC_CTX *mem_ctx,
}
info = talloc_zero(state, struct sss_dp_get_sudoers_info);
+ if (info == NULL) {
+ ret = ENOMEM;
+ goto error;
+ }
info->fast_reply = fast_reply;
info->type = type;
info->name = name;
--
2.15.1

View File

@ -0,0 +1,50 @@
From c514089df0e3c357bb8465bca297806b253569e9 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Tue, 7 Nov 2017 17:11:52 +0100
Subject: [PATCH 36/79] BUILD: Properly expand variables in sssd-ifp.service
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
systemd[1]: [/usr/lib/systemd/system/sssd-ifp.service:9]
Path '-@environment_file@' is not absolute, ignoring.
sh-4.2# systemctl cat sssd-ifp.service
# /usr/lib/systemd/system/sssd-ifp.service
[Unit]
Description=SSSD IFP Service responder
Documentation=man:sssd-ifp(5)
After=sssd.service
BindsTo=sssd.service
[Service]
Environment=DEBUG_LOGGER=--logger=files
EnvironmentFile=-@environment_file@
Type=dbus
BusName=org.freedesktop.sssd.infopipe
ExecStart=/usr/libexec/sssd/sssd_ifp --uid 0 --gid 0 --dbus-activated ${DEBUG_LOGGER}
Resolves:
https://pagure.io/SSSD/sssd/issue/3433
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
Makefile.am | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.am b/Makefile.am
index 286ba47e3c421864362717be5258de960efca9f2..bbc90d9bad4d22ca0284ea95281a487d42399c05 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1491,7 +1491,7 @@ EXTRA_DIST += \
src/responder/ifp/org.freedesktop.sssd.infopipe.service.in \
$(NULL)
-ifp_edit_cmd = $(SED) \
+ifp_edit_cmd = $(edit_cmd) \
-e 's|@ifp_exec_cmd[@]|$(ifp_exec_cmd)|g' \
-e 's|@ifp_systemdservice[@]|$(ifp_systemdservice)|g' \
-e 's|@ifp_restart[@]|$(ifp_restart)|g'
--
2.15.1

View File

@ -0,0 +1,38 @@
From 8d1779240b4b193ecdc7ff8601def88a95cd7d47 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 8 Nov 2017 14:09:36 +0100
Subject: [PATCH 37/79] SYSTEMD: Clean pid file in corner cases
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
SSSD can cleanup pid file in case of standard stopping of daemon.
It's done in function monitor_cleanup. However monitor does not have a
change to cleanup file in case of OOM or sending SIGKILL to monitor.
Even though PIDFile is not necessary for services with Type notify
we should let systemd to clean this file in unexpected situations.
Resolves:
https://pagure.io/SSSD/sssd/issue/3528
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/sysv/systemd/sssd.service.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/sysv/systemd/sssd.service.in b/src/sysv/systemd/sssd.service.in
index cea848fac80303d6fae12dd84316a91dbc60072d..0c515d34caaa3ea397c4c7e95eef0188df170840 100644
--- a/src/sysv/systemd/sssd.service.in
+++ b/src/sysv/systemd/sssd.service.in
@@ -10,6 +10,7 @@ EnvironmentFile=-@environment_file@
ExecStart=@sbindir@/sssd -i ${DEBUG_LOGGER}
Type=notify
NotifyAccess=main
+PIDFile=@localstatedir@/run/sssd.pid
[Install]
WantedBy=multi-user.target
--
2.15.1

View File

@ -0,0 +1,197 @@
From 9ff9b0e5f6599d178d374753d7fbc99e7258ca4c Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 8 Nov 2017 08:13:02 +0100
Subject: [PATCH 38/79] CHILD: Pass information about logger to children
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Variables debug_to_file or debug_to_stderr were not set
because back-end already user parameter --logger=%s.
And therefore logs were not sent to files.
It could only work in case of direct usage of --debug-to-files in back-end via
command configuration option.
Resolves:
https://pagure.io/SSSD/sssd/issue/3433
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/p11_child/p11_child_nss.c | 4 +++-
src/providers/ad/ad_gpo_child.c | 3 ++-
src/providers/ipa/selinux_child.c | 3 ++-
src/providers/krb5/krb5_child.c | 3 ++-
src/providers/ldap/ldap_child.c | 3 ++-
src/util/child_common.c | 24 ++++++++++--------------
6 files changed, 21 insertions(+), 19 deletions(-)
diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c
index e7dbcb689220d1cd2585fbde5f26e84f8fa15cc2..b0ec69be321c4b4186ce851c07bfcc3e1afe9694 100644
--- a/src/p11_child/p11_child_nss.c
+++ b/src/p11_child/p11_child_nss.c
@@ -537,7 +537,7 @@ int main(int argc, const char *argv[])
int opt;
poptContext pc;
int debug_fd = -1;
- char *opt_logger = NULL;
+ const char *opt_logger = NULL;
errno_t ret;
TALLOC_CTX *main_ctx = NULL;
char *cert;
@@ -673,7 +673,9 @@ int main(int argc, const char *argv[])
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n");
}
+ opt_logger = sss_logger_str[FILES_LOGGER];
}
+
sss_set_logger(opt_logger);
DEBUG(SSSDBG_TRACE_FUNC, "p11_child started.\n");
diff --git a/src/providers/ad/ad_gpo_child.c b/src/providers/ad/ad_gpo_child.c
index 5375cc691e8649c289672b74c4bfe5266c8222c9..a0bd6e13a31fe0f92924d49302d1b8b17bac4d67 100644
--- a/src/providers/ad/ad_gpo_child.c
+++ b/src/providers/ad/ad_gpo_child.c
@@ -687,7 +687,7 @@ main(int argc, const char *argv[])
int opt;
poptContext pc;
int debug_fd = -1;
- char *opt_logger = NULL;
+ const char *opt_logger = NULL;
errno_t ret;
int sysvol_gpt_version;
int result;
@@ -744,6 +744,7 @@ main(int argc, const char *argv[])
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n");
}
+ opt_logger = sss_logger_str[FILES_LOGGER];
}
sss_set_logger(opt_logger);
diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c
index 120492686963241b7e419413f489cc38953e32f2..a7e20f715626d0f3ecef7cc06f3de5d44b6a15c1 100644
--- a/src/providers/ipa/selinux_child.c
+++ b/src/providers/ipa/selinux_child.c
@@ -206,7 +206,7 @@ int main(int argc, const char *argv[])
struct response *resp = NULL;
ssize_t written;
bool needs_update;
- char *opt_logger = NULL;
+ const char *opt_logger = NULL;
struct poptOption long_options[] = {
POPT_AUTOHELP
@@ -254,6 +254,7 @@ int main(int argc, const char *argv[])
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n");
}
+ opt_logger = sss_logger_str[FILES_LOGGER];
}
sss_set_logger(opt_logger);
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index b44f3a20f1c0725304a37620d36f8872cf9ca5d7..7ee6c34eb1f8b78d5a6fd7b6f87996e3c9572d4f 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -3020,7 +3020,7 @@ int main(int argc, const char *argv[])
int opt;
poptContext pc;
int debug_fd = -1;
- char *opt_logger = NULL;
+ const char *opt_logger = NULL;
errno_t ret;
krb5_error_code kerr;
uid_t fast_uid;
@@ -3097,6 +3097,7 @@ int main(int argc, const char *argv[])
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n");
}
+ opt_logger = sss_logger_str[FILES_LOGGER];
}
sss_set_logger(opt_logger);
diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c
index baeed239db5dc7ffa482edcbc155f25f718c8249..c0618d6d8828f102c32cf56731995e2b370590e7 100644
--- a/src/providers/ldap/ldap_child.c
+++ b/src/providers/ldap/ldap_child.c
@@ -599,7 +599,7 @@ int main(int argc, const char *argv[])
int kerr;
int opt;
int debug_fd = -1;
- char *opt_logger = NULL;
+ const char *opt_logger = NULL;
poptContext pc;
TALLOC_CTX *main_ctx = NULL;
uint8_t *buf = NULL;
@@ -657,6 +657,7 @@ int main(int argc, const char *argv[])
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n");
}
+ opt_logger = sss_logger_str[FILES_LOGGER];
}
sss_set_logger(opt_logger);
diff --git a/src/util/child_common.c b/src/util/child_common.c
index dc070f26446305e07cbb34edd1e4d72db72aedc5..203c115f9e7c4ecc2178b5660473d4f960fbbb6d 100644
--- a/src/util/child_common.c
+++ b/src/util/child_common.c
@@ -630,14 +630,11 @@ static errno_t prepare_child_argv(TALLOC_CTX *mem_ctx,
}
/* Save the current state in case an interrupt changes it */
- bool child_debug_to_file = debug_to_file;
bool child_debug_timestamps = debug_timestamps;
bool child_debug_microseconds = debug_microseconds;
- bool child_debug_stderr = debug_to_stderr;
if (!extra_args_only) {
- if (child_debug_to_file) argc++;
- if (child_debug_stderr) argc++;
+ argc++;
}
if (extra_argv) {
@@ -675,21 +672,20 @@ static errno_t prepare_child_argv(TALLOC_CTX *mem_ctx,
goto fail;
}
- if (child_debug_stderr) {
- argv[--argc] = talloc_strdup(argv, "--logger=stderr");
- if (argv[argc] == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- }
-
- if (child_debug_to_file) {
+ if (sss_logger == FILES_LOGGER) {
argv[--argc] = talloc_asprintf(argv, "--debug-fd=%d",
child_debug_fd);
if (argv[argc] == NULL) {
ret = ENOMEM;
goto fail;
}
+ } else {
+ argv[--argc] = talloc_asprintf(argv, "--logger=%s",
+ sss_logger_str[sss_logger]);
+ if (argv[argc] == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
}
argv[--argc] = talloc_asprintf(argv, "--debug-timestamps=%d",
@@ -816,7 +812,7 @@ errno_t child_debug_init(const char *logfile, int *debug_fd)
return EOK;
}
- if (debug_to_file != 0 && *debug_fd == -1) {
+ if (sss_logger == FILES_LOGGER && *debug_fd == -1) {
ret = open_debug_file_ex(logfile, &debug_filep, false);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE, "Error setting up logging (%d) [%s]\n",
--
2.15.1

View File

@ -0,0 +1,33 @@
From 6d15db05c0975fed2b18cc52056fa29aedec823c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Tue, 7 Nov 2017 09:09:55 +0100
Subject: [PATCH 39/79] TOOLS: Double quote array expansions in sss_debuglevel
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Otherwise they're like $* and break on spaces.
This issue has been caught by coverity:
Defect type: SHELLCHECK_WARNING
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
---
src/tools/wrappers/sss_debuglevel.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tools/wrappers/sss_debuglevel.in b/src/tools/wrappers/sss_debuglevel.in
index 4deeafff6bf472dbe63578f57bfacee7b774d09f..aa19f790a26c67186123c87675d527f403b06264 100644
--- a/src/tools/wrappers/sss_debuglevel.in
+++ b/src/tools/wrappers/sss_debuglevel.in
@@ -1,4 +1,4 @@
#!/bin/sh
sbindir=@sbindir@
echo "Redirecting to $sbindir/sssctl debug-level" >&2
-$sbindir/sssctl debug-level $@
+$sbindir/sssctl debug-level "$@"
--
2.15.1

View File

@ -0,0 +1,31 @@
From 58932b42802c93fdfc3eea8cdcdcca4534293941 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Wed, 8 Nov 2017 17:59:15 +0100
Subject: [PATCH 40/79] TOOLS: Call "exec" for sss_debuglevel
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This suggestion came from Lukáš Slebodník. The advantage of calling
"exec" is to avoid forking another child of the process.
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
---
src/tools/wrappers/sss_debuglevel.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tools/wrappers/sss_debuglevel.in b/src/tools/wrappers/sss_debuglevel.in
index aa19f790a26c67186123c87675d527f403b06264..a55afcddc547dfda4ac0a7e22da5f9f9407fe45f 100644
--- a/src/tools/wrappers/sss_debuglevel.in
+++ b/src/tools/wrappers/sss_debuglevel.in
@@ -1,4 +1,4 @@
#!/bin/sh
sbindir=@sbindir@
echo "Redirecting to $sbindir/sssctl debug-level" >&2
-$sbindir/sssctl debug-level "$@"
+exec $sbindir/sssctl debug-level "$@"
--
2.15.1

View File

@ -0,0 +1,57 @@
From 1e50148c7eadeff96b96811ede747399628a06c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Tue, 7 Nov 2017 23:34:42 +0100
Subject: [PATCH 41/79] LDAP: Improve error treatment from sdap_cli_connect()
in ldap_auth
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Because we weren't treating the errors coming from
sdap_cli_connect_recv() properly we ended up introducing a regression in
the commit add72860c7, related to offline authentication.
From now on, let's properly treat errors coming from auth_connect_send(),
which were treated before by going offline when be_resolve_server_recv()
failed, and propagate ETIMEDOUT to the request, thus going offline and
allowing offline authentication on those cases.
Related:
https://pagure.io/SSSD/sssd/issue/3451
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
---
src/providers/ldap/ldap_auth.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index a3b1480aae4272d2e10f105a1eaf3a5816c3487c..2e0e2cfd6f8af2bf0c9ad15bd956a55a34777a3c 100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -716,8 +716,20 @@ static void auth_connect_done(struct tevent_req *subreq)
ret = sdap_cli_connect_recv(subreq, state, NULL, &state->sh, NULL);
talloc_zfree(subreq);
if (ret != EOK) {
- if (auth_connect_send(req) == NULL) {
- tevent_req_error(req, ENOMEM);
+ /* As sdap_cli_connect_recv() returns EIO in case all the servers are
+ * down and we have to go offline, let's treat it accordingly here and
+ * allow the PAM responder to with to offline authentication.
+ *
+ * Unfortunately, there's not much pattern within our code and the way
+ * to indicate we're going down in this part of the code is returning
+ * an ETIMEDOUT.
+ */
+ if (ret == EIO) {
+ tevent_req_error(req, ETIMEDOUT);
+ } else {
+ if (auth_connect_send(req) == NULL) {
+ tevent_req_error(req, ENOMEM);
+ }
}
return;
}
--
2.15.1

View File

@ -0,0 +1,597 @@
From 78fd324fd1eb82319248987639376e85ad7204b1 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 17 Jan 2017 15:55:18 +0100
Subject: [PATCH 42/79] p11_child: return multiple certs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch refactors the handling of certificates in p11_child. Not only
the first but all certificates suitable for authentication are returned.
The PAM responder component calling p11_child is refactored to handle
multiple certificate returned by p11_child but so far only returns the
first one to its callers.
Related to https://pagure.io/SSSD/sssd/issue/3560
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Tested-by: Scott Poore <spoore@redhat.com>
---
src/p11_child/p11_child_nss.c | 131 +++++++++++++---------
src/responder/pam/pamsrv.h | 2 +
src/responder/pam/pamsrv_p11.c | 242 +++++++++++++++++++++++------------------
3 files changed, 219 insertions(+), 156 deletions(-)
diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c
index b0ec69be321c4b4186ce851c07bfcc3e1afe9694..50bde2f4f91f6c00260b0db383d0962112686ebc 100644
--- a/src/p11_child/p11_child_nss.c
+++ b/src/p11_child/p11_child_nss.c
@@ -72,8 +72,7 @@ static char *password_passthrough(PK11SlotInfo *slot, PRBool retry, void *arg)
int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
enum op_mode mode, const char *pin,
struct cert_verify_opts *cert_verify_opts,
- char **cert, char **token_name_out, char **module_name_out,
- char **key_id_out)
+ char **_multi)
{
int ret;
SECStatus rv;
@@ -110,7 +109,10 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
PK11SlotListElement *le;
SECItem *key_id = NULL;
char *key_id_str = NULL;
-
+ CERTCertList *valid_certs = NULL;
+ char *cert_b64 = NULL;
+ char *multi = NULL;
+ PRCList *node;
nss_ctx = NSS_InitContext(nss_db, "", "", SECMOD_DB, &parameters, flags);
if (nss_ctx == NULL) {
@@ -303,6 +305,14 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
}
found_cert = NULL;
+ valid_certs = CERT_NewCertList();
+ if (valid_certs == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "CERT_NewCertList failed [%d].\n",
+ PR_GetError());
+ ret = ENOMEM;
+ goto done;
+ }
+
DEBUG(SSSDBG_TRACE_ALL, "Filtered certificates:\n");
for (cert_list_node = CERT_LIST_HEAD(cert_list);
!CERT_LIST_END(cert_list_node, cert_list);
@@ -326,6 +336,13 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
}
}
+ rv = CERT_AddCertToListTail(valid_certs, cert_list_node->cert);
+ if (rv != SECSuccess) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "CERT_AddCertToListTail failed [%d].\n", PR_GetError());
+ ret = EIO;
+ goto done;
+ }
if (found_cert == NULL) {
found_cert = cert_list_node->cert;
@@ -352,9 +369,7 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
if (found_cert == NULL) {
DEBUG(SSSDBG_TRACE_ALL, "No certificate found.\n");
- *cert = NULL;
- *token_name_out = NULL;
- *module_name_out = NULL;
+ *_multi = NULL;
ret = EOK;
goto done;
}
@@ -421,51 +436,55 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
"Certificate verified and validated.\n");
}
- key_id = PK11_GetLowLevelKeyIDForCert(slot, found_cert, NULL);
- if (key_id == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "PK11_GetLowLevelKeyIDForCert failed [%d].\n",
- PR_GetError());
- ret = EINVAL;
- goto done;
- }
-
- key_id_str = CERT_Hexify(key_id, PR_FALSE);
- if (key_id_str == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d].\n", PR_GetError());
+ multi = talloc_strdup(mem_ctx, "");
+ if (multi == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create output string.\n");
ret = ENOMEM;
goto done;
}
- DEBUG(SSSDBG_TRACE_ALL, "Found certificate has key id [%s].\n", key_id_str);
+ for (cert_list_node = CERT_LIST_HEAD(valid_certs);
+ !CERT_LIST_END(cert_list_node, valid_certs);
+ cert_list_node = CERT_LIST_NEXT(cert_list_node)) {
- *key_id_out = talloc_strdup(mem_ctx, key_id_str);
- if (*key_id_out == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy key id.\n");
- ret = ENOMEM;
- goto done;
- }
+ found_cert = cert_list_node->cert;
- *cert = sss_base64_encode(mem_ctx, found_cert->derCert.data,
- found_cert->derCert.len);
- if (*cert == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "sss_base64_encode failed.\n");
- ret = ENOMEM;
- goto done;
- }
+ SECITEM_FreeItem(key_id, PR_TRUE);
+ PORT_Free(key_id_str);
+ key_id = PK11_GetLowLevelKeyIDForCert(slot, found_cert, NULL);
+ if (key_id == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "PK11_GetLowLevelKeyIDForCert failed [%d].\n",
+ PR_GetError());
+ ret = EINVAL;
+ goto done;
+ }
- *token_name_out = talloc_strdup(mem_ctx, token_name);
- if (*token_name_out == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy slot name.\n");
- ret = ENOMEM;
- goto done;
- }
+ key_id_str = CERT_Hexify(key_id, PR_FALSE);
+ if (key_id_str == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d].\n",
+ PR_GetError());
+ ret = ENOMEM;
+ goto done;
+ }
- *module_name_out = talloc_strdup(mem_ctx, module_name);
- if (*module_name_out == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy module_name_out name.\n");
- ret = ENOMEM;
- goto done;
+ talloc_free(cert_b64);
+ cert_b64 = sss_base64_encode(mem_ctx, found_cert->derCert.data,
+ found_cert->derCert.len);
+ if (cert_b64 == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_encode failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_ALL, "Found certificate has key id [%s].\n",
+ key_id_str);
+
+ multi = talloc_asprintf_append(multi, "%s\n%s\n%s\n%s\n",
+ token_name, module_name, key_id_str,
+ cert_b64);
}
+ *_multi = multi;
ret = EOK;
@@ -474,6 +493,18 @@ done:
PK11_FreeSlot(slot);
}
+ if (valid_certs != NULL) {
+ /* The certificates can be found in valid_certs and cert_list and
+ * CERT_DestroyCertList() will free the certificates as well. To avoid
+ * a double free the nodes from valid_certs are removed first because
+ * valid_certs will only have a sub-set of the certificates. */
+ while (!PR_CLIST_IS_EMPTY(&valid_certs->list)) {
+ node = PR_LIST_HEAD(&valid_certs->list);
+ PR_REMOVE_LINK(node);
+ }
+ CERT_DestroyCertList(valid_certs);
+ }
+
if (cert_list != NULL) {
CERT_DestroyCertList(cert_list);
}
@@ -483,6 +514,8 @@ done:
PORT_Free(signed_random_value.data);
+ talloc_free(cert_b64);
+
rv = NSS_ShutdownContext(nss_ctx);
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE, "NSS_ShutdownContext failed [%d].\n",
@@ -540,17 +573,14 @@ int main(int argc, const char *argv[])
const char *opt_logger = NULL;
errno_t ret;
TALLOC_CTX *main_ctx = NULL;
- char *cert;
enum op_mode mode = OP_NONE;
enum pin_mode pin_mode = PIN_NONE;
char *pin = NULL;
char *slot_name_in = NULL;
- char *token_name_out = NULL;
- char *module_name_out = NULL;
- char *key_id_out = NULL;
char *nss_db = NULL;
struct cert_verify_opts *cert_verify_opts;
char *verify_opts = NULL;
+ char *multi = NULL;
struct poptOption long_options[] = {
POPT_AUTOHELP
@@ -715,17 +745,14 @@ int main(int argc, const char *argv[])
}
ret = do_work(main_ctx, nss_db, slot_name_in, mode, pin, cert_verify_opts,
- &cert, &token_name_out, &module_name_out, &key_id_out);
+ &multi);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "do_work failed.\n");
goto fail;
}
- if (cert != NULL) {
- fprintf(stdout, "%s\n", token_name_out);
- fprintf(stdout, "%s\n", module_name_out);
- fprintf(stdout, "%s\n", key_id_out);
- fprintf(stdout, "%s\n", cert);
+ if (multi != NULL) {
+ fprintf(stdout, "%s", multi);
}
talloc_free(main_ctx);
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index 57a37b72594f030995f5e22255eb7a8fcd63d10e..896f71befbc9947a53b5eb20cba0bb3d104c4cf2 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -88,6 +88,8 @@ int LOCAL_pam_handler(struct pam_auth_req *preq);
errno_t p11_child_init(struct pam_ctx *pctx);
+struct cert_auth_info;
+
struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
int child_debug_fd,
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index 4dce43800c3c6b026c545df35c846269cbb49610..ff32d1e726808caa36ca7cca557220866ef1a9ab 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -35,6 +35,15 @@
#define P11_CHILD_LOG_FILE "p11_child"
#define P11_CHILD_PATH SSSD_LIBEXEC_PATH"/p11_child"
+struct cert_auth_info {
+ char *cert;
+ char *token_name;
+ char *module_name;
+ char *key_id;
+ struct cert_auth_info *prev;
+ struct cert_auth_info *next;
+};
+
errno_t p11_child_init(struct pam_ctx *pctx)
{
return child_debug_init(P11_CHILD_LOG_FILE, &pctx->p11_child_debug_fd);
@@ -132,18 +141,15 @@ static errno_t get_p11_child_write_buffer(TALLOC_CTX *mem_ctx,
}
static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf,
- ssize_t buf_len, char **_cert,
- char **_token_name, char **_module_name,
- char **_key_id)
+ ssize_t buf_len,
+ struct cert_auth_info **_cert_list)
{
int ret;
TALLOC_CTX *tmp_ctx = NULL;
uint8_t *p;
uint8_t *pn;
- char *cert = NULL;
- char *token_name = NULL;
- char *module_name = NULL;
- char *key_id = NULL;
+ struct cert_auth_info *cert_list = NULL;
+ struct cert_auth_info *cert_auth_info;
if (buf_len < 0) {
DEBUG(SSSDBG_CRIT_FAILURE,
@@ -157,108 +163,132 @@ static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf,
goto done;
}
- p = memchr(buf, '\n', buf_len);
- if (p == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "Missing new-line in p11_child response.\n");
- return EINVAL;
- }
- if (p == buf) {
- DEBUG(SSSDBG_OP_FAILURE, "Missing counter in p11_child response.\n");
- return EINVAL;
- }
-
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
return ENOMEM;
}
- token_name = talloc_strndup(tmp_ctx, (char*) buf, (p - buf));
- if (token_name == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
- ret = ENOMEM;
- goto done;
- }
+ p = buf;
- p++;
- pn = memchr(p, '\n', buf_len - (p - buf));
- if (pn == NULL) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Missing new-line in p11_child response.\n");
- ret = EINVAL;
- goto done;
- }
+ do {
+ cert_auth_info = talloc_zero(tmp_ctx, struct cert_auth_info);
+ if (cert_auth_info == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
+ return ENOMEM;
+ }
- if (pn == p) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Missing module name in p11_child response.\n");
- ret = EINVAL;
- goto done;
- }
+ pn = memchr(p, '\n', buf_len - (p - buf));
+ if (pn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Missing new-line in p11_child response.\n");
+ return EINVAL;
+ }
+ if (pn == p) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Missing counter in p11_child response.\n");
+ return EINVAL;
+ }
- module_name = talloc_strndup(tmp_ctx, (char *) p, (pn - p));
- if (module_name == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
- ret = ENOMEM;
- goto done;
- }
- DEBUG(SSSDBG_TRACE_ALL, "Found module name [%s].\n", module_name);
+ cert_auth_info->token_name = talloc_strndup(cert_auth_info, (char *)p,
+ (pn - p));
+ if (cert_auth_info->token_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ DEBUG(SSSDBG_TRACE_ALL, "Found token name [%s].\n",
+ cert_auth_info->token_name);
- p = ++pn;
- pn = memchr(p, '\n', buf_len - (p - buf));
- if (pn == NULL) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Missing new-line in p11_child response.\n");
- ret = EINVAL;
- goto done;
- }
+ p = ++pn;
+ pn = memchr(p, '\n', buf_len - (p - buf));
+ if (pn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Missing new-line in p11_child response.\n");
+ ret = EINVAL;
+ goto done;
+ }
- if (pn == p) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Missing key id in p11_child response.\n");
- ret = EINVAL;
- goto done;
- }
+ if (pn == p) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Missing module name in p11_child response.\n");
+ ret = EINVAL;
+ goto done;
+ }
- key_id = talloc_strndup(tmp_ctx, (char *) p, (pn - p));
- if (key_id == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
- ret = ENOMEM;
- goto done;
- }
- DEBUG(SSSDBG_TRACE_ALL, "Found key id [%s].\n", key_id);
+ cert_auth_info->module_name = talloc_strndup(cert_auth_info, (char *)p,
+ (pn - p));
+ if (cert_auth_info->module_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ DEBUG(SSSDBG_TRACE_ALL, "Found module name [%s].\n",
+ cert_auth_info->module_name);
- p = pn + 1;
- pn = memchr(p, '\n', buf_len - (p - buf));
- if (pn == NULL) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Missing new-line in p11_child response.\n");
- ret = EINVAL;
- goto done;
- }
+ p = ++pn;
+ pn = memchr(p, '\n', buf_len - (p - buf));
+ if (pn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Missing new-line in p11_child response.\n");
+ ret = EINVAL;
+ goto done;
+ }
- if (pn == p) {
- DEBUG(SSSDBG_OP_FAILURE, "Missing cert in p11_child response.\n");
- ret = EINVAL;
- goto done;
- }
+ if (pn == p) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Missing key id in p11_child response.\n");
+ ret = EINVAL;
+ goto done;
+ }
- cert = talloc_strndup(tmp_ctx, (char *) p, (pn - p));
- if(cert == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
- ret = ENOMEM;
- goto done;
- }
- DEBUG(SSSDBG_TRACE_ALL, "Found cert [%s].\n", cert);
+ cert_auth_info->key_id = talloc_strndup(cert_auth_info, (char *)p,
+ (pn - p));
+ if (cert_auth_info->key_id == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ DEBUG(SSSDBG_TRACE_ALL, "Found key id [%s].\n", cert_auth_info->key_id);
+
+ p = ++pn;
+ pn = memchr(p, '\n', buf_len - (p - buf));
+ if (pn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Missing new-line in p11_child response.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ if (pn == p) {
+ DEBUG(SSSDBG_OP_FAILURE, "Missing cert in p11_child response.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ cert_auth_info->cert = talloc_strndup(cert_auth_info, (char *)p,
+ (pn - p));
+ if (cert_auth_info->cert == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ DEBUG(SSSDBG_TRACE_ALL, "Found cert [%s].\n", cert_auth_info->cert);
+
+ DLIST_ADD(cert_list, cert_auth_info);
+
+ p = ++pn;
+ } while ((pn - buf) < buf_len);
ret = EOK;
done:
if (ret == EOK) {
- *_token_name = talloc_steal(mem_ctx, token_name);
- *_cert = talloc_steal(mem_ctx, cert);
- *_module_name = talloc_steal(mem_ctx, module_name);
- *_key_id = talloc_steal(mem_ctx, key_id);
+ DLIST_FOR_EACH(cert_auth_info, cert_list) {
+ talloc_steal(mem_ctx, cert_auth_info);
+ }
+
+ *_cert_list = cert_list;
}
talloc_free(tmp_ctx);
@@ -273,10 +303,8 @@ struct pam_check_cert_state {
struct tevent_context *ev;
struct child_io_fds *io;
- char *cert;
- char *token_name;
- char *module_name;
- char *key_id;
+
+ struct cert_auth_info *cert_list;
};
static void p11_child_write_done(struct tevent_req *subreq);
@@ -349,9 +377,6 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
state->ev = ev;
state->child_status = EFAULT;
- state->cert = NULL;
- state->token_name = NULL;
- state->module_name = NULL;
state->io = talloc(state, struct child_io_fds);
if (state->io == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
@@ -514,11 +539,9 @@ static void p11_child_done(struct tevent_req *subreq)
PIPE_FD_CLOSE(state->io->read_from_child_fd);
- ret = parse_p11_child_response(state, buf, buf_len, &state->cert,
- &state->token_name, &state->module_name,
- &state->key_id);
+ ret = parse_p11_child_response(state, buf, buf_len, &state->cert_list);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "parse_p11_child_respose failed.\n");
+ DEBUG(SSSDBG_OP_FAILURE, "parse_p11_child_response failed.\n");
tevent_req_error(req, ret);
return;
}
@@ -551,20 +574,31 @@ errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
TEVENT_REQ_RETURN_ON_ERROR(req);
+ if (state->cert_list == NULL) {
+ *token_name = NULL;
+ *cert = NULL;
+ *module_name = NULL;
+ *key_id = NULL;
+ }
+
if (cert != NULL) {
- *cert = talloc_steal(mem_ctx, state->cert);
+ *cert = (state->cert_list == NULL) ? NULL
+ : talloc_steal(mem_ctx, state->cert_list->cert);
}
if (token_name != NULL) {
- *token_name = talloc_steal(mem_ctx, state->token_name);
+ *token_name = (state->cert_list == NULL) ? NULL
+ : talloc_steal(mem_ctx, state->cert_list->token_name);
}
if (module_name != NULL) {
- *module_name = talloc_steal(mem_ctx, state->module_name);
+ *module_name = (state->cert_list == NULL) ? NULL
+ : talloc_steal(mem_ctx, state->cert_list->module_name);
}
if (key_id != NULL) {
- *key_id = talloc_steal(mem_ctx, state->key_id);
+ *key_id = (state->cert_list == NULL) ? NULL
+ : talloc_steal(mem_ctx, state->cert_list->key_id);
}
return EOK;
--
2.15.1

View File

@ -0,0 +1,976 @@
From 5649511243126866c97df0892c51227ab9257347 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 25 Aug 2017 12:51:09 +0200
Subject: [PATCH 43/79] PAM: handled multiple certs in the responder
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch refactors the handling of the certificate and the attributes
to address the certificate on the Smartcard (module name, token name and
key id). Instead of using individual variables the values are put into a
new struct cert_auth_info. Since the new struct can be used as a list
the PAM responder can now handle multiple certificates on the Smartcard
and can send the needed data to pam_sss with multiple SSS_PAM_CERT_INFO
messages.
Unit tests are added to confirm the expected behavior.
Related to https://pagure.io/SSSD/sssd/issue/3560
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Tested-by: Scott Poore <spoore@redhat.com>
---
src/responder/pam/pamsrv.h | 25 ++--
src/responder/pam/pamsrv_cmd.c | 257 ++++++++++++++++++++++++++--------------
src/responder/pam/pamsrv_p11.c | 181 ++++++++++++++++++++--------
src/tests/cmocka/test_pam_srv.c | 167 +++++++++++++++++++++++++-
src/tests/whitespace_test | 2 +-
5 files changed, 483 insertions(+), 149 deletions(-)
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index 896f71befbc9947a53b5eb20cba0bb3d104c4cf2..f15f7f19f1f38626288416c9f2038371c6f58b47 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -73,10 +73,8 @@ struct pam_auth_req {
struct pam_auth_dp_req *dpreq_spy;
struct ldb_message *user_obj;
- struct ldb_result *cert_user_objs;
- char *token_name;
- char *module_name;
- char *key_id;
+ struct cert_auth_info *cert_list;
+ struct cert_auth_info *current_cert;
bool cert_auth_local;
};
@@ -89,6 +87,16 @@ int LOCAL_pam_handler(struct pam_auth_req *preq);
errno_t p11_child_init(struct pam_ctx *pctx);
struct cert_auth_info;
+const char *sss_cai_get_cert(struct cert_auth_info *i);
+const char *sss_cai_get_token_name(struct cert_auth_info *i);
+const char *sss_cai_get_module_name(struct cert_auth_info *i);
+const char *sss_cai_get_key_id(struct cert_auth_info *i);
+struct cert_auth_info *sss_cai_get_next(struct cert_auth_info *i);
+struct ldb_result *sss_cai_get_cert_user_objs(struct cert_auth_info *i);
+void sss_cai_set_cert_user_objs(struct cert_auth_info *i,
+ struct ldb_result *cert_user_objs);
+void sss_cai_check_users(struct cert_auth_info **list, size_t *_cert_count,
+ size_t *_cert_user_count);
struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -98,12 +106,11 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
const char *verify_opts,
struct pam_data *pd);
errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- char **cert, char **token_name, char **module_name,
- char **key_id);
+ struct cert_auth_info **cert_list);
-errno_t add_pam_cert_response(struct pam_data *pd, const char *user,
- const char *token_name, const char *module_name,
- const char *key_id, enum response_type type);
+errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username,
+ struct cert_auth_info *cert_info,
+ enum response_type type);
bool may_do_cert_auth(struct pam_ctx *pctx, struct pam_data *pd);
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 51d8185650cf823da289a3398b10133065d82ae4..8b2c086e206796ad4c977495be957c56b3255e7f 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -1389,21 +1389,17 @@ done:
return pam_check_user_done(preq, ret);
}
+static errno_t pam_user_by_cert_step(struct pam_auth_req *preq);
static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req);
static void pam_forwarder_cert_cb(struct tevent_req *req)
{
struct pam_auth_req *preq = tevent_req_callback_data(req,
struct pam_auth_req);
- struct cli_ctx *cctx = preq->cctx;
struct pam_data *pd;
errno_t ret = EOK;
- char *cert;
- struct pam_ctx *pctx =
- talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx);
+ const char *cert;
- ret = pam_check_cert_recv(req, preq, &cert, &preq->token_name,
- &preq->module_name,
- &preq->key_id);
+ ret = pam_check_cert_recv(req, preq, &preq->cert_list);
talloc_free(req);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "get_cert request failed.\n");
@@ -1412,6 +1408,8 @@ static void pam_forwarder_cert_cb(struct tevent_req *req)
pd = preq->pd;
+ cert = sss_cai_get_cert(preq->cert_list);
+
if (cert == NULL) {
if (pd->logon_name == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
@@ -1431,21 +1429,42 @@ static void pam_forwarder_cert_cb(struct tevent_req *req)
goto done;
}
+ preq->current_cert = preq->cert_list;
+ ret = pam_user_by_cert_step(preq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "pam_user_by_cert_step failed.\n");
+ goto done;
+ }
+
+ return;
+
+done:
+ pam_check_user_done(preq, ret);
+}
+
+static errno_t pam_user_by_cert_step(struct pam_auth_req *preq)
+{
+ struct cli_ctx *cctx = preq->cctx;
+ struct tevent_req *req;
+ struct pam_ctx *pctx =
+ talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx);
+
+ if (preq->current_cert == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing certificate data.\n");
+ return EINVAL;
+ }
req = cache_req_user_by_cert_send(preq, cctx->ev, cctx->rctx,
pctx->rctx->ncache, 0,
preq->req_dom_type, NULL,
- cert);
+ sss_cai_get_cert(preq->current_cert));
if (req == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "cache_req_user_by_cert_send failed.\n");
- ret = ENOMEM;
- goto done;
+ return ENOMEM;
}
+
tevent_req_set_callback(req, pam_forwarder_lookup_by_cert_done, preq);
- return;
-
-done:
- pam_check_user_done(preq, ret);
+ return EOK;
}
static errno_t get_results_from_all_domains(TALLOC_CTX *mem_ctx,
@@ -1511,6 +1530,9 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
struct pam_auth_req *preq = tevent_req_callback_data(req,
struct pam_auth_req);
const char *cert_user = NULL;
+ size_t cert_count = 0;
+ size_t cert_user_count = 0;
+ struct ldb_result *cert_user_objs;
ret = cache_req_recv(preq, req, &results);
talloc_zfree(req);
@@ -1521,12 +1543,39 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
if (ret == EOK) {
ret = get_results_from_all_domains(preq, results,
- &preq->cert_user_objs);
+ &cert_user_objs);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "get_results_from_all_domains failed.\n");
goto done;
}
+ sss_cai_set_cert_user_objs(preq->current_cert, cert_user_objs);
+ }
+
+ preq->current_cert = sss_cai_get_next(preq->current_cert);
+ if (preq->current_cert != NULL) {
+ ret = pam_user_by_cert_step(preq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "pam_user_by_cert_step failed.\n");
+ goto done;
+ }
+ return;
+ }
+
+ sss_cai_check_users(&preq->cert_list, &cert_count, &cert_user_count);
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Found [%zu] certificates and [%zu] related users.\n",
+ cert_count, cert_user_count);
+
+ if (cert_user_count == 0) {
+ if (preq->pd->logon_name == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Missing logon name and no certificate user found.\n");
+ ret = ENOENT;
+ goto done;
+ }
+ } else {
+
if (preq->pd->logon_name == NULL) {
if (preq->pd->cmd != SSS_PAM_PREAUTH) {
DEBUG(SSSDBG_CRIT_FAILURE,
@@ -1535,9 +1584,39 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
goto done;
}
- if (preq->cert_user_objs->count == 1) {
+ if (cert_count > 1) {
+ for (preq->current_cert = preq->cert_list;
+ preq->current_cert != NULL;
+ preq->current_cert = sss_cai_get_next(preq->current_cert)) {
+
+ ret = add_pam_cert_response(preq->pd, "",
+ preq->current_cert,
+ preq->cctx->rctx->domains->user_name_hint
+ ? SSS_PAM_CERT_INFO_WITH_HINT
+ : SSS_PAM_CERT_INFO);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "add_pam_cert_response failed.\n");
+ preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL;
+ }
+ }
+
+ ret = EOK;
+ preq->pd->pam_status = PAM_SUCCESS;
+ pam_reply(preq);
+ goto done;
+ }
+
+ if (cert_user_count == 1) {
+ cert_user_objs = sss_cai_get_cert_user_objs(preq->cert_list);
+ if (cert_user_objs == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing certificate user.\n");
+ ret = ENOENT;
+ goto done;
+ }
+
cert_user = ldb_msg_find_attr_as_string(
- preq->cert_user_objs->msgs[0],
+ cert_user_objs->msgs[0],
SYSDB_NAME, NULL);
if (cert_user == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
@@ -1564,9 +1643,7 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
if (preq->cctx->rctx->domains->user_name_hint) {
ret = add_pam_cert_response(preq->pd, cert_user,
- preq->token_name,
- preq->module_name,
- preq->key_id,
+ preq->cert_list,
SSS_PAM_CERT_INFO_WITH_HINT);
preq->pd->pam_status = PAM_SUCCESS;
if (ret != EOK) {
@@ -1596,13 +1673,6 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
goto done;
}
}
- } else {
- if (preq->pd->logon_name == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Missing logon name and no certificate user found.\n");
- ret = ENOENT;
- goto done;
- }
}
if (preq->user_obj == NULL) {
@@ -1884,7 +1954,9 @@ static void pam_dom_forwarder(struct pam_auth_req *preq)
struct pam_ctx *pctx =
talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx);
const char *cert_user;
+ struct ldb_result *cert_user_objs;
size_t c;
+ bool found = false;
if (!preq->pd->domain) {
preq->pd->domain = preq->domain->name;
@@ -1921,76 +1993,87 @@ static void pam_dom_forwarder(struct pam_auth_req *preq)
return;
}
- if (may_do_cert_auth(pctx, preq->pd) && preq->cert_user_objs != NULL) {
+ if (may_do_cert_auth(pctx, preq->pd) && preq->cert_list != NULL) {
/* Check if user matches certificate user */
- for (c = 0; c < preq->cert_user_objs->count; c++) {
- cert_user = ldb_msg_find_attr_as_string(
- preq->cert_user_objs->msgs[c],
- SYSDB_NAME,
- NULL);
- if (cert_user == NULL) {
- /* Even if there might be other users mapped to the
- * certificate a missing SYSDB_NAME indicates some critical
- * condition which justifies that the whole request is aborted
- * */
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Certificate user object has no name.\n");
- preq->pd->pam_status = PAM_USER_UNKNOWN;
- pam_reply(preq);
- return;
+ found = false;
+ for (preq->current_cert = preq->cert_list;
+ preq->current_cert != NULL;
+ preq->current_cert = sss_cai_get_next(preq->current_cert)) {
+
+ cert_user_objs = sss_cai_get_cert_user_objs(preq->current_cert);
+ if (cert_user_objs == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Unexpteced missing certificate user, "
+ "trying next certificate.\n");
+ continue;
}
- /* pam_check_user_search() calls pd_set_primary_name() is the search
- * was successful, so pd->user contains the canonical sysdb name
- * as well */
- if (ldb_dn_compare(preq->cert_user_objs->msgs[c]->dn,
- preq->user_obj->dn) == 0) {
-
- if (preq->pd->cmd == SSS_PAM_PREAUTH) {
- ret = sss_authtok_set_sc(preq->pd->authtok,
- SSS_AUTHTOK_TYPE_SC_PIN, NULL, 0,
- preq->token_name, 0,
- preq->module_name, 0,
- preq->key_id, 0);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_set_sc failed, "
- "Smartcard authentication "
- "detection might fail in the "
- "backend.\n");
- }
-
- ret = add_pam_cert_response(preq->pd, cert_user,
- preq->token_name,
- preq->module_name,
- preq->key_id,
- SSS_PAM_CERT_INFO);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "add_pam_cert_response failed.\n");
- preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL;
- }
- }
-
- /* We are done if we do not have to call the backend */
- if (preq->pd->cmd == SSS_PAM_AUTHENTICATE
- && preq->cert_auth_local) {
- preq->pd->pam_status = PAM_SUCCESS;
- preq->callback = pam_reply;
+ for (c = 0; c < cert_user_objs->count; c++) {
+ cert_user = ldb_msg_find_attr_as_string(cert_user_objs->msgs[c],
+ SYSDB_NAME, NULL);
+ if (cert_user == NULL) {
+ /* Even if there might be other users mapped to the
+ * certificate a missing SYSDB_NAME indicates some critical
+ * condition which justifies that the whole request is aborted
+ * */
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Certificate user object has no name.\n");
+ preq->pd->pam_status = PAM_USER_UNKNOWN;
pam_reply(preq);
return;
}
+
+ if (ldb_dn_compare(cert_user_objs->msgs[c]->dn,
+ preq->user_obj->dn) == 0) {
+ found = true;
+ if (preq->pd->cmd == SSS_PAM_PREAUTH) {
+ ret = sss_authtok_set_sc(preq->pd->authtok,
+ SSS_AUTHTOK_TYPE_SC_PIN, NULL, 0,
+ sss_cai_get_token_name(preq->current_cert), 0,
+ sss_cai_get_module_name(preq->current_cert), 0,
+ sss_cai_get_key_id(preq->current_cert), 0);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sss_authtok_set_sc failed, Smartcard "
+ "authentication detection might fail in "
+ "the backend.\n");
+ }
+
+ /* FIXME: use the right cert info */
+ ret = add_pam_cert_response(preq->pd, cert_user,
+ preq->current_cert,
+ SSS_PAM_CERT_INFO);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "add_pam_cert_response failed.\n");
+ preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL;
+ }
+ }
+
+ }
}
}
- if (preq->pd->cmd == SSS_PAM_PREAUTH) {
- DEBUG(SSSDBG_TRACE_FUNC,
- "User and certificate user do not match, "
- "continue with other authentication methods.\n");
+ if (found) {
+ /* We are done if we do not have to call the backend */
+ if (preq->pd->cmd == SSS_PAM_AUTHENTICATE
+ && preq->cert_auth_local) {
+ preq->pd->pam_status = PAM_SUCCESS;
+ preq->callback = pam_reply;
+ pam_reply(preq);
+ return;
+ }
} else {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "User and certificate user do not match.\n");
- preq->pd->pam_status = PAM_AUTH_ERR;
- pam_reply(preq);
- return;
+ if (preq->pd->cmd == SSS_PAM_PREAUTH) {
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "User and certificate user do not match, "
+ "continue with other authentication methods.\n");
+ } else {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "User and certificate user do not match.\n");
+ preq->pd->pam_status = PAM_AUTH_ERR;
+ pam_reply(preq);
+ return;
+ }
}
}
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index ff32d1e726808caa36ca7cca557220866ef1a9ab..57c8e1e464f4262f2d78f869c52ca48bd469d90a 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -40,10 +40,80 @@ struct cert_auth_info {
char *token_name;
char *module_name;
char *key_id;
+ struct ldb_result *cert_user_objs;
struct cert_auth_info *prev;
struct cert_auth_info *next;
};
+const char *sss_cai_get_cert(struct cert_auth_info *i)
+{
+ return i != NULL ? i->cert : NULL;
+}
+
+const char *sss_cai_get_token_name(struct cert_auth_info *i)
+{
+ return i != NULL ? i->token_name : NULL;
+}
+
+const char *sss_cai_get_module_name(struct cert_auth_info *i)
+{
+ return i != NULL ? i->module_name : NULL;
+}
+
+const char *sss_cai_get_key_id(struct cert_auth_info *i)
+{
+ return i != NULL ? i->key_id : NULL;
+}
+
+struct cert_auth_info *sss_cai_get_next(struct cert_auth_info *i)
+{
+ return i != NULL ? i->next : NULL;
+}
+
+struct ldb_result *sss_cai_get_cert_user_objs(struct cert_auth_info *i)
+{
+ return i != NULL ? i->cert_user_objs : NULL;
+}
+
+void sss_cai_set_cert_user_objs(struct cert_auth_info *i,
+ struct ldb_result *cert_user_objs)
+{
+ if (i->cert_user_objs != NULL) {
+ talloc_free(i->cert_user_objs);
+ }
+ i->cert_user_objs = talloc_steal(i, cert_user_objs);
+}
+
+void sss_cai_check_users(struct cert_auth_info **list, size_t *_cert_count,
+ size_t *_cert_user_count)
+{
+ struct cert_auth_info *c;
+ struct cert_auth_info *tmp;
+ size_t cert_count = 0;
+ size_t cert_user_count = 0;
+ struct ldb_result *user_objs;
+
+ DLIST_FOR_EACH_SAFE(c, tmp, *list) {
+ user_objs = sss_cai_get_cert_user_objs(c);
+ if (user_objs != NULL) {
+ cert_count++;
+ cert_user_count += user_objs->count;
+ } else {
+ DLIST_REMOVE(*list, c);
+ }
+ }
+
+ if (_cert_count != NULL) {
+ *_cert_count = cert_count;
+ }
+
+ if (_cert_user_count != NULL) {
+ *_cert_user_count = cert_user_count;
+ }
+
+ return;
+}
+
errno_t p11_child_init(struct pam_ctx *pctx)
{
return child_debug_init(P11_CHILD_LOG_FILE, &pctx->p11_child_debug_fd);
@@ -566,39 +636,71 @@ static void p11_child_timeout(struct tevent_context *ev,
}
errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- char **cert, char **token_name, char **module_name,
- char **key_id)
+ struct cert_auth_info **cert_list)
{
+ struct cert_auth_info *tmp_cert_auth_info;
struct pam_check_cert_state *state =
tevent_req_data(req, struct pam_check_cert_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
- if (state->cert_list == NULL) {
- *token_name = NULL;
- *cert = NULL;
- *module_name = NULL;
- *key_id = NULL;
+ if (cert_list != NULL) {
+ DLIST_FOR_EACH(tmp_cert_auth_info, state->cert_list) {
+ talloc_steal(mem_ctx, tmp_cert_auth_info);
+ }
+
+ *cert_list = state->cert_list;
}
- if (cert != NULL) {
- *cert = (state->cert_list == NULL) ? NULL
- : talloc_steal(mem_ctx, state->cert_list->cert);
+ return EOK;
+}
+
+static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username,
+ struct cert_auth_info *cert_info,
+ uint8_t **_msg, size_t *_msg_len)
+{
+ uint8_t *msg = NULL;
+ size_t msg_len;
+ const char *token_name;
+ const char *module_name;
+ const char *key_id;
+ size_t user_len;
+ size_t token_len;
+ size_t module_len;
+ size_t key_id_len;
+ const char *username = "";
+
+ if (sysdb_username != NULL) {
+ username = sysdb_username;
}
- if (token_name != NULL) {
- *token_name = (state->cert_list == NULL) ? NULL
- : talloc_steal(mem_ctx, state->cert_list->token_name);
+ token_name = sss_cai_get_token_name(cert_info);
+ module_name = sss_cai_get_module_name(cert_info);
+ key_id = sss_cai_get_key_id(cert_info);
+
+ user_len = strlen(username) + 1;
+ token_len = strlen(token_name) + 1;
+ module_len = strlen(module_name) + 1;
+ key_id_len = strlen(key_id) + 1;
+ msg_len = user_len + token_len + module_len + key_id_len;
+
+ msg = talloc_zero_size(mem_ctx, msg_len);
+ if (msg == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n");
+ return ENOMEM;
}
- if (module_name != NULL) {
- *module_name = (state->cert_list == NULL) ? NULL
- : talloc_steal(mem_ctx, state->cert_list->module_name);
+ memcpy(msg, username, user_len);
+ memcpy(msg + user_len, token_name, token_len);
+ memcpy(msg + user_len + token_len, module_name, module_len);
+ memcpy(msg + user_len + token_len + module_len, key_id, key_id_len);
+
+ if (_msg != NULL) {
+ *_msg = msg;
}
- if (key_id != NULL) {
- *key_id = (state->cert_list == NULL) ? NULL
- : talloc_steal(mem_ctx, state->cert_list->key_id);
+ if (_msg_len != NULL) {
+ *_msg_len = msg_len;
}
return EOK;
@@ -613,18 +715,13 @@ errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
#define PKCS11_LOGIN_TOKEN_ENV_NAME "PKCS11_LOGIN_TOKEN_NAME"
errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username,
- const char *token_name, const char *module_name,
- const char *key_id, enum response_type type)
+ struct cert_auth_info *cert_info,
+ enum response_type type)
{
uint8_t *msg = NULL;
char *env = NULL;
- size_t user_len;
size_t msg_len;
- size_t slot_len;
- size_t module_len;
- size_t key_id_len;
int ret;
- const char *username = "";
if (type != SSS_PAM_CERT_INFO && type != SSS_PAM_CERT_INFO_WITH_HINT) {
DEBUG(SSSDBG_CRIT_FAILURE, "Invalid response type [%d].\n", type);
@@ -632,26 +729,14 @@ errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username,
}
if ((type == SSS_PAM_CERT_INFO && sysdb_username == NULL)
- || token_name == NULL || module_name == NULL || key_id == NULL) {
+ || cert_info == NULL
+ || sss_cai_get_token_name(cert_info) == NULL
+ || sss_cai_get_module_name(cert_info) == NULL
+ || sss_cai_get_key_id(cert_info) == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Missing mandatory user or slot name.\n");
return EINVAL;
}
- if (sysdb_username != NULL) {
- username = sysdb_username;
- }
- user_len = strlen(username) + 1;
- slot_len = strlen(token_name) + 1;
- module_len = strlen(module_name) + 1;
- key_id_len = strlen(key_id) + 1;
- msg_len = user_len + slot_len + module_len + key_id_len;
-
- msg = talloc_zero_size(pd, msg_len);
- if (msg == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n");
- return ENOMEM;
- }
-
/* sysdb_username is a fully-qualified name which is used by pam_sss when
* prompting the user for the PIN and as login name if it wasn't set by
* the PAM caller but has to be determined based on the inserted
@@ -659,10 +744,12 @@ errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username,
* re_expression config option was set in a way that user@domain cannot be
* handled anymore some more logic has to be added here. But for the time
* being I think using sysdb_username is fine. */
- memcpy(msg, username, user_len);
- memcpy(msg + user_len, token_name, slot_len);
- memcpy(msg + user_len + slot_len, module_name, module_len);
- memcpy(msg + user_len + slot_len + module_len, key_id, key_id_len);
+
+ ret = pack_cert_data(pd, sysdb_username, cert_info, &msg, &msg_len);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "pack_cert_data failed.\n");
+ return ret;
+ }
ret = pam_add_response(pd, type, msg_len, msg);
talloc_free(msg);
@@ -674,7 +761,7 @@ errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username,
if (strcmp(pd->service, "gdm-smartcard") == 0) {
env = talloc_asprintf(pd, "%s=%s", PKCS11_LOGIN_TOKEN_ENV_NAME,
- token_name);
+ sss_cai_get_token_name(cert_info));
if (env == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
return ENOMEM;
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index 351067eb664431cda159f73590de772920504380..6adbc15f580997c41a02819d0d6aa253f2d5a64b 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -47,6 +47,9 @@
#define NSS_DB_PATH TESTS_PATH
#define NSS_DB "sql:"NSS_DB_PATH
+#define NSS_DB_PATH_2CERTS TESTS_PATH "_2certs"
+#define NSS_DB_2CERTS "sql:"NSS_DB_PATH_2CERTS
+
#define TEST_TOKEN_NAME "SSSD Test Token"
#define TEST_MODULE_NAME "NSS-Internal"
#define TEST_KEY_ID "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7"
@@ -74,6 +77,28 @@
"8Z+9gqZhCa7FEKJOPNR9RVtJs0qUUutMZrp1zpyx0GTmXQBA7LbgPxy8L68uymEQ" \
"XyQBwOYRORlnfGyu+Yc9c3E0Wx8Tlznz0lqPR9g="
+#define TEST2_KEY_ID "C8D60E009EB195D01A7083EE1D5419251AA87C2C"
+#define TEST_TOKEN_2ND_CERT \
+"MIIDazCCAlOgAwIBAgIBBzANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \
+"REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA1MjMx" \
+"NDEzMDFaFw0xODA1MTMxNDEzMDFaMCUxEjAQBgNVBAoMCUlQQS5ERVZFTDEPMA0G" \
+"A1UEAwwGSVBBIFJBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3abE" \
+"8LmIc6QN16VVxsMlN/rrCOoZKyyJolSzpP4+K66t+KZUiW/1j1MZogjyYyD39U1F" \
+"zpa2H+pID74XYrdiqP7sp+uE9/k2XOv/nN3FobXDt+fSINLDriCmxNhUZqpgo2uq" \
+"Mmka+yx2iJZwkntEoJTcd3aynoa2Sa2ZZbkMBy5p6/pUQKwnD6scOwe6mUDppIBK" \
+"+ZZRm+u/NDdIRFI5wfKLRR1r/ONaJA9nz1TxSEsgLsjG/1m+Zbb6lGG4pePIFkQ9" \
+"Iotpi64obBh93oIxzQR29lBG/FMjQVHlPIbx+xuGx11Vtp5pAomgFz0HRrj0leI7" \
+"bROE+jnC/VGPLQD2aQIDAQABo4GWMIGTMB8GA1UdIwQYMBaAFPci/0Km5D/L5z7Y" \
+"qwEc7E1/GwgcMEEGCCsGAQUFBwEBBDUwMzAxBggrBgEFBQcwAYYlaHR0cDovL2lw" \
+"YS1kZXZlbC5pcGEuZGV2ZWw6ODAvY2Evb2NzcDAOBgNVHQ8BAf8EBAMCBPAwHQYD" \
+"VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBg" \
+"4Sppx2C3eXPJ4Pd9XElkQPOaBReXf1vV0uk/GlK+rG+aAqAkA2Lryx5PK/iAuzAU" \
+"M6JUpELuQYgqugoCgBXMgsMlpAO/0C3CFq4ZH3KgIsRlRngKPrt6RG0UPMRD1CE2" \
+"tSVkwUWvyK83lDiu2BbWDXyMyz5eZOlp7uHusf5BKvob8jEndHj1YzaNTmVSsDM5" \
+"kiIwf8qgFhsO1HCq08PtAnbVHhqkcvnmIJN98eNWNfTKodDmFVbN8gB0wK+WB5ii" \
+"WVOw7+3/zF1QgqnYX3t+kPLRryip/wvTZkzXWwMNj/W6UHgjNF/4gWGoBgCHu+u3" \
+"EvjMmbVSrEkesibpGQS5"
+
static char CACHED_AUTH_TIMEOUT_STR[] = "4";
static const int CACHED_AUTH_TIMEOUT = 4;
@@ -111,6 +136,13 @@ static errno_t setup_nss_db(void)
return ret;
}
+ ret = mkdir(NSS_DB_PATH_2CERTS, 0775);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Failed to create " NSS_DB_PATH_2CERTS ".\n");
+ return ret;
+ }
+
child_pid = fork();
if (child_pid == 0) { /* child */
ret = execlp("certutil", "certutil", "-N", "--empty-password", "-d",
@@ -127,6 +159,22 @@ static errno_t setup_nss_db(void)
return ret;
}
+ child_pid = fork();
+ if (child_pid == 0) { /* child */
+ ret = execlp("certutil", "certutil", "-N", "--empty-password", "-d",
+ NSS_DB_2CERTS, NULL);
+ if (ret == -1) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "execl() failed.\n");
+ exit(-1);
+ }
+ } else if (child_pid > 0) {
+ wait(&status);
+ } else {
+ ret = errno;
+ DEBUG(SSSDBG_FATAL_FAILURE, "fork() failed\n");
+ return ret;
+ }
+
fp = fopen(NSS_DB_PATH"/pkcs11.txt", "w");
if (fp == NULL) {
DEBUG(SSSDBG_FATAL_FAILURE, "fopen() failed.\n");
@@ -148,6 +196,27 @@ static errno_t setup_nss_db(void)
return ret;
}
+ fp = fopen(NSS_DB_PATH_2CERTS"/pkcs11.txt", "w");
+ if (fp == NULL) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "fopen() failed.\n");
+ return ret;
+ }
+ ret = fprintf(fp, "library=libsoftokn3.so\nname=soft\n");
+ if (ret < 0) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "fprintf() failed.\n");
+ return ret;
+ }
+ ret = fprintf(fp, "parameters=configdir='sql:%s/src/tests/cmocka/p11_nssdb_2certs' dbSlotDescription='SSSD Test Slot' dbTokenDescription='SSSD Test Token' secmod='secmod.db' flags=readOnly \n\n", ABS_SRC_DIR);
+ if (ret < 0) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "fprintf() failed.\n");
+ return ret;
+ }
+ ret = fclose(fp);
+ if (ret != 0) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "fclose() failed.\n");
+ return ret;
+ }
+
return EOK;
}
@@ -174,6 +243,26 @@ static void cleanup_nss_db(void)
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Failed to remove " NSS_DB_PATH "\n");
}
+
+ ret = unlink(NSS_DB_PATH_2CERTS"/cert9.db");
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove cert9.db.\n");
+ }
+
+ ret = unlink(NSS_DB_PATH_2CERTS"/key4.db");
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove key4.db.\n");
+ }
+
+ ret = unlink(NSS_DB_PATH_2CERTS"/pkcs11.txt");
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove pkcs11.db.\n");
+ }
+
+ ret = rmdir(NSS_DB_PATH_2CERTS);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove " NSS_DB_PATH "\n");
+ }
}
struct pam_ctx *mock_pctx(TALLOC_CTX *mem_ctx)
@@ -749,7 +838,8 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body,
}
static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
- enum response_type type, const char *name)
+ enum response_type type, const char *name,
+ const char *name2)
{
size_t rp = 0;
uint32_t val;
@@ -763,7 +853,11 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
if (name == NULL || *name == '\0') {
assert_int_equal(val, 1);
} else {
- assert_int_equal(val, 2);
+ if (name2 == NULL || *name2 == '\0') {
+ assert_int_equal(val, 2);
+ } else {
+ assert_int_equal(val, 3);
+ }
SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
assert_int_equal(val, SSS_PAM_DOMAIN_NAME);
@@ -801,6 +895,33 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
assert_string_equal(body + rp, TEST_KEY_ID);
rp += sizeof(TEST_KEY_ID);
+ if (name2 != NULL && *name2 != '\0') {
+ SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
+ assert_int_equal(val, type);
+
+ SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
+ assert_int_equal(val, (strlen(name) + 1
+ + sizeof(TEST_TOKEN_NAME)
+ + sizeof(TEST_MODULE_NAME)
+ + sizeof(TEST2_KEY_ID)));
+
+ assert_int_equal(*(body + rp + strlen(name)), 0);
+ assert_string_equal(body + rp, name);
+ rp += strlen(name) + 1;
+
+ assert_int_equal(*(body + rp + sizeof(TEST_TOKEN_NAME) - 1), 0);
+ assert_string_equal(body + rp, TEST_TOKEN_NAME);
+ rp += sizeof(TEST_TOKEN_NAME);
+
+ assert_int_equal(*(body + rp + sizeof(TEST_MODULE_NAME) - 1), 0);
+ assert_string_equal(body + rp, TEST_MODULE_NAME);
+ rp += sizeof(TEST_MODULE_NAME);
+
+ assert_int_equal(*(body + rp + sizeof(TEST2_KEY_ID) - 1), 0);
+ assert_string_equal(body + rp, TEST2_KEY_ID);
+ rp += sizeof(TEST2_KEY_ID);
+ }
+
assert_int_equal(rp, blen);
return EOK;
@@ -809,7 +930,8 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
static int test_pam_cert_check(uint32_t status, uint8_t *body, size_t blen)
{
return test_pam_cert_check_ex(status, body, blen,
- SSS_PAM_CERT_INFO, "pamuser@"TEST_DOM_NAME);
+ SSS_PAM_CERT_INFO, "pamuser@"TEST_DOM_NAME,
+ NULL);
}
static int test_pam_cert_check_with_hint(uint32_t status, uint8_t *body,
@@ -817,14 +939,22 @@ static int test_pam_cert_check_with_hint(uint32_t status, uint8_t *body,
{
return test_pam_cert_check_ex(status, body, blen,
SSS_PAM_CERT_INFO_WITH_HINT,
- "pamuser@"TEST_DOM_NAME);
+ "pamuser@"TEST_DOM_NAME, NULL);
}
static int test_pam_cert_check_with_hint_no_user(uint32_t status, uint8_t *body,
size_t blen)
{
return test_pam_cert_check_ex(status, body, blen,
- SSS_PAM_CERT_INFO_WITH_HINT, "");
+ SSS_PAM_CERT_INFO_WITH_HINT, "", NULL);
+}
+
+int test_pam_cert_check_2certs(uint32_t status, uint8_t *body,
+ size_t blen)
+{
+ return test_pam_cert_check_ex(status, body, blen,
+ SSS_PAM_CERT_INFO, "pamuser@"TEST_DOM_NAME,
+ "pamuser@"TEST_DOM_NAME);
}
static int test_pam_offline_chauthtok_check(uint32_t status,
@@ -1737,6 +1867,33 @@ static int test_lookup_by_cert_cb(void *pvt)
return EOK;
}
+int test_lookup_by_cert_cb_2nd_cert_same_user(void *pvt)
+{
+ int ret;
+ struct sysdb_attrs *attrs;
+ unsigned char *der = NULL;
+ size_t der_size;
+
+ test_lookup_by_cert_cb(pvt);
+
+ attrs = sysdb_new_attrs(pam_test_ctx);
+ assert_non_null(attrs);
+
+ der = sss_base64_decode(pam_test_ctx, TEST_TOKEN_2ND_CERT, &der_size);
+ assert_non_null(der);
+
+ ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_MAPPED_CERT, der, der_size);
+ talloc_free(der);
+ assert_int_equal(ret, EOK);
+
+ ret = sysdb_set_user_attr(pam_test_ctx->tctx->dom,
+ pam_test_ctx->pam_user_fqdn,
+ attrs,
+ LDB_FLAG_MOD_ADD);
+ assert_int_equal(ret, EOK);
+
+ return EOK;
+}
static int test_lookup_by_cert_double_cb(void *pvt)
{
diff --git a/src/tests/whitespace_test b/src/tests/whitespace_test
index 799e35358b1d5ae4b10c4405068fb507cb234b6f..f055ed4c255db4001194844f45a9df7cda774b38 100755
--- a/src/tests/whitespace_test
+++ b/src/tests/whitespace_test
@@ -39,7 +39,7 @@ fi
declare found_file=false
while read file; do
[[ $file == "src/config/testconfigs/noparse.api.conf" ]] && continue
- [[ $file =~ ^src/tests/cmocka/p11_nssdb/.*db ]] && continue
+ [[ $file =~ ^src/tests/cmocka/p11_nssdb.*/.*db ]] && continue
test `tail -c 1 $ABS_TOP_SRCDIR/$file` && \
echo "Missing new line at the eof: $file" && \
found_file=true
--
2.15.1

View File

@ -0,0 +1,679 @@
From 55deead9f2a98c3ba1fd5754bd38203b6c02b6a1 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 16 Oct 2017 14:13:10 +0200
Subject: [PATCH 44/79] pam_sss: refactoring, use struct cert_auth_info
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Similar as in the PAM responder this patch replaces the individual
certificate authentication related attributes by a struct which can be
used as a list. With the pam_sss can handle multiple SSS_PAM_CERT_INFO
message and place the data in individual list items.
If multiple certificates are returned before prompting for the PIN a
dialog to select a certificate is shown to the users. If available a GDM
PAM extension is used to let the user choose from a list. All coded
needed at runtime to check if the extension is available and handle the
data is provided by GDM as macros. This means that there are no
additional run-time requirements.
Related to https://pagure.io/SSSD/sssd/issue/3560
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Tested-by: Scott Poore <spoore@redhat.com>
---
contrib/sssd.spec.in | 9 +
src/external/pam.m4 | 12 ++
src/sss_client/pam_message.h | 8 +-
src/sss_client/pam_sss.c | 439 ++++++++++++++++++++++++++++++++++---------
4 files changed, 370 insertions(+), 98 deletions(-)
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 4aafd1832b67161ff1c25a4e9ad689586a227a25..c716efdce05ab7b9178be66f34d09124c78071b5 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -121,6 +121,12 @@
%global with_kcm_option --without-kcm
%endif
+%if (0%{?fedora} >= 27 || (0%{?rhel} >= 7 && 0%{?rhel7_minor} > 4))
+ %global with_gdm_pam_extensions 1
+%else
+ %global with_gdm_pam_extensions 0
+%endif
+
Name: @PACKAGE_NAME@
Version: @PACKAGE_VERSION@
Release: 0@PRERELEASE_VERSION@%{?dist}
@@ -233,6 +239,9 @@ BuildRequires: libuuid-devel
BuildRequires: jansson-devel
BuildRequires: libcurl-devel
%endif
+%if (0%{?with_gdm_pam_extensions} == 1)
+BuildRequires: gdm-devel
+%endif
%description
Provides a set of daemons to manage access to remote directories and
diff --git a/src/external/pam.m4 b/src/external/pam.m4
index 4776b6ae338409f0a2729dfc4cf5962463a40dfd..0dc7f19d0df6a4588cf893ecff6e518111462433 100644
--- a/src/external/pam.m4
+++ b/src/external/pam.m4
@@ -27,3 +27,15 @@ AC_CHECK_FUNCS(pam_modutil_getlogin pam_vsyslog)
dnl restore LIBS
LIBS="$save_LIBS"
+
+PKG_CHECK_MODULES([GDM_PAM_EXTENSIONS], [gdm-pam-extensions],
+ [found_gdm_pam_extensions=yes],
+ [AC_MSG_NOTICE([gdm-pam-extensions were not found. gdm support
+for multiple certificates will not be build.
+])])
+
+AC_SUBST(GDM_PAM_EXTENSIONS_CFLAGS)
+
+AS_IF([test x"$found_gdm_pam_extensions" = xyes],
+ [AC_DEFINE_UNQUOTED(HAVE_GDM_PAM_EXTENSIONS, 1,
+ [Build with gdm-pam-extensions support])])
diff --git a/src/sss_client/pam_message.h b/src/sss_client/pam_message.h
index f215392f6879f01a0ca12abc8807bac5fc1f1cbb..11526a80a767ff5602b194d14765ff261e8f9707 100644
--- a/src/sss_client/pam_message.h
+++ b/src/sss_client/pam_message.h
@@ -29,6 +29,8 @@
#include "sss_client/sss_cli.h"
+struct cert_auth_info;
+
struct pam_items {
const char *pam_service;
const char *pam_user;
@@ -59,11 +61,9 @@ struct pam_items {
char *first_factor;
bool password_prompting;
- char *cert_user;
- char *token_name;
- char *module_name;
- char *key_id;
bool user_name_hint;
+ struct cert_auth_info *cert_list;
+ struct cert_auth_info *selected_cert;
};
int pack_message_v3(struct pam_items *pi, size_t *size, uint8_t **buffer);
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index 303809b9ea05b5a8709c05ae230d5f289b57de31..c147d4b3d76443d69e27eb2da042f8eebd1ae6ab 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -36,6 +36,10 @@
#include <security/pam_modules.h>
#include <security/pam_appl.h>
+#ifdef HAVE_GDM_PAM_EXTENSIONS
+#include <gdm/gdm-pam-extensions.h>
+#endif
+
#include "sss_pam_compat.h"
#include "sss_pam_macros.h"
@@ -43,6 +47,7 @@
#include "pam_message.h"
#include "util/atomic_io.h"
#include "util/authtok-utils.h"
+#include "util/dlinklist.h"
#include <libintl.h>
#define _(STRING) dgettext (PACKAGE, STRING)
@@ -118,6 +123,40 @@ static void close_fd(pam_handle_t *pamh, void *ptr, int err)
sss_pam_close_fd();
}
+struct cert_auth_info {
+ char *cert_user;
+ char *cert;
+ char *token_name;
+ char *module_name;
+ char *key_id;
+ struct cert_auth_info *prev;
+ struct cert_auth_info *next;
+};
+
+static void free_cai(struct cert_auth_info *cai)
+{
+ if (cai != NULL) {
+ free(cai->cert_user);
+ free(cai->cert);
+ free(cai->token_name);
+ free(cai->key_id);
+ free(cai);
+ }
+}
+
+static void free_cert_list(struct cert_auth_info *list)
+{
+ struct cert_auth_info *cai;
+ struct cert_auth_info *cai_next;
+
+ if (list != NULL) {
+ DLIST_FOR_EACH_SAFE(cai, cai_next, list) {
+ DLIST_REMOVE(list, cai);
+ free_cai(cai);
+ }
+ }
+}
+
static void overwrite_and_free_authtoks(struct pam_items *pi)
{
if (pi->pam_authtok != NULL) {
@@ -158,17 +197,9 @@ static void overwrite_and_free_pam_items(struct pam_items *pi)
free(pi->otp_challenge);
pi->otp_challenge = NULL;
- free(pi->cert_user);
- pi->cert_user = NULL;
-
- free(pi->token_name);
- pi->token_name = NULL;
-
- free(pi->module_name);
- pi->module_name = NULL;
-
- free(pi->key_id);
- pi->key_id = NULL;
+ free_cert_list(pi->cert_list);
+ pi->cert_list = NULL;
+ pi->selected_cert = NULL;
}
static int null_strcmp(const char *s1, const char *s2) {
@@ -821,6 +852,90 @@ static int eval_user_info_response(pam_handle_t *pamh, size_t buflen,
return ret;
}
+static int parse_cert_info(struct pam_items *pi, uint8_t *buf, size_t len,
+ size_t *p, const char **cert_user)
+{
+ struct cert_auth_info *cai = NULL;
+ size_t offset;
+ int ret;
+
+ if (buf[*p + (len - 1)] != '\0') {
+ D(("cert info does not end with \\0."));
+ return EINVAL;
+ }
+
+ cai = calloc(1, sizeof(struct cert_auth_info));
+ if (cai == NULL) {
+ return ENOMEM;
+ }
+
+ cai->cert_user = strdup((char *) &buf[*p]);
+ if (cai->cert_user == NULL) {
+ D(("strdup failed"));
+ ret = ENOMEM;
+ goto done;
+ }
+ if (cert_user != NULL) {
+ *cert_user = cai->cert_user;
+ }
+
+ offset = strlen(cai->cert_user) + 1;
+ if (offset >= len) {
+ D(("Cert message size mismatch"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ cai->token_name = strdup((char *) &buf[*p + offset]);
+ if (cai->token_name == NULL) {
+ D(("strdup failed"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ offset += strlen(cai->token_name) + 1;
+ if (offset >= len) {
+ D(("Cert message size mismatch"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ cai->module_name = strdup((char *) &buf[*p + offset]);
+ if (cai->module_name == NULL) {
+ D(("strdup failed"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ offset += strlen(cai->module_name) + 1;
+ if (offset >= len) {
+ D(("Cert message size mismatch"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ cai->key_id = strdup((char *) &buf[*p + offset]);
+ if (cai->key_id == NULL) {
+ D(("strdup failed"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ D(("cert user: [%s] token name: [%s] module: [%s] key id: [%s]",
+ cai->cert_user, cai->token_name, cai->module_name,
+ cai->key_id));
+
+ DLIST_ADD(pi->cert_list, cai);
+ ret = 0;
+
+done:
+ if (ret != 0) {
+ free_cai(cai);
+ }
+
+ return ret;
+}
+
static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf,
struct pam_items *pi)
{
@@ -832,6 +947,7 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf,
int32_t len;
int32_t pam_status;
size_t offset;
+ const char *cert_user;
if (buflen < (2*sizeof(int32_t))) {
D(("response buffer is too small"));
@@ -988,27 +1104,21 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf,
break;
}
- free(pi->cert_user);
- pi->cert_user = strdup((char *) &buf[p]);
- if (pi->cert_user == NULL) {
- D(("strdup failed"));
- break;
- }
-
- if (type == SSS_PAM_CERT_INFO && *pi->cert_user == '\0') {
- D(("Invalid CERT message"));
- break;
- }
-
if (type == SSS_PAM_CERT_INFO_WITH_HINT) {
pi->user_name_hint = true;
} else {
pi->user_name_hint = false;
}
+ ret = parse_cert_info(pi, buf, len, &p, &cert_user);
+ if (ret != 0) {
+ D(("Failed to parse cert info"));
+ break;
+ }
+
if ((pi->pam_user == NULL || *(pi->pam_user) == '\0')
- && *pi->cert_user != '\0') {
- ret = pam_set_item(pamh, PAM_USER, pi->cert_user);
+ && *cert_user != '\0') {
+ ret = pam_set_item(pamh, PAM_USER, cert_user);
if (ret != PAM_SUCCESS) {
D(("Failed to set PAM_USER during "
"Smartcard authentication [%s]",
@@ -1027,59 +1137,6 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf,
pi->pam_user_size = strlen(pi->pam_user) + 1;
}
-
- offset = strlen(pi->cert_user) + 1;
- if (offset >= len) {
- D(("Cert message size mismatch"));
- free(pi->cert_user);
- pi->cert_user = NULL;
- break;
- }
- free(pi->token_name);
- pi->token_name = strdup((char *) &buf[p + offset]);
- if (pi->token_name == NULL) {
- D(("strdup failed"));
- free(pi->cert_user);
- pi->cert_user = NULL;
- break;
- }
-
- offset += strlen(pi->token_name) + 1;
- if (offset >= len) {
- D(("Cert message size mismatch"));
- free(pi->cert_user);
- pi->cert_user = NULL;
- free(pi->token_name);
- pi->token_name = NULL;
- break;
- }
- free(pi->module_name);
- pi->module_name = strdup((char *) &buf[p + offset]);
- if (pi->module_name == NULL) {
- D(("strdup failed"));
- break;
- }
-
- offset += strlen(pi->module_name) + 1;
- if (offset >= len) {
- D(("Cert message size mismatch"));
- free(pi->cert_user);
- pi->cert_user = NULL;
- free(pi->token_name);
- pi->token_name = NULL;
- free(pi->module_name);
- pi->module_name = NULL;
- break;
- }
- free(pi->key_id);
- pi->key_id = strdup((char *) &buf[p + offset]);
- if (pi->key_id == NULL) {
- D(("strdup failed"));
- break;
- }
- D(("cert user: [%s] token name: [%s] module: [%s] key id: [%s]",
- pi->cert_user, pi->token_name, pi->module_name,
- pi->key_id));
break;
case SSS_PASSWORD_PROMPTING:
D(("Password prompting available."));
@@ -1175,10 +1232,8 @@ static int get_pam_items(pam_handle_t *pamh, uint32_t flags,
pi->otp_challenge = NULL;
pi->password_prompting = false;
- pi->cert_user = NULL;
- pi->token_name = NULL;
- pi->module_name = NULL;
- pi->key_id = NULL;
+ pi->cert_list = NULL;
+ pi->selected_cert = NULL;
return PAM_SUCCESS;
}
@@ -1484,6 +1539,184 @@ done:
#define SC_PROMPT_FMT "PIN for %s"
+#ifndef discard_const
+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
+#endif
+
+#define CERT_SEL_PROMPT_FMT "Certificate: %s"
+#define SEL_TITLE discard_const("Please select a certificate")
+
+static int prompt_multi_cert_gdm(pam_handle_t *pamh, struct pam_items *pi)
+{
+#ifdef HAVE_GDM_PAM_EXTENSIONS
+ int ret;
+ size_t cert_count = 0;
+ size_t c;
+ const struct pam_conv *conv;
+ struct cert_auth_info *cai;
+ GdmPamExtensionChoiceListRequest *request = NULL;
+ GdmPamExtensionChoiceListResponse *response = NULL;
+ struct pam_message prompt_message;
+ const struct pam_message *prompt_messages[1];
+ struct pam_response *reply = NULL;
+ char *prompt;
+
+ if (!GDM_PAM_EXTENSION_SUPPORTED(GDM_PAM_EXTENSION_CHOICE_LIST)) {
+ return ENOTSUP;
+ }
+
+ if (pi->cert_list == NULL) {
+ return EINVAL;
+ }
+
+ DLIST_FOR_EACH(cai, pi->cert_list) {
+ cert_count++;
+ }
+
+ ret = pam_get_item(pamh, PAM_CONV, (const void **)&conv);
+ if (ret != PAM_SUCCESS) {
+ ret = EIO;
+ return ret;
+ }
+
+ request = calloc(1, GDM_PAM_EXTENSION_CHOICE_LIST_REQUEST_SIZE(cert_count));
+ if (request == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ GDM_PAM_EXTENSION_CHOICE_LIST_REQUEST_INIT(request, SEL_TITLE, cert_count);
+
+ c = 0;
+ DLIST_FOR_EACH(cai, pi->cert_list) {
+ ret = asprintf(&prompt, CERT_SEL_PROMPT_FMT, cai->key_id);
+ if (ret == -1) {
+ ret = ENOMEM;
+ goto done;
+ }
+ request->list.items[c].key = cai->key_id;
+ request->list.items[c++].text = prompt;
+ }
+
+ GDM_PAM_EXTENSION_MESSAGE_TO_BINARY_PROMPT_MESSAGE(request,
+ &prompt_message);
+ prompt_messages[0] = &prompt_message;
+
+ ret = conv->conv(1, prompt_messages, &reply, conv->appdata_ptr);
+ if (ret != PAM_SUCCESS) {
+ ret = EIO;
+ goto done;
+ }
+
+ ret = EIO;
+ response = GDM_PAM_EXTENSION_REPLY_TO_CHOICE_LIST_RESPONSE(reply);
+ if (response->key == NULL) {
+ goto done;
+ }
+
+ DLIST_FOR_EACH(cai, pi->cert_list) {
+ if (strcmp(response->key, cai->key_id) == 0) {
+ pam_info(pamh, "Certificate %s selected", cai->key_id);
+ pi->selected_cert = cai;
+ ret = 0;
+ break;
+ }
+ }
+
+done:
+ if (request != NULL) {
+ for (c = 0; c < cert_count; c++) {
+ free(discard_const(request->list.items[c++].text));
+ }
+ free(request);
+ }
+ free(response);
+
+ return ret;
+#else
+ return ENOTSUP;
+#endif
+}
+
+#define TEXT_CERT_SEL_PROMPT_FMT "%s[%zu] Certificate: %s\n"
+#define TEXT_SEL_TITLE discard_const("Please select a certificate by typing " \
+ "the corresponding number\n")
+static int prompt_multi_cert(pam_handle_t *pamh, struct pam_items *pi)
+{
+ int ret;
+ size_t cert_count = 0;
+ size_t tries = 0;
+ long int resp = -1;
+ struct cert_auth_info *cai;
+ char *prompt;
+ char *tmp;
+ char *answer;
+ char *ep;
+
+ /* First check if gdm extension is supported */
+ ret = prompt_multi_cert_gdm(pamh, pi);
+ if (ret != ENOTSUP) {
+ return ret;
+ }
+
+ if (pi->cert_list == NULL) {
+ return EINVAL;
+ }
+
+ prompt = strdup(TEXT_SEL_TITLE);
+ if (prompt == NULL) {
+ return ENOMEM;
+ }
+
+ DLIST_FOR_EACH(cai, pi->cert_list) {
+ cert_count++;
+ ret = asprintf(&tmp, TEXT_CERT_SEL_PROMPT_FMT, prompt, cert_count,
+ cai->key_id);
+ free(prompt);
+ if (ret == -1) {
+ return ENOMEM;
+ }
+
+ prompt = tmp;
+ }
+
+ do {
+ ret = do_pam_conversation(pamh, PAM_PROMPT_ECHO_ON, prompt, NULL,
+ &answer);
+ if (ret != PAM_SUCCESS) {
+ D(("do_pam_conversation failed."));
+ break;
+ }
+
+ errno = 0;
+ resp = strtol(answer, &ep, 10);
+ if (errno == 0 && *ep == '\0' && resp > 0 && resp <= cert_count) {
+ /* do not free answer ealier because ep is pointing to it */
+ free(answer);
+ break;
+ }
+ free(answer);
+ resp = -1;
+ } while (++tries < 5);
+ free(prompt);
+
+ pi->selected_cert = NULL;
+ ret = ENOENT;
+ if (resp > 0 && resp <= cert_count) {
+ cert_count = 0;
+ DLIST_FOR_EACH(cai, pi->cert_list) {
+ cert_count++;
+ if (resp == cert_count) {
+ pam_info(pamh, "Certificate %s selected", cai->key_id);
+ pi->selected_cert = cai;
+ ret = 0;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
static int prompt_sc_pin(pam_handle_t *pamh, struct pam_items *pi)
{
int ret;
@@ -1495,19 +1728,20 @@ static int prompt_sc_pin(pam_handle_t *pamh, struct pam_items *pi)
const struct pam_message *mesg[2] = { NULL, NULL };
struct pam_message m[2] = { { 0 }, { 0 } };
struct pam_response *resp = NULL;
+ struct cert_auth_info *cai = pi->selected_cert;
- if (pi->token_name == NULL || *pi->token_name == '\0') {
+ if (cai == NULL || cai->token_name == NULL || *cai->token_name == '\0') {
return EINVAL;
}
- size = sizeof(SC_PROMPT_FMT) + strlen(pi->token_name);
+ size = sizeof(SC_PROMPT_FMT) + strlen(cai->token_name);
prompt = malloc(size);
if (prompt == NULL) {
D(("malloc failed."));
return ENOMEM;
}
- ret = snprintf(prompt, size, SC_PROMPT_FMT, pi->token_name);
+ ret = snprintf(prompt, size, SC_PROMPT_FMT, cai->token_name);
if (ret < 0 || ret >= size) {
D(("snprintf failed."));
free(prompt);
@@ -1604,9 +1838,9 @@ static int prompt_sc_pin(pam_handle_t *pamh, struct pam_items *pi)
pi->pam_authtok_size=0;
} else {
- ret = sss_auth_pack_sc_blob(answer, 0, pi->token_name, 0,
- pi->module_name, 0,
- pi->key_id, 0,
+ ret = sss_auth_pack_sc_blob(answer, 0, cai->token_name, 0,
+ cai->module_name, 0,
+ cai->key_id, 0,
NULL, 0, &needed_size);
if (ret != EAGAIN) {
D(("sss_auth_pack_sc_blob failed."));
@@ -1621,9 +1855,9 @@ static int prompt_sc_pin(pam_handle_t *pamh, struct pam_items *pi)
goto done;
}
- ret = sss_auth_pack_sc_blob(answer, 0, pi->token_name, 0,
- pi->module_name, 0,
- pi->key_id, 0,
+ ret = sss_auth_pack_sc_blob(answer, 0, cai->token_name, 0,
+ cai->module_name, 0,
+ cai->key_id, 0,
(uint8_t *) pi->pam_authtok, needed_size,
&needed_size);
if (ret != EOK) {
@@ -1786,7 +2020,17 @@ static int get_authtok_for_authentication(pam_handle_t *pamh,
ret = prompt_2fa(pamh, pi, _("First Factor: "),
_("Second Factor: "));
}
- } else if (pi->token_name != NULL && *(pi->token_name) != '\0') {
+ } else if (pi->cert_list != NULL) {
+ if (pi->cert_list->next == NULL) {
+ /* Only one certificate */
+ pi->selected_cert = pi->cert_list;
+ } else {
+ ret = prompt_multi_cert(pamh, pi);
+ if (ret != 0) {
+ D(("Failed to select certificate"));
+ return PAM_AUTHTOK_ERR;
+ }
+ }
ret = prompt_sc_pin(pamh, pi);
} else {
ret = prompt_password(pamh, pi, _("Password: "));
@@ -1905,14 +2149,21 @@ static int check_login_token_name(pam_handle_t *pamh, struct pam_items *pi,
char *prompt = NULL;
size_t size;
char *answer = NULL;
+ /* TODO: check multiple cert case */
+ struct cert_auth_info *cai = pi->cert_list;
+
+ if (cai == NULL) {
+ D(("No certificate information available"));
+ return EINVAL;
+ }
login_token_name = getenv("PKCS11_LOGIN_TOKEN_NAME");
if (login_token_name == NULL) {
return PAM_SUCCESS;
}
- while (pi->token_name == NULL
- || strcmp(login_token_name, pi->token_name) != 0) {
+ while (cai->token_name == NULL
+ || strcmp(login_token_name, cai->token_name) != 0) {
size = sizeof(SC_ENTER_FMT) + strlen(login_token_name);
prompt = malloc(size);
if (prompt == NULL) {
--
2.15.1

View File

@ -0,0 +1,590 @@
From 4aef95ff22cb926998773330cc860879b0dea5c2 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 27 Oct 2017 10:13:36 +0200
Subject: [PATCH 45/79] p11_child: use options to select certificate for
authentication
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
New options are added to p11_child to select a specific certificate
during authentication.
The related unit tests are updated by adding the needed attributes to
the requests. The was not necessary before because although the
attribute were already send by pam_sss they were not used in the PAM
responder but only forwarded to the back where they were used by the
PKINIT code to select the expected certificate.
Related to https://pagure.io/SSSD/sssd/issue/3560
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Tested-by: Scott Poore <spoore@redhat.com>
---
src/p11_child/p11_child_nss.c | 213 ++++++++++++++++++++++++++--------------
src/responder/pam/pamsrv_p11.c | 30 +++++-
src/tests/cmocka/test_pam_srv.c | 60 +++++++----
3 files changed, 208 insertions(+), 95 deletions(-)
diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c
index 50bde2f4f91f6c00260b0db383d0962112686ebc..c676375cf7f6677a1d7f38f09b9bb5fd820d60c5 100644
--- a/src/p11_child/p11_child_nss.c
+++ b/src/p11_child/p11_child_nss.c
@@ -67,12 +67,34 @@ static char *password_passthrough(PK11SlotInfo *slot, PRBool retry, void *arg)
return PL_strdup((char *)arg);
}
+static char *get_key_id_str(PK11SlotInfo *slot, CERTCertificate *cert)
+{
+ SECItem *key_id = NULL;
+ char *key_id_str = NULL;
+ key_id = PK11_GetLowLevelKeyIDForCert(slot, cert, NULL);
+ if (key_id == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "PK11_GetLowLevelKeyIDForCert failed [%d].\n",
+ PR_GetError());
+ return NULL;
+ }
-int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
+ key_id_str = CERT_Hexify(key_id, PR_FALSE);
+ SECITEM_FreeItem(key_id, PR_TRUE);
+ if (key_id_str == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d].\n", PR_GetError());
+ return NULL;
+ }
+
+ return key_id_str;
+}
+
+int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
enum op_mode mode, const char *pin,
struct cert_verify_opts *cert_verify_opts,
- char **_multi)
+ const char *module_name_in, const char *token_name_in,
+ const char *key_id_in, char **_multi)
{
int ret;
SECStatus rv;
@@ -153,42 +175,31 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
mod_list_item->module->dllName);
}
- if (slot_name_in != NULL) {
- slot = PK11_FindSlotByName(slot_name_in);
- if (slot == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "PK11_FindSlotByName failed for [%s]: [%d].\n",
- slot_name_in, PR_GetError());
- return EIO;
- }
- } else {
-
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE,
- NULL);
- if (list == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "PK11_GetAllTokens failed.\n");
- return EIO;
- }
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE,
+ NULL);
+ if (list == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "PK11_GetAllTokens failed.\n");
+ return EIO;
+ }
- for (le = list->head; le; le = le->next) {
- CK_SLOT_INFO slInfo;
+ for (le = list->head; le; le = le->next) {
+ CK_SLOT_INFO slInfo;
- slInfo.flags = 0;
- rv = PK11_GetSlotInfo(le->slot, &slInfo);
- DEBUG(SSSDBG_TRACE_ALL,
- "Description [%s] Manufacturer [%s] flags [%lu].\n",
- slInfo.slotDescription, slInfo.manufacturerID, slInfo.flags);
- if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) {
- slot = PK11_ReferenceSlot(le->slot);
- break;
- }
- }
- PK11_FreeSlotList(list);
- if (slot == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "No removable slots found.\n");
- return EIO;
+ slInfo.flags = 0;
+ rv = PK11_GetSlotInfo(le->slot, &slInfo);
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Description [%s] Manufacturer [%s] flags [%lu].\n",
+ slInfo.slotDescription, slInfo.manufacturerID, slInfo.flags);
+ if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) {
+ slot = PK11_ReferenceSlot(le->slot);
+ break;
}
}
-
+ PK11_FreeSlotList(list);
+ if (slot == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "No removable slots found.\n");
+ return EIO;
+ }
slot_id = PK11_GetSlotID(slot);
module_id = PK11_GetModuleID(slot);
@@ -317,24 +328,60 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
for (cert_list_node = CERT_LIST_HEAD(cert_list);
!CERT_LIST_END(cert_list_node, cert_list);
cert_list_node = CERT_LIST_NEXT(cert_list_node)) {
- if (cert_list_node->cert) {
- DEBUG(SSSDBG_TRACE_ALL, "found cert[%s][%s]\n",
- cert_list_node->cert->nickname,
- cert_list_node->cert->subjectName);
+ if (cert_list_node->cert == NULL) {
+ DEBUG(SSSDBG_TRACE_ALL, "--- empty cert list node ---\n");
+ continue;
+ }
- if (cert_verify_opts->do_verification) {
- rv = CERT_VerifyCertificateNow(handle, cert_list_node->cert,
- PR_TRUE,
- certificateUsageSSLClient,
- NULL, NULL);
- if (rv != SECSuccess) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Certificate [%s][%s] not valid [%d], skipping.\n",
- cert_list_node->cert->nickname,
- cert_list_node->cert->subjectName, PR_GetError());
- continue;
- }
+ DEBUG(SSSDBG_TRACE_ALL,
+ "found cert[%s][%s]\n",
+ cert_list_node->cert->nickname,
+ cert_list_node->cert->subjectName);
+
+ if (cert_verify_opts->do_verification) {
+ rv = CERT_VerifyCertificateNow(handle, cert_list_node->cert,
+ PR_TRUE,
+ certificateUsageSSLClient,
+ NULL, NULL);
+ if (rv != SECSuccess) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Certificate [%s][%s] not valid [%d], skipping.\n",
+ cert_list_node->cert->nickname,
+ cert_list_node->cert->subjectName, PR_GetError());
+ continue;
}
+ }
+
+ if (key_id_in != NULL) {
+ PORT_Free(key_id_str);
+ key_id_str = NULL;
+ key_id_str = get_key_id_str(slot, cert_list_node->cert);
+ }
+ /* Check if we found the certificates we needed for authentication or
+ * the requested ones for pre-auth. For authentication all attributes
+ * must be given and match, for pre-auth only the given ones must
+ * match. */
+ DEBUG(SSSDBG_TRACE_ALL, "%s %s %s %s %s %s.\n",
+ module_name_in, module_name, token_name_in, token_name,
+ key_id_in, key_id_str);
+ if ((mode == OP_AUTH
+ && module_name_in != NULL
+ && token_name_in != NULL
+ && key_id_in != NULL
+ && key_id_str != NULL
+ && strcmp(key_id_in, key_id_str) == 0
+ && strcmp(token_name_in, token_name) == 0
+ && strcmp(module_name_in, module_name) == 0)
+ || (mode == OP_PREAUTH
+ && (module_name_in == NULL
+ || (module_name_in != NULL
+ && strcmp(module_name_in, module_name) == 0))
+ && (token_name_in == NULL
+ || (token_name_in != NULL
+ && strcmp(token_name_in, token_name) == 0))
+ && (key_id_in == NULL
+ || (key_id_in != NULL && key_id_str != NULL
+ && strcmp(key_id_in, key_id_str) == 0)))) {
rv = CERT_AddCertToListTail(valid_certs, cert_list_node->cert);
if (rv != SECSuccess) {
@@ -343,15 +390,6 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
ret = EIO;
goto done;
}
-
- if (found_cert == NULL) {
- found_cert = cert_list_node->cert;
- } else {
- DEBUG(SSSDBG_TRACE_ALL, "More than one certificate found, " \
- "using just the first one.\n");
- }
- } else {
- DEBUG(SSSDBG_TRACE_ALL, "--- empty cert list node ---\n");
}
}
@@ -367,7 +405,7 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
}
}
- if (found_cert == NULL) {
+ if (CERT_LIST_EMPTY(valid_certs)) {
DEBUG(SSSDBG_TRACE_ALL, "No certificate found.\n");
*_multi = NULL;
ret = EOK;
@@ -375,6 +413,23 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
}
if (mode == OP_AUTH) {
+ cert_list_node = CERT_LIST_HEAD(valid_certs);
+ if (!CERT_LIST_END(CERT_LIST_NEXT(cert_list_node), valid_certs)) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "More than one certificate found for authentication, "
+ "aborting!\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ found_cert = cert_list_node->cert;
+ if (found_cert == NULL) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "No certificate found for authentication, aborting!\n");
+ ret = EINVAL;
+ goto done;
+ }
+
rv = PK11_GenerateRandom(random_value, sizeof(random_value));
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE,
@@ -449,21 +504,10 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in,
found_cert = cert_list_node->cert;
- SECITEM_FreeItem(key_id, PR_TRUE);
PORT_Free(key_id_str);
- key_id = PK11_GetLowLevelKeyIDForCert(slot, found_cert, NULL);
- if (key_id == NULL) {
- DEBUG(SSSDBG_OP_FAILURE,
- "PK11_GetLowLevelKeyIDForCert failed [%d].\n",
- PR_GetError());
- ret = EINVAL;
- goto done;
- }
-
- key_id_str = CERT_Hexify(key_id, PR_FALSE);
+ key_id_str = get_key_id_str(slot, found_cert);
if (key_id_str == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d].\n",
- PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE, "get_key_id_str [%d].\n", PR_GetError());
ret = ENOMEM;
goto done;
}
@@ -576,11 +620,13 @@ int main(int argc, const char *argv[])
enum op_mode mode = OP_NONE;
enum pin_mode pin_mode = PIN_NONE;
char *pin = NULL;
- char *slot_name_in = NULL;
char *nss_db = NULL;
struct cert_verify_opts *cert_verify_opts;
char *verify_opts = NULL;
char *multi = NULL;
+ char *module_name = NULL;
+ char *token_name = NULL;
+ char *key_id = NULL;
struct poptOption long_options[] = {
POPT_AUTOHELP
@@ -605,6 +651,12 @@ int main(int argc, const char *argv[])
NULL},
{"nssdb", 0, POPT_ARG_STRING, &nss_db, 0, _("NSS DB to use"),
NULL},
+ {"module_name", 0, POPT_ARG_STRING, &module_name, 0,
+ _("Module name for authentication"), NULL},
+ {"token_name", 0, POPT_ARG_STRING, &token_name, 0,
+ _("Token name for authentication"), NULL},
+ {"key_id", 0, POPT_ARG_STRING, &key_id, 0,
+ _("Key ID for authentication"), NULL},
POPT_TABLEEND
};
@@ -730,6 +782,15 @@ int main(int argc, const char *argv[])
}
talloc_steal(main_ctx, debug_prg_name);
+ if (mode == OP_AUTH && (module_name == NULL || token_name == NULL
+ || key_id == NULL)) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "--module_name, --token_name and --key_id must be for "
+ "authentication");
+ ret = EINVAL;
+ goto fail;
+ }
+
ret = parse_cert_verify_opts(main_ctx, verify_opts, &cert_verify_opts);
if (ret != EOK) {
DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse verifiy option.\n");
@@ -744,8 +805,8 @@ int main(int argc, const char *argv[])
}
}
- ret = do_work(main_ctx, nss_db, slot_name_in, mode, pin, cert_verify_opts,
- &multi);
+ ret = do_work(main_ctx, nss_db, mode, pin, cert_verify_opts, module_name,
+ token_name, key_id, &multi);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "do_work failed.\n");
goto fail;
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index 57c8e1e464f4262f2d78f869c52ca48bd469d90a..4d5572164763ed0b3a842019f820680a4dc2dfdc 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -399,10 +399,13 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
struct timeval tv;
int pipefd_to_child[2] = PIPE_INIT;
int pipefd_from_child[2] = PIPE_INIT;
- const char *extra_args[7] = { NULL };
+ const char *extra_args[13] = { NULL };
uint8_t *write_buf = NULL;
size_t write_buf_len = 0;
size_t arg_c;
+ const char *module_name = NULL;
+ const char *token_name = NULL;
+ const char *key_id = NULL;
req = tevent_req_create(mem_ctx, &state, struct pam_check_cert_state);
if (req == NULL) {
@@ -423,6 +426,30 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
extra_args[arg_c++] = verify_opts;
extra_args[arg_c++] = "--verify";
}
+
+ if (sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_SC_PIN
+ || sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_SC_KEYPAD) {
+ ret = sss_authtok_get_sc(pd->authtok, NULL, NULL, &token_name, NULL,
+ &module_name, NULL, &key_id, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_sc failed.\n");
+ goto done;
+ }
+
+ if (module_name != NULL && *module_name != '\0') {
+ extra_args[arg_c++] = module_name;
+ extra_args[arg_c++] = "--module_name";
+ }
+ if (token_name != NULL && *token_name != '\0') {
+ extra_args[arg_c++] = token_name;
+ extra_args[arg_c++] = "--token_name";
+ }
+ if (key_id != NULL && *key_id != '\0') {
+ extra_args[arg_c++] = key_id;
+ extra_args[arg_c++] = "--key_id";
+ }
+ }
+
if (pd->cmd == SSS_PAM_AUTHENTICATE) {
extra_args[arg_c++] = "--auth";
switch (sss_authtok_get_type(pd->authtok)) {
@@ -437,6 +464,7 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
ret = EINVAL;
goto done;
}
+
} else if (pd->cmd == SSS_PAM_PREAUTH) {
extra_args[arg_c++] = "--pre";
} else {
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index 6adbc15f580997c41a02819d0d6aa253f2d5a64b..ad5aeb6e252d989b6587525d9d2355ce9505f0e5 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -687,7 +687,9 @@ static void mock_input_pam(TALLOC_CTX *mem_ctx,
}
static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name,
- const char *pin, const char *service,
+ const char *pin, const char *token_name,
+ const char *module_name, const char *key_id,
+ const char *service,
acct_cb_t acct_cb, const char *cert,
bool only_one_provider_call)
{
@@ -697,6 +699,7 @@ static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name,
struct pam_items pi = { 0 };
int ret;
bool already_mocked = false;
+ size_t needed_size;
if (name != NULL) {
pi.pam_user = name;
@@ -707,9 +710,21 @@ static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name,
}
if (pin != NULL) {
- pi.pam_authtok = discard_const(pin);
- pi.pam_authtok_size = strlen(pi.pam_authtok) + 1;
+ ret = sss_auth_pack_sc_blob(pin, 0, token_name, 0, module_name, 0,
+ key_id, 0, NULL, 0, &needed_size);
+ assert_int_equal(ret, EAGAIN);
+
+ pi.pam_authtok = malloc(needed_size);
+ assert_non_null(pi.pam_authtok);
+
+ ret = sss_auth_pack_sc_blob(pin, 0, token_name, 0, module_name, 0,
+ key_id, 0,
+ (uint8_t *)pi.pam_authtok, needed_size,
+ &needed_size);
+ assert_int_equal(ret, EOK);
+
pi.pam_authtok_type = SSS_AUTHTOK_TYPE_SC_PIN;
+ pi.pam_authtok_size = needed_size;
}
pi.pam_service = service == NULL ? "login" : service;
@@ -724,6 +739,7 @@ static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name,
pi.cli_pid = 12345;
ret = pack_message_v3(&pi, &buf_size, &m_buf);
+ free(pi.pam_authtok);
assert_int_equal(ret, 0);
buf = talloc_memdup(mem_ctx, m_buf, buf_size);
@@ -1732,7 +1748,8 @@ void test_pam_preauth_no_logon_name(void **state)
{
int ret;
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, false);
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, false);
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -1824,7 +1841,8 @@ void test_pam_preauth_cert_nocert(void **state)
set_cert_auth_param(pam_test_ctx->pctx, "/no/path");
- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, false);
+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, false);
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -1962,7 +1980,7 @@ void test_pam_preauth_cert_nomatch(void **state)
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL,
+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL,
test_lookup_by_cert_cb, NULL, false);
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
@@ -1984,7 +2002,7 @@ void test_pam_preauth_cert_match(void **state)
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL,
+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL,
test_lookup_by_cert_cb, TEST_TOKEN_CERT, false);
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
@@ -2007,8 +2025,9 @@ void test_pam_preauth_cert_match_gdm_smartcard(void **state)
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, "gdm-smartcard",
- test_lookup_by_cert_cb, TEST_TOKEN_CERT, false);
+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL,
+ "gdm-smartcard", test_lookup_by_cert_cb,
+ TEST_TOKEN_CERT, false);
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -2029,7 +2048,7 @@ void test_pam_preauth_cert_match_wrong_user(void **state)
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL,
+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL,
test_lookup_by_cert_wrong_user_cb,
TEST_TOKEN_CERT, false);
@@ -2061,7 +2080,7 @@ void test_pam_preauth_cert_no_logon_name(void **state)
* Additionally sss_parse_inp_recv() must be mocked because the cache
* request will be done with the username found by the certificate
* lookup. */
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL,
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
test_lookup_by_cert_cb, TEST_TOKEN_CERT, false);
mock_account_recv_simple();
mock_parse_inp("pamuser", NULL, EOK);
@@ -2090,7 +2109,7 @@ void test_pam_preauth_cert_no_logon_name_with_hint(void **state)
* Since user name hint is enabled we do not have to search the user
* during pre-auth and there is no need for an extra mocked response as in
* test_pam_preauth_cert_no_logon_name. */
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL,
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
test_lookup_by_cert_cb, TEST_TOKEN_CERT, false);
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
@@ -2112,7 +2131,7 @@ void test_pam_preauth_cert_no_logon_name_double_cert(void **state)
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL,
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
test_lookup_by_cert_double_cb, TEST_TOKEN_CERT, false);
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
@@ -2135,7 +2154,7 @@ void test_pam_preauth_cert_no_logon_name_double_cert_with_hint(void **state)
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
pam_test_ctx->rctx->domains->user_name_hint = true;
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL,
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
test_lookup_by_cert_double_cb, TEST_TOKEN_CERT, false);
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
@@ -2157,7 +2176,8 @@ void test_pam_preauth_no_cert_no_logon_name(void **state)
set_cert_auth_param(pam_test_ctx->pctx, "/no/path");
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, false);
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, false);
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
@@ -2178,7 +2198,7 @@ void test_pam_preauth_cert_no_logon_name_no_match(void **state)
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL,
+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
test_lookup_by_cert_cb, NULL, false);
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH);
@@ -2206,7 +2226,9 @@ void test_pam_cert_auth(void **state)
* is looked up. Since the first mocked reply already adds the certificate
* to the user entry the lookup by certificate will already find the user
* in the cache and no second request to the backend is needed. */
- mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", NULL,
+ mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", "SSSD Test Token",
+ "NSS-Internal",
+ "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7", NULL,
test_lookup_by_cert_cb, TEST_TOKEN_CERT, true);
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
@@ -2232,7 +2254,9 @@ void test_pam_cert_auth_double_cert(void **state)
set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
- mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", NULL,
+ mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", "SSSD Test Token",
+ "NSS-Internal",
+ "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7", NULL,
test_lookup_by_cert_double_cb, TEST_TOKEN_CERT, true);
will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
--
2.15.1

View File

@ -0,0 +1,336 @@
From 0d7127a62b76f0d0cd66902c59cddb78ff010b04 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 30 Oct 2017 08:03:42 +0100
Subject: [PATCH 46/79] pam: add prompt string for certificate authentication
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
A new certificate attribute is added which contains a string which is
used in the certificate selection list displayed to the user. The
Subject-DN of the certificate is used here because it is present in all
certificate and in general differs for certificate with different usage.
libsss_certmap is used to extract the subject-DN from the certificate
and convert it into a string.
Related to https://pagure.io/SSSD/sssd/issue/3560
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Tested-by: Scott Poore <spoore@redhat.com>
---
Makefile.am | 2 ++
src/responder/pam/pamsrv_p11.c | 65 ++++++++++++++++++++++++++++++++++++++++-
src/sss_client/pam_sss.c | 31 ++++++++++++++++----
src/tests/cmocka/test_pam_srv.c | 23 +++++++++++++--
4 files changed, 111 insertions(+), 10 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index bbc90d9bad4d22ca0284ea95281a487d42399c05..04e7d59e9fb0fdbdd420573e7d737a9a465b66ea 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1398,6 +1398,7 @@ sssd_pam_LDADD = \
$(SELINUX_LIBS) \
$(PAM_LIBS) \
$(SYSTEMD_DAEMON_LIBS) \
+ libsss_certmap.la \
$(SSSD_INTERNAL_LTLIBS) \
$(NULL)
@@ -2421,6 +2422,7 @@ pam_srv_tests_LDADD = \
$(SYSTEMD_DAEMON_LIBS) \
libsss_test_common.la \
libsss_idmap.la \
+ libsss_certmap.la \
$(NULL)
EXTRA_responder_get_domains_tests_DEPENDENCIES = \
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index 4d5572164763ed0b3a842019f820680a4dc2dfdc..5a3eeff0ec977829a9ad8c80b4fc6b2e06857097 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -26,6 +26,8 @@
#include "util/child_common.h"
#include "util/strtonum.h"
#include "responder/pam/pamsrv.h"
+#include "lib/certmap/sss_certmap.h"
+#include "util/crypto/sss_crypto.h"
#ifndef SSSD_LIBEXEC_PATH
@@ -683,6 +685,54 @@ errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
return EOK;
}
+static char *get_cert_prompt(TALLOC_CTX *mem_ctx, const char *cert)
+{
+ int ret;
+ struct sss_certmap_ctx *ctx = NULL;
+ unsigned char *der = NULL;
+ size_t der_size;
+ char *prompt = NULL;
+ char *filter = NULL;
+ char **domains = NULL;
+
+ ret = sss_certmap_init(mem_ctx, NULL, NULL, &ctx);
+ if (ret != 0) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_init failed.\n");
+ return NULL;
+ }
+
+ ret = sss_certmap_add_rule(ctx, 10, "KRB5:<ISSUER>.*",
+ "LDAP:{subject_dn!nss}", NULL);
+ if (ret != 0) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_add_rule failed.\n");
+ goto done;
+ }
+
+ der = sss_base64_decode(mem_ctx, cert, &der_size);
+ if (der == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n");
+ goto done;
+ }
+
+ ret = sss_certmap_get_search_filter(ctx, der, der_size, &filter, &domains);
+ if (ret != 0) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_get_search_filter failed.\n");
+ goto done;
+ }
+
+ prompt = talloc_strdup(mem_ctx, filter);
+ if (prompt == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
+ }
+
+done:
+ sss_certmap_free_filter_and_domains(filter, domains);
+ sss_certmap_free_ctx(ctx);
+ talloc_free(der);
+
+ return prompt;
+}
+
static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username,
struct cert_auth_info *cert_info,
uint8_t **_msg, size_t *_msg_len)
@@ -692,16 +742,24 @@ static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username,
const char *token_name;
const char *module_name;
const char *key_id;
+ char *prompt;
size_t user_len;
size_t token_len;
size_t module_len;
size_t key_id_len;
+ size_t prompt_len;
const char *username = "";
if (sysdb_username != NULL) {
username = sysdb_username;
}
+ prompt = get_cert_prompt(mem_ctx, sss_cai_get_cert(cert_info));
+ if (prompt == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "get_cert_prompt failed.\n");
+ return EIO;
+ }
+
token_name = sss_cai_get_token_name(cert_info);
module_name = sss_cai_get_module_name(cert_info);
key_id = sss_cai_get_key_id(cert_info);
@@ -710,10 +768,12 @@ static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username,
token_len = strlen(token_name) + 1;
module_len = strlen(module_name) + 1;
key_id_len = strlen(key_id) + 1;
- msg_len = user_len + token_len + module_len + key_id_len;
+ prompt_len = strlen(prompt) + 1;
+ msg_len = user_len + token_len + module_len + key_id_len + prompt_len;
msg = talloc_zero_size(mem_ctx, msg_len);
if (msg == NULL) {
+ talloc_free(prompt);
DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n");
return ENOMEM;
}
@@ -722,6 +782,9 @@ static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username,
memcpy(msg + user_len, token_name, token_len);
memcpy(msg + user_len + token_len, module_name, module_len);
memcpy(msg + user_len + token_len + module_len, key_id, key_id_len);
+ memcpy(msg + user_len + token_len + module_len + key_id_len,
+ prompt, prompt_len);
+ talloc_free(prompt);
if (_msg != NULL) {
*_msg = msg;
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index c147d4b3d76443d69e27eb2da042f8eebd1ae6ab..1dc51ea0536a92a63ec2f4d97f65dbb02604dbb3 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -129,6 +129,7 @@ struct cert_auth_info {
char *token_name;
char *module_name;
char *key_id;
+ char *prompt_str;
struct cert_auth_info *prev;
struct cert_auth_info *next;
};
@@ -140,6 +141,7 @@ static void free_cai(struct cert_auth_info *cai)
free(cai->cert);
free(cai->token_name);
free(cai->key_id);
+ free(cai->prompt_str);
free(cai);
}
}
@@ -921,9 +923,25 @@ static int parse_cert_info(struct pam_items *pi, uint8_t *buf, size_t len,
goto done;
}
- D(("cert user: [%s] token name: [%s] module: [%s] key id: [%s]",
+ offset += strlen(cai->key_id) + 1;
+ if (offset >= len) {
+ D(("Cert message size mismatch"));
+ ret = EINVAL;
+ goto done;
+ }
+
+ cai->prompt_str = strdup((char *) &buf[*p + offset]);
+ if (cai->prompt_str == NULL) {
+ D(("strdup failed"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+
+ D(("cert user: [%s] token name: [%s] module: [%s] key id: [%s] "
+ "prompt: [%s]",
cai->cert_user, cai->token_name, cai->module_name,
- cai->key_id));
+ cai->key_id, cai->prompt_str));
DLIST_ADD(pi->cert_list, cai);
ret = 0;
@@ -1543,7 +1561,7 @@ done:
#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
#endif
-#define CERT_SEL_PROMPT_FMT "Certificate: %s"
+#define CERT_SEL_PROMPT_FMT "%s"
#define SEL_TITLE discard_const("Please select a certificate")
static int prompt_multi_cert_gdm(pam_handle_t *pamh, struct pam_items *pi)
@@ -1588,7 +1606,7 @@ static int prompt_multi_cert_gdm(pam_handle_t *pamh, struct pam_items *pi)
c = 0;
DLIST_FOR_EACH(cai, pi->cert_list) {
- ret = asprintf(&prompt, CERT_SEL_PROMPT_FMT, cai->key_id);
+ ret = asprintf(&prompt, CERT_SEL_PROMPT_FMT, cai->prompt_str);
if (ret == -1) {
ret = ENOMEM;
goto done;
@@ -1637,9 +1655,10 @@ done:
#endif
}
-#define TEXT_CERT_SEL_PROMPT_FMT "%s[%zu] Certificate: %s\n"
+#define TEXT_CERT_SEL_PROMPT_FMT "%s\n[%zu]:\n%s\n"
#define TEXT_SEL_TITLE discard_const("Please select a certificate by typing " \
"the corresponding number\n")
+
static int prompt_multi_cert(pam_handle_t *pamh, struct pam_items *pi)
{
int ret;
@@ -1670,7 +1689,7 @@ static int prompt_multi_cert(pam_handle_t *pamh, struct pam_items *pi)
DLIST_FOR_EACH(cai, pi->cert_list) {
cert_count++;
ret = asprintf(&tmp, TEXT_CERT_SEL_PROMPT_FMT, prompt, cert_count,
- cai->key_id);
+ cai->prompt_str);
free(prompt);
if (ret == -1) {
return ENOMEM;
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index ad5aeb6e252d989b6587525d9d2355ce9505f0e5..02b7ddd16e6d30fec4c703c676066ae1eef1cf89 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -53,6 +53,7 @@
#define TEST_TOKEN_NAME "SSSD Test Token"
#define TEST_MODULE_NAME "NSS-Internal"
#define TEST_KEY_ID "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7"
+#define TEST_SUBJECT_DN "CN=ipa-devel.ipa.devel,O=IPA.DEVEL"
#define TEST_TOKEN_CERT \
"MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \
"REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA1MjMx" \
@@ -78,6 +79,7 @@
"XyQBwOYRORlnfGyu+Yc9c3E0Wx8Tlznz0lqPR9g="
#define TEST2_KEY_ID "C8D60E009EB195D01A7083EE1D5419251AA87C2C"
+#define TEST2_SUBJECT_DN "CN=IPA RA,O=IPA.DEVEL"
#define TEST_TOKEN_2ND_CERT \
"MIIDazCCAlOgAwIBAgIBBzANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \
"REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA1MjMx" \
@@ -831,7 +833,8 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body,
assert_int_equal(val, (sizeof("pamuser@"TEST_DOM_NAME)
+ sizeof(TEST_TOKEN_NAME)
+ sizeof(TEST_MODULE_NAME)
- + sizeof(TEST_KEY_ID)));
+ + sizeof(TEST_KEY_ID)
+ + sizeof(TEST_SUBJECT_DN)));
assert_int_equal(*(body + rp + sizeof("pamuser@"TEST_DOM_NAME) - 1), 0);
assert_string_equal(body + rp, "pamuser@"TEST_DOM_NAME);
@@ -849,6 +852,10 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body,
assert_string_equal(body + rp, TEST_KEY_ID);
rp += sizeof(TEST_KEY_ID);
+ assert_int_equal(*(body + rp + sizeof(TEST_SUBJECT_DN) - 1), 0);
+ assert_string_equal(body + rp, TEST_SUBJECT_DN);
+ rp += sizeof(TEST_SUBJECT_DN);
+
assert_int_equal(rp, blen);
return EOK;
}
@@ -893,7 +900,8 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
assert_int_equal(val, (strlen(name) + 1
+ sizeof(TEST_TOKEN_NAME)
+ sizeof(TEST_MODULE_NAME)
- + sizeof(TEST_KEY_ID)));
+ + sizeof(TEST_KEY_ID)
+ + sizeof(TEST_SUBJECT_DN)));
assert_int_equal(*(body + rp + strlen(name)), 0);
assert_string_equal(body + rp, name);
@@ -911,6 +919,10 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
assert_string_equal(body + rp, TEST_KEY_ID);
rp += sizeof(TEST_KEY_ID);
+ assert_int_equal(*(body + rp + sizeof(TEST_SUBJECT_DN) - 1), 0);
+ assert_string_equal(body + rp, TEST_SUBJECT_DN);
+ rp += sizeof(TEST_SUBJECT_DN);
+
if (name2 != NULL && *name2 != '\0') {
SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
assert_int_equal(val, type);
@@ -919,7 +931,8 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
assert_int_equal(val, (strlen(name) + 1
+ sizeof(TEST_TOKEN_NAME)
+ sizeof(TEST_MODULE_NAME)
- + sizeof(TEST2_KEY_ID)));
+ + sizeof(TEST2_KEY_ID)
+ + sizeof(TEST2_SUBJECT_DN)));
assert_int_equal(*(body + rp + strlen(name)), 0);
assert_string_equal(body + rp, name);
@@ -936,6 +949,10 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
assert_int_equal(*(body + rp + sizeof(TEST2_KEY_ID) - 1), 0);
assert_string_equal(body + rp, TEST2_KEY_ID);
rp += sizeof(TEST2_KEY_ID);
+
+ assert_int_equal(*(body + rp + sizeof(TEST2_SUBJECT_DN) - 1), 0);
+ assert_string_equal(body + rp, TEST2_SUBJECT_DN);
+ rp += sizeof(TEST2_SUBJECT_DN);
}
assert_int_equal(rp, blen);
--
2.15.1

View File

@ -0,0 +1,255 @@
From 85c087a88ac5d45b68bef609b5b098bf50e95d39 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 30 Oct 2017 17:11:56 +0100
Subject: [PATCH 47/79] PAM: allow missing logon_name during certificate
authentication
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If only one certificate is available and the logon_name is the user is
not given the PAM responder already tried to find the name during the
pre-auth step. With multiple certificates this might cause useless extra
effort and the name should be determined after the certificate is
selected in the authentication step. This might currently only happen
with GDM because all other PAM clients will prompt for the user name
unconditionally.
New unit tests are added to cover this new case.
Related to https://pagure.io/SSSD/sssd/issue/3560
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Tested-by: Scott Poore <spoore@redhat.com>
---
src/responder/pam/pamsrv_cmd.c | 63 ++++++++++++++++++++++++++-----
src/tests/cmocka/test_pam_srv.c | 82 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 135 insertions(+), 10 deletions(-)
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 8b2c086e206796ad4c977495be957c56b3255e7f..caf6c99489b8378d2e850473191223709920cd79 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -1151,6 +1151,7 @@ static errno_t pam_forwarder_parse_data(struct cli_ctx *cctx, struct pam_data *p
size_t blen;
errno_t ret;
uint32_t terminator;
+ const char *key_id;
prctx = talloc_get_type(cctx->protocol_ctx, struct cli_protocol);
@@ -1191,9 +1192,33 @@ static errno_t pam_forwarder_parse_data(struct cli_ctx *cctx, struct pam_data *p
pd->logon_name,
&pd->domain, &pd->user);
} else {
- /* Only SSS_PAM_PREAUTH request may have a missing name, e.g. if the
- * name is determined with the help of a certificate */
- if (pd->cmd == SSS_PAM_PREAUTH
+ /* SSS_PAM_PREAUTH request may have a missing name, e.g. if the
+ * name is determined with the help of a certificate. During
+ * SSS_PAM_AUTHENTICATE at least a key ID is needed to identify the
+ * selected certificate. */
+ if (pd->cmd == SSS_PAM_AUTHENTICATE
+ && may_do_cert_auth(talloc_get_type(cctx->rctx->pvt_ctx,
+ struct pam_ctx), pd)
+ && (sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_SC_PIN
+ || sss_authtok_get_type(pd->authtok)
+ == SSS_AUTHTOK_TYPE_SC_KEYPAD)) {
+ ret = sss_authtok_get_sc(pd->authtok, NULL, NULL, NULL, NULL, NULL,
+ NULL, &key_id, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_sc failed.\n");
+ goto done;
+ }
+
+ if (key_id == NULL || *key_id == '\0') {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Missing logon and Smartcard key ID during "
+ "authentication.\n");
+ ret = ERR_NO_CREDS;
+ goto done;
+ }
+
+ ret = EOK;
+ } else if (pd->cmd == SSS_PAM_PREAUTH
&& may_do_cert_auth(talloc_get_type(cctx->rctx->pvt_ctx,
struct pam_ctx), pd)) {
ret = EOK;
@@ -1375,9 +1400,12 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
/* Determine what domain type to contact */
preq->req_dom_type = get_domain_request_type(preq, pctx);
- /* try backend first for authentication before doing local Smartcard
- * authentication */
- if (pd->cmd != SSS_PAM_AUTHENTICATE && may_do_cert_auth(pctx, pd)) {
+ /* Try backend first for authentication before doing local Smartcard
+ * authentication if a logon name is available. Otherwise try to derive
+ * the logon name from the certificate first. */
+ if ((pd->cmd != SSS_PAM_AUTHENTICATE
+ || (pd->cmd == SSS_PAM_AUTHENTICATE && pd->logon_name == NULL))
+ && may_do_cert_auth(pctx, pd)) {
ret = check_cert(cctx, cctx->ev, pctx, preq, pd);
/* Finish here */
goto done;
@@ -1577,9 +1605,10 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
} else {
if (preq->pd->logon_name == NULL) {
- if (preq->pd->cmd != SSS_PAM_PREAUTH) {
+ if (preq->pd->cmd != SSS_PAM_PREAUTH
+ && preq->pd->cmd != SSS_PAM_AUTHENTICATE) {
DEBUG(SSSDBG_CRIT_FAILURE,
- "Missing logon name only allowed during pre-auth.\n");
+ "Missing logon name only allowed during (pre-)auth.\n");
ret = ENOENT;
goto done;
}
@@ -1641,7 +1670,8 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
}
}
- if (preq->cctx->rctx->domains->user_name_hint) {
+ if (preq->cctx->rctx->domains->user_name_hint
+ && preq->pd->cmd == SSS_PAM_PREAUTH) {
ret = add_pam_cert_response(preq->pd, cert_user,
preq->cert_list,
SSS_PAM_CERT_INFO_WITH_HINT);
@@ -1664,6 +1694,20 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
goto done;
}
+ /* If logon_name was not given during authentication add a
+ * SSS_PAM_CERT_INFO message to send the name to the caller. */
+ if (preq->pd->cmd == SSS_PAM_AUTHENTICATE
+ && preq->pd->logon_name == NULL) {
+ ret = add_pam_cert_response(preq->pd, cert_user,
+ preq->cert_list,
+ SSS_PAM_CERT_INFO);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "add_pam_cert_response failed.\n");
+ preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL;
+ goto done;
+ }
+ }
+
/* cert_user will be returned to the PAM client as user name, so
* we can use it here already e.g. to set in initgroups timeout */
preq->pd->logon_name = talloc_strdup(preq->pd, cert_user);
@@ -2039,7 +2083,6 @@ static void pam_dom_forwarder(struct pam_auth_req *preq)
"the backend.\n");
}
- /* FIXME: use the right cert info */
ret = add_pam_cert_response(preq->pd, cert_user,
preq->current_cert,
SSS_PAM_CERT_INFO);
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index 02b7ddd16e6d30fec4c703c676066ae1eef1cf89..f5ba131357b536adac4b3466ebbc257a838d1420 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -967,6 +967,16 @@ static int test_pam_cert_check(uint32_t status, uint8_t *body, size_t blen)
NULL);
}
+static int test_pam_cert_check_auth_success(uint32_t status, uint8_t *body,
+ size_t blen)
+{
+ assert_int_equal(pam_test_ctx->exp_pam_status, PAM_BAD_ITEM);
+ pam_test_ctx->exp_pam_status = PAM_SUCCESS;
+ return test_pam_cert_check_ex(status, body, blen,
+ SSS_PAM_CERT_INFO, "pamuser@"TEST_DOM_NAME,
+ NULL);
+}
+
static int test_pam_cert_check_with_hint(uint32_t status, uint8_t *body,
size_t blen)
{
@@ -2265,6 +2275,74 @@ void test_pam_cert_auth(void **state)
assert_int_equal(ret, EOK);
}
+void test_pam_cert_auth_no_logon_name(void **state)
+{
+ int ret;
+
+ set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
+
+ /* Here the last option must be set to true because the backend is only
+ * connected once. During authentication the backend is connected first to
+ * see if it can handle Smartcard authentication, but before that the user
+ * is looked up. Since the first mocked reply already adds the certificate
+ * to the user entry the lookup by certificate will already find the user
+ * in the cache and no second request to the backend is needed. */
+ mock_input_pam_cert(pam_test_ctx, NULL, "123456", "SSSD Test Token",
+ "NSS-Internal",
+ "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7", NULL,
+ test_lookup_by_cert_cb, TEST_TOKEN_CERT, true);
+
+ mock_account_recv_simple();
+ mock_parse_inp("pamuser", NULL, EOK);
+
+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+ /* Assume backend cannot handle Smartcard credentials */
+ pam_test_ctx->exp_pam_status = PAM_BAD_ITEM;
+
+ set_cmd_cb(test_pam_cert_check_auth_success);
+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
+ pam_test_ctx->pam_cmds);
+ assert_int_equal(ret, EOK);
+
+ /* Wait until the test finishes with EOK */
+ ret = test_ev_loop(pam_test_ctx->tctx);
+ assert_int_equal(ret, EOK);
+}
+
+void test_pam_cert_auth_no_logon_name_no_key_id(void **state)
+{
+ int ret;
+
+ set_cert_auth_param(pam_test_ctx->pctx, NSS_DB);
+
+ /* Here the last option must be set to true because the backend is only
+ * connected once. During authentication the backend is connected first to
+ * see if it can handle Smartcard authentication, but before that the user
+ * is looked up. Since the first mocked reply already adds the certificate
+ * to the user entry the lookup by certificate will already find the user
+ * in the cache and no second request to the backend is needed. */
+ mock_input_pam_cert(pam_test_ctx, NULL, "123456", "SSSD Test Token",
+ "NSS-Internal", NULL, NULL,
+ NULL, NULL, false);
+
+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE);
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
+
+ /* Assume backend cannot handle Smartcard credentials */
+ pam_test_ctx->exp_pam_status = PAM_BAD_ITEM;
+
+ set_cmd_cb(test_pam_creds_insufficient_check);
+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE,
+ pam_test_ctx->pam_cmds);
+ assert_int_equal(ret, EOK);
+
+ /* Wait until the test finishes with EOK */
+ ret = test_ev_loop(pam_test_ctx->tctx);
+ assert_int_equal(ret, EOK);
+}
+
void test_pam_cert_auth_double_cert(void **state)
{
int ret;
@@ -2721,6 +2799,10 @@ int main(int argc, const char *argv[])
pam_test_teardown),
cmocka_unit_test_setup_teardown(test_pam_cert_auth_double_cert,
pam_test_setup, pam_test_teardown),
+ cmocka_unit_test_setup_teardown(test_pam_cert_auth_no_logon_name,
+ pam_test_setup, pam_test_teardown),
+ cmocka_unit_test_setup_teardown(test_pam_cert_auth_no_logon_name_no_key_id,
+ pam_test_setup, pam_test_teardown),
#endif /* HAVE_NSS */
cmocka_unit_test_setup_teardown(test_filter_response,
--
2.15.1

View File

@ -0,0 +1,275 @@
From 5b0dacffcf33837390f46b6f25146fd0e3e17f3a Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 30 Oct 2017 10:22:33 +0100
Subject: [PATCH 48/79] p11_child: add descriptions for error codes to debug
messages
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Additionally to the NSS erro code a text message describing the error is
added. This will help to see why p11_child ignores specific
certificates. For example it would be more obvious why the certificate
is not valid (expired, missing CA cert, failed OCSP etc).
Related to https://pagure.io/SSSD/sssd/issue/3560
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Tested-by: Scott Poore <spoore@redhat.com>
---
src/p11_child/p11_child_nss.c | 91 ++++++++++++++++++++++++-------------------
1 file changed, 50 insertions(+), 41 deletions(-)
diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c
index c676375cf7f6677a1d7f38f09b9bb5fd820d60c5..5f289688e41f4ea610292b907036e05cf95eb29d 100644
--- a/src/p11_child/p11_child_nss.c
+++ b/src/p11_child/p11_child_nss.c
@@ -75,15 +75,16 @@ static char *get_key_id_str(PK11SlotInfo *slot, CERTCertificate *cert)
key_id = PK11_GetLowLevelKeyIDForCert(slot, cert, NULL);
if (key_id == NULL) {
DEBUG(SSSDBG_OP_FAILURE,
- "PK11_GetLowLevelKeyIDForCert failed [%d].\n",
- PR_GetError());
+ "PK11_GetLowLevelKeyIDForCert failed [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
return NULL;
}
key_id_str = CERT_Hexify(key_id, PR_FALSE);
SECITEM_FreeItem(key_id, PR_TRUE);
if (key_id_str == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d].\n", PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
return NULL;
}
@@ -138,8 +139,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
nss_ctx = NSS_InitContext(nss_db, "", "", SECMOD_DB, &parameters, flags);
if (nss_ctx == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "NSS_InitContext failed [%d].\n",
- PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE, "NSS_InitContext failed [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
return EIO;
}
@@ -232,8 +233,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
if (pin != NULL) {
rv = PK11_Authenticate(slot, PR_FALSE, discard_const(pin));
if (rv != SECSuccess) {
- DEBUG(SSSDBG_OP_FAILURE, "PK11_Authenticate failed: [%d].\n",
- PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE, "PK11_Authenticate failed: [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
return EIO;
}
} else {
@@ -246,8 +247,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
cert_list = PK11_ListCertsInSlot(slot);
if (cert_list == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "PK11_ListCertsInSlot failed: [%d].\n",
- PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE, "PK11_ListCertsInSlot failed: [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
return EIO;
}
@@ -265,31 +266,33 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
rv = CERT_FilterCertListByUsage(cert_list, certUsageSSLClient, PR_FALSE);
if (rv != SECSuccess) {
- DEBUG(SSSDBG_OP_FAILURE, "CERT_FilterCertListByUsage failed: [%d].\n",
- PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE, "CERT_FilterCertListByUsage failed: [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
return EIO;
}
rv = CERT_FilterCertListForUserCerts(cert_list);
if (rv != SECSuccess) {
- DEBUG(SSSDBG_OP_FAILURE, "CERT_FilterCertListForUserCerts failed: [%d].\n",
- PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE,
+ "CERT_FilterCertListForUserCerts failed: [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
return EIO;
}
handle = CERT_GetDefaultCertDB();
if (handle == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "CERT_GetDefaultCertDB failed: [%d].\n",
- PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE, "CERT_GetDefaultCertDB failed: [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
return EIO;
}
if (cert_verify_opts->do_ocsp) {
rv = CERT_EnableOCSPChecking(handle);
if (rv != SECSuccess) {
- DEBUG(SSSDBG_OP_FAILURE, "CERT_EnableOCSPChecking failed: [%d].\n",
- PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE,
+ "CERT_EnableOCSPChecking failed: [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
return EIO;
}
@@ -300,16 +303,16 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
cert_verify_opts->ocsp_default_responder_signing_cert);
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE,
- "CERT_SetOCSPDefaultResponder failed: [%d].\n",
- PR_GetError());
+ "CERT_SetOCSPDefaultResponder failed: [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
return EIO;
}
rv = CERT_EnableOCSPDefaultResponder(handle);
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE,
- "CERT_EnableOCSPDefaultResponder failed: [%d].\n",
- PR_GetError());
+ "CERT_EnableOCSPDefaultResponder failed: [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
return EIO;
}
}
@@ -318,8 +321,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
found_cert = NULL;
valid_certs = CERT_NewCertList();
if (valid_certs == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "CERT_NewCertList failed [%d].\n",
- PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE, "CERT_NewCertList failed [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
ret = ENOMEM;
goto done;
}
@@ -345,9 +348,10 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
NULL, NULL);
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE,
- "Certificate [%s][%s] not valid [%d], skipping.\n",
+ "Certificate [%s][%s] not valid [%d][%s], skipping.\n",
cert_list_node->cert->nickname,
- cert_list_node->cert->subjectName, PR_GetError());
+ cert_list_node->cert->subjectName,
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
continue;
}
}
@@ -386,7 +390,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
rv = CERT_AddCertToListTail(valid_certs, cert_list_node->cert);
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE,
- "CERT_AddCertToListTail failed [%d].\n", PR_GetError());
+ "CERT_AddCertToListTail failed [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
ret = EIO;
goto done;
}
@@ -400,8 +405,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
rv = CERT_DisableOCSPDefaultResponder(handle);
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE,
- "CERT_DisableOCSPDefaultResponder failed: [%d].\n",
- PR_GetError());
+ "CERT_DisableOCSPDefaultResponder failed: [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
}
}
@@ -433,15 +438,17 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
rv = PK11_GenerateRandom(random_value, sizeof(random_value));
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE,
- "PK11_GenerateRandom failed [%d].\n", PR_GetError());
+ "PK11_GenerateRandom failed [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
return EIO;
}
priv_key = PK11_FindPrivateKeyFromCert(slot, found_cert, NULL);
if (priv_key == NULL) {
DEBUG(SSSDBG_OP_FAILURE,
- "PK11_FindPrivateKeyFromCert failed [%d]." \
- "Maybe pin is missing.\n", PR_GetError());
+ "PK11_FindPrivateKeyFromCert failed [%d][%s]."
+ "Maybe pin is missing.\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
ret = EIO;
goto done;
}
@@ -451,8 +458,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
if (algtag == SEC_OID_UNKNOWN) {
SECKEY_DestroyPrivateKey(priv_key);
DEBUG(SSSDBG_OP_FAILURE,
- "SEC_GetSignatureAlgorithmOidTag failed [%d].\n",
- PR_GetError());
+ "SEC_GetSignatureAlgorithmOidTag failed [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
ret = EIO;
goto done;
}
@@ -462,8 +469,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
priv_key, algtag);
SECKEY_DestroyPrivateKey(priv_key);
if (rv != SECSuccess) {
- DEBUG(SSSDBG_OP_FAILURE, "SEC_SignData failed [%d].\n",
- PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE, "SEC_SignData failed [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
ret = EIO;
goto done;
}
@@ -471,7 +478,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
pub_key = CERT_ExtractPublicKey(found_cert);
if (pub_key == NULL) {
DEBUG(SSSDBG_OP_FAILURE,
- "CERT_ExtractPublicKey failed [%d].\n", PR_GetError());
+ "CERT_ExtractPublicKey failed [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
ret = EIO;
goto done;
}
@@ -481,8 +489,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
NULL);
SECKEY_DestroyPublicKey(pub_key);
if (rv != SECSuccess) {
- DEBUG(SSSDBG_OP_FAILURE, "VFY_VerifyData failed [%d].\n",
- PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE, "VFY_VerifyData failed [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
ret = EACCES;
goto done;
}
@@ -507,7 +515,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
PORT_Free(key_id_str);
key_id_str = get_key_id_str(slot, found_cert);
if (key_id_str == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "get_key_id_str [%d].\n", PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE, "get_key_id_str [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
ret = ENOMEM;
goto done;
}
@@ -562,8 +571,8 @@ done:
rv = NSS_ShutdownContext(nss_ctx);
if (rv != SECSuccess) {
- DEBUG(SSSDBG_OP_FAILURE, "NSS_ShutdownContext failed [%d].\n",
- PR_GetError());
+ DEBUG(SSSDBG_OP_FAILURE, "NSS_ShutdownContext failed [%d][%s].\n",
+ PR_GetError(), PORT_ErrorToString(PR_GetError()));
}
return ret;
--
2.15.1

View File

@ -0,0 +1,356 @@
From 1889bd761a16a67cfb22063a2b277b4def670aae Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 6 Nov 2017 15:26:38 +0100
Subject: [PATCH 49/79] pam: filter certificates in the responder not in the
child
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
With the new selection option and the handling of multiple certificates
in the PAM responder it is not needed anymore to filter the certificates
in p11_child but the matching rules can be applied by the PAM responder
directly.
Related to https://pagure.io/SSSD/sssd/issue/3560
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Tested-by: Scott Poore <spoore@redhat.com>
---
src/p11_child/p11_child_nss.c | 18 +-----
src/responder/pam/pamsrv.h | 6 ++
src/responder/pam/pamsrv_cmd.c | 10 ++-
src/responder/pam/pamsrv_p11.c | 135 +++++++++++++++++++++++++++++++++++++++-
src/tests/cmocka/test_pam_srv.c | 3 +
5 files changed, 152 insertions(+), 20 deletions(-)
diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c
index 5f289688e41f4ea610292b907036e05cf95eb29d..e59aba0d1561f58206252f7251ecd88315836b1b 100644
--- a/src/p11_child/p11_child_nss.c
+++ b/src/p11_child/p11_child_nss.c
@@ -264,22 +264,6 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
}
}
- rv = CERT_FilterCertListByUsage(cert_list, certUsageSSLClient, PR_FALSE);
- if (rv != SECSuccess) {
- DEBUG(SSSDBG_OP_FAILURE, "CERT_FilterCertListByUsage failed: [%d][%s].\n",
- PR_GetError(), PORT_ErrorToString(PR_GetError()));
- return EIO;
- }
-
- rv = CERT_FilterCertListForUserCerts(cert_list);
- if (rv != SECSuccess) {
- DEBUG(SSSDBG_OP_FAILURE,
- "CERT_FilterCertListForUserCerts failed: [%d][%s].\n",
- PR_GetError(), PORT_ErrorToString(PR_GetError()));
- return EIO;
- }
-
-
handle = CERT_GetDefaultCertDB();
if (handle == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "CERT_GetDefaultCertDB failed: [%d][%s].\n",
@@ -344,7 +328,7 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
if (cert_verify_opts->do_verification) {
rv = CERT_VerifyCertificateNow(handle, cert_list_node->cert,
PR_TRUE,
- certificateUsageSSLClient,
+ certificateUsageCheckAllUsages,
NULL, NULL);
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE,
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index f15f7f19f1f38626288416c9f2038371c6f58b47..0bc229212844602ed461d1c7db48bf51ac2e2194 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -27,6 +27,7 @@
#include "sbus/sssd_dbus.h"
#include "responder/common/responder.h"
#include "responder/common/cache_req/cache_req.h"
+#include "lib/certmap/sss_certmap.h"
struct pam_auth_req;
@@ -49,6 +50,7 @@ struct pam_ctx {
bool cert_auth;
int p11_child_debug_fd;
char *nss_db;
+ struct sss_certmap_ctx *sss_certmap_ctx;
};
struct pam_auth_dp_req {
@@ -104,6 +106,7 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
const char *nss_db,
time_t timeout,
const char *verify_opts,
+ struct sss_certmap_ctx *sss_certmap_ctx,
struct pam_data *pd);
errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
struct cert_auth_info **cert_list);
@@ -114,6 +117,9 @@ errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username,
bool may_do_cert_auth(struct pam_ctx *pctx, struct pam_data *pd);
+errno_t p11_refresh_certmap_ctx(struct pam_ctx *pctx,
+ struct certmap_info **certmap_list);
+
errno_t
pam_set_last_online_auth_with_curr_token(struct sss_domain_info *domain,
const char *username,
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index caf6c99489b8378d2e850473191223709920cd79..0e76c9e772f1775635677f35b870e9613b2faf64 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -1336,7 +1336,8 @@ static errno_t check_cert(TALLOC_CTX *mctx,
req = pam_check_cert_send(mctx, ev, pctx->p11_child_debug_fd,
pctx->nss_db, p11_child_timeout,
- cert_verification_opts, pd);
+ cert_verification_opts, pctx->sss_certmap_ctx,
+ pd);
if (req == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "pam_check_cert_send failed.\n");
return ENOMEM;
@@ -1749,6 +1750,13 @@ static void pam_forwarder_cb(struct tevent_req *req)
goto done;
}
+ ret = p11_refresh_certmap_ctx(pctx, pctx->rctx->domains->certmaps);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "p11_refresh_certmap_ctx failed, "
+ "certificate matching might not work as expected");
+ }
+
pd = preq->pd;
ret = pam_forwarder_parse_data(cctx, pd);
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index 5a3eeff0ec977829a9ad8c80b4fc6b2e06857097..ec52c5ae7163d41144fe082643a201b766a1e201 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -36,6 +36,7 @@
#define P11_CHILD_LOG_FILE "p11_child"
#define P11_CHILD_PATH SSSD_LIBEXEC_PATH"/p11_child"
+#define CERT_AUTH_DEFAULT_MATCHING_RULE "KRB5:<EKU>clientAuth"
struct cert_auth_info {
char *cert;
@@ -116,8 +117,110 @@ void sss_cai_check_users(struct cert_auth_info **list, size_t *_cert_count,
return;
}
+struct priv_sss_debug {
+ int level;
+};
+
+static void ext_debug(void *private, const char *file, long line,
+ const char *function, const char *format, ...)
+{
+ va_list ap;
+ struct priv_sss_debug *data = private;
+ int level = SSSDBG_OP_FAILURE;
+
+ if (data != NULL) {
+ level = data->level;
+ }
+
+ if (DEBUG_IS_SET(level)) {
+ va_start(ap, format);
+ sss_vdebug_fn(file, line, function, level, APPEND_LINE_FEED,
+ format, ap);
+ va_end(ap);
+ }
+}
+
+errno_t p11_refresh_certmap_ctx(struct pam_ctx *pctx,
+ struct certmap_info **certmap_list)
+{
+ int ret;
+ struct sss_certmap_ctx *sss_certmap_ctx = NULL;
+ size_t c;
+
+ ret = sss_certmap_init(pctx, ext_debug, NULL, &sss_certmap_ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_init failed.\n");
+ goto done;
+ }
+
+ if (certmap_list == NULL || *certmap_list == NULL) {
+ /* Try to add default matching rule */
+ ret = sss_certmap_add_rule(sss_certmap_ctx, SSS_CERTMAP_MIN_PRIO,
+ CERT_AUTH_DEFAULT_MATCHING_RULE, NULL, NULL);
+ if (ret != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to add default matching rule.\n");
+ }
+
+ goto done;
+ }
+
+ for (c = 0; certmap_list[c] != NULL; c++) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Trying to add rule [%s][%d][%s][%s].\n",
+ certmap_list[c]->name, certmap_list[c]->priority,
+ certmap_list[c]->match_rule, certmap_list[c]->map_rule);
+
+ ret = sss_certmap_add_rule(sss_certmap_ctx, certmap_list[c]->priority,
+ certmap_list[c]->match_rule,
+ certmap_list[c]->map_rule,
+ certmap_list[c]->domains);
+ if (ret != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "sss_certmap_add_rule failed for rule [%s] "
+ "with error [%d][%s], skipping. "
+ "Please check for typos and if rule syntax is supported.\n",
+ certmap_list[c]->name, ret, sss_strerror(ret));
+ continue;
+ }
+ }
+
+ ret = EOK;
+
+done:
+ if (ret == EOK) {
+ sss_certmap_free_ctx(pctx->sss_certmap_ctx);
+ pctx->sss_certmap_ctx = sss_certmap_ctx;
+ } else {
+ sss_certmap_free_ctx(sss_certmap_ctx);
+ }
+
+ return ret;
+}
+
errno_t p11_child_init(struct pam_ctx *pctx)
{
+ int ret;
+ struct certmap_info **certmaps;
+ bool user_name_hint;
+ struct sss_domain_info *dom = pctx->rctx->domains;
+
+ ret = sysdb_get_certmap(dom, dom->sysdb, &certmaps, &user_name_hint);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_certmap failed.\n");
+ return ret;
+ }
+
+ dom->user_name_hint = user_name_hint;
+ talloc_free(dom->certmaps);
+ dom->certmaps = certmaps;
+
+ ret = p11_refresh_certmap_ctx(pctx, dom->certmaps);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "p11_refresh_certmap_ctx failed.\n");
+ return ret;
+ }
+
return child_debug_init(P11_CHILD_LOG_FILE, &pctx->p11_child_debug_fd);
}
@@ -214,6 +317,7 @@ static errno_t get_p11_child_write_buffer(TALLOC_CTX *mem_ctx,
static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf,
ssize_t buf_len,
+ struct sss_certmap_ctx *sss_certmap_ctx,
struct cert_auth_info **_cert_list)
{
int ret;
@@ -222,6 +326,8 @@ static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf,
uint8_t *pn;
struct cert_auth_info *cert_list = NULL;
struct cert_auth_info *cert_auth_info;
+ unsigned char *der = NULL;
+ size_t der_size;
if (buf_len < 0) {
DEBUG(SSSDBG_CRIT_FAILURE,
@@ -347,7 +453,22 @@ static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf,
}
DEBUG(SSSDBG_TRACE_ALL, "Found cert [%s].\n", cert_auth_info->cert);
- DLIST_ADD(cert_list, cert_auth_info);
+ der = sss_base64_decode(tmp_ctx, cert_auth_info->cert, &der_size);
+ if (der == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n");
+ ret = EIO;
+ goto done;
+ }
+
+ ret = sss_certmap_match_cert(sss_certmap_ctx, der, der_size);
+ if (ret == 0) {
+ DLIST_ADD(cert_list, cert_auth_info);
+ } else {
+ DEBUG(SSSDBG_TRACE_LIBS,
+ "Cert [%s] does not match matching rules and is ignored.\n",
+ cert_auth_info->cert);
+ talloc_free(cert_auth_info);
+ }
p = ++pn;
} while ((pn - buf) < buf_len);
@@ -373,6 +494,7 @@ struct pam_check_cert_state {
struct sss_child_ctx_old *child_ctx;
struct tevent_timer *timeout_handler;
struct tevent_context *ev;
+ struct sss_certmap_ctx *sss_certmap_ctx;
struct child_io_fds *io;
@@ -391,6 +513,7 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
const char *nss_db,
time_t timeout,
const char *verify_opts,
+ struct sss_certmap_ctx *sss_certmap_ctx,
struct pam_data *pd)
{
errno_t ret;
@@ -420,6 +543,12 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
goto done;
}
+ if (sss_certmap_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing certificate matching context.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
/* extra_args are added in revers order */
arg_c = 0;
extra_args[arg_c++] = nss_db;
@@ -476,6 +605,7 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
}
state->ev = ev;
+ state->sss_certmap_ctx = sss_certmap_ctx;
state->child_status = EFAULT;
state->io = talloc(state, struct child_io_fds);
if (state->io == NULL) {
@@ -639,7 +769,8 @@ static void p11_child_done(struct tevent_req *subreq)
PIPE_FD_CLOSE(state->io->read_from_child_fd);
- ret = parse_p11_child_response(state, buf, buf_len, &state->cert_list);
+ ret = parse_p11_child_response(state, buf, buf_len, state->sss_certmap_ctx,
+ &state->cert_list);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "parse_p11_child_response failed.\n");
tevent_req_error(req, ret);
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index f5ba131357b536adac4b3466ebbc257a838d1420..f86719f4fb154524fc9620aa8cb583690ca597f3 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -287,6 +287,9 @@ struct pam_ctx *mock_pctx(TALLOC_CTX *mem_ctx)
return NULL;
}
+ ret = p11_refresh_certmap_ctx(pctx, NULL);
+ assert_int_equal(ret, 0);
+
return pctx;
}
--
2.15.1

View File

@ -0,0 +1,273 @@
From a89494e7c173bb82344099dd84c59cb3b7214484 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 7 Nov 2017 09:52:56 +0100
Subject: [PATCH 50/79] PAM: add certificate's label to the selection prompt
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some types of Smartcards contain multiple certificate with the same
subject-DN for different usages. To make it easier to choose between
them in case the matching rules allow more than one of them for
authentication the label assigned to the certificate on the Smartcard is
shown in the selection prompt as well.
Related to https://pagure.io/SSSD/sssd/issue/3560
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Tested-by: Scott Poore <spoore@redhat.com>
---
src/p11_child/p11_child_nss.c | 18 ++++++++++++++----
src/responder/pam/pamsrv.h | 1 +
src/responder/pam/pamsrv_p11.c | 41 +++++++++++++++++++++++++++++++++++++----
src/tests/cmocka/test_pam_srv.c | 28 ++++++++++++++--------------
4 files changed, 66 insertions(+), 22 deletions(-)
diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c
index e59aba0d1561f58206252f7251ecd88315836b1b..21c508eb1b1b68b3606d0a5eed36573b01f27a19 100644
--- a/src/p11_child/p11_child_nss.c
+++ b/src/p11_child/p11_child_nss.c
@@ -130,7 +130,7 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
CERTCertificate *found_cert = NULL;
PK11SlotList *list = NULL;
PK11SlotListElement *le;
- SECItem *key_id = NULL;
+ const char *label;
char *key_id_str = NULL;
CERTCertList *valid_certs = NULL;
char *cert_b64 = NULL;
@@ -505,6 +505,17 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
goto done;
}
+ /* The NSS nickname is typically token_name:label, so the label starts
+ * after the ':'. */
+ if (found_cert->nickname != NULL) {
+ if ((label = strchr(found_cert->nickname, ':')) == NULL) {
+ label = found_cert->nickname;
+ } else {
+ label++;
+ }
+ } else {
+ label = "- no label found -";
+ }
talloc_free(cert_b64);
cert_b64 = sss_base64_encode(mem_ctx, found_cert->derCert.data,
found_cert->derCert.len);
@@ -517,9 +528,9 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db,
DEBUG(SSSDBG_TRACE_ALL, "Found certificate has key id [%s].\n",
key_id_str);
- multi = talloc_asprintf_append(multi, "%s\n%s\n%s\n%s\n",
+ multi = talloc_asprintf_append(multi, "%s\n%s\n%s\n%s\n%s\n",
token_name, module_name, key_id_str,
- cert_b64);
+ label, cert_b64);
}
*_multi = multi;
@@ -546,7 +557,6 @@ done:
CERT_DestroyCertList(cert_list);
}
- SECITEM_FreeItem(key_id, PR_TRUE);
PORT_Free(key_id_str);
PORT_Free(signed_random_value.data);
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index 0bc229212844602ed461d1c7db48bf51ac2e2194..dfd982178446d6327e09afc652018886c08fd88a 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -93,6 +93,7 @@ const char *sss_cai_get_cert(struct cert_auth_info *i);
const char *sss_cai_get_token_name(struct cert_auth_info *i);
const char *sss_cai_get_module_name(struct cert_auth_info *i);
const char *sss_cai_get_key_id(struct cert_auth_info *i);
+const char *sss_cai_get_label(struct cert_auth_info *i);
struct cert_auth_info *sss_cai_get_next(struct cert_auth_info *i);
struct ldb_result *sss_cai_get_cert_user_objs(struct cert_auth_info *i);
void sss_cai_set_cert_user_objs(struct cert_auth_info *i,
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index ec52c5ae7163d41144fe082643a201b766a1e201..fa2435543ea305f7cdb1e18753525beb373eaf4c 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -43,6 +43,7 @@ struct cert_auth_info {
char *token_name;
char *module_name;
char *key_id;
+ char *label;
struct ldb_result *cert_user_objs;
struct cert_auth_info *prev;
struct cert_auth_info *next;
@@ -68,6 +69,11 @@ const char *sss_cai_get_key_id(struct cert_auth_info *i)
return i != NULL ? i->key_id : NULL;
}
+const char *sss_cai_get_label(struct cert_auth_info *i)
+{
+ return i != NULL ? i->label : NULL;
+}
+
struct cert_auth_info *sss_cai_get_next(struct cert_auth_info *i)
{
return i != NULL ? i->next : NULL;
@@ -438,6 +444,31 @@ static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf,
goto done;
}
+ if (pn == p) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Missing label in p11_child response.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ cert_auth_info->label = talloc_strndup(cert_auth_info, (char *) p,
+ (pn - p));
+ if (cert_auth_info->label == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ DEBUG(SSSDBG_TRACE_ALL, "Found label [%s].\n", cert_auth_info->label);
+
+ p = ++pn;
+ pn = memchr(p, '\n', buf_len - (p - buf));
+ if (pn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Missing new-line in p11_child response.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
if (pn == p) {
DEBUG(SSSDBG_OP_FAILURE, "Missing cert in p11_child response.\n");
ret = EINVAL;
@@ -816,7 +847,8 @@ errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
return EOK;
}
-static char *get_cert_prompt(TALLOC_CTX *mem_ctx, const char *cert)
+static char *get_cert_prompt(TALLOC_CTX *mem_ctx,
+ struct cert_auth_info *cert_info)
{
int ret;
struct sss_certmap_ctx *ctx = NULL;
@@ -839,7 +871,7 @@ static char *get_cert_prompt(TALLOC_CTX *mem_ctx, const char *cert)
goto done;
}
- der = sss_base64_decode(mem_ctx, cert, &der_size);
+ der = sss_base64_decode(mem_ctx, sss_cai_get_cert(cert_info), &der_size);
if (der == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n");
goto done;
@@ -851,7 +883,8 @@ static char *get_cert_prompt(TALLOC_CTX *mem_ctx, const char *cert)
goto done;
}
- prompt = talloc_strdup(mem_ctx, filter);
+ prompt = talloc_asprintf(mem_ctx, "%s\n%s", sss_cai_get_label(cert_info),
+ filter);
if (prompt == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
}
@@ -885,7 +918,7 @@ static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username,
username = sysdb_username;
}
- prompt = get_cert_prompt(mem_ctx, sss_cai_get_cert(cert_info));
+ prompt = get_cert_prompt(mem_ctx, cert_info);
if (prompt == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "get_cert_prompt failed.\n");
return EIO;
diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c
index f86719f4fb154524fc9620aa8cb583690ca597f3..d7b47507b75044793996bc5156163616a55e05f6 100644
--- a/src/tests/cmocka/test_pam_srv.c
+++ b/src/tests/cmocka/test_pam_srv.c
@@ -53,7 +53,7 @@
#define TEST_TOKEN_NAME "SSSD Test Token"
#define TEST_MODULE_NAME "NSS-Internal"
#define TEST_KEY_ID "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7"
-#define TEST_SUBJECT_DN "CN=ipa-devel.ipa.devel,O=IPA.DEVEL"
+#define TEST_PROMPT "Server-Cert\nCN=ipa-devel.ipa.devel,O=IPA.DEVEL"
#define TEST_TOKEN_CERT \
"MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \
"REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA1MjMx" \
@@ -79,7 +79,7 @@
"XyQBwOYRORlnfGyu+Yc9c3E0Wx8Tlznz0lqPR9g="
#define TEST2_KEY_ID "C8D60E009EB195D01A7083EE1D5419251AA87C2C"
-#define TEST2_SUBJECT_DN "CN=IPA RA,O=IPA.DEVEL"
+#define TEST2_PROMPT "ipaCert\nCN=IPA RA,O=IPA.DEVEL"
#define TEST_TOKEN_2ND_CERT \
"MIIDazCCAlOgAwIBAgIBBzANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \
"REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA1MjMx" \
@@ -837,7 +837,7 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body,
+ sizeof(TEST_TOKEN_NAME)
+ sizeof(TEST_MODULE_NAME)
+ sizeof(TEST_KEY_ID)
- + sizeof(TEST_SUBJECT_DN)));
+ + sizeof(TEST_PROMPT)));
assert_int_equal(*(body + rp + sizeof("pamuser@"TEST_DOM_NAME) - 1), 0);
assert_string_equal(body + rp, "pamuser@"TEST_DOM_NAME);
@@ -855,9 +855,9 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body,
assert_string_equal(body + rp, TEST_KEY_ID);
rp += sizeof(TEST_KEY_ID);
- assert_int_equal(*(body + rp + sizeof(TEST_SUBJECT_DN) - 1), 0);
- assert_string_equal(body + rp, TEST_SUBJECT_DN);
- rp += sizeof(TEST_SUBJECT_DN);
+ assert_int_equal(*(body + rp + sizeof(TEST_PROMPT) - 1), 0);
+ assert_string_equal(body + rp, TEST_PROMPT);
+ rp += sizeof(TEST_PROMPT);
assert_int_equal(rp, blen);
return EOK;
@@ -904,7 +904,7 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
+ sizeof(TEST_TOKEN_NAME)
+ sizeof(TEST_MODULE_NAME)
+ sizeof(TEST_KEY_ID)
- + sizeof(TEST_SUBJECT_DN)));
+ + sizeof(TEST_PROMPT)));
assert_int_equal(*(body + rp + strlen(name)), 0);
assert_string_equal(body + rp, name);
@@ -922,9 +922,9 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
assert_string_equal(body + rp, TEST_KEY_ID);
rp += sizeof(TEST_KEY_ID);
- assert_int_equal(*(body + rp + sizeof(TEST_SUBJECT_DN) - 1), 0);
- assert_string_equal(body + rp, TEST_SUBJECT_DN);
- rp += sizeof(TEST_SUBJECT_DN);
+ assert_int_equal(*(body + rp + sizeof(TEST_PROMPT) - 1), 0);
+ assert_string_equal(body + rp, TEST_PROMPT);
+ rp += sizeof(TEST_PROMPT);
if (name2 != NULL && *name2 != '\0') {
SAFEALIGN_COPY_UINT32(&val, body + rp, &rp);
@@ -935,7 +935,7 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
+ sizeof(TEST_TOKEN_NAME)
+ sizeof(TEST_MODULE_NAME)
+ sizeof(TEST2_KEY_ID)
- + sizeof(TEST2_SUBJECT_DN)));
+ + sizeof(TEST2_PROMPT)));
assert_int_equal(*(body + rp + strlen(name)), 0);
assert_string_equal(body + rp, name);
@@ -953,9 +953,9 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen,
assert_string_equal(body + rp, TEST2_KEY_ID);
rp += sizeof(TEST2_KEY_ID);
- assert_int_equal(*(body + rp + sizeof(TEST2_SUBJECT_DN) - 1), 0);
- assert_string_equal(body + rp, TEST2_SUBJECT_DN);
- rp += sizeof(TEST2_SUBJECT_DN);
+ assert_int_equal(*(body + rp + sizeof(TEST2_PROMPT) - 1), 0);
+ assert_string_equal(body + rp, TEST2_PROMPT);
+ rp += sizeof(TEST2_PROMPT);
}
assert_int_equal(rp, blen);
--
2.15.1

View File

@ -0,0 +1,127 @@
From 38bc29c3475421d9e9ce62810739b6b8b10ad7c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Mon, 13 Nov 2017 08:29:53 +0100
Subject: [PATCH 51/79] SYSDB: Remove code causing a covscan warning
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There's no reason to check for both ret != EOK and sanitized == NULL, as
the second should never ever happen.
This check is causing a clang warning in our code:
Defect type: CLANG_WARNING
1. sssd-1.16.0/src/db/sysdb_ops.c:4223:9: warning: Dereference of undefined pointer value
# if (res->count > 1) {
# ^~~~~~~~~~
4. sssd-1.16.0/src/db/sysdb_ops.c:4199:5: note: 'res' declared without an initial value
# struct ldb_result *res;
# ^~~~~~~~~~~~~~~~~~~~~~
7. sssd-1.16.0/src/db/sysdb_ops.c:4202:9: note: Assuming 'sid_str' is non-null
# if (!sid_str) return EINVAL;
# ^~~~~~~~
10. sssd-1.16.0/src/db/sysdb_ops.c:4202:5: note: Taking false branch
# if (!sid_str) return EINVAL;
# ^
13. sssd-1.16.0/src/db/sysdb_ops.c:4205:9: note: Assuming 'tmp_ctx' is non-null
# if (!tmp_ctx) {
# ^~~~~~~~
16. sssd-1.16.0/src/db/sysdb_ops.c:4205:5: note: Taking false branch
# if (!tmp_ctx) {
# ^
19. sssd-1.16.0/src/db/sysdb_ops.c:4209:11: note: Calling 'sysdb_search_object_by_sid'
# ret = sysdb_search_object_by_sid(tmp_ctx, domain, sid_str, NULL, &res);
# ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22. sssd-1.16.0/src/db/sysdb_ops.c:4960:12: note: Calling 'sysdb_search_object_by_str_attr'
# return sysdb_search_object_by_str_attr(mem_ctx, domain, SYSDB_SID_FILTER,
# ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25. sssd-1.16.0/src/db/sysdb_ops.c:4872:5: note: Taking false branch
# if (str == NULL) {
# ^
28. sssd-1.16.0/src/db/sysdb_ops.c:4877:9: note: Assuming 'ret' is equal to 0
# if (ret != EOK || sanitized == NULL) {
# ^~~~~~~~~~
31. sssd-1.16.0/src/db/sysdb_ops.c:4877:9: note: Left side of '||' is false
32. sssd-1.16.0/src/db/sysdb_ops.c:4877:23: note: Assuming 'sanitized' is equal to null
# if (ret != EOK || sanitized == NULL) {
# ^~~~~~~~~~~~~~~~~
35. sssd-1.16.0/src/db/sysdb_ops.c:4877:5: note: Taking true branch
# if (ret != EOK || sanitized == NULL) {
# ^
38. sssd-1.16.0/src/db/sysdb_ops.c:4878:9: note: Left side of '||' is false
# DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize failed.\n");
# ^
41. sssd-1.16.0/src/util/debug.h:123:9: note: expanded from macro 'DEBUG'
# if (DEBUG_IS_SET(__debug_macro_level)) { \
# ^
44. sssd-1.16.0/src/util/debug.h:135:30: note: expanded from macro 'DEBUG_IS_SET'
# #define DEBUG_IS_SET(level) (debug_level & (level) || \
# ^
47. sssd-1.16.0/src/db/sysdb_ops.c:4878:9: note: Assuming 'debug_level' is not equal to 0
# DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize failed.\n");
# ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50. sssd-1.16.0/src/util/debug.h:123:9: note: expanded from macro 'DEBUG'
# if (DEBUG_IS_SET(__debug_macro_level)) { \
# ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
53. sssd-1.16.0/src/util/debug.h:136:30: note: expanded from macro 'DEBUG_IS_SET'
# (debug_level == SSSDBG_UNRESOLVED && \
# ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
56. sssd-1.16.0/src/db/sysdb_ops.c:4878:9: note: Left side of '&&' is false
57. sssd-1.16.0/src/util/debug.h:123:9: note: expanded from macro 'DEBUG'
# if (DEBUG_IS_SET(__debug_macro_level)) { \
# ^
60. sssd-1.16.0/src/util/debug.h:136:63: note: expanded from macro 'DEBUG_IS_SET'
# (debug_level == SSSDBG_UNRESOLVED && \
# ^
63. sssd-1.16.0/src/db/sysdb_ops.c:4878:9: note: Loop condition is false. Exiting loop
64. sssd-1.16.0/src/util/debug.h:121:35: note: expanded from macro 'DEBUG'
# #define DEBUG(level, format, ...) do { \
# ^
67. sssd-1.16.0/src/db/sysdb_ops.c:4879:9: note: Control jumps to line 4892
# goto done;
# ^
70. sssd-1.16.0/src/db/sysdb_ops.c:4960:12: note: Returning from 'sysdb_search_object_by_str_attr'
# return sysdb_search_object_by_str_attr(mem_ctx, domain, SYSDB_SID_FILTER,
# ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
73. sssd-1.16.0/src/db/sysdb_ops.c:4209:11: note: Returning from 'sysdb_search_object_by_sid'
# ret = sysdb_search_object_by_sid(tmp_ctx, domain, sid_str, NULL, &res);
# ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
76. sssd-1.16.0/src/db/sysdb_ops.c:4211:5: note: Taking false branch
# if (ret == ENOENT) {
# ^
79. sssd-1.16.0/src/db/sysdb_ops.c:4217:12: note: Taking false branch
# } else if (ret != EOK) {
# ^
82. sssd-1.16.0/src/db/sysdb_ops.c:4223:9: note: Dereference of undefined pointer value
# if (res->count > 1) {
# ^~~~~~~~~~
# 4221| }
# 4222|
# 4223|-> if (res->count > 1) {
# 4224| DEBUG(SSSDBG_FATAL_FAILURE, "getbysid call returned more than one " \
# 4225| "result !?!\n");
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/db/sysdb_ops.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 2f8e36c6c9a2c2cefe4af5fb78957763304d989a..635c7db51f516e2217c93016409499e49289004c 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -4874,7 +4874,7 @@ static errno_t sysdb_search_object_by_str_attr(TALLOC_CTX *mem_ctx,
}
ret = sss_filter_sanitize(NULL, str, &sanitized);
- if (ret != EOK || sanitized == NULL) {
+ if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize failed.\n");
goto done;
}
--
2.15.1

View File

@ -0,0 +1,93 @@
From e728796cde9a95fd4186ad2c30faadc62497472e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Thu, 26 Oct 2017 18:38:42 +0200
Subject: [PATCH 52/79] SYSDB: Better debugging for email conflicts
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add DEBUG message when conflicts in FQ names or emails
are detected.
Also improve man page to hint on how to work around issue
with conflicting emails.
Note: We store emails in two different attributes in sysdb:
- SYSDB_USER_EMAIL
- SYSDB_NAME_ALIAS - this one is lowercased and used in getpwnam
searches.
Resolves:
https://fedorahosted.org/sssd/ticket/3293
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/db/sysdb_ops.c | 4 +++-
src/db/sysdb_search.c | 15 +++++++++++++++
src/man/sssd-ldap.5.xml | 9 +++++++++
3 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 635c7db51f516e2217c93016409499e49289004c..1539c41c93e7d6ebd1e544abbb1707df5578cd72 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -640,7 +640,9 @@ int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx,
goto done;
} else if (res->count > 1) {
DEBUG(SSSDBG_OP_FAILURE,
- "Search for upn [%s] returns more than one result.\n", upn);
+ "Search for upn [%s] returns more than one result. One of the "
+ "possible reasons can be that several users share the same "
+ "email address.\n", upn);
ret = EINVAL;
goto done;
}
diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c
index f488442afcc6eef114437a7110722759f86fe19e..8083966900429b268a3b984f1cad3d47d1099198 100644
--- a/src/db/sysdb_search.c
+++ b/src/db/sysdb_search.c
@@ -218,6 +218,21 @@ int sysdb_getpwnam(TALLOC_CTX *mem_ctx,
goto done;
}
+ if (res->count > 1) {
+ /* We expected either 0 or 1 result for search with
+ * SYSDB_PWNAM_FILTER, but we got more. This error
+ * is handled individually depending on what function
+ * called sysdb_getpwnam, so we just print a message
+ * here and let the caller decide what error code to
+ * propagate based on res->count > 1. */
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Search for [%s] returned multiple results. It can be an email "
+ "address shared among multiple users or an email address of a "
+ "user that conflicts with another user's fully qualified name. "
+ "SSSD will not be able to handle those users properly.\n",
+ sanitized_name);
+ }
+
/* Merge in the timestamps from the fast ts db */
ret = sysdb_merge_res_ts_attrs(domain->sysdb, res, attrs);
if (ret != EOK) {
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index d38bac3607d294c53ea692130a6b93ced9b0ab82..de596f0da62be9eb61b880b6e1d4a0f33689e25a 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -877,6 +877,15 @@
Name of the LDAP attribute containing the email
address of the user.
</para>
+ <para>
+ Note: If an email address of a user conflicts with
+ an email address or fully qualified name of another
+ user, then SSSD will not be able to serve those
+ users properly. If for some reason several users
+ need to share the same email address then set
+ this option to a nonexistent attribute name in
+ order to disable user lookup/login by email.
+ </para>
<para>
Default: mail
</para>
--
2.15.1

View File

@ -0,0 +1,38 @@
From 22cc09e379710b29520d5bbc6fdf6ad84473cd43 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 6 Nov 2017 17:03:19 +0100
Subject: [PATCH 53/79] NSS: Use enum_ctx as memory_context in
_setnetgrent_set_timeout()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We've noticed some crashes that happened because enum_ctx is already
freed, but the timeout handler is still called. In order to avoid that,
let's remove the timeout handler when enum_ctx is freed at other places.
Resolves: https://pagure.io/SSSD/sssd/issue/3523
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
src/responder/nss/nss_enum.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/responder/nss/nss_enum.c b/src/responder/nss/nss_enum.c
index aa7d8428f37e943a6b5904495c40ad4b8011b767..da844fbced529f606a3e98669fb7b95e0696ce00 100644
--- a/src/responder/nss/nss_enum.c
+++ b/src/responder/nss/nss_enum.c
@@ -283,7 +283,7 @@ nss_setnetgrent_set_timeout(struct tevent_context *ev,
timeout = enum_ctx->result[0]->domain->netgroup_timeout;
tv = tevent_timeval_current_ofs(timeout, 0);
- te = tevent_add_timer(ev, nss_ctx, tv, nss_setnetgrent_timeout, enum_ctx);
+ te = tevent_add_timer(ev, enum_ctx, tv, nss_setnetgrent_timeout, enum_ctx);
if (te == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Could not set up life timer for enumeration object.\n");
--
2.15.1

View File

@ -0,0 +1,67 @@
From 5fb2959852b53c6015cbf1cea653365708b379e9 Mon Sep 17 00:00:00 2001
From: amitkuma <amitkuma@redhat.com>
Date: Tue, 14 Nov 2017 13:59:12 +0530
Subject: [PATCH 54/79] cache_req: Correction of cache_req debug string ID
format
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The cache-req debug string representation uses a wrong format
specifier for by-ID requests.
data->id (uint32_t) should be replaced with %"PRIu32"
in cache_req_group_by_id.c, cache_req_object_by_id.c &
cache_req_user_by_id.c.
Resolves:
https://pagure.io/SSSD/sssd/issue/3570
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
---
src/responder/common/cache_req/plugins/cache_req_group_by_id.c | 2 +-
src/responder/common/cache_req/plugins/cache_req_object_by_id.c | 2 +-
src/responder/common/cache_req/plugins/cache_req_user_by_id.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c
index 5ca64283a781318bc4e4d6920fff989c3f3919b4..121f95abe86d2466aaea69f0fe68dfb33b1fee9e 100644
--- a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c
+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c
@@ -31,7 +31,7 @@ cache_req_group_by_id_create_debug_name(TALLOC_CTX *mem_ctx,
struct cache_req_data *data,
struct sss_domain_info *domain)
{
- return talloc_asprintf(mem_ctx, "GID:%d@%s", data->id, domain->name);
+ return talloc_asprintf(mem_ctx, "GID:%"PRIu32"@%s", data->id, domain->name);
}
static errno_t
diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c
index 339bd4f5fef827acc1aa3c123d041e426d9e4782..4c88e1035b41969703c1c38d740e15516ac0d622 100644
--- a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c
+++ b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c
@@ -31,7 +31,7 @@ cache_req_object_by_id_create_debug_name(TALLOC_CTX *mem_ctx,
struct cache_req_data *data,
struct sss_domain_info *domain)
{
- return talloc_asprintf(mem_ctx, "ID:%d@%s", data->id, domain->name);
+ return talloc_asprintf(mem_ctx, "ID:%"PRIu32"@%s", data->id, domain->name);
}
static errno_t
diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c
index 913f9be5bcc2dfd074b52cb3b15fb6948826e831..3c25c7631b3da4a829ab577629334a7ee97980da 100644
--- a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c
+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c
@@ -31,7 +31,7 @@ cache_req_user_by_id_create_debug_name(TALLOC_CTX *mem_ctx,
struct cache_req_data *data,
struct sss_domain_info *domain)
{
- return talloc_asprintf(mem_ctx, "UID:%d@%s", data->id, domain->name);
+ return talloc_asprintf(mem_ctx, "UID:%"PRIu32"@%s", data->id, domain->name);
}
static errno_t
--
2.15.1

View File

@ -1,7 +1,7 @@
From caae0e53e6091806634943699f4398b6a20273b4 Mon Sep 17 00:00:00 2001
From 0e73859e68b8dc348c2ee1e00a45646d9ac2c63c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Mon, 13 Nov 2017 16:15:21 +0100
Subject: [PATCH] TESTS: Order list of entries in some lists
Subject: [PATCH 55/79] TESTS: Order list of entries in some lists
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
@ -167,5 +167,5 @@ index 0378254b4440b29c3182faf2adde8c3db8a4ce97..dd3eb50f9310ff925734dcf51a669d08
"three", TEST_GID_OVERRIDE_BASE + 2);
assert_group_attrs(res->msgs[1], test_ctx->domain, "two",
--
2.15.0
2.15.1

View File

@ -0,0 +1,503 @@
From f4d860aa678d899fdcbcd8c991c99b3b85c5c8e0 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 23 Oct 2017 18:08:12 +0200
Subject: [PATCH 56/79] TOOLS: Add a new sssctl command access-report
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves:
https://pagure.io/SSSD/sssd/issue/2840
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
Makefile.am | 1 +
src/tools/sssctl/sssctl.c | 1 +
src/tools/sssctl/sssctl.h | 5 +
src/tools/sssctl/sssctl_access_report.c | 435 ++++++++++++++++++++++++++++++++
4 files changed, 442 insertions(+)
create mode 100644 src/tools/sssctl/sssctl_access_report.c
diff --git a/Makefile.am b/Makefile.am
index 04e7d59e9fb0fdbdd420573e7d737a9a465b66ea..4c8fe64c3e689c0d411277d58995a4c0fb008dc1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1752,6 +1752,7 @@ sssctl_SOURCES = \
src/tools/sssctl/sssctl_sifp.c \
src/tools/sssctl/sssctl_config.c \
src/tools/sssctl/sssctl_user_checks.c \
+ src/tools/sssctl/sssctl_access_report.c \
$(SSSD_TOOLS_OBJ) \
$(NULL)
sssctl_LDADD = \
diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c
index d9bc897c1a32954bbdd2d4ae2b0a9fb6d2c34752..afaa84bc0b44a0fc91fe8b62c0c1fd36ac4e1e0b 100644
--- a/src/tools/sssctl/sssctl.c
+++ b/src/tools/sssctl/sssctl.c
@@ -264,6 +264,7 @@ int main(int argc, const char **argv)
SSS_TOOL_COMMAND("domain-list", "List available domains", 0, sssctl_domain_list),
SSS_TOOL_COMMAND("domain-status", "Print information about domain", 0, sssctl_domain_status),
SSS_TOOL_COMMAND("user-checks", "Print information about a user and check authentication", 0, sssctl_user_checks),
+ SSS_TOOL_COMMAND("access-report", "Generate access report for a domain", 0, sssctl_access_report),
SSS_TOOL_DELIMITER("Information about cached content:"),
SSS_TOOL_COMMAND("user-show", "Information about cached user", 0, sssctl_user_show),
SSS_TOOL_COMMAND("group-show", "Information about cached group", 0, sssctl_group_show),
diff --git a/src/tools/sssctl/sssctl.h b/src/tools/sssctl/sssctl.h
index 22ca5d41e2c084e64b58bc5aa066414b002e7e8b..70fc19eff07317c264978a1ecb9159ae3acdfced 100644
--- a/src/tools/sssctl/sssctl.h
+++ b/src/tools/sssctl/sssctl.h
@@ -133,4 +133,9 @@ errno_t sssctl_config_check(struct sss_cmdline *cmdline,
errno_t sssctl_user_checks(struct sss_cmdline *cmdline,
struct sss_tool_ctx *tool_ctx,
void *pvt);
+
+errno_t sssctl_access_report(struct sss_cmdline *cmdline,
+ struct sss_tool_ctx *tool_ctx,
+ void *pvt);
+
#endif /* _SSSCTL_H_ */
diff --git a/src/tools/sssctl/sssctl_access_report.c b/src/tools/sssctl/sssctl_access_report.c
new file mode 100644
index 0000000000000000000000000000000000000000..11172329817b4dedaca480ab8a4537149853c330
--- /dev/null
+++ b/src/tools/sssctl/sssctl_access_report.c
@@ -0,0 +1,435 @@
+/*
+ Copyright (C) 2017 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <security/pam_appl.h>
+
+#include "util/util.h"
+#include "tools/common/sss_tools.h"
+#include "tools/sssctl/sssctl.h"
+
+/*
+ * We're searching the cache directly..
+ */
+#include "providers/ipa/ipa_hbac_private.h"
+#include "providers/ipa/ipa_rules_common.h"
+
+#ifdef HAVE_SECURITY_PAM_MISC_H
+# include <security/pam_misc.h>
+#elif defined(HAVE_SECURITY_OPENPAM_H)
+# include <security/openpam.h>
+#endif
+
+#ifdef HAVE_SECURITY_PAM_MISC_H
+static struct pam_conv conv = {
+ misc_conv,
+ NULL
+};
+#elif defined(HAVE_SECURITY_OPENPAM_H)
+static struct pam_conv conv = {
+ openpam_ttyconv,
+ NULL
+};
+#else
+# error "Missing text based pam conversation function"
+#endif
+
+#ifndef DEFAULT_SERVICE
+#define DEFAULT_SERVICE "system-auth"
+#endif /* DEFAULT_SERVICE */
+
+#ifndef DEFAULT_USER
+#define DEFAULT_USER "admin"
+#endif /* DEFAULT_USER */
+
+typedef errno_t (*sssctl_dom_access_reporter_fn)(struct sss_tool_ctx *tool_ctx,
+ const char *user,
+ const char *service,
+ struct sss_domain_info *domain);
+
+static errno_t run_pam_acct(struct sss_tool_ctx *tool_ctx,
+ const char *user,
+ const char *service,
+ struct sss_domain_info *domain)
+{
+ errno_t ret;
+ pam_handle_t *pamh;
+
+ ret = pam_start(service, user, &conv, &pamh);
+ if (ret != PAM_SUCCESS) {
+ ERROR("pam_start failed: %s\n", pam_strerror(pamh, ret));
+ return EIO;
+ }
+
+ ret = pam_acct_mgmt(pamh, 0);
+ pam_end(pamh, ret);
+ return ret;
+}
+
+static errno_t get_rdn_value(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *dom,
+ const char *dn_attr,
+ const char **_rdn_value)
+{
+ errno_t ret;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_dn *dn = NULL;
+ const struct ldb_val *rdn_val;
+ const char *rdn_str;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ dn = ldb_dn_new(tmp_ctx, sysdb_ctx_get_ldb(dom->sysdb), dn_attr);
+ if (dn == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ rdn_val = ldb_dn_get_rdn_val(dn);
+ if (rdn_val == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "No RDN value?\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ rdn_str = talloc_strndup(tmp_ctx,
+ (const char *)rdn_val->data,
+ rdn_val->length);
+ if (rdn_str == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = EOK;
+ *_rdn_value = talloc_steal(mem_ctx, rdn_str);
+done:
+ talloc_zfree(tmp_ctx);
+ return ret;
+}
+
+static errno_t is_member_group(struct sss_domain_info *dom,
+ const char *dn_attr,
+ const char *group_rdn,
+ bool *_is_group)
+{
+ const char *comp_name;
+ const struct ldb_val *comp_val;
+ TALLOC_CTX *tmp_ctx;
+ bool is_group = false;
+ errno_t ret;
+ struct ldb_dn *dn = NULL;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ dn = ldb_dn_new(tmp_ctx, sysdb_ctx_get_ldb(dom->sysdb), dn_attr);
+ if (dn == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ comp_name = ldb_dn_get_component_name(dn, 1);
+ comp_val = ldb_dn_get_component_val(dn, 1);
+ if (strcasecmp("cn", comp_name) == 0
+ && strncasecmp(group_rdn,
+ (const char *) comp_val->data,
+ comp_val->length) == 0) {
+ is_group = true;
+ }
+
+ ret = EOK;
+done:
+ *_is_group = is_group;
+ talloc_zfree(tmp_ctx);
+ return ret;
+}
+
+static void print_category(struct sss_domain_info *domain,
+ struct ldb_message *rule_msg,
+ const char *category_attr_name,
+ const char *category_label)
+{
+ struct ldb_message_element *category_attr;
+
+ category_attr = ldb_msg_find_element(rule_msg, category_attr_name);
+ if (category_attr == NULL) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot find %s\n", category_attr_name);
+ return;
+ }
+
+ if (category_attr->num_values > 0) {
+ PRINT("\t%s: ", category_label);
+ for (unsigned i = 0; i < category_attr->num_values; i++) {
+ PRINT("%s%s",
+ i > 0 ? ", " : "",
+ (const char *) category_attr->values[i].data);
+ }
+ PRINT("\n");
+ }
+}
+
+static void print_member_attr(struct sss_domain_info *domain,
+ struct ldb_message *rule_msg,
+ const char *member_attr_name,
+ const char *group_rdn,
+ const char *object_label,
+ const char *group_label)
+{
+ errno_t ret;
+ TALLOC_CTX *tmp_ctx = NULL;
+ const char **member_names = NULL;
+ size_t name_count = 0;
+ const char **member_group_names = NULL;
+ size_t group_count = 0;
+ struct ldb_message_element *member_attr = NULL;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return;
+ }
+
+ member_attr = ldb_msg_find_element(rule_msg, member_attr_name);
+ if (member_attr == NULL) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot find %s\n", member_attr_name);
+ goto done;
+ }
+
+ member_names = talloc_zero_array(tmp_ctx,
+ const char *,
+ member_attr->num_values + 1);
+ member_group_names = talloc_zero_array(tmp_ctx,
+ const char *,
+ member_attr->num_values + 1);
+ if (member_names == NULL || member_group_names == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "OOM?\n");
+ goto done;
+ }
+
+ for (size_t i = 0; i < member_attr->num_values; i++) {
+ bool is_group;
+ const char *rdn_string;
+ const char *dn_attr;
+
+ dn_attr = (const char *) member_attr->values[i].data;
+
+ ret = is_member_group(domain, dn_attr, group_rdn, &is_group);
+ if (ret != EOK) {
+ continue;
+ }
+
+ ret = get_rdn_value(tmp_ctx, domain, dn_attr, &rdn_string);
+ if (ret != EOK) {
+ continue;
+ }
+
+ if (is_group == false) {
+ member_names[name_count] = talloc_steal(member_names,
+ rdn_string);
+ if (member_names[name_count] == NULL) {
+ goto done;
+ }
+ name_count++;
+ } else {
+ member_group_names[group_count] = talloc_strdup(member_group_names,
+ rdn_string);
+ if (member_group_names[group_count] == NULL) {
+ goto done;
+ }
+ group_count++;
+ }
+ }
+
+ if (member_names[0] != NULL) {
+ PRINT("\t%s: ", object_label);
+ for (int i = 0; member_names[i]; i++) {
+ PRINT("%s%s", i > 0 ? ", " : "", member_names[i]);
+ }
+ PRINT("\n");
+ }
+
+ if (member_group_names[0] != NULL) {
+ PRINT("\t%s: ", group_label);
+ for (int i = 0; member_group_names[i]; i++) {
+ PRINT("%s%s", i > 0 ? ", " : "", member_group_names[i]);
+ }
+ PRINT("\n");
+ }
+
+done:
+ talloc_free(tmp_ctx);
+}
+
+static void print_ipa_hbac_rule(struct sss_domain_info *domain,
+ struct ldb_message *rule_msg)
+{
+ struct ldb_message_element *el;
+
+ el = ldb_msg_find_element(rule_msg, IPA_CN);
+ if (el == NULL || el->num_values < 1) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "A rule with no name\n");
+ return;
+ }
+
+ PRINT("Rule name: %1$s\n", el->values[0].data);
+
+ print_member_attr(domain,
+ rule_msg,
+ IPA_MEMBER_USER,
+ "groups",
+ _("Member users"),
+ _("Member groups"));
+ print_category(domain,
+ rule_msg,
+ IPA_USER_CATEGORY,
+ _("User category"));
+
+ print_member_attr(domain,
+ rule_msg,
+ IPA_MEMBER_SERVICE,
+ "hbacservicegroups",
+ _("Member services"),
+ _("Member service groups"));
+ print_category(domain,
+ rule_msg,
+ IPA_SERVICE_CATEGORY,
+ _("Service category"));
+
+ PRINT("\n");
+}
+
+static errno_t sssctl_ipa_access_report(struct sss_tool_ctx *tool_ctx,
+ const char *user,
+ const char *service,
+ struct sss_domain_info *domain)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ const char *filter = NULL;
+ errno_t ret;
+ const char *attrs[] = {
+ OBJECTCLASS,
+ IPA_CN,
+ IPA_MEMBER_USER,
+ IPA_USER_CATEGORY,
+ IPA_MEMBER_SERVICE,
+ IPA_SERVICE_CATEGORY,
+ IPA_MEMBER_HOST,
+ IPA_HOST_CATEGORY,
+ NULL,
+ };
+ size_t rule_count;
+ struct ldb_message **msgs = NULL;
+
+ /* Run the pam account phase to make sure the rules are fetched by SSSD */
+ ret = run_pam_acct(tool_ctx, user, service, domain);
+ if (ret != PAM_SUCCESS && ret != PAM_PERM_DENIED) {
+ ERROR("Cannot run the PAM account phase, reporting stale rules\n");
+ /* Non-fatal */
+ }
+
+ tmp_ctx = talloc_new(tool_ctx);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ filter = talloc_asprintf(tmp_ctx, "(objectClass=%s)", IPA_HBAC_RULE);
+ if (filter == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_search_custom(tmp_ctx, domain, filter,
+ HBAC_RULES_SUBDIR, attrs,
+ &rule_count, &msgs);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up HBAC rules\n");
+ goto done;
+ }
+
+ if (ret == ENOENT) {
+ PRINT("No cached rules. All users will be denied access\n");
+ ret = EOK;
+ goto done;
+ }
+
+ PRINT("%1$zu rules cached\n\n", rule_count);
+
+ for (size_t i = 0; i < rule_count; i++) {
+ print_ipa_hbac_rule(domain, msgs[i]);
+ }
+
+ ret = EOK;
+done:
+ talloc_zfree(tmp_ctx);
+ return ret;
+}
+
+sssctl_dom_access_reporter_fn get_report_fn(const char *provider)
+{
+ if (strcmp(provider, "ipa") == 0) {
+ return sssctl_ipa_access_report;
+ }
+
+ return NULL;
+}
+
+errno_t sssctl_access_report(struct sss_cmdline *cmdline,
+ struct sss_tool_ctx *tool_ctx,
+ void *pvt)
+{
+ errno_t ret;
+ const char *domname = NULL;
+ sssctl_dom_access_reporter_fn reporter;
+ struct sss_domain_info *dom;
+ const char *user = DEFAULT_USER;
+ const char *service = DEFAULT_SERVICE;
+
+ /* Parse command line. */
+ struct poptOption options[] = {
+ { "user", 'u', POPT_ARG_STRING, &user, 0,
+ _("PAM user, default: " DEFAULT_USER), NULL },
+ { "service", 's', POPT_ARG_STRING, &service, 0,
+ _("PAM service, default: " DEFAULT_SERVICE), NULL },
+ POPT_TABLEEND
+ };
+
+ ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL,
+ NULL, NULL, "DOMAIN", _("Specify domain name."),
+ &domname, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command arguments\n");
+ return ret;
+ }
+
+ dom = find_domain_by_name(tool_ctx->domains, domname, true);
+ if (dom == NULL) {
+ ERROR("Cannot find domain %1$s\n", domname);
+ return ERR_DOMAIN_NOT_FOUND;
+ }
+
+ reporter = get_report_fn(dom->provider);
+ if (reporter == NULL) {
+ ERROR("Access report not implemented for domains of type %1$s\n",
+ dom->provider);
+ return ret;
+ }
+
+ return reporter(tool_ctx, user, service, dom);
+}
--
2.15.1

View File

@ -0,0 +1,49 @@
From 7130dad936c55ce0d3d895e9f216c3bc9fbd371b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 2 Nov 2017 14:58:05 +0100
Subject: [PATCH 57/79] dp: use void * to express empty output argument list
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Since we cannot use plain void type is function definition.
Related:
https://pagure.io/SSSD/sssd/issue/2840
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/providers/data_provider/dp_private.h | 2 +-
src/providers/data_provider/dp_request_reply.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/providers/data_provider/dp_private.h b/src/providers/data_provider/dp_private.h
index 2e71a373fdc8886fccb23bfb8283dc5bc341b1b0..028070f7f1866854c145a148e44c2cb108d2fc58 100644
--- a/src/providers/data_provider/dp_private.h
+++ b/src/providers/data_provider/dp_private.h
@@ -136,7 +136,7 @@ typedef void (*dp_req_reply_fn)(const char *req_name,
void dp_req_reply_default(const char *req_name,
struct sbus_request *sbus_req,
- void *data);
+ void **data);
/* Data provider request table. */
diff --git a/src/providers/data_provider/dp_request_reply.c b/src/providers/data_provider/dp_request_reply.c
index 27d9654bad76a099b004846463f035bf2e6d1243..34440fda7f28f0026d63af1af9958dcea3c6aaec 100644
--- a/src/providers/data_provider/dp_request_reply.c
+++ b/src/providers/data_provider/dp_request_reply.c
@@ -31,7 +31,7 @@
void dp_req_reply_default(const char *req_name,
struct sbus_request *sbus_req,
- void *data)
+ void **data)
{
DP_REQ_DEBUG(SSSDBG_TRACE_FUNC, req_name, "Replying with empty message");
--
2.15.1

View File

@ -0,0 +1,191 @@
From 78643d6c3b10c370cbefe0194a6b40f31aebe29b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 2 Nov 2017 14:58:38 +0100
Subject: [PATCH 58/79] dp: add method to refresh access control rules
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Related:
https://pagure.io/SSSD/sssd/issue/2840
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
src/providers/data_provider/dp.h | 2 ++
src/providers/data_provider/dp_iface.c | 6 ++++++
src/providers/data_provider/dp_iface.h | 4 ++++
src/providers/data_provider/dp_iface.xml | 6 ++++++
src/providers/data_provider/dp_iface_generated.c | 27 ++++++++++++++++++++++++
src/providers/data_provider/dp_iface_generated.h | 16 ++++++++++++++
src/providers/data_provider/dp_target_auth.c | 14 ++++++++++++
7 files changed, 75 insertions(+)
diff --git a/src/providers/data_provider/dp.h b/src/providers/data_provider/dp.h
index 9cdbe5b3a56ba159f9a10df6e010e616e4aefcac..aa5b781158c54545b26034602bb25db46b189e87 100644
--- a/src/providers/data_provider/dp.h
+++ b/src/providers/data_provider/dp.h
@@ -83,6 +83,8 @@ enum dp_methods {
DPM_DOMAINS_HANDLER,
DPM_SESSION_HANDLER,
+ DPM_REFRESH_ACCESS_RULES,
+
DP_METHOD_SENTINEL
};
diff --git a/src/providers/data_provider/dp_iface.c b/src/providers/data_provider/dp_iface.c
index 4b2b0ddca68be8899f7285b4d881a91444b99362..28d70e686f63a3572ac595f493aa1d59436c563f 100644
--- a/src/providers/data_provider/dp_iface.c
+++ b/src/providers/data_provider/dp_iface.c
@@ -48,10 +48,16 @@ struct iface_dp_failover iface_dp_failover = {
.ListServers = dp_failover_list_servers
};
+struct iface_dp_access_control iface_dp_access_control = {
+ { &iface_dp_access_control_meta, 0 },
+ .RefreshRules = dp_access_control_refresh_rules_handler
+};
+
static struct sbus_iface_map dp_map[] = {
{ DP_PATH, &iface_dp.vtable },
{ DP_PATH, &iface_dp_backend.vtable },
{ DP_PATH, &iface_dp_failover.vtable },
+ { DP_PATH, &iface_dp_access_control.vtable },
{ NULL, NULL }
};
diff --git a/src/providers/data_provider/dp_iface.h b/src/providers/data_provider/dp_iface.h
index 8ae7a2ad7a61f82b000493f3309926cd932211f6..759b9e6c9eb7f53836ae0b641b34e6c31e65779f 100644
--- a/src/providers/data_provider/dp_iface.h
+++ b/src/providers/data_provider/dp_iface.h
@@ -76,4 +76,8 @@ errno_t dp_failover_list_servers(struct sbus_request *sbus_req,
void *dp_cli,
const char *service_name);
+/* org.freedesktop.sssd.DataProvider.AccessControl */
+errno_t dp_access_control_refresh_rules_handler(struct sbus_request *sbus_req,
+ void *dp_cli);
+
#endif /* DP_IFACE_H_ */
diff --git a/src/providers/data_provider/dp_iface.xml b/src/providers/data_provider/dp_iface.xml
index a3969873ad1660c71ebdcae7a951757f5254c865..2bfa9dfa7e9d02d2d12c3358967f6969438a97a2 100644
--- a/src/providers/data_provider/dp_iface.xml
+++ b/src/providers/data_provider/dp_iface.xml
@@ -32,6 +32,12 @@
</method>
</interface>
+ <interface name="org.freedesktop.sssd.DataProvider.AccessControl">
+ <annotation value="iface_dp_access_control" name="org.freedesktop.DBus.GLib.CSymbol"/>
+ <method name="RefreshRules">
+ </method>
+ </interface>
+
<interface name="org.freedesktop.sssd.dataprovider">
<annotation value="iface_dp" name="org.freedesktop.DBus.GLib.CSymbol"/>
<method name="pamHandler">
diff --git a/src/providers/data_provider/dp_iface_generated.c b/src/providers/data_provider/dp_iface_generated.c
index e2e0216bd98c498b2b34c524ba615b70564420a2..11ee2e24a69cc8d4d19fdbeed613e76081aef15d 100644
--- a/src/providers/data_provider/dp_iface_generated.c
+++ b/src/providers/data_provider/dp_iface_generated.c
@@ -187,6 +187,33 @@ const struct sbus_interface_meta iface_dp_failover_meta = {
sbus_invoke_get_all, /* GetAll invoker */
};
+int iface_dp_access_control_RefreshRules_finish(struct sbus_request *req)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_INVALID);
+}
+
+/* methods for org.freedesktop.sssd.DataProvider.AccessControl */
+const struct sbus_method_meta iface_dp_access_control__methods[] = {
+ {
+ "RefreshRules", /* name */
+ NULL, /* no in_args */
+ NULL, /* no out_args */
+ offsetof(struct iface_dp_access_control, RefreshRules),
+ NULL, /* no invoker */
+ },
+ { NULL, }
+};
+
+/* interface info for org.freedesktop.sssd.DataProvider.AccessControl */
+const struct sbus_interface_meta iface_dp_access_control_meta = {
+ "org.freedesktop.sssd.DataProvider.AccessControl", /* name */
+ iface_dp_access_control__methods,
+ NULL, /* no signals */
+ NULL, /* no properties */
+ sbus_invoke_get_all, /* GetAll invoker */
+};
+
/* arguments for org.freedesktop.sssd.dataprovider.autofsHandler */
const struct sbus_arg_meta iface_dp_autofsHandler__in[] = {
{ "dp_flags", "u" },
diff --git a/src/providers/data_provider/dp_iface_generated.h b/src/providers/data_provider/dp_iface_generated.h
index b7f63fb438d7b3024a0f66de0a5d15cc3d426f44..541a90b0b5a5bc0a346cbd04974d33c8bb0983c5 100644
--- a/src/providers/data_provider/dp_iface_generated.h
+++ b/src/providers/data_provider/dp_iface_generated.h
@@ -26,6 +26,10 @@
#define IFACE_DP_FAILOVER_ACTIVESERVER "ActiveServer"
#define IFACE_DP_FAILOVER_LISTSERVERS "ListServers"
+/* constants for org.freedesktop.sssd.DataProvider.AccessControl */
+#define IFACE_DP_ACCESS_CONTROL "org.freedesktop.sssd.DataProvider.AccessControl"
+#define IFACE_DP_ACCESS_CONTROL_REFRESHRULES "RefreshRules"
+
/* constants for org.freedesktop.sssd.dataprovider */
#define IFACE_DP "org.freedesktop.sssd.dataprovider"
#define IFACE_DP_PAMHANDLER "pamHandler"
@@ -88,6 +92,15 @@ int iface_dp_failover_ActiveServer_finish(struct sbus_request *req, const char *
/* finish function for ListServers */
int iface_dp_failover_ListServers_finish(struct sbus_request *req, const char *arg_servers[], int len_servers);
+/* vtable for org.freedesktop.sssd.DataProvider.AccessControl */
+struct iface_dp_access_control {
+ struct sbus_vtable vtable; /* derive from sbus_vtable */
+ int (*RefreshRules)(struct sbus_request *req, void *data);
+};
+
+/* finish function for RefreshRules */
+int iface_dp_access_control_RefreshRules_finish(struct sbus_request *req);
+
/* vtable for org.freedesktop.sssd.dataprovider */
struct iface_dp {
struct sbus_vtable vtable; /* derive from sbus_vtable */
@@ -130,6 +143,9 @@ extern const struct sbus_interface_meta iface_dp_backend_meta;
/* interface info for org.freedesktop.sssd.DataProvider.Failover */
extern const struct sbus_interface_meta iface_dp_failover_meta;
+/* interface info for org.freedesktop.sssd.DataProvider.AccessControl */
+extern const struct sbus_interface_meta iface_dp_access_control_meta;
+
/* interface info for org.freedesktop.sssd.dataprovider */
extern const struct sbus_interface_meta iface_dp_meta;
diff --git a/src/providers/data_provider/dp_target_auth.c b/src/providers/data_provider/dp_target_auth.c
index 6bb3313b2de002466e5ca84464c962acd2412bfa..4b47975569a04a4d79aef4c16fcacf92c295de25 100644
--- a/src/providers/data_provider/dp_target_auth.c
+++ b/src/providers/data_provider/dp_target_auth.c
@@ -306,3 +306,17 @@ void dp_pam_handler_selinux_done(struct tevent_req *req)
dp_pam_reply(state->sbus_req, state->request_name, pd);
return;
}
+
+errno_t dp_access_control_refresh_rules_handler(struct sbus_request *sbus_req,
+ void *dp_cli)
+{
+ const char *key;
+
+ key = "RefreshRules";
+
+ dp_req_with_reply(dp_cli, NULL, "Refresh Access Control Rules", key,
+ sbus_req, DPT_ACCESS, DPM_REFRESH_ACCESS_RULES, 0, NULL,
+ dp_req_reply_default, void *);
+
+ return EOK;
+}
--
2.15.1

View File

@ -0,0 +1,139 @@
From 0b9d469b90b38b864134100de2a999152fe85507 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 2 Nov 2017 14:59:19 +0100
Subject: [PATCH 59/79] ipa: implement method to refresh HBAC rules
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Related:
https://pagure.io/SSSD/sssd/issue/2840
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
src/providers/ipa/ipa_access.c | 68 ++++++++++++++++++++++++++++++++++++++++--
src/providers/ipa/ipa_access.h | 10 +++++++
src/providers/ipa/ipa_init.c | 4 +++
3 files changed, 80 insertions(+), 2 deletions(-)
diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c
index 32ccf541c9436b633e7724b2c44ee545810a7fb8..de9f68170b6e9c38fd8b6d23f1d565250bbf78d2 100644
--- a/src/providers/ipa/ipa_access.c
+++ b/src/providers/ipa/ipa_access.c
@@ -682,8 +682,8 @@ done:
errno_t
ipa_pam_access_handler_recv(TALLOC_CTX *mem_ctx,
- struct tevent_req *req,
- struct pam_data **_data)
+ struct tevent_req *req,
+ struct pam_data **_data)
{
struct ipa_pam_access_handler_state *state = NULL;
@@ -695,3 +695,67 @@ ipa_pam_access_handler_recv(TALLOC_CTX *mem_ctx,
return EOK;
}
+
+struct ipa_refresh_access_rules_state {
+ int dummy;
+};
+
+static void ipa_refresh_access_rules_done(struct tevent_req *subreq);
+
+struct tevent_req *
+ipa_refresh_access_rules_send(TALLOC_CTX *mem_ctx,
+ struct ipa_access_ctx *access_ctx,
+ void *no_input_data,
+ struct dp_req_params *params)
+{
+ struct ipa_refresh_access_rules_state *state;
+ struct tevent_req *subreq;
+ struct tevent_req *req;
+
+ DEBUG(SSSDBG_TRACE_FUNC, "Refreshing HBAC rules\n");
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct ipa_refresh_access_rules_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n");
+ return NULL;
+ }
+
+ subreq = ipa_fetch_hbac_send(state, params->ev, params->be_ctx, access_ctx);
+ if (subreq == NULL) {
+ tevent_req_error(req, ENOMEM);
+ tevent_req_post(req, params->ev);
+ return req;
+ }
+
+ tevent_req_set_callback(subreq, ipa_refresh_access_rules_done, req);
+
+ return req;
+}
+
+static void ipa_refresh_access_rules_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req;
+ errno_t ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+
+ ret = ipa_fetch_hbac_recv(subreq);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+ return;
+}
+
+errno_t ipa_refresh_access_rules_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ void **_no_output_data)
+{
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ return EOK;
+}
diff --git a/src/providers/ipa/ipa_access.h b/src/providers/ipa/ipa_access.h
index de690350218bd47165a2b48c10059b8de96b718a..9cec0d1063fd39380a77093526e3240523752075 100644
--- a/src/providers/ipa/ipa_access.h
+++ b/src/providers/ipa/ipa_access.h
@@ -63,4 +63,14 @@ ipa_pam_access_handler_recv(TALLOC_CTX *mem_ctx,
struct tevent_req *req,
struct pam_data **_data);
+struct tevent_req *
+ipa_refresh_access_rules_send(TALLOC_CTX *mem_ctx,
+ struct ipa_access_ctx *access_ctx,
+ void *no_input_data,
+ struct dp_req_params *params);
+
+errno_t ipa_refresh_access_rules_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ void **_no_output_data);
+
#endif /* _IPA_ACCESS_H_ */
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index 5b7c8e1348f561901782c872078a0e7391d4ff75..f335d51fd65959d256c54a5d92c594a24e895b7c 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -831,6 +831,10 @@ errno_t sssm_ipa_access_init(TALLOC_CTX *mem_ctx,
ipa_pam_access_handler_send, ipa_pam_access_handler_recv, access_ctx,
struct ipa_access_ctx, struct pam_data, struct pam_data *);
+ dp_set_method(dp_methods, DPM_REFRESH_ACCESS_RULES,
+ ipa_refresh_access_rules_send, ipa_refresh_access_rules_recv, access_ctx,
+ struct ipa_access_ctx, void, void *);
+
ret = EOK;
done:
--
2.15.1

View File

@ -0,0 +1,157 @@
From 77ff1aa3fdb0231f649d5bb3e583bf8244ad23ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 2 Nov 2017 14:59:57 +0100
Subject: [PATCH 60/79] ifp: add method to refresh access control rules in
domain
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Related:
https://pagure.io/SSSD/sssd/issue/2840
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
src/responder/ifp/ifp_domains.c | 22 ++++++++++++++++++++++
src/responder/ifp/ifp_domains.h | 3 +++
src/responder/ifp/ifp_iface.c | 3 ++-
src/responder/ifp/ifp_iface.xml | 3 +++
src/responder/ifp/ifp_iface_generated.c | 13 +++++++++++++
src/responder/ifp/ifp_iface_generated.h | 5 +++++
6 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/src/responder/ifp/ifp_domains.c b/src/responder/ifp/ifp_domains.c
index 977bbfcbe818f08873ce072d34fdcf900cabf52f..cd7e2fc7aeff5467514269e5b078b0da88ab4f50 100644
--- a/src/responder/ifp/ifp_domains.c
+++ b/src/responder/ifp/ifp_domains.c
@@ -630,3 +630,25 @@ int ifp_domains_domain_list_servers(struct sbus_request *sbus_req,
return EOK;
}
+
+int ifp_domains_domain_refresh_access_rules(struct sbus_request *sbus_req,
+ void *data)
+{
+ struct ifp_ctx *ifp_ctx;
+ struct sss_domain_info *dom;
+
+ ifp_ctx = talloc_get_type(data, struct ifp_ctx);
+
+ dom = get_domain_info_from_req(sbus_req, data);
+ if (dom == NULL) {
+ sbus_request_reply_error(sbus_req, SBUS_ERROR_UNKNOWN_DOMAIN,
+ "Unknown domain");
+ return EOK;
+ }
+
+ rdp_message_send_and_reply(sbus_req, ifp_ctx->rctx, dom, DP_PATH,
+ IFACE_DP_ACCESS_CONTROL,
+ IFACE_DP_ACCESS_CONTROL_REFRESHRULES);
+
+ return EOK;
+}
diff --git a/src/responder/ifp/ifp_domains.h b/src/responder/ifp/ifp_domains.h
index 621ba6158e285911cb8298cef212219dfd3afec8..d8cc9d34c92cd04b6db432c1fc0e179a717001da 100644
--- a/src/responder/ifp/ifp_domains.h
+++ b/src/responder/ifp/ifp_domains.h
@@ -108,4 +108,7 @@ int ifp_domains_domain_list_servers(struct sbus_request *sbus_req,
void *data,
const char *service);
+int ifp_domains_domain_refresh_access_rules(struct sbus_request *sbus_req,
+ void *data);
+
#endif /* IFP_DOMAINS_H_ */
diff --git a/src/responder/ifp/ifp_iface.c b/src/responder/ifp/ifp_iface.c
index 3293b92d750d33b2ecf77a03098c5169d052c924..f995e28f99f9489ca17fbc51fa6894d458f9e21f 100644
--- a/src/responder/ifp/ifp_iface.c
+++ b/src/responder/ifp/ifp_iface.c
@@ -79,7 +79,8 @@ struct iface_ifp_domains_domain iface_ifp_domains_domain = {
.IsOnline = ifp_domains_domain_is_online,
.ListServices = ifp_domains_domain_list_services,
.ActiveServer = ifp_domains_domain_active_server,
- .ListServers = ifp_domains_domain_list_servers
+ .ListServers = ifp_domains_domain_list_servers,
+ .RefreshAccessRules = ifp_domains_domain_refresh_access_rules
};
struct iface_ifp_users iface_ifp_users = {
diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml
index 39385e866f31131c7860001ae4d6e6b51105aa52..1aa7eac03f0a3dc86f1d25883ac37f2fabf6b9e8 100644
--- a/src/responder/ifp/ifp_iface.xml
+++ b/src/responder/ifp/ifp_iface.xml
@@ -112,6 +112,9 @@
<arg name="service_name" type="s" direction="in" />
<arg name="servers" type="as" direction="out" />
</method>
+
+ <method name="RefreshAccessRules">
+ </method>
</interface>
<interface name="org.freedesktop.sssd.infopipe.Cache">
diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c
index 6943e38e3b6d2fc9e09ade1a863905c8d81a39ba..c2cdbf5b0ef3d59068aeed7a8f45099c14c4a94a 100644
--- a/src/responder/ifp/ifp_iface_generated.c
+++ b/src/responder/ifp/ifp_iface_generated.c
@@ -552,6 +552,12 @@ int iface_ifp_domains_domain_ListServers_finish(struct sbus_request *req, const
DBUS_TYPE_INVALID);
}
+int iface_ifp_domains_domain_RefreshAccessRules_finish(struct sbus_request *req)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_INVALID);
+}
+
/* methods for org.freedesktop.sssd.infopipe.Domains.Domain */
const struct sbus_method_meta iface_ifp_domains_domain__methods[] = {
{
@@ -582,6 +588,13 @@ const struct sbus_method_meta iface_ifp_domains_domain__methods[] = {
offsetof(struct iface_ifp_domains_domain, ListServers),
invoke_s_method,
},
+ {
+ "RefreshAccessRules", /* name */
+ NULL, /* no in_args */
+ NULL, /* no out_args */
+ offsetof(struct iface_ifp_domains_domain, RefreshAccessRules),
+ NULL, /* no invoker */
+ },
{ NULL, }
};
diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h
index 30752bf063de1f2530c7451f01cc22ad3e863185..f1e6c80bab27d0ed581abc566a178e6857794805 100644
--- a/src/responder/ifp/ifp_iface_generated.h
+++ b/src/responder/ifp/ifp_iface_generated.h
@@ -57,6 +57,7 @@
#define IFACE_IFP_DOMAINS_DOMAIN_LISTSERVICES "ListServices"
#define IFACE_IFP_DOMAINS_DOMAIN_ACTIVESERVER "ActiveServer"
#define IFACE_IFP_DOMAINS_DOMAIN_LISTSERVERS "ListServers"
+#define IFACE_IFP_DOMAINS_DOMAIN_REFRESHACCESSRULES "RefreshAccessRules"
/* constants for org.freedesktop.sssd.infopipe.Cache */
#define IFACE_IFP_CACHE "org.freedesktop.sssd.infopipe.Cache"
@@ -209,6 +210,7 @@ struct iface_ifp_domains_domain {
int (*ListServices)(struct sbus_request *req, void *data);
int (*ActiveServer)(struct sbus_request *req, void *data, const char *arg_service);
int (*ListServers)(struct sbus_request *req, void *data, const char *arg_service_name);
+ int (*RefreshAccessRules)(struct sbus_request *req, void *data);
};
/* finish function for IsOnline */
@@ -223,6 +225,9 @@ int iface_ifp_domains_domain_ActiveServer_finish(struct sbus_request *req, const
/* finish function for ListServers */
int iface_ifp_domains_domain_ListServers_finish(struct sbus_request *req, const char *arg_servers[], int len_servers);
+/* finish function for RefreshAccessRules */
+int iface_ifp_domains_domain_RefreshAccessRules_finish(struct sbus_request *req);
+
/* vtable for org.freedesktop.sssd.infopipe.Cache */
struct iface_ifp_cache {
struct sbus_vtable vtable; /* derive from sbus_vtable */
--
2.15.1

View File

@ -0,0 +1,199 @@
From a5bf38afa217b8e22fe221977959f78a44f15843 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 2 Nov 2017 15:00:17 +0100
Subject: [PATCH 61/79] sssctl: call dbus instead of pam to refresh HBAC rules
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Related:
https://pagure.io/SSSD/sssd/issue/2840
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/tools/sssctl/sssctl_access_report.c | 127 +++++++++++++++-----------------
1 file changed, 58 insertions(+), 69 deletions(-)
diff --git a/src/tools/sssctl/sssctl_access_report.c b/src/tools/sssctl/sssctl_access_report.c
index 11172329817b4dedaca480ab8a4537149853c330..8cf1a8a871b27827c317d658c0f93f34773c4841 100644
--- a/src/tools/sssctl/sssctl_access_report.c
+++ b/src/tools/sssctl/sssctl_access_report.c
@@ -15,11 +15,11 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <security/pam_appl.h>
-
#include "util/util.h"
#include "tools/common/sss_tools.h"
#include "tools/sssctl/sssctl.h"
+#include "sbus/sssd_dbus.h"
+#include "responder/ifp/ifp_iface.h"
/*
* We're searching the cache directly..
@@ -27,58 +27,9 @@
#include "providers/ipa/ipa_hbac_private.h"
#include "providers/ipa/ipa_rules_common.h"
-#ifdef HAVE_SECURITY_PAM_MISC_H
-# include <security/pam_misc.h>
-#elif defined(HAVE_SECURITY_OPENPAM_H)
-# include <security/openpam.h>
-#endif
-
-#ifdef HAVE_SECURITY_PAM_MISC_H
-static struct pam_conv conv = {
- misc_conv,
- NULL
-};
-#elif defined(HAVE_SECURITY_OPENPAM_H)
-static struct pam_conv conv = {
- openpam_ttyconv,
- NULL
-};
-#else
-# error "Missing text based pam conversation function"
-#endif
-
-#ifndef DEFAULT_SERVICE
-#define DEFAULT_SERVICE "system-auth"
-#endif /* DEFAULT_SERVICE */
-
-#ifndef DEFAULT_USER
-#define DEFAULT_USER "admin"
-#endif /* DEFAULT_USER */
-
typedef errno_t (*sssctl_dom_access_reporter_fn)(struct sss_tool_ctx *tool_ctx,
- const char *user,
- const char *service,
struct sss_domain_info *domain);
-static errno_t run_pam_acct(struct sss_tool_ctx *tool_ctx,
- const char *user,
- const char *service,
- struct sss_domain_info *domain)
-{
- errno_t ret;
- pam_handle_t *pamh;
-
- ret = pam_start(service, user, &conv, &pamh);
- if (ret != PAM_SUCCESS) {
- ERROR("pam_start failed: %s\n", pam_strerror(pamh, ret));
- return EIO;
- }
-
- ret = pam_acct_mgmt(pamh, 0);
- pam_end(pamh, ret);
- return ret;
-}
-
static errno_t get_rdn_value(TALLOC_CTX *mem_ctx,
struct sss_domain_info *dom,
const char *dn_attr,
@@ -315,9 +266,58 @@ static void print_ipa_hbac_rule(struct sss_domain_info *domain,
PRINT("\n");
}
+static errno_t refresh_hbac_rules(struct sss_tool_ctx *tool_ctx,
+ struct sss_domain_info *domain)
+{
+ TALLOC_CTX *tmp_ctx;
+ sss_sifp_error error;
+ sss_sifp_ctx *sifp;
+ DBusMessage *reply;
+ const char *path;
+ errno_t ret;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+ return ENOMEM;
+ }
+
+ path = sbus_opath_compose(tmp_ctx, IFP_PATH_DOMAINS, domain->name);
+ if (path == NULL) {
+ printf(_("Out of memory!\n"));
+ ret = ENOMEM;
+ goto done;
+ }
+
+ error = sssctl_sifp_init(tool_ctx, &sifp);
+ if (error != SSS_SIFP_OK) {
+ sssctl_sifp_error(sifp, error, "Unable to connect to the InfoPipe");
+ ret = EIO;
+ goto done;
+ }
+
+ error = sssctl_sifp_send(tmp_ctx, sifp, &reply, path,
+ IFACE_IFP_DOMAINS_DOMAIN,
+ IFACE_IFP_DOMAINS_DOMAIN_REFRESHACCESSRULES);
+ if (error != SSS_SIFP_OK) {
+ sssctl_sifp_error(sifp, error, "Unable to refresh HBAC rules");
+ ret = EIO;
+ goto done;
+ }
+
+ ret = sbus_parse_reply(reply);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
static errno_t sssctl_ipa_access_report(struct sss_tool_ctx *tool_ctx,
- const char *user,
- const char *service,
struct sss_domain_info *domain)
{
TALLOC_CTX *tmp_ctx = NULL;
@@ -338,9 +338,9 @@ static errno_t sssctl_ipa_access_report(struct sss_tool_ctx *tool_ctx,
struct ldb_message **msgs = NULL;
/* Run the pam account phase to make sure the rules are fetched by SSSD */
- ret = run_pam_acct(tool_ctx, user, service, domain);
- if (ret != PAM_SUCCESS && ret != PAM_PERM_DENIED) {
- ERROR("Cannot run the PAM account phase, reporting stale rules\n");
+ ret = refresh_hbac_rules(tool_ctx, domain);
+ if (ret != EOK) {
+ ERROR("Unable to refresh HBAC rules, using cached content\n");
/* Non-fatal */
}
@@ -398,19 +398,8 @@ errno_t sssctl_access_report(struct sss_cmdline *cmdline,
const char *domname = NULL;
sssctl_dom_access_reporter_fn reporter;
struct sss_domain_info *dom;
- const char *user = DEFAULT_USER;
- const char *service = DEFAULT_SERVICE;
- /* Parse command line. */
- struct poptOption options[] = {
- { "user", 'u', POPT_ARG_STRING, &user, 0,
- _("PAM user, default: " DEFAULT_USER), NULL },
- { "service", 's', POPT_ARG_STRING, &service, 0,
- _("PAM service, default: " DEFAULT_SERVICE), NULL },
- POPT_TABLEEND
- };
-
- ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL,
+ ret = sss_tool_popt_ex(cmdline, NULL, SSS_TOOL_OPT_OPTIONAL,
NULL, NULL, "DOMAIN", _("Specify domain name."),
&domname, NULL);
if (ret != EOK) {
@@ -431,5 +420,5 @@ errno_t sssctl_access_report(struct sss_cmdline *cmdline,
return ret;
}
- return reporter(tool_ctx, user, service, dom);
+ return reporter(tool_ctx, dom);
}
--
2.15.1

View File

@ -0,0 +1,36 @@
From cd36d84d4996ac768b13f43e00a7a219ea28bb99 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Thu, 16 Nov 2017 12:11:28 +0100
Subject: [PATCH 62/79] SPEC: Reduce build time dependencies
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Total download size: 139 M
Installed size: 465 M
vs
Total size: 11 k
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
contrib/sssd.spec.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index c716efdce05ab7b9178be66f34d09124c78071b5..d1cd1965f6673be9a756f216dea187c88660e99d 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -240,7 +240,7 @@ BuildRequires: jansson-devel
BuildRequires: libcurl-devel
%endif
%if (0%{?with_gdm_pam_extensions} == 1)
-BuildRequires: gdm-devel
+BuildRequires: gdm-pam-extensions-devel
%endif
%description
--
2.15.1

View File

@ -0,0 +1,42 @@
From 97b56f1ec15a3270cc2e85c9b367e4d38f91ae1a Mon Sep 17 00:00:00 2001
From: Victor Tapia <victor.tapia@canonical.com>
Date: Mon, 16 Oct 2017 09:45:24 +0200
Subject: [PATCH 63/79] WATCHDOG: Restart providers with SIGUSR2 after time
drift
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Restarting the providers using the already implemented SIGUSR2 (for
method .resetOffline, used after netlink detects an interface change)
when a time drift is detected, ensures that affected connection retries
(e.g. LDAP) will be rescheduled immediately instead of having to wait
the time shifted to return to its normal execution.
Resolves:
https://pagure.io/SSSD/sssd/issue/3285
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/util/util_watchdog.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/util/util_watchdog.c b/src/util/util_watchdog.c
index 59293db60e4ffbe566f8b17f3f289503e8d9aee6..20a8b896791118c1ae9b5bfe101a539b213497a4 100644
--- a/src/util/util_watchdog.c
+++ b/src/util/util_watchdog.c
@@ -160,6 +160,10 @@ static void watchdog_fd_read_handler(struct tevent_context *ev,
"[%d]: %s\n", ret, sss_strerror(ret));
orderly_shutdown(1);
}
+ if (strncmp(debug_prg_name, "sssd[be[", sizeof("sssd[be[") - 1) == 0) {
+ kill(getpid(), SIGUSR2);
+ DEBUG(SSSDBG_IMPORTANT_INFO, "SIGUSR2 sent to %s\n", debug_prg_name);
+ }
}
int setup_watchdog(struct tevent_context *ev, int interval)
--
2.15.1

View File

@ -0,0 +1,168 @@
From b70b4099b049b6a2bd85e773dbd81974dee24e05 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 17 Nov 2017 10:51:44 +0100
Subject: [PATCH 64/79] mmap_cache: make checks independent of input size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Currently the consistency checks for the mmap_cache payload data on the
client and the responder side include the length of the input string of
the current request. Since there might be hash collisions which other
much longer or much shorter names those checks might fail although there
is no data corruption.
This patch removes the checks using the length of the input and adds a
check if the name found in the payload is zero-terminated inside of the
payload data.
Resolves https://pagure.io/SSSD/sssd/issue/3571
Reviewed-by: Michal Židek <mzidek@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
---
src/responder/nss/nsssrv_mmap_cache.c | 34 ++++++++++++++++++++++++----------
src/sss_client/nss_mc_group.c | 12 ++++++------
src/sss_client/nss_mc_initgr.c | 12 +++++++-----
src/sss_client/nss_mc_passwd.c | 12 ++++++------
4 files changed, 43 insertions(+), 27 deletions(-)
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index a87ad646f9b741db3eb18680678697032fc420ba..ad5adbce15e50c065d4d16e626be97fd23d06643 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -547,18 +547,32 @@ static struct sss_mc_rec *sss_mc_find_record(struct sss_mc_ctx *mcc,
return NULL;
}
+ if (key->len > strs_len) {
+ /* The string cannot be in current record */
+ slot = sss_mc_next_slot_with_hash(rec, hash);
+ continue;
+ }
+
safealign_memcpy(&name_ptr, rec->data, sizeof(rel_ptr_t), NULL);
- if (key->len > strs_len
- || (name_ptr + key->len) > (strs_offset + strs_len)
- || (uint8_t *)rec->data + strs_offset + strs_len > max_addr) {
- DEBUG(SSSDBG_FATAL_FAILURE,
- "Corrupted fastcache. name_ptr value is %u.\n", name_ptr);
- sss_mc_save_corrupted(mcc);
- sss_mmap_cache_reset(mcc);
- return NULL;
- }
-
t_key = (char *)rec->data + name_ptr;
+ /* name_ptr must point to some data in the strs/gids area of the data
+ * payload. Since it is a pointer relative to rec->data it must larger
+ * equal strs_offset and must be smaller then strs_offset + strs_len.
+ * Additionally the area must not end outside of the data table and
+ * t_key must be a zero-terminates string. */
+ if (name_ptr < strs_offset
+ || name_ptr >= strs_offset + strs_len
+ || (uint8_t *)rec->data > max_addr
+ || strs_offset > max_addr - (uint8_t *)rec->data
+ || strs_len > max_addr - (uint8_t *)rec->data - strs_offset) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Corrupted fastcache entry at slot %u. "
+ "name_ptr value is %u.\n", slot, name_ptr);
+ sss_mc_save_corrupted(mcc);
+ sss_mmap_cache_reset(mcc);
+ return NULL;
+ }
+
if (strcmp(key->str, t_key) == 0) {
break;
}
diff --git a/src/sss_client/nss_mc_group.c b/src/sss_client/nss_mc_group.c
index ce88d42fdaf4f19e78fc43e187bc28651cdc3c4e..ba582fe55cf3abf90d8e016c82a0bee48608ce78 100644
--- a/src/sss_client/nss_mc_group.c
+++ b/src/sss_client/nss_mc_group.c
@@ -148,20 +148,20 @@ errno_t sss_nss_mc_getgrnam(const char *name, size_t name_len,
}
data = (struct sss_mc_grp_data *)rec->data;
+ rec_name = (char *)data + data->name;
/* Integrity check
- * - name_len cannot be longer than all strings
* - data->name cannot point outside strings
* - all strings must be within copy of record
- * - size of record must be lower that data table size */
- if (name_len > data->strs_len
- || (data->name + name_len) > (strs_offset + data->strs_len)
+ * - record must not end outside data table
+ * - rec_name is a zero-terminated string */
+ if (data->name < strs_offset
+ || data->name >= strs_offset + data->strs_len
|| data->strs_len > rec->len
- || rec->len > data_size) {
+ || (uint8_t *) rec + rec->len > gr_mc_ctx.data_table + data_size ) {
ret = ENOENT;
goto done;
}
- rec_name = (char *)data + data->name;
if (strcmp(name, rec_name) == 0) {
break;
}
diff --git a/src/sss_client/nss_mc_initgr.c b/src/sss_client/nss_mc_initgr.c
index a77088d849ad3601cb3edb55fc5ea4ae4c52fe38..606f1c7ee2526a15378831d4512e943bac214d0e 100644
--- a/src/sss_client/nss_mc_initgr.c
+++ b/src/sss_client/nss_mc_initgr.c
@@ -131,15 +131,17 @@ errno_t sss_nss_mc_initgroups_dyn(const char *name, size_t name_len,
data = (struct sss_mc_initgr_data *)rec->data;
rec_name = (char *)data + data->name;
/* Integrity check
- * - name_len cannot be longer than all strings or data
+ * - data->name cannot point outside all strings or data
* - all data must be within copy of record
* - size of record must be lower that data table size
- * - data->strs cannot point outside strings */
- if (name_len > data->strs_len
+ * - data->strs cannot point outside strings
+ * - rec_name is a zero-terminated string */
+ if (data->name < data_offset
+ || data->name >= data_offset + data->data_len
|| data->strs_len > data->data_len
|| data->data_len > rec->len
- || rec->len > data_size
- || (data->strs + name_len) > (data_offset + data->data_len)) {
+ || (uint8_t *) rec + rec->len
+ > initgr_mc_ctx.data_table + data_size ) {
ret = ENOENT;
goto done;
}
diff --git a/src/sss_client/nss_mc_passwd.c b/src/sss_client/nss_mc_passwd.c
index 0da7ad0aeece7d38ca34bb3fde64adc898eaf0ae..0bc1237446d3691c8c83aa0fc0cf692d4b336f9e 100644
--- a/src/sss_client/nss_mc_passwd.c
+++ b/src/sss_client/nss_mc_passwd.c
@@ -141,20 +141,20 @@ errno_t sss_nss_mc_getpwnam(const char *name, size_t name_len,
}
data = (struct sss_mc_pwd_data *)rec->data;
+ rec_name = (char *)data + data->name;
/* Integrity check
- * - name_len cannot be longer than all strings
* - data->name cannot point outside strings
* - all strings must be within copy of record
- * - size of record must be lower that data table size */
- if (name_len > data->strs_len
- || (data->name + name_len) > (strs_offset + data->strs_len)
+ * - record must not end outside data table
+ * - rec_name is a zero-terminated string */
+ if (data->name < strs_offset
+ || data->name >= strs_offset + data->strs_len
|| data->strs_len > rec->len
- || rec->len > data_size) {
+ || (uint8_t *) rec + rec->len > pw_mc_ctx.data_table + data_size ) {
ret = ENOENT;
goto done;
}
- rec_name = (char *)data + data->name;
if (strcmp(name, rec_name) == 0) {
break;
}
--
2.15.1

View File

@ -0,0 +1,53 @@
From 91d9cf1d38ffa4de06504c70b1f2af02da169b30 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Tue, 21 Nov 2017 16:12:24 +0100
Subject: [PATCH 65/79] NSS: Fix covscan warning
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Error: NULL_RETURNS (CWE-476): [#def1]
sssd-1.16.1/src/responder/nss/nss_protocol.c:162: returned_null: "memchr" returns null (checked 7 out of 8 times).
sssd-1.16.1/src/responder/nss/nsssrv_mmap_cache.c:557: example_checked: Example 1: "memchr(t_key, 0, strs_offset + strs_len - name_ptr)" has its value checked in "memchr(t_key, 0, strs_offset + strs_len - name_ptr) == NULL".
sssd-1.16.1/src/sss_client/idmap/sss_nss_idmap.c:171: example_assign: Example 2: Assigning: "p" = return value from "memchr(p, 0, buf_len - (p - buf))".
sssd-1.16.1/src/sss_client/idmap/sss_nss_idmap.c:172: example_checked: Example 2 (cont.): "p" has its value checked in "p == NULL".
sssd-1.16.1/src/sss_client/nss_mc_group.c:157: example_checked: Example 3: "memchr(rec_name, 0, 16UL + data->strs_len - data->name)" has its value checked in "memchr(rec_name, 0, 16UL + data->strs_len - data->name) == NULL".
sssd-1.16.1/src/sss_client/nss_mc_initgr.c:139: example_checked: Example 4: "memchr(rec_name, 0, 24UL + data->data_len - data->name)" has its value checked in "memchr(rec_name, 0, 24UL + data->data_len - data->name) == NULL".
sssd-1.16.1/src/sss_client/nss_mc_passwd.c:150: example_checked: Example 5: "memchr(rec_name, 0, 16UL + data->strs_len - data->name)" has its value checked in "memchr(rec_name, 0, 16UL + data->strs_len - data->name) == NULL".
sssd-1.16.1/src/responder/nss/nss_protocol.c:162: var_assigned: Assigning: "p" = null return value from "memchr".
sssd-1.16.1/src/responder/nss/nss_protocol.c:176: dereference: Incrementing a pointer which might be null: "p".
# 174| }
# 175|
# 176|-> p++;
# 177| if ((p - body) + sizeof(uint32_t) != blen) {
# 178| DEBUG(SSSDBG_CRIT_FAILURE, "Body has unexpected size!\n");
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Reviewed-by: Michal Židek <mzidek@redhat.com>
---
src/responder/nss/nss_protocol.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/responder/nss/nss_protocol.c b/src/responder/nss/nss_protocol.c
index 2655386498754c46fbb363bdd1f976f9ded6a434..13f6d1541b79bf5494e1560841f027bf98bef72b 100644
--- a/src/responder/nss/nss_protocol.c
+++ b/src/responder/nss/nss_protocol.c
@@ -160,6 +160,13 @@ nss_protocol_parse_name_ex(struct cli_ctx *cli_ctx, const char **_rawname,
}
p = memchr(body, '\0', blen);
+ /* Although body for sure is null terminated, let's add this check here
+ * so static analyzers are happier. */
+ if (p == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "memchr() returned NULL, body is not null terminated!\n");
+ return EINVAL;
+ }
/* If the body isn't valid UTF-8, fail */
if (!sss_utf8_check(body, (p - body))) {
--
2.15.1

View File

@ -0,0 +1,187 @@
From 209caaad9d545aeb601f64854a2ffb978b77c4b1 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 27 Nov 2017 13:45:14 +0100
Subject: [PATCH 66/79] krb5: show error message for krb5_init_context()
failures
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If there are typos in /etc/krb5.conf (or one of the included config
snippets) krb5_init_context(), the initial call always needed to do any
other operation with libkrb5, fails because /etc/krb5.conf cannot be
parsed.
Currently the related debug/syslog messages might be misleading, e.g.
failed to read keytab. This is because SSSD does not use a global krb5
context but creates a fresh one for every new request or operation (to
always use the latest settings from /etc/krb5.conf) and typically there
is an error message indicating that the related operation failed but not
giving more details.
Since krb5_init_context() is fundamental for Kerberos support this patch
tries to add as much details as libkrb5 provides in the logs if the call
fails.
Resolves:
https://pagure.io/SSSD/sssd/issue/3586
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Reviewed-by: Robbie Harwood <rharwood@redhat.com>
---
src/providers/krb5/krb5_ccache.c | 6 +++---
src/providers/krb5/krb5_common.c | 2 +-
src/providers/ldap/ldap_child.c | 2 +-
src/providers/ldap/ldap_common.c | 2 +-
src/responder/kcm/kcm.c | 3 ++-
src/util/sss_krb5.c | 25 ++++++++++++++++++++++---
src/util/sss_krb5.h | 2 ++
7 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/src/providers/krb5/krb5_ccache.c b/src/providers/krb5/krb5_ccache.c
index f9bb25efd4ca3257845c3b157667d21d24299f4a..2e28276b72b6d5961de33c0ceb61774074a92d11 100644
--- a/src/providers/krb5/krb5_ccache.c
+++ b/src/providers/krb5/krb5_ccache.c
@@ -299,7 +299,7 @@ static errno_t sss_open_ccache_as_user(TALLOC_CTX *mem_ctx,
goto done;
}
- kerr = krb5_init_context(&cc->context);
+ kerr = sss_krb5_init_context(&cc->context);
if (kerr) {
ret = EIO;
goto done;
@@ -565,9 +565,9 @@ errno_t get_ccache_file_data(const char *ccache_file, const char *client_name,
const char *realm_name;
int realm_length;
- kerr = krb5_init_context(&ctx);
+ kerr = sss_krb5_init_context(&ctx);
if (kerr != 0) {
- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_init_context failed.\n");
+ DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_init_context failed.\n");
goto done;
}
diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
index 0b32da94dd8320d51708e2b7e827b94c472642a6..520e7591ce1b37b4a8dea357b6dd0ec7afd76f58 100644
--- a/src/providers/krb5/krb5_common.c
+++ b/src/providers/krb5/krb5_common.c
@@ -106,7 +106,7 @@ static errno_t sss_get_system_ccname_template(TALLOC_CTX *mem_ctx,
*ccname = NULL;
- ret = krb5_init_context(&ctx);
+ ret = sss_krb5_init_context(&ctx);
if (ret) return ret;
ret = krb5_get_profile(ctx, &p);
diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c
index c0618d6d8828f102c32cf56731995e2b370590e7..4558fd7c42be03c4472dbf3092ce8044e8ae89d9 100644
--- a/src/providers/ldap/ldap_child.c
+++ b/src/providers/ldap/ldap_child.c
@@ -574,7 +574,7 @@ static krb5_error_code privileged_krb5_setup(struct input_buffer *ibuf)
krb5_error_code kerr;
char *keytab_name;
- kerr = krb5_init_context(&ibuf->context);
+ kerr = sss_krb5_init_context(&ibuf->context);
if (kerr != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to init kerberos context\n");
return kerr;
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index 0597e91f7fade47aeb34565597c730ac406e0cfc..4ec36584ad5acc52cf442b015caec80a6a8936da 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -364,7 +364,7 @@ sdap_gssapi_get_default_realm(TALLOC_CTX *mem_ctx)
krb5_error_code krberr;
krb5_context context = NULL;
- krberr = krb5_init_context(&context);
+ krberr = sss_krb5_init_context(&context);
if (krberr) {
DEBUG(SSSDBG_OP_FAILURE, "Failed to init kerberos context\n");
goto done;
diff --git a/src/responder/kcm/kcm.c b/src/responder/kcm/kcm.c
index 358fcc18165dec7b41a7389a3ef22660ac04b4a8..0fc09376888544570ca1bcf8c1ff1ba1d72d5906 100644
--- a/src/responder/kcm/kcm.c
+++ b/src/responder/kcm/kcm.c
@@ -28,6 +28,7 @@
#include "responder/kcm/kcmsrv_pvt.h"
#include "responder/common/responder.h"
#include "util/util.h"
+#include "util/sss_krb5.h"
#define DEFAULT_KCM_FD_LIMIT 2048
@@ -183,7 +184,7 @@ static struct kcm_resp_ctx *kcm_data_setup(TALLOC_CTX *mem_ctx,
return NULL;
}
- kret = krb5_init_context(&kcm_data->k5c);
+ kret = sss_krb5_init_context(&kcm_data->k5c);
if (kret != EOK) {
talloc_free(kcm_data);
return NULL;
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
index a702a8b57c55bdb4215edf73731ddeaba156a84f..12660b0dd2e9170108afd54492e7ce30415741cb 100644
--- a/src/util/sss_krb5.c
+++ b/src/util/sss_krb5.c
@@ -113,7 +113,7 @@ errno_t select_principal_from_keytab(TALLOC_CTX *mem_ctx,
return ENOMEM;
}
- kerr = krb5_init_context(&krb_ctx);
+ kerr = sss_krb5_init_context(&krb_ctx);
if (kerr) {
DEBUG(SSSDBG_OP_FAILURE, "Failed to init kerberos context\n");
ret = EFAULT;
@@ -1096,9 +1096,9 @@ bool sss_krb5_realm_has_proxy(const char *realm)
return false;
}
- kerr = krb5_init_context(&context);
+ kerr = sss_krb5_init_context(&context);
if (kerr != 0) {
- DEBUG(SSSDBG_OP_FAILURE, "krb5_init_context failed.\n");
+ DEBUG(SSSDBG_OP_FAILURE, "sss_krb5_init_context failed.\n");
return false;
}
@@ -1330,3 +1330,22 @@ krb5_error_code sss_krb5_marshal_princ(krb5_principal princ,
}
return EOK;
}
+
+krb5_error_code sss_krb5_init_context(krb5_context *context)
+{
+ krb5_error_code kerr;
+ const char *msg;
+
+ kerr = krb5_init_context(context);
+ if (kerr != 0) {
+ /* It is safe to call (sss_)krb5_get_error_message() with NULL as first
+ * argument. */
+ msg = sss_krb5_get_error_message(NULL, kerr);
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ "Failed to init kerberos context [%s]\n", msg);
+ sss_log(SSS_LOG_CRIT, "Failed to init kerberos context [%s]\n", msg);
+ sss_krb5_free_error_message(NULL, msg);
+ }
+
+ return kerr;
+}
diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h
index 0d9043be98749b1a21a1b74c68f07298fa27f230..423951443c8c512211b1e894c41f1c8891be479f 100644
--- a/src/util/sss_krb5.h
+++ b/src/util/sss_krb5.h
@@ -195,4 +195,6 @@ krb5_error_code sss_krb5_unmarshal_princ(TALLOC_CTX *mem_ctx,
struct sss_iobuf *iobuf,
krb5_principal *_princ);
+krb5_error_code sss_krb5_init_context(krb5_context *context);
+
#endif /* __SSS_KRB5_H__ */
--
2.15.1

View File

@ -0,0 +1,58 @@
From ddff278e709a2aa882f2d8d64c263cddc3a93a2c Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Tue, 28 Nov 2017 12:19:54 +0100
Subject: [PATCH 67/79] responder: Fix talloc hierarchy in sized_output_name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
sized_output_name was a called with NULL context in
memcache_delete_entry but returned data from sized_output_name
didn't have proper talloc hierarchy and we could not release all
all returned data.
==00:01:01:29.871 10088== 934,414 bytes in 8,731 blocks are definitely lost in loss record 121 of 121
==00:01:01:29.871 10088== at 0x4C29BE3: malloc (vg_replace_malloc.c:299)
==00:01:01:29.871 10088== by 0x8FF4EAB: talloc_strdup (in /usr/lib64/libtalloc.so.2.1.9)
==00:01:01:29.871 10088== by 0x52933B9: sss_output_name (usertools.c:808)
==00:01:01:29.871 10088== by 0x5293550: sss_output_fqname (usertools.c:863)
==00:01:01:29.871 10088== by 0x1211F9: sized_output_name (responder_common.c:1708)
==00:01:01:29.871 10088== by 0x1137E6: memcache_delete_entry (nss_get_object.c:112)
==00:01:01:29.871 10088== by 0x113BB6: nss_get_object_done (nss_get_object.c:245)
==00:01:01:29.871 10088== by 0x8DE5291: _tevent_req_error (in /usr/lib64/libtevent.so.0.9.31)
==00:01:01:29.871 10088== by 0x1276CE: cache_req_done (cache_req.c:1047)
==00:01:01:29.871 10088== by 0x8DE5291: _tevent_req_error (in /usr/lib64/libtevent.so.0.9.31)
==00:01:01:29.871 10088== by 0x126AF6: cache_req_search_domains_done (cache_req.c:607)
==00:01:01:29.871 10088== by 0x8DE4AB9: tevent_common_loop_immediate (in /usr/lib64/libtevent.so.0.9.31)
==00:01:01:29.871 10088== by 0x8DE9C9C: ??? (in /usr/lib64/libtevent.so.0.9.31)
==00:01:01:29.871 10088== by 0x8DE82A6: ??? (in /usr/lib64/libtevent.so.0.9.31)
==00:01:01:29.871 10088== by 0x8DE40CC: _tevent_loop_once (in /usr/lib64/libtevent.so.0.9.31)
==00:01:01:29.871 10088== by 0x8DE42FA: tevent_common_loop_wait (in /usr/lib64/libtevent.so.0.9.31)
==00:01:01:29.871 10088== by 0x8DE8246: ??? (in /usr/lib64/libtevent.so.0.9.31)
==00:01:01:29.871 10088== by 0x5291B32: server_loop (server.c:718)
==00:01:01:29.871 10088== by 0x11004C: main (nsssrv.c:560)
Resolves:
https://pagure.io/SSSD/sssd/issue/3588
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/responder/common/responder_common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 6b4d2d9e5936c79944b6f883e9fe46fd03ff32f6..e1100ce4b1eaae8bc561246699dc9bacc96133c8 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -1815,7 +1815,7 @@ int sized_output_name(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = sss_output_fqname(mem_ctx, name_dom, orig_name,
+ ret = sss_output_fqname(name, name_dom, orig_name,
rctx->override_space, &name_str);
if (ret != EOK) {
goto done;
--
2.15.1

View File

@ -0,0 +1,57 @@
From 878fa7d0d4a3c9de1e813a550c5968153faae0a9 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Tue, 28 Nov 2017 12:20:26 +0100
Subject: [PATCH 68/79] test_responder: Check memory leak in sized_output_name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves:
https://pagure.io/SSSD/sssd/issue/3588
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/tests/cmocka/test_responder_common.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/src/tests/cmocka/test_responder_common.c b/src/tests/cmocka/test_responder_common.c
index fb7e4ee500570319999e6e85ee14a05cddea8de3..5441167caeb284982ee76926117da029966ec997 100644
--- a/src/tests/cmocka/test_responder_common.c
+++ b/src/tests/cmocka/test_responder_common.c
@@ -316,6 +316,23 @@ void test_schedule_get_domains_task(void **state)
talloc_free(dummy_ncache_ptr);
}
+void test_sss_output_fqname(void **state)
+{
+ struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state,
+ struct parse_inp_test_ctx);
+ errno_t ret;
+ struct sized_string *res = NULL;
+
+ ret = sized_output_name(parse_inp_ctx, parse_inp_ctx->rctx, "dummy",
+ parse_inp_ctx->tctx->dom, &res);
+ assert_int_equal(ret, EOK);
+ assert_non_null(res);
+ assert_string_equal("dummy", res->str);
+ assert_int_equal(6, res->len);
+
+ talloc_zfree(res);
+}
+
int main(int argc, const char *argv[])
{
int rv;
@@ -346,6 +363,9 @@ int main(int argc, const char *argv[])
cmocka_unit_test_setup_teardown(test_schedule_get_domains_task,
parse_inp_test_setup,
parse_inp_test_teardown),
+ cmocka_unit_test_setup_teardown(test_sss_output_fqname,
+ parse_inp_test_setup,
+ parse_inp_test_teardown),
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */
--
2.15.1

View File

@ -0,0 +1,81 @@
From 8b98ab849993ddd2bddbe475f443fbee24081c1a Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 20 Nov 2017 12:08:30 +0100
Subject: [PATCH 69/79] UTIL: add find_domain_by_object_name_ex()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The _ex version of find_domain_by_object_name() has a additional option
'strict'. If set to 'true' NULL is return instead to domain from the
first argument. This way the caller can see if the provider object name
really contains a known domain.
Related to https://pagure.io/SSSD/sssd/issue/3579
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/util/domain_info_utils.c | 17 ++++++++++++++---
src/util/util.h | 4 ++++
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
index 3a3f5130a32e2c5fe4b81819bf2de697a4474111..66077092a40111967a98b0937506d9e4472f50d5 100644
--- a/src/util/domain_info_utils.c
+++ b/src/util/domain_info_utils.c
@@ -174,8 +174,8 @@ sss_get_domain_by_sid_ldap_fallback(struct sss_domain_info *domain,
}
struct sss_domain_info *
-find_domain_by_object_name(struct sss_domain_info *domain,
- const char *object_name)
+find_domain_by_object_name_ex(struct sss_domain_info *domain,
+ const char *object_name, bool strict)
{
TALLOC_CTX *tmp_ctx;
struct sss_domain_info *dom = NULL;
@@ -197,7 +197,11 @@ find_domain_by_object_name(struct sss_domain_info *domain,
}
if (domainname == NULL) {
- dom = domain;
+ if (strict) {
+ dom = NULL;
+ } else {
+ dom = domain;
+ }
} else {
dom = find_domain_by_name(domain, domainname, true);
}
@@ -207,6 +211,13 @@ done:
return dom;
}
+struct sss_domain_info *
+find_domain_by_object_name(struct sss_domain_info *domain,
+ const char *object_name)
+{
+ return find_domain_by_object_name_ex(domain, object_name, false);
+}
+
errno_t sssd_domain_init(TALLOC_CTX *mem_ctx,
struct confdb_ctx *cdb,
const char *domain_name,
diff --git a/src/util/util.h b/src/util/util.h
index 37383011763a9a2a3c2c066215e3ed94aca77308..2521b1789b0b8701b1fbcce33890eedb7fe18d5e 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -551,6 +551,10 @@ struct sss_domain_info *
find_domain_by_object_name(struct sss_domain_info *domain,
const char *object_name);
+struct sss_domain_info *
+find_domain_by_object_name_ex(struct sss_domain_info *domain,
+ const char *object_name, bool strict);
+
bool subdomain_enumerates(struct sss_domain_info *parent,
const char *sd_name);
--
2.15.1

View File

@ -0,0 +1,75 @@
From 2029b7b32c868dd5ad33dcc9b078d362ee9bb602 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 20 Nov 2017 12:04:50 +0100
Subject: [PATCH 70/79] ipa: handle users from different domains in
ipa_resolve_user_list_send()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Instead of assuming that all users in the list can be found in the
provided domain with this patch the domain name part of the user name is
preferred. The provided domain name is used as a fallback.
Related to https://pagure.io/SSSD/sssd/issue/3579
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/providers/ipa/ipa_id.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c
index 5044577f0faa95b19de9233240e92aa60f029774..9a092bc837f762af8d229ff5a7eb4c4ba4b78f2f 100644
--- a/src/providers/ipa/ipa_id.c
+++ b/src/providers/ipa/ipa_id.c
@@ -63,6 +63,8 @@ struct ipa_resolve_user_list_state {
struct ipa_id_ctx *ipa_ctx;
struct ldb_message_element *users;
const char *domain_name;
+ struct sss_domain_info *domain;
+ struct sss_domain_info *user_domain;
size_t user_idx;
int dp_error;
@@ -91,6 +93,8 @@ ipa_resolve_user_list_send(TALLOC_CTX *memctx, struct tevent_context *ev,
state->ev = ev;
state->ipa_ctx = ipa_ctx;
state->domain_name = domain_name;
+ state->domain = find_domain_by_name(state->ipa_ctx->sdap_id_ctx->be->domain,
+ state->domain_name, true);
state->users = users;
state->user_idx = 0;
state->dp_error = DP_ERR_FATAL;
@@ -132,8 +136,17 @@ static errno_t ipa_resolve_user_list_get_user_step(struct tevent_req *req)
DEBUG(SSSDBG_TRACE_ALL, "Trying to resolve user [%s].\n", ar->filter_value);
- if (strcasecmp(state->domain_name,
- state->ipa_ctx->sdap_id_ctx->be->domain->name) != 0) {
+ state->user_domain = find_domain_by_object_name_ex(
+ state->ipa_ctx->sdap_id_ctx->be->domain,
+ ar->filter_value, true);
+ /* Use provided domain as as fallback is no known domain was found in the
+ * user name. */
+ if (state->user_domain == NULL) {
+ state->user_domain = state->domain;
+ }
+ ar->domain = state->user_domain->name;
+
+ if (state->user_domain != state->ipa_ctx->sdap_id_ctx->be->domain) {
subreq = ipa_subdomain_account_send(state, state->ev, state->ipa_ctx,
ar);
} else {
@@ -158,8 +171,7 @@ static void ipa_resolve_user_list_get_user_done(struct tevent_req *subreq)
struct ipa_resolve_user_list_state);
int ret;
- if (strcasecmp(state->domain_name,
- state->ipa_ctx->sdap_id_ctx->be->domain->name) != 0) {
+ if (state->user_domain != state->ipa_ctx->sdap_id_ctx->be->domain) {
ret = ipa_subdomain_account_recv(subreq, &state->dp_error);
} else {
ret = ipa_id_get_account_info_recv(subreq, &state->dp_error);
--
2.15.1

View File

@ -0,0 +1,202 @@
From 3edca52d650154bcd784674d631a76512c6c4004 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 20 Nov 2017 15:51:27 +0100
Subject: [PATCH 71/79] overrides: fixes for sysdb_invalidate_overrides()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There were two issues in sysdb_invalidate_overrides().
First, SYSDB_CACHE_EXPIRE was only reset for the entry in the data cache
but not in the timestamp cache.
Second, if one of the steps in the combined replace and delete operation
failed no change was committed to the cache. If, for whatever reasons,
a user or group object didn't had SYSDB_OVERRIDE_DN set the delete
failed and hence SYSDB_CACHE_EXPIRE wasn't reset as well. To make sure
the cache is in a consistent state after a view change the replace and
the delete operations are don in two steps.
Related to https://pagure.io/SSSD/sssd/issue/3579
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/db/sysdb_views.c | 111 +++++++++++++++++++++++++++++++++++++--------------
1 file changed, 80 insertions(+), 31 deletions(-)
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
index f640c813acf4deafe98eb15708d3a94790502dcb..bcd7dd46168aecdf808ad315175a12cef9ee03dd 100644
--- a/src/db/sysdb_views.c
+++ b/src/db/sysdb_views.c
@@ -279,6 +279,45 @@ done:
return ret;
}
+static errno_t invalidate_entry_override(struct sysdb_ctx *sysdb,
+ struct ldb_dn *dn,
+ struct ldb_message *msg_del,
+ struct ldb_message *msg_repl)
+{
+ int ret;
+
+ msg_del->dn = dn;
+ msg_repl->dn = dn;
+
+ ret = ldb_modify(sysdb->ldb, msg_del);
+ if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "ldb_modify failed: [%s](%d)[%s]\n",
+ ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb));
+ return sysdb_error_to_errno(ret);
+ }
+
+ ret = ldb_modify(sysdb->ldb, msg_repl);
+ if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "ldb_modify failed: [%s](%d)[%s]\n",
+ ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb));
+ return sysdb_error_to_errno(ret);
+ }
+
+ if (sysdb->ldb_ts != NULL) {
+ ret = ldb_modify(sysdb->ldb_ts, msg_repl);
+ if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "ldb_modify failed: [%s](%d)[%s]\n",
+ ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb_ts));
+ return sysdb_error_to_errno(ret);
+ }
+ }
+
+ return EOK;
+}
+
errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb)
{
int ret;
@@ -287,22 +326,23 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb)
bool in_transaction = false;
struct ldb_result *res;
size_t c;
- struct ldb_message *msg;
+ struct ldb_message *msg_del;
+ struct ldb_message *msg_repl;
struct ldb_dn *base_dn;
+ if (sysdb->ldb_ts == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Timestamp cache context not available, cache might not be "
+ "invalidated completely. Please call 'sss_cache -E' or remove "
+ "the cache file if there are issues after a view name change.\n");
+ }
+
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
return ENOMEM;
}
- msg = ldb_msg_new(tmp_ctx);
- if (msg == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n");
- ret = ENOMEM;
- goto done;
- }
-
base_dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE);
if (base_dn == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed\n");
@@ -310,27 +350,40 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb)
goto done;
}
- ret = ldb_msg_add_empty(msg, SYSDB_CACHE_EXPIRE, LDB_FLAG_MOD_REPLACE,
+ msg_del = ldb_msg_new(tmp_ctx);
+ if (msg_del == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = ldb_msg_add_empty(msg_del, SYSDB_OVERRIDE_DN, LDB_FLAG_MOD_DELETE,
NULL);
if (ret != LDB_SUCCESS) {
DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n");
ret = sysdb_error_to_errno(ret);
goto done;
}
- ret = ldb_msg_add_string(msg, SYSDB_CACHE_EXPIRE, "1");
+
+ msg_repl = ldb_msg_new(tmp_ctx);
+ if (msg_repl == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = ldb_msg_add_empty(msg_repl, SYSDB_CACHE_EXPIRE,
+ LDB_FLAG_MOD_REPLACE, NULL);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n");
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+ ret = ldb_msg_add_string(msg_repl, SYSDB_CACHE_EXPIRE, "1");
if (ret != LDB_SUCCESS) {
DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed.\n");
ret = sysdb_error_to_errno(ret);
goto done;
}
- ret = ldb_msg_add_empty(msg, SYSDB_OVERRIDE_DN, LDB_FLAG_MOD_DELETE, NULL);
- if (ret != LDB_SUCCESS) {
- DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n");
- ret = sysdb_error_to_errno(ret);
- goto done;
- }
-
ret = sysdb_transaction_start(sysdb);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_start failed.\n");
@@ -347,14 +400,12 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb)
}
for (c = 0; c < res->count; c++) {
- msg->dn = res->msgs[c]->dn;
-
- ret = ldb_modify(sysdb->ldb, msg);
- if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) {
+ ret = invalidate_entry_override(sysdb, res->msgs[c]->dn, msg_del,
+ msg_repl);
+ if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
- "ldb_modify failed: [%s](%d)[%s]\n",
- ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb));
- ret = sysdb_error_to_errno(ret);
+ "invalidate_entry_override failed [%d][%s].\n",
+ ret, sss_strerror(ret));
goto done;
}
}
@@ -370,14 +421,12 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb)
}
for (c = 0; c < res->count; c++) {
- msg->dn = res->msgs[c]->dn;
-
- ret = ldb_modify(sysdb->ldb, msg);
- if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) {
+ ret = invalidate_entry_override(sysdb, res->msgs[c]->dn, msg_del,
+ msg_repl);
+ if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
- "ldb_modify failed: [%s](%d)[%s]\n",
- ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb));
- ret = sysdb_error_to_errno(ret);
+ "invalidate_entry_override failed [%d][%s].\n",
+ ret, sss_strerror(ret));
goto done;
}
}
--
2.15.1

View File

@ -0,0 +1,253 @@
From afa3e5d8401c529dad9fb6f2e3a3f4c2aa79a977 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 20 Nov 2017 16:12:58 +0100
Subject: [PATCH 72/79] ipa: check for SYSDB_OVERRIDE_DN in process_members and
get_group_dn_list
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
process_members() and get_group_dn_list() are used on an IPA client to
determine a list of users or groups which are missing in the cache and
are needed to properly add a group or user object to the cache
respectively.
If a non-default view is assigned to the client the SYSDB_OVERRIDE_DN
must be set for all user and group objects to indicate that it was
already checked if there is an id-override defined for the object or
not. There a circumstances were SYSDB_OVERRIDE_DN is not set, e.g. after
a view name change. To make sure the cache is in a consistent state with
this patch user and group entries without SYSDB_OVERRIDE_DN are
considered as missing is a non-default view is assigned to the client.
Related to https://pagure.io/SSSD/sssd/issue/3579
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/providers/ipa/ipa_s2n_exop.c | 145 ++++++++++++++++++++++-----------------
1 file changed, 83 insertions(+), 62 deletions(-)
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
index 39ed17cbf0e8c523212084197e9f2963fed88dc8..c6132f509dcc8e7af84e03e8bfe20701107d1392 100644
--- a/src/providers/ipa/ipa_s2n_exop.c
+++ b/src/providers/ipa/ipa_s2n_exop.c
@@ -1523,6 +1523,7 @@ fail:
}
static errno_t process_members(struct sss_domain_info *domain,
+ bool is_default_view,
struct sysdb_attrs *group_attrs,
char **members,
TALLOC_CTX *mem_ctx, char ***_missing_members)
@@ -1536,6 +1537,7 @@ static errno_t process_members(struct sss_domain_info *domain,
struct sss_domain_info *parent_domain;
char **missing_members = NULL;
size_t miss_count = 0;
+ const char *attrs[] = {SYSDB_NAME, SYSDB_OVERRIDE_DN, NULL};
if (members == NULL) {
DEBUG(SSSDBG_TRACE_INTERNAL, "No members\n");
@@ -1572,53 +1574,59 @@ static errno_t process_members(struct sss_domain_info *domain,
goto done;
}
- ret = sysdb_search_user_by_name(tmp_ctx, obj_domain, members[c], NULL,
+ ret = sysdb_search_user_by_name(tmp_ctx, obj_domain, members[c], attrs,
&msg);
- if (ret == EOK) {
- if (group_attrs != NULL) {
- dn_str = ldb_dn_get_linearized(msg->dn);
- if (dn_str == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_get_linearized failed.\n");
- ret = EINVAL;
- goto done;
- }
-
- DEBUG(SSSDBG_TRACE_ALL, "Adding member [%s][%s]\n",
- members[c], dn_str);
+ if (ret == EOK || ret == ENOENT) {
+ if (ret == ENOENT
+ || (!is_default_view
+ && ldb_msg_find_attr_as_string(msg, SYSDB_OVERRIDE_DN,
+ NULL) == NULL)) {
+ /* only add ghost if the member is really missing */
+ if (group_attrs != NULL && ret == ENOENT) {
+ DEBUG(SSSDBG_TRACE_ALL, "Adding ghost member [%s]\n",
+ members[c]);
- ret = sysdb_attrs_add_string_safe(group_attrs, SYSDB_MEMBER,
- dn_str);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "sysdb_attrs_add_string_safe failed.\n");
- goto done;
+ /* There were cases where the server returned the same user
+ * multiple times */
+ ret = sysdb_attrs_add_string_safe(group_attrs, SYSDB_GHOST,
+ members[c]);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_attrs_add_string failed.\n");
+ goto done;
+ }
}
- }
- } else if (ret == ENOENT) {
- if (group_attrs != NULL) {
- DEBUG(SSSDBG_TRACE_ALL, "Adding ghost member [%s]\n",
- members[c]);
- /* There were cases where the server returned the same user
- * multiple times */
- ret = sysdb_attrs_add_string_safe(group_attrs, SYSDB_GHOST,
- members[c]);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "sysdb_attrs_add_string failed.\n");
- goto done;
+ if (missing_members != NULL) {
+ missing_members[miss_count] = talloc_strdup(missing_members,
+ members[c]);
+ if (missing_members[miss_count] == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ miss_count++;
}
- }
+ } else {
+ if (group_attrs != NULL) {
+ dn_str = ldb_dn_get_linearized(msg->dn);
+ if (dn_str == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_get_linearized failed.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_ALL, "Adding member [%s][%s]\n",
+ members[c], dn_str);
- if (missing_members != NULL) {
- missing_members[miss_count] = talloc_strdup(missing_members,
- members[c]);
- if (missing_members[miss_count] == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
- ret = ENOMEM;
- goto done;
+ ret = sysdb_attrs_add_string_safe(group_attrs, SYSDB_MEMBER,
+ dn_str);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sysdb_attrs_add_string_safe failed.\n");
+ goto done;
+ }
}
- miss_count++;
}
} else {
DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_name failed.\n");
@@ -1649,6 +1657,7 @@ done:
}
static errno_t get_group_dn_list(TALLOC_CTX *mem_ctx,
+ bool is_default_view,
struct sss_domain_info *dom,
size_t ngroups, char **groups,
struct ldb_dn ***_dn_list,
@@ -1664,6 +1673,7 @@ static errno_t get_group_dn_list(TALLOC_CTX *mem_ctx,
size_t n_missing = 0;
struct sss_domain_info *obj_domain;
struct sss_domain_info *parent_domain;
+ const char *attrs[] = {SYSDB_NAME, SYSDB_OVERRIDE_DN, NULL};
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
@@ -1689,25 +1699,31 @@ static errno_t get_group_dn_list(TALLOC_CTX *mem_ctx,
goto done;
}
- ret = sysdb_search_group_by_name(tmp_ctx, obj_domain, groups[c], NULL,
+ ret = sysdb_search_group_by_name(tmp_ctx, obj_domain, groups[c], attrs,
&msg);
- if (ret == EOK) {
- dn_list[n_dns] = ldb_dn_copy(dn_list, msg->dn);
- if (dn_list[n_dns] == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_copy failed.\n");
- ret = ENOMEM;
- goto done;
+ if (ret == EOK || ret == ENOENT) {
+ if (ret == ENOENT
+ || (!is_default_view
+ && ldb_msg_find_attr_as_string(msg, SYSDB_OVERRIDE_DN,
+ NULL) == NULL)) {
+ missing_groups[n_missing] = talloc_strdup(missing_groups,
+ groups[c]);
+ if (missing_groups[n_missing] == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ n_missing++;
+
+ } else {
+ dn_list[n_dns] = ldb_dn_copy(dn_list, msg->dn);
+ if (dn_list[n_dns] == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_copy failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ n_dns++;
}
- n_dns++;
- } else if (ret == ENOENT) {
- missing_groups[n_missing] = talloc_strdup(missing_groups,
- groups[c]);
- if (missing_groups[n_missing] == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
- ret = ENOMEM;
- goto done;
- }
- n_missing++;
} else {
DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_group_by_name failed.\n");
goto done;
@@ -1803,7 +1819,9 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq)
}
- ret = get_group_dn_list(state, state->dom,
+ ret = get_group_dn_list(state,
+ is_default_view(state->ipa_ctx->view_name),
+ state->dom,
attrs->ngroups, attrs->groups,
&group_dn_list, &missing_list);
if (ret != EOK) {
@@ -1832,8 +1850,10 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq)
}
break;
} else if (attrs->response_type == RESP_GROUP_MEMBERS) {
- ret = process_members(state->dom, NULL, attrs->a.group.gr_mem,
- state, &missing_list);
+ ret = process_members(state->dom,
+ is_default_view(state->ipa_ctx->view_name),
+ NULL, attrs->a.group.gr_mem, state,
+ &missing_list);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "process_members failed.\n");
goto done;
@@ -2572,8 +2592,9 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
}
}
- ret = process_members(dom, attrs->sysdb_attrs,
- attrs->a.group.gr_mem, NULL, NULL);
+ ret = process_members(dom, is_default_view(view_name),
+ attrs->sysdb_attrs, attrs->a.group.gr_mem,
+ NULL, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "process_members failed.\n");
goto done;
--
2.15.1

View File

@ -0,0 +1,69 @@
From d1d62630e1d1c6a88fe4bf8612cb4f9a2fff7181 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 20 Nov 2017 16:41:29 +0100
Subject: [PATCH 73/79] IPA: use cache searches in get_groups_dns()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the group name is overridden in the default view we have to search
for the name and cannot construct it because the extdom plugin will
return the overridden name but the DN of the related group object in the
cache will contain the original name.
Related to https://pagure.io/SSSD/sssd/issue/3579
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/providers/ipa/ipa_s2n_exop.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
index c6132f509dcc8e7af84e03e8bfe20701107d1392..49c393e9a1eb19ab683949cf633a6838274bc0fe 100644
--- a/src/providers/ipa/ipa_s2n_exop.c
+++ b/src/providers/ipa/ipa_s2n_exop.c
@@ -2038,6 +2038,7 @@ static errno_t get_groups_dns(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom,
int c;
struct sss_domain_info *root_domain;
char **dn_list;
+ struct ldb_message *msg;
if (name_list == NULL) {
*_dn_list = NULL;
@@ -2082,15 +2083,25 @@ static errno_t get_groups_dns(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom,
goto done;
}
- /* This might fail if some unexpected cases are used. But current
- * sysdb code which handles group membership constructs DNs this way
- * as well, IPA names are lowercased and AD names by default will be
- * lowercased as well. If there are really use-cases which cause an
- * issue here, sysdb_group_strdn() has to be replaced by a proper
- * search. */
- dn_list[c] = sysdb_group_strdn(dn_list, dom->name, name_list[c]);
+ /* If the group name is overridden in the default view we have to
+ * search for the name and cannot construct it because the extdom
+ * plugin will return the overridden name but the DN of the related
+ * group object in the cache will contain the original name. */
+
+ ret = sysdb_search_group_by_name(tmp_ctx, dom, name_list[c], NULL,
+ &msg);
+ if (ret == EOK) {
+ dn_list[c] = ldb_dn_alloc_linearized(dn_list, msg->dn);
+ } else {
+ /* best effort, try to construct the DN */
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "sysdb_search_group_by_name failed with [%d], "
+ "generating DN for [%s] in domain [%s].\n",
+ ret, name_list[c], dom->name);
+ dn_list[c] = sysdb_group_strdn(dn_list, dom->name, name_list[c]);
+ }
if (dn_list[c] == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_group_strdn failed.\n");
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_alloc_linearized failed.\n");
ret = ENOMEM;
goto done;
}
--
2.15.1

View File

@ -0,0 +1,85 @@
From 97becd502f5d8aa74b94eee78a949825222b6933 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 20 Nov 2017 16:45:45 +0100
Subject: [PATCH 74/79] ipa: compare DNs instead of group names in
ipa_s2n_save_objects()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If group names are used to compare the current list of group memberships
returned by the server with the one from the cache some groups might end
up in the wrong result list if group names are overridden. This
ambiguity can be resolved by using the DNs of the cached objects.
Related to https://pagure.io/SSSD/sssd/issue/3579
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
---
src/providers/ipa/ipa_s2n_exop.c | 31 ++++++++++++-------------------
1 file changed, 12 insertions(+), 19 deletions(-)
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
index 49c393e9a1eb19ab683949cf633a6838274bc0fe..8b97f78620f19b0708e8a480cb72fd7f12d96dfb 100644
--- a/src/providers/ipa/ipa_s2n_exop.c
+++ b/src/providers/ipa/ipa_s2n_exop.c
@@ -2185,10 +2185,9 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
struct ldb_result *res;
enum sysdb_member_type type;
char **sysdb_grouplist;
- char **add_groups;
char **add_groups_dns;
- char **del_groups;
char **del_groups_dns;
+ char **groups_dns;
bool in_transaction = false;
int tret;
struct sysdb_attrs *gid_override_attrs = NULL;
@@ -2514,33 +2513,27 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
}
if (attrs->response_type == RESP_USER_GROUPLIST) {
- ret = get_sysdb_grouplist(tmp_ctx, dom->sysdb, dom, name,
- &sysdb_grouplist);
+ ret = get_sysdb_grouplist_dn(tmp_ctx, dom->sysdb, dom, name,
+ &sysdb_grouplist);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "get_sysdb_grouplist failed.\n");
goto done;
}
- ret = diff_string_lists(tmp_ctx, attrs->groups,
- sysdb_grouplist, &add_groups,
- &del_groups, NULL);
+ ret = get_groups_dns(tmp_ctx, dom, attrs->groups, &groups_dns);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "get_groups_dns failed.\n");
+ goto done;
+ }
+
+ ret = diff_string_lists(tmp_ctx, groups_dns,
+ sysdb_grouplist, &add_groups_dns,
+ &del_groups_dns, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "diff_string_lists failed.\n");
goto done;
}
- ret = get_groups_dns(tmp_ctx, dom, add_groups, &add_groups_dns);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "get_groups_dns failed.\n");
- goto done;
- }
-
- ret = get_groups_dns(tmp_ctx, dom, del_groups, &del_groups_dns);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "get_groups_dns failed.\n");
- goto done;
- }
-
DEBUG(SSSDBG_TRACE_INTERNAL, "Updating memberships for %s\n",
name);
ret = sysdb_update_members_dn(dom, name, SYSDB_MEMBER_USER,
--
2.15.1

View File

@ -0,0 +1,150 @@
From fd0fb14e613f15a7d1fbde86bf371a72d8dfe3b8 Mon Sep 17 00:00:00 2001
From: Carlos O'Donell <carlos@systemhalted.org>
Date: Wed, 29 Nov 2017 22:36:39 -0800
Subject: [PATCH 75/79] nss: Fix invalid enum nss_status return values.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The upstream glibc test nss/bug17079 covers several cases where the
NSS infrastructure passes invalid pointers to NSS plugins. The plugins
should return correct results for the invalid values e.g. ERANGE,
but it should do so by setting *errnop to the error and returning
NSS_STATUS_TRYAGAIN. This commit fixes the group, netgroup, passwd
and service handling code to correctly return ERANGE in *errnop
and NSS_TATUS_TRYAGAIN in the case of invalid buffer (NULL) or
zero sized buffer length. This fixes the nss/bug17079 regression test
when run in a test configuration with sss enabled for any of the
above mentioned services.
Upstream glibc bug:
Bug 22530 - FAIL: nss/bug17079 due to _nss_sss_getpwuid_r
https://sourceware.org/bugzilla/show_bug.cgi?id=22530
Merges: https://pagure.io/SSSD/sssd/pull-request/3561
Signed-off-by: Carlos O'Donell <carlos@redhat.com>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
---
src/sss_client/nss_group.c | 10 ++++++++--
src/sss_client/nss_netgroup.c | 5 ++++-
src/sss_client/nss_passwd.c | 10 ++++++++--
src/sss_client/nss_services.c | 15 ++++++++++++---
4 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/src/sss_client/nss_group.c b/src/sss_client/nss_group.c
index 42fba6242d23fc1d52cfd7be10cf10383010f091..054f30e13f8d5f8300a3e63c9035b98d30473c0e 100644
--- a/src/sss_client/nss_group.c
+++ b/src/sss_client/nss_group.c
@@ -522,7 +522,10 @@ enum nss_status _nss_sss_getgrgid_r(gid_t gid, struct group *result,
int ret;
/* Caught once glibc passing in buffer == 0x0 */
- if (!buffer || !buflen) return ERANGE;
+ if (!buffer || !buflen) {
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+ }
ret = sss_nss_mc_getgrgid(gid, result, buffer, buflen);
switch (ret) {
@@ -655,7 +658,10 @@ static enum nss_status internal_getgrent_r(struct group *result,
int ret;
/* Caught once glibc passing in buffer == 0x0 */
- if (!buffer || !buflen) return ERANGE;
+ if (!buffer || !buflen) {
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+ }
/* if there are leftovers return the next one */
if (sss_nss_getgrent_data.data != NULL &&
diff --git a/src/sss_client/nss_netgroup.c b/src/sss_client/nss_netgroup.c
index 8594fc460514d6f92e786605168fa7d15c7ee913..3a1834a311e6658c6160b5f95a01434fed69ad1c 100644
--- a/src/sss_client/nss_netgroup.c
+++ b/src/sss_client/nss_netgroup.c
@@ -231,7 +231,10 @@ static enum nss_status internal_getnetgrent_r(struct __netgrent *result,
int ret;
/* Caught once glibc passing in buffer == 0x0 */
- if (!buffer || !buflen) return ERANGE;
+ if (!buffer || !buflen) {
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+ }
/* If we're already processing result data, continue to
* return it.
diff --git a/src/sss_client/nss_passwd.c b/src/sss_client/nss_passwd.c
index 61e2a567e684fbc7664b5d425e81cfa28a98e845..5b1c2ce66b0954bc304dfb458f509defa8eed889 100644
--- a/src/sss_client/nss_passwd.c
+++ b/src/sss_client/nss_passwd.c
@@ -251,7 +251,10 @@ enum nss_status _nss_sss_getpwuid_r(uid_t uid, struct passwd *result,
int ret;
/* Caught once glibc passing in buffer == 0x0 */
- if (!buffer || !buflen) return ERANGE;
+ if (!buffer || !buflen) {
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+ }
ret = sss_nss_mc_getpwuid(uid, result, buffer, buflen);
switch (ret) {
@@ -376,7 +379,10 @@ static enum nss_status internal_getpwent_r(struct passwd *result,
int ret;
/* Caught once glibc passing in buffer == 0x0 */
- if (!buffer || !buflen) return ERANGE;
+ if (!buffer || !buflen) {
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+ }
/* if there are leftovers return the next one */
if (sss_nss_getpwent_data.data != NULL &&
diff --git a/src/sss_client/nss_services.c b/src/sss_client/nss_services.c
index 64e0b43e1643e4e76d2381a6b062335c3d513a21..161dad9ae27f822b40af8368e5af38b020d6549a 100644
--- a/src/sss_client/nss_services.c
+++ b/src/sss_client/nss_services.c
@@ -177,7 +177,10 @@ _nss_sss_getservbyname_r(const char *name,
int ret;
/* Caught once glibc passing in buffer == 0x0 */
- if (!buffer || !buflen) return ERANGE;
+ if (!buffer || !buflen) {
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+ }
ret = sss_strnlen(name, SSS_NAME_MAX, &name_len);
if (ret != 0) {
@@ -278,7 +281,10 @@ _nss_sss_getservbyport_r(int port, const char *protocol,
int ret;
/* Caught once glibc passing in buffer == 0x0 */
- if (!buffer || !buflen) return ERANGE;
+ if (!buffer || !buflen) {
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+ }
if (protocol) {
ret = sss_strnlen(protocol, SSS_NAME_MAX, &proto_len);
@@ -411,7 +417,10 @@ static enum nss_status internal_getservent_r(struct servent *result,
int ret;
/* Caught once glibc passing in buffer == 0x0 */
- if (!buffer || !buflen) return ERANGE;
+ if (!buffer || !buflen) {
+ *errnop = ERANGE;
+ return NSS_STATUS_TRYAGAIN;
+ }
/* if there are leftovers return the next one */
if (sss_nss_getservent_data.data != NULL &&
--
2.15.1

View File

@ -0,0 +1,110 @@
From 5af7dcbba7a54c9a017a7d317f74453254125eb7 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 29 Nov 2017 17:57:56 +0100
Subject: [PATCH 76/79] confdb: Move detection files to separate function
---
src/confdb/confdb.c | 73 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 41 insertions(+), 32 deletions(-)
diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index a028224817f12ace2a0c4165d7b9cb0bb80ce5a1..c41bd5087592ba15d8956e0279aaf72ba86936ed 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -1718,52 +1718,61 @@ done:
return ret;
}
-static int confdb_has_files_domain(struct confdb_ctx *cdb)
+static bool need_implicit_files_domain(TALLOC_CTX *tmp_ctx,
+ struct ldb_result *doms)
{
- TALLOC_CTX *tmp_ctx = NULL;
- struct ldb_dn *dn = NULL;
- struct ldb_result *res = NULL;
- static const char *attrs[] = { CONFDB_DOMAIN_ID_PROVIDER, NULL };
const char *id_provider = NULL;
- int ret;
unsigned int i;
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- return ENOMEM;
- }
-
- dn = ldb_dn_new(tmp_ctx, cdb->ldb, CONFDB_DOMAIN_BASEDN);
- if (dn == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_ONELEVEL,
- attrs, NULL);
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- goto done;
- }
-
- for (i = 0; i < res->count; i++) {
- id_provider = ldb_msg_find_attr_as_string(res->msgs[i],
+ for (i = 0; i < doms->count; i++) {
+ id_provider = ldb_msg_find_attr_as_string(doms->msgs[i],
CONFDB_DOMAIN_ID_PROVIDER,
NULL);
if (id_provider == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE,
+ DEBUG(SSSDBG_OP_FAILURE,
"The object [%s] doesn't have a id_provider\n",
- ldb_dn_get_linearized(res->msgs[i]->dn));
- ret = EINVAL;
- goto done;
+ ldb_dn_get_linearized(doms->msgs[i]->dn));
+ continue;
}
if (strcasecmp(id_provider, "files") == 0) {
- break;
+ return false;
}
}
- ret = i < res->count ? EOK : ENOENT;
+ return true;
+}
+
+static int confdb_has_files_domain(struct confdb_ctx *cdb)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ struct ldb_dn *dn = NULL;
+ struct ldb_result *res = NULL;
+ static const char *attrs[] = { CONFDB_DOMAIN_ID_PROVIDER, NULL };
+ int ret;
+ bool need_files_dom;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ dn = ldb_dn_new(tmp_ctx, cdb->ldb, CONFDB_DOMAIN_BASEDN);
+ if (dn == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_ONELEVEL,
+ attrs, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = EIO;
+ goto done;
+ }
+
+ need_files_dom = need_implicit_files_domain(tmp_ctx, res);
+
+ ret = need_files_dom ? ENOENT : EOK;
done:
talloc_free(tmp_ctx);
return ret;
--
2.15.1

View File

@ -0,0 +1,96 @@
From 57720f0d0945262a13d9ab7d1ec8220837ab618f Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 29 Nov 2017 20:02:35 +0100
Subject: [PATCH 77/79] confdb: Fix starting of implicit files domain
We did not start implicit_files domain when sssd configuration
contains files domain which was disabled.
---
src/confdb/confdb.c | 36 +++++++++++++++++++++++++++++++++--
src/tests/intg/test_files_provider.py | 3 +++
2 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index c41bd5087592ba15d8956e0279aaf72ba86936ed..ef1be4a6e6daee2644d535e561fac7735eb6a0b2 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -1719,12 +1719,43 @@ done:
}
static bool need_implicit_files_domain(TALLOC_CTX *tmp_ctx,
+ struct confdb_ctx *cdb,
struct ldb_result *doms)
{
const char *id_provider = NULL;
unsigned int i;
+ errno_t ret;
+ char **domlist;
+ const char *val;
+
+ ret = confdb_get_string_as_list(cdb, tmp_ctx,
+ CONFDB_MONITOR_CONF_ENTRY,
+ CONFDB_MONITOR_ACTIVE_DOMAINS,
+ &domlist);
+ if (ret == ENOENT) {
+ return true;
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot get active domains %d[%s]\n",
+ ret, sss_strerror(ret));
+ return false;
+ }
for (i = 0; i < doms->count; i++) {
+ val = ldb_msg_find_attr_as_string(doms->msgs[i], CONFDB_DOMAIN_ATTR,
+ NULL);
+ if (val == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "The object [%s] doesn't have a name\n",
+ ldb_dn_get_linearized(doms->msgs[i]->dn));
+ continue;
+ }
+
+ /* skip disabled domain */
+ if (!string_in_list(val, domlist, false)) {
+ continue;
+ }
+
id_provider = ldb_msg_find_attr_as_string(doms->msgs[i],
CONFDB_DOMAIN_ID_PROVIDER,
NULL);
@@ -1748,7 +1779,8 @@ static int confdb_has_files_domain(struct confdb_ctx *cdb)
TALLOC_CTX *tmp_ctx = NULL;
struct ldb_dn *dn = NULL;
struct ldb_result *res = NULL;
- static const char *attrs[] = { CONFDB_DOMAIN_ID_PROVIDER, NULL };
+ static const char *attrs[] = { CONFDB_DOMAIN_ID_PROVIDER,
+ CONFDB_DOMAIN_ATTR, NULL };
int ret;
bool need_files_dom;
@@ -1770,7 +1802,7 @@ static int confdb_has_files_domain(struct confdb_ctx *cdb)
goto done;
}
- need_files_dom = need_implicit_files_domain(tmp_ctx, res);
+ need_files_dom = need_implicit_files_domain(tmp_ctx, cdb, res);
ret = need_files_dom ? ENOENT : EOK;
done:
diff --git a/src/tests/intg/test_files_provider.py b/src/tests/intg/test_files_provider.py
index e507ea10d78b9b35ee57178e78f4621372d0c2e5..169da713767b6495e117d805b29d8d6346237ebc 100644
--- a/src/tests/intg/test_files_provider.py
+++ b/src/tests/intg/test_files_provider.py
@@ -167,6 +167,9 @@ def no_files_domain(request):
[domain/local]
id_provider = local
+
+ [domain/disabled.files]
+ id_provider = files
""").format(**locals())
create_conf_fixture(request, conf)
create_sssd_fixture(request)
--
2.15.1

View File

@ -0,0 +1,59 @@
From 8cf5e390b38f0be4f88b0ebbbd1b14f52d35cd02 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Thu, 30 Nov 2017 07:59:33 +0100
Subject: [PATCH 78/79] confdb: Do not start implicit_files with proxy domain
id_provider = proxy + proxy_lib_name = files is equivalent
to id_provider = files. But requests to user hit implicit_files
domain instead of proxy domain and therefore it broke usage
of proxy domain with auth_provider = krb5.
Resolves:
https://pagure.io/SSSD/sssd/issue/3590
---
src/confdb/confdb.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index ef1be4a6e6daee2644d535e561fac7735eb6a0b2..0a4be57e08791f8a9eb5fc143a56352cd4ef4b5e 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -1769,6 +1769,25 @@ static bool need_implicit_files_domain(TALLOC_CTX *tmp_ctx,
if (strcasecmp(id_provider, "files") == 0) {
return false;
}
+
+ if (strcasecmp(id_provider, "proxy") == 0) {
+ val = ldb_msg_find_attr_as_string(doms->msgs[i],
+ CONFDB_PROXY_LIBNAME, NULL);
+ if (val == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "The object [%s] doesn't have proxy_lib_name with "
+ "id_provider proxy\n",
+ ldb_dn_get_linearized(doms->msgs[i]->dn));
+ continue;
+ }
+
+ /* id_provider = proxy + proxy_lib_name = files is equivalent
+ * to id_provider = files
+ */
+ if (strcmp(val, "files") == 0) {
+ return false;
+ }
+ }
}
return true;
@@ -1780,7 +1799,8 @@ static int confdb_has_files_domain(struct confdb_ctx *cdb)
struct ldb_dn *dn = NULL;
struct ldb_result *res = NULL;
static const char *attrs[] = { CONFDB_DOMAIN_ID_PROVIDER,
- CONFDB_DOMAIN_ATTR, NULL };
+ CONFDB_DOMAIN_ATTR,
+ CONFDB_PROXY_LIBNAME, NULL };
int ret;
bool need_files_dom;
--
2.15.1

View File

@ -0,0 +1,73 @@
From f9518dce861a1fe9a3a5c5c63ac45f67fdbc5e68 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Thu, 30 Nov 2017 10:21:17 +0100
Subject: [PATCH 79/79] test_files_provider: Regression test for implicit_files
+ proxy
Related to:
https://pagure.io/SSSD/sssd/issue/3590
---
src/tests/intg/test_files_provider.py | 40 +++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/src/tests/intg/test_files_provider.py b/src/tests/intg/test_files_provider.py
index 169da713767b6495e117d805b29d8d6346237ebc..ea4e5b70a3626cb43217b59488cf186e3325ae8d 100644
--- a/src/tests/intg/test_files_provider.py
+++ b/src/tests/intg/test_files_provider.py
@@ -145,6 +145,26 @@ def files_domain_only(request):
return None
+@pytest.fixture
+def proxy_to_files_domain_only(request):
+ conf = unindent("""\
+ [sssd]
+ domains = proxy, local
+ services = nss
+
+ [domain/local]
+ id_provider = local
+
+ [domain/proxy]
+ id_provider = proxy
+ proxy_lib_name = files
+ auth_provider = none
+ """).format(**locals())
+ create_conf_fixture(request, conf)
+ create_sssd_fixture(request)
+ return None
+
+
@pytest.fixture
def no_sssd_domain(request):
conf = unindent("""\
@@ -980,6 +1000,26 @@ def test_no_sssd_domain(add_user_with_canary, no_sssd_domain):
assert user == USER1
+def test_proxy_to_files_domain_only(add_user_with_canary,
+ proxy_to_files_domain_only):
+ """
+ Test that implicit_files domain is not started together with proxy to files
+ """
+ local_user1 = dict(name='user1', passwd='*', uid=10009, gid=10009,
+ gecos='user1', dir='/home/user1', shell='/bin/bash')
+
+ # Add a user with a different UID than the one in files
+ subprocess.check_call(
+ ["sss_useradd", "-u", "10009", "-M", USER1["name"]])
+
+ res, user = call_sssd_getpwnam(USER1["name"])
+ assert res == NssReturnCode.SUCCESS
+ assert user == local_user1
+
+ res, _ = call_sssd_getpwnam("{0}@implicit_files".format(USER1["name"]))
+ assert res == NssReturnCode.NOTFOUND
+
+
def test_no_files_domain(add_user_with_canary, no_files_domain):
"""
Test that if no files domain is configured, sssd will add the implicit one
--
2.15.1

View File

@ -1,4 +1,4 @@
From 5381ad1bd7693a6681f00bef093241f13e3a2c4f Mon Sep 17 00:00:00 2001
From 565ef3ffcaaef69a768b6a341777c339217bbbab Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@fedoraproject.org>
Date: Mon, 12 Dec 2016 21:56:16 +0100
Subject: [PATCH] SYSTEMD: Use capabilities
@ -9,17 +9,17 @@ copied from selinux policy
1 file changed, 1 insertion(+)
diff --git a/src/sysv/systemd/sssd.service.in b/src/sysv/systemd/sssd.service.in
index 05cfd3705084dbff8b46fb07e736612612c58b70..e7bbbdb5093f52e4b71e3c85a9082192013385e8 100644
index 0c515d34caaa3ea397c4c7e95eef0188df170840..252889dbb2b7b1e651966258e7b76eab38357e76 100644
--- a/src/sysv/systemd/sssd.service.in
+++ b/src/sysv/systemd/sssd.service.in
@@ -9,6 +9,7 @@ EnvironmentFile=-@environment_file@
ExecStart=@sbindir@/sssd -i -f
@@ -11,6 +11,7 @@ ExecStart=@sbindir@/sssd -i ${DEBUG_LOGGER}
Type=notify
NotifyAccess=main
PIDFile=@localstatedir@/run/sssd.pid
+CapabilityBoundingSet=CAP_IPC_LOCK CAP_CHOWN CAP_DAC_READ_SEARCH CAP_KILL CAP_NET_ADMIN CAP_SYS_NICE CAP_FOWNER CAP_SETGID CAP_SETUID CAP_SYS_ADMIN CAP_SYS_RESOURCE CAP_BLOCK_SUSPEND
[Install]
WantedBy=multi-user.target
--
2.11.0
2.15.1

116
sssd.spec
View File

@ -20,6 +20,8 @@
%global with_kcm 1
%global with_gdm_pam_extensions 1
%global libwbc_alternatives_version 0.14
%global libwbc_lib_version %{libwbc_alternatives_version}.0
%global libwbc_alternatives_suffix %nil
@ -29,7 +31,7 @@
Name: sssd
Version: 1.16.0
Release: 4%{?dist}
Release: 5%{?dist}
Group: Applications/System
Summary: System Security Services Daemon
License: GPLv3+
@ -38,19 +40,84 @@ Source0: https://releases.pagure.org/SSSD/sssd/%{name}-%{version}.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
### Patches ###
Patch0001: 0001-KCM-Fix-restart-during-after-upgrade.patch
Patch0002: 0002-sss_client-create-nss_common.h.patch
Patch0003: 0003-nss-idmap-add-nss-like-calls-with-timeout-and-flags.patch
Patch0004: 0004-NSS-add-_EX-version-of-some-requests.patch
Patch0005: 0005-NSS-add-support-for-SSS_NSS_EX_FLAG_NO_CACHE.patch
Patch0006: 0006-CACHE_REQ-Add-cache_req_data_set_bypass_dp.patch
Patch0007: 0007-nss-make-memcache_delete_entry-public.patch
Patch0008: 0008-NSS-add-support-for-SSS_NSS_EX_FLAG_INVALIDATE_CACHE.patch
Patch0009: 0009-NSS-TESTS-add-unit-tests-for-_EX-requests.patch
Patch0010: 0010-nss-idmap-add-timeout-version-of-old-sss_nss_-calls.patch
Patch0011: 0011-nss-idmap-allow-empty-buffer-with-SSS_NSS_EX_FLAG_IN.patch
Patch0012: 0012-TESTS-Order-list-of-entries-in-some-lists.patch
Patch0013: 0013-CACHE_REQ-Copy-the-cr_domain-list-for-each-request.patch
Patch0001: 0001-KCM-Fix-typo-in-comments.patch
Patch0002: 0002-Fix-minor-spelling-mistakes.patch
Patch0003: 0003-CONFIG-Add-a-new-option-auto_private_groups.patch
Patch0004: 0004-CONFDB-Remove-the-obsolete-option-magic_private_grou.patch
Patch0005: 0005-SDAP-Allow-the-mpg-flag-for-the-main-domain.patch
Patch0006: 0006-LDAP-Turn-group-request-into-user-request-for-MPG-do.patch
Patch0007: 0007-SYSDB-Prevent-users-and-groups-ID-collision-in-MPG-d.patch
Patch0008: 0008-TESTS-Add-integration-tests-for-the-auto_private_gro.patch
Patch0009: 0009-CACHE_REQ-Copy-the-cr_domain-list-for-each-request.patch
Patch0010: 0010-sudo-document-background-activity.patch
Patch0011: 0011-MAN-GPO-Security-Filtering-limitation.patch
Patch0012: 0012-CI-Ignore-source-file-generated-by-systemtap.patch
Patch0013: 0013-sudo-always-use-srv_opts-from-id-context.patch
Patch0014: 0014-AD-Remember-last-site-discovered.patch
Patch0015: 0015-sysdb-add-functions-to-get-set-client-site.patch
Patch0016: 0016-AD-Remember-last-site-discovered-in-sysdb.patch
Patch0017: 0017-UTIL-Add-wrapper-function-to-configure-logger.patch
Patch0018: 0018-Add-parameter-logger-to-daemons.patch
Patch0019: 0019-SYSTEMD-Replace-parameter-debug-to-files-with-DEBUG_.patch
Patch0020: 0020-SYSTEMD-Add-environment-file-to-responder-service-fi.patch
Patch0021: 0021-UTIL-Hide-and-deprecate-parameter-debug-to-files.patch
Patch0023: 0023-LDAP-Bind-to-the-LDAP-server-also-in-the-auth.patch
Patch0024: 0024-KCM-Fix-restart-during-after-upgrade.patch
Patch0025: 0025-sss_client-create-nss_common.h.patch
Patch0026: 0026-nss-idmap-add-nss-like-calls-with-timeout-and-flags.patch
Patch0027: 0027-NSS-add-_EX-version-of-some-requests.patch
Patch0028: 0028-NSS-add-support-for-SSS_NSS_EX_FLAG_NO_CACHE.patch
Patch0029: 0029-CACHE_REQ-Add-cache_req_data_set_bypass_dp.patch
Patch0030: 0030-nss-make-memcache_delete_entry-public.patch
Patch0031: 0031-NSS-add-support-for-SSS_NSS_EX_FLAG_INVALIDATE_CACHE.patch
Patch0032: 0032-NSS-TESTS-add-unit-tests-for-_EX-requests.patch
Patch0033: 0033-nss-idmap-add-timeout-version-of-old-sss_nss_-calls.patch
Patch0034: 0034-nss-idmap-allow-empty-buffer-with-SSS_NSS_EX_FLAG_IN.patch
Patch0035: 0035-RESP-Add-some-missing-NULL-checks.patch
Patch0036: 0036-BUILD-Properly-expand-variables-in-sssd-ifp.service.patch
Patch0037: 0037-SYSTEMD-Clean-pid-file-in-corner-cases.patch
Patch0038: 0038-CHILD-Pass-information-about-logger-to-children.patch
Patch0039: 0039-TOOLS-Double-quote-array-expansions-in-sss_debugleve.patch
Patch0040: 0040-TOOLS-Call-exec-for-sss_debuglevel.patch
Patch0041: 0041-LDAP-Improve-error-treatment-from-sdap_cli_connect-i.patch
Patch0042: 0042-p11_child-return-multiple-certs.patch
Patch0043: 0043-PAM-handled-multiple-certs-in-the-responder.patch
Patch0044: 0044-pam_sss-refactoring-use-struct-cert_auth_info.patch
Patch0045: 0045-p11_child-use-options-to-select-certificate-for-auth.patch
Patch0046: 0046-pam-add-prompt-string-for-certificate-authentication.patch
Patch0047: 0047-PAM-allow-missing-logon_name-during-certificate-auth.patch
Patch0048: 0048-p11_child-add-descriptions-for-error-codes-to-debug-.patch
Patch0049: 0049-pam-filter-certificates-in-the-responder-not-in-the-.patch
Patch0050: 0050-PAM-add-certificate-s-label-to-the-selection-prompt.patch
Patch0051: 0051-SYSDB-Remove-code-causing-a-covscan-warning.patch
Patch0052: 0052-SYSDB-Better-debugging-for-email-conflicts.patch
Patch0053: 0053-NSS-Use-enum_ctx-as-memory_context-in-_setnetgrent_s.patch
Patch0054: 0054-cache_req-Correction-of-cache_req-debug-string-ID-fo.patch
Patch0055: 0055-TESTS-Order-list-of-entries-in-some-lists.patch
Patch0056: 0056-TOOLS-Add-a-new-sssctl-command-access-report.patch
Patch0057: 0057-dp-use-void-to-express-empty-output-argument-list.patch
Patch0058: 0058-dp-add-method-to-refresh-access-control-rules.patch
Patch0059: 0059-ipa-implement-method-to-refresh-HBAC-rules.patch
Patch0060: 0060-ifp-add-method-to-refresh-access-control-rules-in-do.patch
Patch0061: 0061-sssctl-call-dbus-instead-of-pam-to-refresh-HBAC-rule.patch
Patch0062: 0062-SPEC-Reduce-build-time-dependencies.patch
Patch0063: 0063-WATCHDOG-Restart-providers-with-SIGUSR2-after-time-d.patch
Patch0064: 0064-mmap_cache-make-checks-independent-of-input-size.patch
Patch0065: 0065-NSS-Fix-covscan-warning.patch
Patch0066: 0066-krb5-show-error-message-for-krb5_init_context-failur.patch
Patch0067: 0067-responder-Fix-talloc-hierarchy-in-sized_output_name.patch
Patch0068: 0068-test_responder-Check-memory-leak-in-sized_output_nam.patch
Patch0069: 0069-UTIL-add-find_domain_by_object_name_ex.patch
Patch0070: 0070-ipa-handle-users-from-different-domains-in-ipa_resol.patch
Patch0071: 0071-overrides-fixes-for-sysdb_invalidate_overrides.patch
Patch0072: 0072-ipa-check-for-SYSDB_OVERRIDE_DN-in-process_members-a.patch
Patch0073: 0073-IPA-use-cache-searches-in-get_groups_dns.patch
Patch0074: 0074-ipa-compare-DNs-instead-of-group-names-in-ipa_s2n_sa.patch
Patch0075: 0075-nss-Fix-invalid-enum-nss_status-return-values.patch
Patch0076: 0076-confdb-Move-detection-files-to-separate-function.patch
Patch0077: 0077-confdb-Fix-starting-of-implicit-files-domain.patch
Patch0078: 0078-confdb-Do-not-start-implicit_files-with-proxy-domain.patch
Patch0079: 0079-test_files_provider-Regression-test-for-implicit_fil.patch
Patch0502: 0502-SYSTEMD-Use-capabilities.patch
Patch0503: 0503-Disable-stopping-idle-socket-activated-responders.patch
@ -132,6 +199,7 @@ BuildRequires: http-parser-devel
BuildRequires: libuuid-devel
BuildRequires: jansson-devel
BuildRequires: libcurl-devel
BuildRequires: gdm-pam-extensions-devel
%description
Provides a set of daemons to manage access to remote directories and
@ -852,8 +920,6 @@ done
%attr(700,root,root) %dir %{_sysconfdir}/sssd
%attr(711,root,root) %dir %{_sysconfdir}/sssd/conf.d
%ghost %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/sssd/sssd.conf
%attr(755,root,root) %dir %{_sysconfdir}/systemd/system/sssd.service.d
%config(noreplace) %{_sysconfdir}/systemd/system/sssd.service.d/journal.conf
%dir %{_sysconfdir}/logrotate.d
%config(noreplace) %{_sysconfdir}/logrotate.d/sssd
%dir %{_sysconfdir}/rwtab.d
@ -1253,6 +1319,24 @@ fi
%{_libdir}/%{name}/modules/libwbclient.so
%changelog
* Mon Dec 04 2017 Lukas Slebodnik <lslebodn@fedoraproject.org> - 1.16.0-5
- Resolves: upstream#3523 - ABRT crash - /usr/libexec/sssd/sssd_nss in
setnetgrent_result_timeout
- Resolves: upstream#3588 - sssd_nss consumes more memory until restarted
or machine swaps
- Resolves: failure in glibc tests
https://sourceware.org/bugzilla/show_bug.cgi?id=22530
- Resolves: upstream#3451 - When sssd is configured with id_provider proxy and
auth_provider ldap, login fails if the LDAP server
is not allowing anonymous binds
- Resolves: upstream#3285 - SSSD needs restart after incorrect clock is
corrected with AD
- Resolves: upstream#3586 - Give a more detailed debug and system-log message
if krb5_init_context() failed
- Resolves: rhbz#1431153 - SSSD ships a drop-in configuration snippet
in /etc/systemd/system
- Backport few upstream features from 1.16.1
* Tue Nov 21 2017 Lukas Slebodnik <lslebodn@fedoraproject.org> - 1.16.0-4
- Resolves: rhbz#1494002 - sssd_nss crashed in cache_req_search_domains_next